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~ -------------------------- */