[PD-cvs] pd/src d_resample.c,1.2,1.2.4.1 g_io.c,1.3.4.1,1.3.4.2 m_pd.h,1.4.4.1,1.4.4.2

IOhannes m zmölnig zmoelnig at users.sourceforge.net
Wed Nov 10 14:52:38 CET 2004


Update of /cvsroot/pure-data/pd/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20844

Modified Files:
      Tag: devel_0_38
	d_resample.c g_io.c m_pd.h 
Log Message:
added another re-sampling method: "block" (really, stupid name!) that does as follows:
downsampling: the first part of the parent signal is taken and copied 1:1; the remaining of the parent is skipped
upsampling: the parent is copied 1:1; the rest of the child is zero-padded

WHAT FOR: in fft-domain we often only work on the 1st half of the signal-vector (the other is redundant) - this will save us some CPU


Index: m_pd.h
===================================================================
RCS file: /cvsroot/pure-data/pd/src/m_pd.h,v
retrieving revision 1.4.4.1
retrieving revision 1.4.4.2
diff -C2 -d -r1.4.4.1 -r1.4.4.2
*** m_pd.h	5 Nov 2004 14:27:46 -0000	1.4.4.1
--- m_pd.h	10 Nov 2004 13:52:36 -0000	1.4.4.2
***************
*** 597,600 ****
--- 597,615 ----
  
  /* IOhannes { (up/downsampling) */
+ /* use zero-padding to generate samples inbetween */
+ #define RESAMPLE_ZERO 0
+ /* use sample-and-hold to generate samples inbetween */
+ #define RESAMPLE_HOLD 1 
+ /* use linear interpolation to generate samples inbetween */
+ #define RESAMPLE_LINEAR 2
+ /* not a real up/downsampling:
+  * upsampling: copy the original vector to the first part of the upsampled vector; the rest is zero
+  * downsampling: take the first part of the original vector as the downsampled vector
+  * WHAT FOR: we often want to process only the first half of an FFT-signal (the rest is redundant)
+  */
+ #define RESAMPLE_BLOCK 3
+ 
+ #define RESAMPLE_DEFAULT RESAMPLE_ZERO
+ 
  typedef struct _resample
  {

Index: g_io.c
===================================================================
RCS file: /cvsroot/pure-data/pd/src/g_io.c,v
retrieving revision 1.3.4.1
retrieving revision 1.3.4.2
diff -C2 -d -r1.3.4.1 -r1.3.4.2
*** g_io.c	5 Nov 2004 14:27:46 -0000	1.3.4.1
--- g_io.c	10 Nov 2004 13:52:36 -0000	1.3.4.2
***************
*** 308,314 ****
       * up till now we provide several upsampling methods and 1 single downsampling method (no filtering !)
       */
!     if (s == gensym("hold"))x->x_updown.method=1;     /* up: sample and hold */
!     else if (s == gensym("lin"))x->x_updown.method=2; /* up: linear interpolation */
!     else x->x_updown.method=0;                        /* up: zero-padding */
  
      return (x);
--- 308,323 ----
       * up till now we provide several upsampling methods and 1 single downsampling method (no filtering !)
       */
!     if (s){
!       char c=*s->s_name;
!       switch(c){
!       case 'h': case 'H': x->x_updown.method=RESAMPLE_HOLD; /* up: sample and hold */
! 	break;
!       case 'l': case 'L': x->x_updown.method=RESAMPLE_LINEAR; /* up: linear interpolation */
! 	break;
!       case 'b': case 'B': x->x_updown.method=RESAMPLE_BLOCK; /* down: ignore the 2nd half of the block */
! 	break;
!       default: x->x_updown.method=RESAMPLE_ZERO;            /* up: zero-padding */
!       }
!     }
  
      return (x);
***************
*** 615,622 ****
       * up till now we provide several upsampling methods and 1 single downsampling method (no filtering !)
       */
!     if (s == gensym("hold"))x->x_updown.method=1;        /* up: sample and hold */
!     else if (s == gensym("lin"))x->x_updown.method=2;    /* up: linear interpolation */
!     else if (s == gensym("linear"))x->x_updown.method=2; /* up: linear interpolation */
!     else x->x_updown.method=0;                           /* up: zero-padding; down: ignore samples inbetween */
  
      return (x);
--- 624,639 ----
       * up till now we provide several upsampling methods and 1 single downsampling method (no filtering !)
       */
!     if (s){
!       char c=*s->s_name;
!       switch(c){
!       case 'h': case 'H': x->x_updown.method=RESAMPLE_HOLD; /* up: sample and hold */
! 	break;
!       case 'l': case 'L': x->x_updown.method=RESAMPLE_LINEAR; /* up: linear interpolation */
! 	break;
!       case 'b': case 'B': x->x_updown.method=RESAMPLE_BLOCK; /* down: ignore the 2nd half of the block */
! 	break;
!       default: x->x_updown.method=RESAMPLE_ZERO;            /* up: zero-padding */
!       }
!     }
  
      return (x);

Index: d_resample.c
===================================================================
RCS file: /cvsroot/pure-data/pd/src/d_resample.c,v
retrieving revision 1.2
retrieving revision 1.2.4.1
diff -C2 -d -r1.2 -r1.2.4.1
*** d_resample.c	6 Sep 2004 20:20:33 -0000	1.2
--- d_resample.c	10 Nov 2004 13:52:36 -0000	1.2.4.1
***************
*** 9,12 ****
--- 9,13 ----
   *
   * 2509:forum::für::umläute:2001
+  * 0911:forum::für::umläute:2004 added block-resampling
   */
  
***************
*** 16,19 ****
--- 17,23 ----
  
  /* --------------------- up/down-sampling --------------------- */
+ 
+ /* LATER: add some downsampling-filters for HOLD and LINEAR */
+ 
  t_int *downsampling_perform_0(t_int *w)
  {
***************
*** 33,36 ****
--- 37,60 ----
  }
  
+ t_int *downsampling_perform_block(t_int *w)
+ {
+   /* the downsampled vector is exactly the first part of the parent vector
+    * the rest of the parent is just skipped
+    * cool for FFT-data, where you only want to process the significant (1st) part of the vector
+    */
+   t_float *in  = (t_float *)(w[1]); /* original signal     */
+   t_float *out = (t_float *)(w[2]); /* downsampled signal  */
+   int down     = (int)(w[3]);       /* downsampling factor */
+   int parent   = (int)(w[4]);       /* original vectorsize */
+ 
+   int n=parent/down;
+ 
+   while(n--){
+     *out++=*in++;
+   }
+ 
+   return (w+5);
+ }
+ 
  t_int *upsampling_perform_0(t_int *w)
  {
***************
*** 84,103 ****
    t_float *in  = (t_float *)(w[2]); /* original signal     */
    t_float *out = (t_float *)(w[3]); /* upsampled signal    */
!   int up       = (int)(w[4]);       /* upsampling factor   */
!   int parent   = (int)(w[5]);       /* original vectorsize */
!   int length   = parent*up;
    int n;
    t_float *fp;
!   t_float a=*x->buffer, b=*in;
  
!   
    for (n=0; n<length; n++) {
!     t_float findex = (t_float)(n+1)/up;
!     int     index  = findex;
!     t_float frac=findex - index;
!     if (frac==0.)frac=1.;
      *out++ = frac * b + (1.-frac) * a;
!     fp = in+index;
      b=*fp;
      a=(index)?*(fp-1):a;
    }
--- 108,128 ----
    t_float *in  = (t_float *)(w[2]); /* original signal     */
    t_float *out = (t_float *)(w[3]); /* upsampled signal    */
!   const int up       = (int)(w[4]);       /* upsampling factor   */
!   const int parent   = (int)(w[5]);       /* original vectorsize */
!   const int length   = parent*up;
    int n;
    t_float *fp;
!   t_float a=*x->buffer, b=*in;  
  
!   const t_float up_inv = (t_float)1.0/up;
!   t_float findex = 0.f;
    for (n=0; n<length; n++) {
!     const int index = (findex+=up_inv);
!     t_float frac=findex-index;
!     if(frac==0.)frac=1.;
      *out++ = frac * b + (1.-frac) * a;
!     fp=in+index;
      b=*fp;
+     // do we still need the last sample of the previous pointer for interpolation ?
      a=(index)?*(fp-1):a;
    }
***************
*** 107,110 ****
--- 132,159 ----
  }
  
+ t_int *upsampling_perform_block(t_int *w)
+ {
+   /* 1st part of the upsampled signal-vector will be the original one
+    * 2nd part of the upsampled signal-vector is just 0
+    * cool for FFT-data, where you only want to process the significant (1st) part of the vector
+    */
+   t_float *in  = (t_float *)(w[1]); /* original signal     */
+   t_float *out = (t_float *)(w[2]); /* upsampled signal    */
+   int up       = (int)(w[3]);       /* upsampling factor   */
+   int parent   = (int)(w[4]);       /* original vectorsize */
+   int i=parent;
+ 
+   int n=parent*(up-1);
+   
+   while (i--) {
+     *out++=*in++;
+   }
+   while(n--) {
+     *out++=0.f;
+   }
+   return (w+5);
+ }
+ 
+ 
  /* ----------------------- public -------------------------------- */
  
***************
*** 150,158 ****
      }
      switch (method) {
      default:
        dsp_add(downsampling_perform_0, 4, in, out, insize/outsize, insize);
      }
  
- 
    } else { /* upsampling */
      if (outsize % insize) {
--- 199,209 ----
      }
      switch (method) {
+     case RESAMPLE_BLOCK:
+       dsp_add(downsampling_perform_block, 4, in, out, insize/outsize, insize);
+       break;
      default:
        dsp_add(downsampling_perform_0, 4, in, out, insize/outsize, insize);
      }
  
    } else { /* upsampling */
      if (outsize % insize) {
***************
*** 161,168 ****
      }
      switch (method) {
!     case 1:
        dsp_add(upsampling_perform_hold, 4, in, out, outsize/insize, insize);
        break;
!     case 2:
        if (x->bufsize != 1) {
          t_freebytes(x->buffer, x->bufsize*sizeof(*x->buffer));
--- 212,219 ----
      }
      switch (method) {
!     case RESAMPLE_HOLD:
        dsp_add(upsampling_perform_hold, 4, in, out, outsize/insize, insize);
        break;
!     case RESAMPLE_LINEAR:
        if (x->bufsize != 1) {
          t_freebytes(x->buffer, x->bufsize*sizeof(*x->buffer));
***************
*** 172,175 ****
--- 223,229 ----
        dsp_add(upsampling_perform_linear, 5, x, in, out, outsize/insize, insize);
        break;
+     case RESAMPLE_BLOCK:
+       dsp_add(upsampling_perform_block, 4, in, out, outsize/insize, insize);
+       break;
      default:
        dsp_add(upsampling_perform_0, 4, in, out, outsize/insize, insize);
***************
*** 196,200 ****
      x->s_n   = outsize;
    }
- 
    resample_dsp(x, in, insize, x->s_vec, x->s_n, method);
    return;
--- 250,253 ----





More information about the Pd-cvs mailing list