summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/d_resample.c
diff options
context:
space:
mode:
authorPeter D'Hoye <peter.dhoye@gmail.com>2009-05-22 21:58:48 +0000
committerPeter D'Hoye <peter.dhoye@gmail.com>2009-05-22 21:58:48 +0000
commit513389b4c1bc8afe4b2dc9947c534bfeb105e3da (patch)
tree10e673b35651ac567fed2eda0c679c7ade64cbc6 /apps/plugins/pdbox/PDa/src/d_resample.c
parent95fa7f6a2ef466444fbe3fe87efc6d5db6b77b36 (diff)
downloadrockbox-513389b4c1bc8afe4b2dc9947c534bfeb105e3da.zip
rockbox-513389b4c1bc8afe4b2dc9947c534bfeb105e3da.tar.gz
rockbox-513389b4c1bc8afe4b2dc9947c534bfeb105e3da.tar.bz2
rockbox-513389b4c1bc8afe4b2dc9947c534bfeb105e3da.tar.xz
Add FS #10214. Initial commit of the original PDa code for the GSoC Pure Data plugin project of Wincent Balin. Stripped some non-sourcefiles and added a rockbox readme that needs a bit more info from Wincent. Is added to CATEGORIES and viewers, but not yet to SUBDIRS (ie doesn't build yet)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21044 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/d_resample.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/d_resample.c450
1 files changed, 450 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/src/d_resample.c b/apps/plugins/pdbox/PDa/src/d_resample.c
new file mode 100644
index 0000000..4e617ec
--- /dev/null
+++ b/apps/plugins/pdbox/PDa/src/d_resample.c
@@ -0,0 +1,450 @@
+/* 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_sample *in = (t_sample *)(w[1]); /* original signal */
+ t_sample *out = (t_sample *)(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_sample *in = (t_sample *)(w[1]); /* original signal */
+ t_sample *out = (t_sample *)(w[2]); /* upsampled signal */
+ int up = (int)(w[3]); /* upsampling factor */
+ int parent = (int)(w[4]); /* original vectorsize */
+
+ int n=parent*up;
+ t_sample *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_sample *in = (t_sample *)(w[1]); /* original signal */
+ t_sample *out = (t_sample *)(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_sample *dum_out = out;
+ t_sample *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_sample *in = (t_sample *)(w[2]); /* original signal */
+ t_sample *out = (t_sample *)(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_sample *fp;
+ t_sample a=*x->buffer, b=*in;
+
+
+ for (n=0; n<length; n++) {
+ t_float findex = (t_float)(n+1)/up;
+ int index = findex;
+ t_sample frac=findex - index;
+ if (frac==0.)frac=1.;
+ *out++ = frac * b + (1.-frac) * a;
+ fp = in+index;
+ b=*fp;
+ a=(index)?*(fp-1):a;
+ }
+
+ *x->buffer = 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_sample *buf=x->s_vec;
+ t_freebytes(buf, x->s_n * sizeof(*buf));
+ buf = (t_sample *)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_sample *buf=x->s_vec;
+ t_freebytes(buf, x->s_n * sizeof(*buf));
+ buf = (t_sample *)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;
+}
+/* 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_sample *in = (t_sample *)(w[1]); /* original signal */
+ t_sample *out = (t_sample *)(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_sample *in = (t_sample *)(w[1]); /* original signal */
+ t_sample *out = (t_sample *)(w[2]); /* upsampled signal */
+ int up = (int)(w[3]); /* upsampling factor */
+ int parent = (int)(w[4]); /* original vectorsize */
+
+ int n=parent*up;
+ t_sample *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_sample *in = (t_sample *)(w[1]); /* original signal */
+ t_sample *out = (t_sample *)(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_sample *dum_out = out;
+ t_sample *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_sample *in = (t_sample *)(w[2]); /* original signal */
+ t_sample *out = (t_sample *)(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_sample *fp;
+ t_sample a=*x->buffer, b=*in;
+
+
+ for (n=0; n<length; n++) {
+ t_float findex = (t_float)(n+1)/up;
+ int index = findex;
+ t_sample frac=findex - index;
+ if (frac==0.)frac=1.;
+ *out++ = frac * b + (1.-frac) * a;
+ fp = in+index;
+ b=*fp;
+ a=(index)?*(fp-1):a;
+ }
+
+ *x->buffer = 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_sample *buf=x->s_vec;
+ t_freebytes(buf, x->s_n * sizeof(*buf));
+ buf = (t_sample *)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_sample *buf=x->s_vec;
+ t_freebytes(buf, x->s_n * sizeof(*buf));
+ buf = (t_sample *)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;
+}