A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
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