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 ----