From 57045df5fe3ec557e57dc7434ac1a07b5521bffc Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Mon, 29 Jul 2002 17:06:19 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r58, which included commits to RCS files with non-trunk default branches. svn path=/trunk/; revision=59 --- pd/src/d_resample.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 pd/src/d_resample.c (limited to 'pd/src/d_resample.c') diff --git a/pd/src/d_resample.c b/pd/src/d_resample.c new file mode 100644 index 00000000..83ed7498 --- /dev/null +++ b/pd/src/d_resample.c @@ -0,0 +1,225 @@ +/* Copyright (c) 1997-1999 Miller Puckette. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +/* upsampling/downsampling methods for inlet~/outlet~ + * + * mfg.gfd.uil + * IOhannes + * + * 2509:forum::für::umläute:2001 + */ + + + +#include "m_pd.h" + +/* --------------------- up/down-sampling --------------------- */ +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 *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 */ + 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; nbuffer = a; + return (w+6); +} + +/* ----------------------- 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) { + 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 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)); + x->bufsize = 1; + x->buffer = t_getbytes(x->bufsize*sizeof(*x->buffer)); + } + dsp_add(upsampling_perform_linear, 5, x, 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; +} -- cgit v1.2.1