comparison decoders/libmpg123/decode_ntom.c @ 562:7e08477b0fc1

MP3 decoder upgrade work. Ripped out SMPEG and mpglib support, replaced it with "mpg123.c" and libmpg123. libmpg123 is a much better version of mpglib, so it should solve all the problems about MP3's not seeking, or most modern MP3's not playing at all, etc. Since you no longer have to make a tradeoff with SMPEG for features, and SMPEG is basically rotting, I removed it from the project. There is still work to be done with libmpg123...there are MMX, 3DNow, SSE, Altivec, etc decoders which we don't have enabled at the moment, and the build system could use some work to make this compile more cleanly, etc. Still: huge win.
author Ryan C. Gordon <icculus@icculus.org>
date Fri, 30 Jan 2009 02:44:47 -0500
parents
children
comparison
equal deleted inserted replaced
561:f2985e08589c 562:7e08477b0fc1
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