Update of /cvsroot/pure-data/pd/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9567
Modified Files:
Tag: desiredata
d_ugen.c makefile.in
Log Message:
merged d_resample.c into d_ugen.c
Index: makefile.in
===================================================================
RCS file: /cvsroot/pure-data/pd/src/makefile.in,v
retrieving revision 1.4.4.2.2.21.2.28
retrieving revision 1.4.4.2.2.21.2.29
diff -C2 -d -r1.4.4.2.2.21.2.28 -r1.4.4.2.2.21.2.29
*** makefile.in 28 Jun 2007 08:33:34 -0000 1.4.4.2.2.21.2.28
--- makefile.in 28 Jun 2007 15:58:10 -0000 1.4.4.2.2.21.2.29
***************
*** 23,27 ****
SRCXX = desire.c kernel.c builtins.c builtins_dsp.c s_path.c s_inter.c s_main.c \
m_sched.c s_loader.c d_soundfile.c d_ugen.c
! SRC = m_fifo.c m_simd.c s_audio.c s_midi.c d_mayer_fft.c d_fftroutine.c d_resample.c
# audio drivers and midi drivers
--- 23,27 ----
SRCXX = desire.c kernel.c builtins.c builtins_dsp.c s_path.c s_inter.c s_main.c \
m_sched.c s_loader.c d_soundfile.c d_ugen.c
! SRC = m_fifo.c m_simd.c s_audio.c s_midi.c d_mayer_fft.c d_fftroutine.c
# audio drivers and midi drivers
Index: d_ugen.c
===================================================================
RCS file: /cvsroot/pure-data/pd/src/d_ugen.c,v
retrieving revision 1.3.4.1.2.5.2.8
retrieving revision 1.3.4.1.2.5.2.9
diff -C2 -d -r1.3.4.1.2.5.2.8 -r1.3.4.1.2.5.2.9
*** d_ugen.c 28 Jun 2007 15:52:02 -0000 1.3.4.1.2.5.2.8
--- d_ugen.c 28 Jun 2007 15:58:10 -0000 1.3.4.1.2.5.2.9
***************
*** 908,911 ****
--- 908,1178 ----
}
+ /* resampling code originally by Johannes Zmölnig in 2001 */
+ /* also "block-resampling" added by Johannes in 2004.09 */
+
+ #include "m_pd.h"
+
+ /* --------------------- up/down-sampling --------------------- */
+
+ /* LATER: add some downsampling-filters for HOLD and LINEAR */
+
+ t_int *downsampling_perform_0(t_int *w)
+ {
+ 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;
+ in+=down;
+ }
+
+ return (w+5);
+ }
+
+ 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)
+ {
+ 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 n=parent*up;
+ t_float *dummy = out;
+
+ while(n--)*out++=0;
+
+ n = parent;
+ out = dummy;
+ while(n--){
+ *out=*in++;
+ out+=up;
+ }
+
+ return (w+5);
+ }
+
+ t_int *upsampling_perform_hold(t_int *w)
+ {
+ 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=up;
+
+ int n=parent;
+ t_float *dum_out = out;
+ t_float *dum_in = in;
+
+ while (i--) {
+ n = parent;
+ out = dum_out+i;
+ in = dum_in;
+ while(n--){
+ *out=*in++;
+ out+=up;
+ }
+ }
+ return (w+5);
+ }
+
+ t_int *upsampling_perform_linear(t_int *w)
+ {
+ t_resample *x= (t_resample *)(w[1]);
+ 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 = int(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;
+ }
+
+ *x->buffer = a;
+ return (w+6);
+ }
+
+ 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 -------------------------------- */
+
+ /* utils */
+
+ void resample_init(t_resample *x)
+ {
+ x->method=0;
+
+ x->downsample=x->upsample=1;
+
+ x->s_n = x->coefsize = x->bufsize = 0;
+ x->s_vec = x->coeffs = x->buffer = 0;
+ }
+
+ void resample_free(t_resample *x)
+ {
+ if (x->s_n) t_freebytes(x->s_vec, x->s_n*sizeof(*x->s_vec));
+ if (x->coefsize) t_freebytes(x->coeffs, x->coefsize*sizeof(*x->coeffs));
+ if (x->bufsize) t_freebytes(x->buffer, x->bufsize*sizeof(*x->buffer));
+
+ x->s_n = x->coefsize = x->bufsize = 0;
+ x->s_vec = x->coeffs = x->buffer = 0;
+ }
+
+
+ /* dsp-adding */
+
+ void resample_dsp(t_resample *x,
+ t_sample* in, int insize,
+ t_sample* out, int outsize,
+ int method)
+ {
+ if (insize == outsize){
+ bug("nothing to be done");
+ return;
+ }
+
+ if (insize > outsize) { /* downsampling */
+ if (insize % outsize) {
+ error("bad downsampling factor");
+ return;
+ }
+ 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) {
+ error("bad upsampling factor");
+ return;
+ }
+ 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));
+ x->bufsize = 1;
+ x->buffer = (t_float *)t_getbytes(x->bufsize*sizeof(*x->buffer));
+ }
+ 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);
+ }
+ }
+ }
+
+ void resamplefrom_dsp(t_resample *x,
+ t_sample *in,
+ int insize, int outsize, int method)
+ {
+ if (insize==outsize) {
+ t_freebytes(x->s_vec, x->s_n * sizeof(*x->s_vec));
+ x->s_n = 0;
+ x->s_vec = in;
+ return;
+ }
+
+ if (x->s_n != outsize) {
+ t_float *buf=x->s_vec;
+ t_freebytes(buf, x->s_n * sizeof(*buf));
+ buf = (t_float *)t_getbytes(outsize * sizeof(*buf));
+ x->s_vec = buf;
+ x->s_n = outsize;
+ }
+ resample_dsp(x, in, insize, x->s_vec, x->s_n, method);
+ return;
+ }
+
+ void resampleto_dsp(t_resample *x,
+ t_sample *out,
+ int insize, int outsize, int method)
+ {
+ if (insize==outsize) {
+ if (x->s_n)t_freebytes(x->s_vec, x->s_n * sizeof(*x->s_vec));
+ x->s_n = 0;
+ x->s_vec = out;
+ return;
+ }
+
+ if (x->s_n != insize) {
+ t_float *buf=x->s_vec;
+ t_freebytes(buf, x->s_n * sizeof(*buf));
+ buf = (t_float *)t_getbytes(insize * sizeof(*buf));
+ x->s_vec = buf;
+ x->s_n = insize;
+ }
+
+ resample_dsp(x, x->s_vec, x->s_n, out, outsize, method);
+
+ return;
+ }
+
/* ------------------------ samplerate~ -------------------------- */