A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 226 lines 5.2 kB view raw
1/* Copyright (c) 1997-1999 Miller Puckette. 2 * For information on usage and redistribution, and for a DISCLAIMER OF ALL 3 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ 4 5/* upsampling/downsampling methods for inlet~/outlet~ 6 * 7 * mfg.gfd.uil 8 * IOhannes 9 * 10 * 2509:forum::für::umläute:2001 11 */ 12 13 14 15#include "m_pd.h" 16 17/* --------------------- up/down-sampling --------------------- */ 18t_int *downsampling_perform_0(t_int *w) 19{ 20 t_sample *in = (t_sample *)(w[1]); /* original signal */ 21 t_sample *out = (t_sample *)(w[2]); /* downsampled signal */ 22 int down = (int)(w[3]); /* downsampling factor */ 23 int parent = (int)(w[4]); /* original vectorsize */ 24 25 int n=parent/down; 26 27 while(n--){ 28 *out++=*in; 29 in+=down; 30 } 31 32 return (w+5); 33} 34 35t_int *upsampling_perform_0(t_int *w) 36{ 37 t_sample *in = (t_sample *)(w[1]); /* original signal */ 38 t_sample *out = (t_sample *)(w[2]); /* upsampled signal */ 39 int up = (int)(w[3]); /* upsampling factor */ 40 int parent = (int)(w[4]); /* original vectorsize */ 41 42 int n=parent*up; 43 t_sample *dummy = out; 44 45 while(n--)*out++=0; 46 47 n = parent; 48 out = dummy; 49 while(n--){ 50 *out=*in++; 51 out+=up; 52 } 53 54 return (w+5); 55} 56 57t_int *upsampling_perform_hold(t_int *w) 58{ 59 t_sample *in = (t_sample *)(w[1]); /* original signal */ 60 t_sample *out = (t_sample *)(w[2]); /* upsampled signal */ 61 int up = (int)(w[3]); /* upsampling factor */ 62 int parent = (int)(w[4]); /* original vectorsize */ 63 int i=up; 64 65 int n=parent; 66 t_sample *dum_out = out; 67 t_sample *dum_in = in; 68 69 while (i--) { 70 n = parent; 71 out = dum_out+i; 72 in = dum_in; 73 while(n--){ 74 *out=*in++; 75 out+=up; 76 } 77 } 78 return (w+5); 79} 80 81t_int *upsampling_perform_linear(t_int *w) 82{ 83 t_resample *x= (t_resample *)(w[1]); 84 t_sample *in = (t_sample *)(w[2]); /* original signal */ 85 t_sample *out = (t_sample *)(w[3]); /* upsampled signal */ 86 int up = (int)(w[4]); /* upsampling factor */ 87 int parent = (int)(w[5]); /* original vectorsize */ 88 int length = parent*up; 89 int n; 90 t_sample *fp; 91 t_sample a=*x->buffer, b=*in; 92 93 94 for (n=0; n<length; n++) { 95 t_float findex = (t_float)(n+1)/up; 96 int index = findex; 97 t_sample frac=findex - index; 98 if (frac==0.)frac=1.; 99 *out++ = frac * b + (1.-frac) * a; 100 fp = in+index; 101 b=*fp; 102 a=(index)?*(fp-1):a; 103 } 104 105 *x->buffer = a; 106 return (w+6); 107} 108 109/* ----------------------- public -------------------------------- */ 110 111/* utils */ 112 113void resample_init(t_resample *x) 114{ 115 x->method=0; 116 117 x->downsample=x->upsample=1; 118 119 x->s_n = x->coefsize = x->bufsize = 0; 120 x->s_vec = x->coeffs = x->buffer = 0; 121} 122 123void resample_free(t_resample *x) 124{ 125 if (x->s_n) t_freebytes(x->s_vec, x->s_n*sizeof(*x->s_vec)); 126 if (x->coefsize) t_freebytes(x->coeffs, x->coefsize*sizeof(*x->coeffs)); 127 if (x->bufsize) t_freebytes(x->buffer, x->bufsize*sizeof(*x->buffer)); 128 129 x->s_n = x->coefsize = x->bufsize = 0; 130 x->s_vec = x->coeffs = x->buffer = 0; 131} 132 133 134/* dsp-adding */ 135 136void resample_dsp(t_resample *x, 137 t_sample* in, int insize, 138 t_sample* out, int outsize, 139 int method) 140{ 141 if (insize == outsize){ 142 bug("nothing to be done"); 143 return; 144 } 145 146 if (insize > outsize) { /* downsampling */ 147 if (insize % outsize) { 148 error("bad downsampling factor"); 149 return; 150 } 151 switch (method) { 152 default: 153 dsp_add(downsampling_perform_0, 4, in, out, insize/outsize, insize); 154 } 155 156 157 } else { /* upsampling */ 158 if (outsize % insize) { 159 error("bad upsampling factor"); 160 return; 161 } 162 switch (method) { 163 case 1: 164 dsp_add(upsampling_perform_hold, 4, in, out, outsize/insize, insize); 165 break; 166 case 2: 167 if (x->bufsize != 1) { 168 t_freebytes(x->buffer, x->bufsize*sizeof(*x->buffer)); 169 x->bufsize = 1; 170 x->buffer = t_getbytes(x->bufsize*sizeof(*x->buffer)); 171 } 172 dsp_add(upsampling_perform_linear, 5, x, in, out, outsize/insize, insize); 173 break; 174 default: 175 dsp_add(upsampling_perform_0, 4, in, out, outsize/insize, insize); 176 } 177 } 178} 179 180void resamplefrom_dsp(t_resample *x, 181 t_sample *in, 182 int insize, int outsize, int method) 183{ 184 if (insize==outsize) { 185 t_freebytes(x->s_vec, x->s_n * sizeof(*x->s_vec)); 186 x->s_n = 0; 187 x->s_vec = in; 188 return; 189 } 190 191 if (x->s_n != outsize) { 192 t_sample *buf=x->s_vec; 193 t_freebytes(buf, x->s_n * sizeof(*buf)); 194 buf = (t_sample *)t_getbytes(outsize * sizeof(*buf)); 195 x->s_vec = buf; 196 x->s_n = outsize; 197 } 198 199 resample_dsp(x, in, insize, x->s_vec, x->s_n, method); 200 return; 201} 202 203void resampleto_dsp(t_resample *x, 204 t_sample *out, 205 int insize, int outsize, int method) 206{ 207 if (insize==outsize) { 208 if (x->s_n)t_freebytes(x->s_vec, x->s_n * sizeof(*x->s_vec)); 209 x->s_n = 0; 210 x->s_vec = out; 211 return; 212 } 213 214 if (x->s_n != insize) { 215 t_sample *buf=x->s_vec; 216 t_freebytes(buf, x->s_n * sizeof(*buf)); 217 buf = (t_sample *)t_getbytes(insize * sizeof(*buf)); 218 x->s_vec = buf; 219 x->s_n = insize; 220 } 221 222 resample_dsp(x, x->s_vec, x->s_n, out, outsize, method); 223 224 return; 225} 226