src/aubioshift~.c: new object for pitch shifting
authorPaul Brossier <piem@piem.org>
Tue, 20 Sep 2016 20:24:24 +0000 (22:24 +0200)
committerPaul Brossier <piem@piem.org>
Tue, 20 Sep 2016 20:24:24 +0000 (22:24 +0200)
src/aubioshift~.c [new file with mode: 0644]

diff --git a/src/aubioshift~.c b/src/aubioshift~.c
new file mode 100644 (file)
index 0000000..2c5af66
--- /dev/null
@@ -0,0 +1,101 @@
+/**
+ *
+ * a puredata wrapper for aubio_pitchshift
+ *
+ * */
+
+#include <m_pd.h>
+#define AUBIO_UNSTABLE 1
+#include <aubio/aubio.h>
+
+char aubioshift_version[] = "aubioshift~ version " PACKAGE_VERSION;
+
+static t_class *aubioshift_tilde_class;
+
+void aubioshift_tilde_setup (void);
+
+typedef struct _aubioshift_tilde
+{
+  t_object x_obj;
+  t_float transpose;
+  t_int pos; /*frames%dspblocksize*/
+  t_int hopsize;
+  aubio_pitchshift_t * pitchshift;
+  fvec_t *input;
+  fvec_t *output;
+} t_aubioshift_tilde;
+
+static t_int *aubioshift_tilde_perform(t_int *w)
+{
+  t_aubioshift_tilde *x = (t_aubioshift_tilde *)(w[1]);
+  t_sample *in  = (t_sample *)(w[2]);
+  t_sample *out = (t_sample *)(w[3]);
+  int n         = (int)(w[4]);
+  int j;
+  smpl_t transpose = (x->transpose < -23.9999) ? -23.9999 : (x->transpose > 24.) ? 24.
+    : x->transpose;
+  for (j=0;j<n;j++) {
+    /* read input */
+    fvec_set_sample(x->input, in[j], x->pos);
+    if (x->pos == x->hopsize-1) {
+      /* block loop */
+      aubio_pitchshift_set_transpose(x->pitchshift, transpose);
+      aubio_pitchshift_do(x->pitchshift, x->input, x->output);
+      /* end of block loop */
+      x->pos = -1; /* so it will be zero next j loop */
+    }
+    x->pos++;
+    /* write output */
+    *out++ = x->output->data[x->pos];
+  }
+  return (w+5);
+}
+
+static void aubioshift_tilde_dsp(t_aubioshift_tilde *x, t_signal **sp)
+{
+  dsp_add(aubioshift_tilde_perform, 4, x,
+      sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+static void aubioshift_tilde_debug(t_aubioshift_tilde *x)
+{
+  uint_t latency = aubio_pitchshift_get_latency(x->pitchshift);
+  post("aubioshift~ hopsize: %d latency: %.2fms (%d), transposition: %.4f",
+      x->hopsize, 1000.*latency/(float)sys_getsr(), latency, x->transpose);
+}
+
+static void *aubioshift_tilde_new (t_floatarg f)
+{
+  t_aubioshift_tilde *x =
+    (t_aubioshift_tilde *)pd_new(aubioshift_tilde_class);
+
+  x->transpose = (f < -23.9999) ? -23.9999 : (f > 24.) ? 24. : f;
+  x->hopsize = sys_getblksize();
+
+  x->input = (fvec_t *)new_fvec(x->hopsize);
+  x->output = (fvec_t *)new_fvec(x->hopsize);
+
+  x->pitchshift = (aubio_pitchshift_t *)new_aubio_pitchshift("default", 1.,
+      x->hopsize, (uint_t)sys_getsr());
+  aubio_pitchshift_set_transpose(x->pitchshift, x->transpose);
+
+  floatinlet_new (&x->x_obj, &x->transpose);
+  outlet_new(&x->x_obj, gensym("signal"));
+  return (void *)x;
+}
+
+void aubioshift_tilde_setup (void)
+{
+  aubioshift_tilde_class = class_new (gensym ("aubioshift~"),
+      (t_newmethod)aubioshift_tilde_new,
+      0, sizeof (t_aubioshift_tilde),
+      CLASS_DEFAULT, A_DEFFLOAT, 0);
+  class_addmethod(aubioshift_tilde_class,
+      (t_method)aubioshift_tilde_dsp,
+      gensym("dsp"), 0);
+  class_addmethod(aubioshift_tilde_class,
+      (t_method)aubioshift_tilde_debug,
+            gensym("debug"), 0);
+  CLASS_MAINSIGNALIN(aubioshift_tilde_class,
+      t_aubioshift_tilde, transpose);
+}