562
|
1 /*
|
|
2 decode_ntom.c: N->M down/up sampling. Not optimized for speed.
|
|
3
|
|
4 copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
|
|
5 see COPYING and AUTHORS files in distribution or http://mpg123.org
|
|
6 initially written by Michael Hipp
|
|
7 */
|
|
8
|
|
9 #define SAFE_NTOM /* Do not depend on off_t*off_t with big values still being in the range... */
|
|
10 #include "mpg123lib_intern.h"
|
|
11 #include "debug.h"
|
|
12
|
|
13 int synth_ntom_set_step(mpg123_handle *fr)
|
|
14 {
|
|
15 long m,n;
|
|
16 m = frame_freq(fr);
|
|
17 n = fr->af.rate;
|
|
18 if(VERBOSE2)
|
|
19 fprintf(stderr,"Init rate converter: %ld->%ld\n",m,n);
|
|
20
|
|
21 if(n > NTOM_MAX_FREQ || m > NTOM_MAX_FREQ || m <= 0 || n <= 0) {
|
|
22 if(NOQUIET) error("NtoM converter: illegal rates");
|
|
23 fr->err = MPG123_BAD_RATE;
|
|
24 return -1;
|
|
25 }
|
|
26
|
|
27 n *= NTOM_MUL;
|
|
28 fr->ntom_step = (unsigned long) n / m;
|
|
29
|
|
30 if(fr->ntom_step > (unsigned long)NTOM_MAX*NTOM_MUL) {
|
|
31 if(NOQUIET) error3("max. 1:%i conversion allowed (%lu vs %lu)!", NTOM_MAX, fr->ntom_step, (unsigned long)8*NTOM_MUL);
|
|
32 fr->err = MPG123_BAD_RATE;
|
|
33 return -1;
|
|
34 }
|
|
35
|
|
36 fr->ntom_val[0] = fr->ntom_val[1] = ntom_val(fr, fr->num);
|
|
37 return 0;
|
|
38 }
|
|
39
|
|
40 /*
|
|
41 The SAFE_NTOM does iterative loops instead of straight multiplication.
|
|
42 The safety is not just about the algorithm closely mimicking the decoder instead of applying some formula,
|
|
43 it is more about avoiding multiplication of possibly big sample offsets (a 32bit off_t could overflow too easily).
|
|
44 */
|
|
45
|
|
46 unsigned long ntom_val(mpg123_handle *fr, off_t frame)
|
|
47 {
|
|
48 off_t ntm;
|
|
49 #ifdef SAFE_NTOM /* Carry out the loop, without the threatening integer overflow. */
|
|
50 off_t f;
|
|
51 ntm = NTOM_MUL>>1; /* for frame 0 */
|
|
52 for(f=0; f<frame; ++f) /* for frame > 0 */
|
|
53 {
|
|
54 ntm += spf(fr)*fr->ntom_step;
|
|
55 ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
|
|
56 }
|
|
57 #else /* Just make one computation with overall sample offset. */
|
|
58 ntm = (NTOM_MUL>>1) + spf(fr)*frame*fr->ntom_step;
|
|
59 ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
|
|
60 #endif
|
|
61 return (unsigned long) ntm;
|
|
62 }
|
|
63
|
|
64 /* Set the ntom value for next expected frame to be decoded.
|
|
65 This is for keeping output consistent across seeks. */
|
|
66 void ntom_set_ntom(mpg123_handle *fr, off_t num)
|
|
67 {
|
|
68 fr->ntom_val[1] = fr->ntom_val[0] = ntom_val(fr, num);
|
|
69 }
|
|
70
|
|
71 /* Convert frame offset to unadjusted output sample offset. */
|
|
72 off_t ntom_frmouts(mpg123_handle *fr, off_t frame)
|
|
73 {
|
|
74 #ifdef SAFE_NTOM
|
|
75 off_t f;
|
|
76 #endif
|
|
77 off_t soff = 0;
|
|
78 off_t ntm = ntom_val(fr,0);
|
|
79 #ifdef SAFE_NTOM
|
|
80 if(frame <= 0) return 0;
|
|
81 for(f=0; f<frame; ++f)
|
|
82 {
|
|
83 ntm += spf(fr)*fr->ntom_step;
|
|
84 soff += ntm/NTOM_MUL;
|
|
85 ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
|
|
86 }
|
|
87 #else
|
|
88 soff = (ntm + frame*(off_t)spf(fr)*(off_t)fr->ntom_step)/(off_t)NTOM_MUL;
|
|
89 #endif
|
|
90 return soff;
|
|
91 }
|
|
92
|
|
93 /* Convert input samples to unadjusted output samples. */
|
|
94 off_t ntom_ins2outs(mpg123_handle *fr, off_t ins)
|
|
95 {
|
|
96 off_t soff = 0;
|
|
97 off_t ntm = ntom_val(fr,0);
|
|
98 #ifdef SAFE_NTOM
|
|
99 {
|
|
100 off_t block = spf(fr);
|
|
101 if(ins <= 0) return 0;
|
|
102 do
|
|
103 {
|
|
104 off_t nowblock = ins > block ? block : ins;
|
|
105 ntm += nowblock*fr->ntom_step;
|
|
106 soff += ntm/NTOM_MUL;
|
|
107 ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
|
|
108 ins -= nowblock;
|
|
109 } while(ins > 0);
|
|
110 }
|
|
111 #else
|
|
112 /* Beware of overflows: when off_t is 32bits, the multiplication blows too easily.
|
|
113 Of course, it blows for 64bits, too, in theory, but that's for _really_ large files. */
|
|
114 soff = ((off_t)ntm + (off_t)ins*(off_t)fr->ntom_step)/(off_t)NTOM_MUL;
|
|
115 #endif
|
|
116 return soff;
|
|
117 }
|
|
118
|
|
119 /* Determine frame offset from unadjusted output sample offset. */
|
|
120 off_t ntom_frameoff(mpg123_handle *fr, off_t soff)
|
|
121 {
|
|
122 off_t ioff = 0; /* frames or samples */
|
|
123 off_t ntm = ntom_val(fr,0);
|
|
124 #ifdef SAFE_NTOM
|
|
125 if(soff <= 0) return 0;
|
|
126 for(ioff=0; 1; ++ioff)
|
|
127 {
|
|
128 ntm += spf(fr)*fr->ntom_step;
|
|
129 if(ntm/NTOM_MUL > soff) break;
|
|
130 soff -= ntm/NTOM_MUL;
|
|
131 ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
|
|
132 }
|
|
133 return ioff;
|
|
134 #else
|
|
135 ioff = (soff*(off_t)NTOM_MUL-ntm)/(off_t)fr->ntom_step;
|
|
136 return ioff/(off_t)spf(fr);
|
|
137 #endif
|
|
138 }
|
|
139
|
|
140 /* Now to the actual decoding/synth functions... */
|
|
141
|
|
142 int synth_ntom_8bit(real *bandPtr,int channel, mpg123_handle *fr, int final)
|
|
143 {
|
|
144 sample_t samples_tmp[8*64];
|
|
145 sample_t *tmp1 = samples_tmp + channel;
|
|
146 int i,ret;
|
|
147
|
|
148 int pnt = fr->buffer.fill;
|
|
149 unsigned char *samples = fr->buffer.data;
|
|
150 fr->buffer.data = (unsigned char*) samples_tmp;
|
|
151 fr->buffer.fill = 0;
|
|
152 ret = synth_ntom(bandPtr, channel, fr, 1);
|
|
153 fr->buffer.data = samples;
|
|
154
|
|
155 samples += channel + pnt;
|
|
156 for(i=0;i<(fr->buffer.fill>>2);i++) {
|
|
157 #ifdef FLOATOUT
|
|
158 *samples = 0;
|
|
159 #else
|
|
160 *samples = fr->conv16to8[*tmp1>>AUSHIFT];
|
|
161 #endif
|
|
162 samples += 2;
|
|
163 tmp1 += 2;
|
|
164 }
|
|
165 fr->buffer.fill = pnt + (final ? fr->buffer.fill>>1 : 0);
|
|
166
|
|
167 return ret;
|
|
168 }
|
|
169
|
|
170 int synth_ntom_8bit_mono(real *bandPtr, mpg123_handle *fr)
|
|
171 {
|
|
172 sample_t samples_tmp[8*64];
|
|
173 sample_t *tmp1 = samples_tmp;
|
|
174 int i,ret;
|
|
175
|
|
176 int pnt = fr->buffer.fill;
|
|
177 unsigned char *samples = fr->buffer.data;
|
|
178 fr->buffer.data = (unsigned char*) samples_tmp;
|
|
179 fr->buffer.fill = 0;
|
|
180 ret = synth_ntom(bandPtr, 0, fr, 1);
|
|
181 fr->buffer.data = samples;
|
|
182
|
|
183 samples += pnt;
|
|
184 for(i=0;i<(fr->buffer.fill>>2);i++) {
|
|
185 #ifdef FLOATOUT
|
|
186 *samples++ = 0;
|
|
187 #else
|
|
188 *samples++ = fr->conv16to8[*tmp1>>AUSHIFT];
|
|
189 #endif
|
|
190 tmp1 += 2;
|
|
191 }
|
|
192 fr->buffer.fill = pnt + (fr->buffer.fill>>2);
|
|
193
|
|
194 return ret;
|
|
195 }
|
|
196
|
|
197 int synth_ntom_8bit_mono2stereo(real *bandPtr, mpg123_handle *fr)
|
|
198 {
|
|
199 sample_t samples_tmp[8*64];
|
|
200 sample_t *tmp1 = samples_tmp;
|
|
201 int i,ret;
|
|
202
|
|
203 int pnt = fr->buffer.fill;
|
|
204 unsigned char *samples = fr->buffer.data;
|
|
205 fr->buffer.data = (unsigned char*) samples_tmp;
|
|
206 fr->buffer.fill = 0;
|
|
207 ret = synth_ntom(bandPtr, 0, fr, 1);
|
|
208 fr->buffer.data = samples;
|
|
209
|
|
210 samples += pnt;
|
|
211 for(i=0;i<(fr->buffer.fill>>2);i++) {
|
|
212 #ifdef FLOATOUT
|
|
213 *samples++ = 0;
|
|
214 *samples++ = 0;
|
|
215 #else
|
|
216 *samples++ = fr->conv16to8[*tmp1>>AUSHIFT];
|
|
217 *samples++ = fr->conv16to8[*tmp1>>AUSHIFT];
|
|
218 #endif
|
|
219 tmp1 += 2;
|
|
220 }
|
|
221 fr->buffer.fill = pnt + (fr->buffer.fill>>1);
|
|
222
|
|
223 return ret;
|
|
224 }
|
|
225
|
|
226 int synth_ntom_mono(real *bandPtr, mpg123_handle *fr)
|
|
227 {
|
|
228 sample_t samples_tmp[8*64];
|
|
229 sample_t *tmp1 = samples_tmp;
|
|
230 int i,ret;
|
|
231
|
|
232 int pnt = fr->buffer.fill;
|
|
233 unsigned char *samples = fr->buffer.data;
|
|
234 fr->buffer.data = (unsigned char*) samples_tmp;
|
|
235 fr->buffer.fill = 0;
|
|
236 ret = synth_ntom(bandPtr, 0, fr, 1);
|
|
237 fr->buffer.data = samples;
|
|
238
|
|
239 samples += pnt;
|
|
240 for(i=0;i<(fr->buffer.fill>>2);i++) {
|
|
241 *( (sample_t *)samples) = *tmp1;
|
|
242 samples += sizeof(sample_t);
|
|
243 tmp1 += 2;
|
|
244 }
|
|
245 fr->buffer.fill = pnt + (fr->buffer.fill>>2)*sizeof(sample_t);
|
|
246
|
|
247 return ret;
|
|
248 }
|
|
249
|
|
250
|
|
251 int synth_ntom_mono2stereo(real *bandPtr, mpg123_handle *fr)
|
|
252 {
|
|
253 int i,ret;
|
|
254 int pnt1 = fr->buffer.fill;
|
|
255 unsigned char *samples = fr->buffer.data + pnt1;
|
|
256
|
|
257 ret = synth_ntom(bandPtr, 0, fr, 1);
|
|
258
|
|
259 for(i=0;i<((fr->buffer.fill-pnt1)>>2);i++) {
|
|
260 ((sample_t *)samples)[1] = ((sample_t *)samples)[0];
|
|
261 samples+=2*sizeof(sample_t);
|
|
262 }
|
|
263
|
|
264 return ret;
|
|
265 }
|
|
266
|
|
267
|
|
268 int synth_ntom(real *bandPtr,int channel, mpg123_handle *fr, int final)
|
|
269 {
|
|
270 static const int step = 2;
|
|
271 sample_t *samples = (sample_t *) (fr->buffer.data + fr->buffer.fill);
|
|
272
|
|
273 real *b0, **buf; /* (*buf)[0x110]; */
|
|
274 int clip = 0;
|
|
275 int bo1;
|
|
276 int ntom;
|
|
277
|
|
278 if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
|
|
279
|
|
280 if(!channel) {
|
|
281 fr->bo[0]--;
|
|
282 fr->bo[0] &= 0xf;
|
|
283 buf = fr->real_buffs[0];
|
|
284 ntom = fr->ntom_val[1] = fr->ntom_val[0];
|
|
285 }
|
|
286 else {
|
|
287 samples++;
|
|
288 buf = fr->real_buffs[1];
|
|
289 ntom = fr->ntom_val[1];
|
|
290 }
|
|
291
|
|
292 if(fr->bo[0] & 0x1) {
|
|
293 b0 = buf[0];
|
|
294 bo1 = fr->bo[0];
|
|
295 opt_dct64(fr)(buf[1]+((fr->bo[0]+1)&0xf),buf[0]+fr->bo[0],bandPtr);
|
|
296 }
|
|
297 else {
|
|
298 b0 = buf[1];
|
|
299 bo1 = fr->bo[0]+1;
|
|
300 opt_dct64(fr)(buf[0]+fr->bo[0],buf[1]+fr->bo[0]+1,bandPtr);
|
|
301 }
|
|
302
|
|
303
|
|
304 {
|
|
305 register int j;
|
|
306 real *window = opt_decwin(fr) + 16 - bo1;
|
|
307
|
|
308 for (j=16;j;j--,window+=0x10)
|
|
309 {
|
|
310 real sum;
|
|
311
|
|
312 ntom += fr->ntom_step;
|
|
313 if(ntom < NTOM_MUL) {
|
|
314 window += 16;
|
|
315 b0 += 16;
|
|
316 continue;
|
|
317 }
|
|
318
|
|
319 sum = REAL_MUL(*window++, *b0++);
|
|
320 sum -= REAL_MUL(*window++, *b0++);
|
|
321 sum += REAL_MUL(*window++, *b0++);
|
|
322 sum -= REAL_MUL(*window++, *b0++);
|
|
323 sum += REAL_MUL(*window++, *b0++);
|
|
324 sum -= REAL_MUL(*window++, *b0++);
|
|
325 sum += REAL_MUL(*window++, *b0++);
|
|
326 sum -= REAL_MUL(*window++, *b0++);
|
|
327 sum += REAL_MUL(*window++, *b0++);
|
|
328 sum -= REAL_MUL(*window++, *b0++);
|
|
329 sum += REAL_MUL(*window++, *b0++);
|
|
330 sum -= REAL_MUL(*window++, *b0++);
|
|
331 sum += REAL_MUL(*window++, *b0++);
|
|
332 sum -= REAL_MUL(*window++, *b0++);
|
|
333 sum += REAL_MUL(*window++, *b0++);
|
|
334 sum -= REAL_MUL(*window++, *b0++);
|
|
335
|
|
336 while(ntom >= NTOM_MUL) {
|
|
337 WRITE_SAMPLE(samples,sum,clip);
|
|
338 samples += step;
|
|
339 ntom -= NTOM_MUL;
|
|
340 }
|
|
341 }
|
|
342
|
|
343 ntom += fr->ntom_step;
|
|
344 if(ntom >= NTOM_MUL)
|
|
345 {
|
|
346 real sum;
|
|
347 sum = REAL_MUL(window[0x0], b0[0x0]);
|
|
348 sum += REAL_MUL(window[0x2], b0[0x2]);
|
|
349 sum += REAL_MUL(window[0x4], b0[0x4]);
|
|
350 sum += REAL_MUL(window[0x6], b0[0x6]);
|
|
351 sum += REAL_MUL(window[0x8], b0[0x8]);
|
|
352 sum += REAL_MUL(window[0xA], b0[0xA]);
|
|
353 sum += REAL_MUL(window[0xC], b0[0xC]);
|
|
354 sum += REAL_MUL(window[0xE], b0[0xE]);
|
|
355
|
|
356 while(ntom >= NTOM_MUL) {
|
|
357 WRITE_SAMPLE(samples,sum,clip);
|
|
358 samples += step;
|
|
359 ntom -= NTOM_MUL;
|
|
360 }
|
|
361 }
|
|
362
|
|
363 b0-=0x10,window-=0x20;
|
|
364 window += bo1<<1;
|
|
365
|
|
366 for (j=15;j;j--,b0-=0x20,window-=0x10)
|
|
367 {
|
|
368 real sum;
|
|
369
|
|
370 ntom += fr->ntom_step;
|
|
371 if(ntom < NTOM_MUL) {
|
|
372 window -= 16;
|
|
373 b0 += 16;
|
|
374 continue;
|
|
375 }
|
|
376
|
|
377 sum = REAL_MUL(-*(--window), *b0++);
|
|
378 sum -= REAL_MUL(*(--window), *b0++);
|
|
379 sum -= REAL_MUL(*(--window), *b0++);
|
|
380 sum -= REAL_MUL(*(--window), *b0++);
|
|
381 sum -= REAL_MUL(*(--window), *b0++);
|
|
382 sum -= REAL_MUL(*(--window), *b0++);
|
|
383 sum -= REAL_MUL(*(--window), *b0++);
|
|
384 sum -= REAL_MUL(*(--window), *b0++);
|
|
385 sum -= REAL_MUL(*(--window), *b0++);
|
|
386 sum -= REAL_MUL(*(--window), *b0++);
|
|
387 sum -= REAL_MUL(*(--window), *b0++);
|
|
388 sum -= REAL_MUL(*(--window), *b0++);
|
|
389 sum -= REAL_MUL(*(--window), *b0++);
|
|
390 sum -= REAL_MUL(*(--window), *b0++);
|
|
391 sum -= REAL_MUL(*(--window), *b0++);
|
|
392 sum -= REAL_MUL(*(--window), *b0++);
|
|
393
|
|
394 while(ntom >= NTOM_MUL) {
|
|
395 WRITE_SAMPLE(samples,sum,clip);
|
|
396 samples += step;
|
|
397 ntom -= NTOM_MUL;
|
|
398 }
|
|
399 }
|
|
400 }
|
|
401
|
|
402 fr->ntom_val[channel] = ntom;
|
|
403 if(final) fr->buffer.fill = ((unsigned char *) samples - fr->buffer.data - (channel ? 2 : 0));
|
|
404
|
|
405 return clip;
|
|
406 }
|
|
407
|
|
408
|