[PD-cvs] SF.net SVN: pure-data:[10338] trunk/externals/iem/iemmatrix/src/ mtx_dispersive_dline.c

fzotter at users.sourceforge.net fzotter at users.sourceforge.net
Wed Oct 22 14:44:32 CEST 2008


Revision: 10338
          http://pure-data.svn.sourceforge.net/pure-data/?rev=10338&view=rev
Author:   fzotter
Date:     2008-10-22 12:44:32 +0000 (Wed, 22 Oct 2008)

Log Message:
-----------
added allpass chain, dispersive delay line matrix object [mtx_dispersive_dline] for warped frequency analysis.

Added Paths:
-----------
    trunk/externals/iem/iemmatrix/src/mtx_dispersive_dline.c

Added: trunk/externals/iem/iemmatrix/src/mtx_dispersive_dline.c
===================================================================
--- trunk/externals/iem/iemmatrix/src/mtx_dispersive_dline.c	                        (rev 0)
+++ trunk/externals/iem/iemmatrix/src/mtx_dispersive_dline.c	2008-10-22 12:44:32 UTC (rev 10338)
@@ -0,0 +1,242 @@
+/******************************************************
+ *
+ * warped delay line
+ *
+ *   written by Franz Zotter
+ *
+ *   2007
+ *
+ *   institute of electronic music and acoustics (iem)
+ *
+ ******************************************************
+ *
+ * license: GNU General Public License v.2
+ *
+ ******************************************************/
+
+
+/* ------------------------ mtx_dispersive_dline~ ----------------------------- */
+
+/* builds a tap vector with first order all-passes A instead of unit delays.
+ * 'ha *' denotes the convolution with the impulse response of A. The chain is of
+ * length L
+   {x[n]} -> {... ha * ha * x[n], ha * x[n], x[n]} 
+
+   especially useful for frequency warped ffts
+
+   All-pass z-Transform A(z)=(1+lambda*z)/(z-lambda), lambda ... input parameter
+   
+inlet:  is a signal matrix with C rows (number of channels) and N columns (samples)
+outlet: C rows and L colums matrix with current state of the dispersive delay 
+   line after computing the N imput samples. It is possible to capture 
+   the list outlet every sample when using a column (sample) vector as input matrix.
+ 
+   creation input parameters are:
+
+1: L ...        length of allpass chain
+2: lambda ...   alpass/warping parameter
+
+
+*/
+
+#include "m_pd.h"
+
+static t_class *mtx_dispersive_dline_class;
+
+typedef struct _mtx_dispersive_dline
+{
+  t_object x_obj;
+  t_float lambda;
+  int length;
+  int channels;
+  int size;
+  t_float *z;
+  t_float *tap;
+  t_atom *list_out;
+  t_outlet *list_outlet;
+} t_mtx_dispersive_dline;
+
+static void mtx_dispersive_dline_bang (t_mtx_dispersive_dline *x)
+{
+   int count;
+   t_atom *list = x->list_out;
+   SETFLOAT(list, (t_float) x->channels);
+   SETFLOAT(list+1, (t_float) x->length);
+
+   list+=2;
+   for (count=0; count < x->size; count++)
+      SETFLOAT(&list[count],x->tap[count]);
+   outlet_anything (x->list_outlet, gensym("matrix"), x->size+2, x->list_out);
+
+}
+
+static void mtx_dispersive_dline_set_lambda(t_mtx_dispersive_dline *x, t_floatarg f)
+{
+  if ((f<1.0f)&&(f>-1.0f))
+	  x->lambda = f;
+  else
+	  post("mtx_dispersive_dline: stable allpass coefficient must be -1<lambda<1");
+}
+
+static void mtx_dispersive_dline_reset(t_mtx_dispersive_dline *x)
+{
+   int count;
+   for (count=0;count<x->size;count++) {
+      x->tap[count]=0;
+      x->z[count]=0;
+   }
+}
+
+static void mtx_dispersive_dline_delete(t_mtx_dispersive_dline *x)
+{
+      if(x->list_out)freebytes(x->list_out, sizeof(t_atom)*(x->size+2));
+      if(x->tap)freebytes(x->tap, sizeof(t_float)*x->size);
+      if(x->z)freebytes(x->z, sizeof(t_float)*x->size);
+      x->z=0;
+      x->tap=0;
+      x->list_out=0;
+}
+
+
+static void mtx_dispersive_dline_resize(t_mtx_dispersive_dline *x, t_symbol *s,
+      int argc, t_atom *argv)
+{
+   int length=(int)atom_getfloat(argv);
+   int channels=x->channels;
+   int size=length*channels;
+
+   if (argc>1) {
+      channels=(int)atom_getfloat(argv+1);
+      size=length*channels;
+      if ((channels<1)||(channels>1000)) {
+	 post("mtx_dispersive_dline: number of channels (input rows) must lie between 1 and 1000!");
+	 return; 
+      }
+   }
+
+   if ((length<1)||(length>10000)) {
+	  post("mtx_dispersive_dline: length not between 1 and 10000!");
+	  return;
+   }
+   if ((x->size!=size)) {
+      mtx_dispersive_dline_delete(x);
+      if(!(x->list_out=(t_atom*) getbytes(sizeof(t_atom)*(size+2)))) {
+	 post("mtx_dispersive_dline: out of memory");
+	 mtx_dispersive_dline_delete(x);
+	 return;
+      }
+      if(!(x->tap=(t_float*) getbytes(sizeof(t_float)*size))) {
+	 post("mtx_dispersive_dline: out of memory");
+	 mtx_dispersive_dline_delete(x);
+	 return;
+      }
+      if(!(x->z = (t_float*) getbytes(sizeof(t_float)*size))) {
+	 post("mtx_dispersive_dline: out of memory");
+	 mtx_dispersive_dline_delete(x);
+	 return;
+      }
+      x->length=length;
+      x->channels=channels;
+      x->size=size;
+   }
+}
+
+static allpass_chain_cycle (t_float x, t_float *y, t_float *z, int n, t_float a) {
+	t_float w, in;
+        int c;
+	in = y[0] = x;
+        // z[0] unused here
+	for (c=1; c<n; c++) {
+		w  = in + a * z[c]; 
+		in = y[c] = z[c] - a * w;
+		z[c] = w;
+	}
+}
+
+static mtx_dispersive_dline_matrix(t_mtx_dispersive_dline *x, t_symbol *s,
+      int argc, t_atom *argv)
+{
+  int channels=(int)atom_getfloat(argv);
+  int samples=(int)atom_getfloat(argv+1);
+  int c,n,n2;
+  t_atom resize_msg[2];
+  
+  if (channels*samples>argc) {
+     post("mtx_dispersive_dline: corrupt matrix passed");
+     return;
+  }
+  post("%d samples, %d channels",samples,channels);
+
+  SETFLOAT(resize_msg,(t_float)x->length);
+  SETFLOAT(resize_msg+1,(t_float)channels);
+  mtx_dispersive_dline_resize(x,gensym("resize"),2,resize_msg);
+
+  post("%d new size",x->size);
+
+  argv+=2;
+  for (c=0, n2=0; c<x->size; c+=x->length) {
+     for (n=0; n<samples; n++, n2++) {
+         allpass_chain_cycle (atom_getfloat(argv+n2),x->tap+c,x->z+c,x->length,x->lambda); 
+     }
+  }
+
+  mtx_dispersive_dline_bang(x);
+}
+
+static void mtx_dispersive_dline_helper(void)
+{
+  post("\n%c mtx_dispersive_dline~-object for warping a signal");
+  post("'help' : view this\n"
+       "signal~");
+  post("outlet : signal~");
+}
+
+static void *mtx_dispersive_dline_new(t_symbol *s, int argc, t_atom *argv)
+{
+  t_mtx_dispersive_dline *x = (t_mtx_dispersive_dline *)pd_new(mtx_dispersive_dline_class);
+  x->list_outlet = outlet_new(&x->x_obj, &s_list);
+  t_float length=1;
+  t_float lambda=0;
+  t_atom resize_msg[2];
+  switch ((argc>2)?2:argc)
+  {
+     case 2:
+	lambda=atom_getfloat(argv+1);
+     case 1:
+	length=atom_getfloat(argv);
+  }
+   
+  x->length=0;
+  x->channels=0;
+  x->size=0;
+  x->z=0;
+  x->tap=0;
+  x->list_out=0;
+  mtx_dispersive_dline_set_lambda (x,lambda);
+  SETFLOAT(resize_msg,(t_float)length);
+  SETFLOAT(resize_msg+1,(t_float)1);
+  mtx_dispersive_dline_resize (x,gensym("resize"),2,resize_msg);
+  mtx_dispersive_dline_reset (x);
+  return (x);
+}
+
+void mtx_dispersive_dline_setup(void)
+{
+  mtx_dispersive_dline_class = class_new(
+	gensym("mtx_dispersive_dline"), 
+	(t_newmethod)mtx_dispersive_dline_new, 
+	(t_method)mtx_dispersive_dline_delete,
+	sizeof(t_mtx_dispersive_dline),
+	CLASS_DEFAULT,
+	A_GIMME,0);
+  class_addmethod (mtx_dispersive_dline_class, (t_method) mtx_dispersive_dline_matrix, 
+	gensym("matrix"),A_GIMME,0);
+  class_addmethod (mtx_dispersive_dline_class, (t_method) mtx_dispersive_dline_reset, 
+	gensym("reset"), 0); 
+  class_addmethod (mtx_dispersive_dline_class, (t_method) mtx_dispersive_dline_resize, 
+	gensym("resize"), A_GIMME,0); 
+  class_addmethod (mtx_dispersive_dline_class, (t_method) mtx_dispersive_dline_set_lambda, 
+	gensym("lambda"), A_DEFFLOAT,0); 
+ 
+  class_addmethod(mtx_dispersive_dline_class, (t_method)mtx_dispersive_dline_helper, gensym("help"), 0);
+}


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Pd-cvs mailing list