comparison decoders/libmpg123/frame.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 frame: Heap of routines dealing with the core mpg123 data structure.
3
4 copyright 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 Thomas Orgis
7 */
8
9 #include "mpg123lib_intern.h"
10 #include "getcpuflags.h"
11 #include "debug.h"
12
13 #define IGNORESHIFT 2
14
15 static void frame_fixed_reset(mpg123_handle *fr);
16
17 /* that's doubled in decode_ntom.c */
18 #define NTOM_MUL (32768)
19 #define aligned_pointer(p,type,alignment) \
20 (((char*)(p)-(char*)NULL) % (alignment)) \
21 ? (type*)((char*)(p) + (alignment) - (((char*)(p)-(char*)NULL) % (alignment))) \
22 : (type*)(p)
23 void frame_default_pars(mpg123_pars *mp)
24 {
25 mp->outscale = MAXOUTBURST;
26 #ifdef GAPLESS
27 mp->flags = MPG123_GAPLESS;
28 #else
29 mp->flags = 0;
30 #endif
31 mp->force_rate = 0;
32 mp->down_sample = 0;
33 mp->rva = 0;
34 mp->halfspeed = 0;
35 mp->doublespeed = 0;
36 mp->verbose = 0;
37 mp->icy_interval = 0;
38 #ifndef WIN32
39 mp->timeout = 0;
40 #endif
41 mp->resync_limit = 1024;
42 #ifdef FRAME_INDEX
43 mp->index_size = INDEX_SIZE;
44 #endif
45 mpg123_fmt_all(mp);
46 }
47
48 void frame_init(mpg123_handle *fr)
49 {
50 frame_init_par(fr, NULL);
51 }
52
53 void frame_init_par(mpg123_handle *fr, mpg123_pars *mp)
54 {
55 fr->own_buffer = FALSE;
56 fr->buffer.data = NULL;
57 fr->rawbuffs = NULL;
58 fr->rawdecwin = NULL;
59 fr->conv16to8_buf = NULL;
60 fr->xing_toc = NULL;
61 fr->cpu_opts.type = defopt;
62 fr->cpu_opts.class = (defopt == mmx || defopt == sse || defopt == dreidnowext) ? mmxsse : normal;
63 /* these two look unnecessary, check guarantee for synth_ntom_set_step (in control_generic, even)! */
64 fr->ntom_val[0] = NTOM_MUL>>1;
65 fr->ntom_val[1] = NTOM_MUL>>1;
66 fr->ntom_step = NTOM_MUL;
67 /* unnecessary: fr->buffer.size = fr->buffer.fill = 0; */
68 mpg123_reset_eq(fr);
69 init_icy(&fr->icy);
70 init_id3(fr);
71 /* frame_outbuffer is missing... */
72 /* frame_buffers is missing... that one needs cpu opt setting! */
73 /* after these... frame_reset is needed before starting full decode */
74 invalidate_format(&fr->af);
75 fr->rdat.r_read = NULL;
76 fr->rdat.r_lseek = NULL;
77 fr->decoder_change = 1;
78 fr->err = MPG123_OK;
79 if(mp == NULL) frame_default_pars(&fr->p);
80 else memcpy(&fr->p, mp, sizeof(struct mpg123_pars_struct));
81
82 fr->down_sample = 0; /* Initialize to silence harmless errors when debugging. */
83 frame_fixed_reset(fr); /* Reset only the fixed data, dynamic buffers are not there yet! */
84 #ifdef FRAME_INDEX
85 fi_init(&fr->index);
86 frame_index_setup(fr); /* Apply the size setting. */
87 #endif
88 }
89
90 mpg123_pars attribute_align_arg *mpg123_new_pars(int *error)
91 {
92 mpg123_pars *mp = malloc(sizeof(struct mpg123_pars_struct));
93 if(mp != NULL){ frame_default_pars(mp); if(error != NULL) *error = MPG123_OK; }
94 else if(error != NULL) *error = MPG123_OUT_OF_MEM;
95 return mp;
96 }
97
98 void attribute_align_arg mpg123_delete_pars(mpg123_pars* mp)
99 {
100 if(mp != NULL) free(mp);
101 }
102
103 int attribute_align_arg mpg123_reset_eq(mpg123_handle *mh)
104 {
105 int i;
106 mh->have_eq_settings = 0;
107 for(i=0; i < 32; ++i) mh->equalizer[0][i] = mh->equalizer[1][i] = DOUBLE_TO_REAL(1.0);
108
109 return MPG123_OK;
110 }
111
112 int frame_outbuffer(mpg123_handle *fr)
113 {
114 size_t size = mpg123_safe_buffer()*AUDIOBUFSIZE;
115 if(!fr->own_buffer) fr->buffer.data = NULL;
116 if(fr->buffer.data != NULL && fr->buffer.size != size)
117 {
118 free(fr->buffer.data);
119 fr->buffer.data = NULL;
120 }
121 fr->buffer.size = size;
122 if(fr->buffer.data == NULL) fr->buffer.data = (unsigned char*) malloc(fr->buffer.size);
123 if(fr->buffer.data == NULL)
124 {
125 fr->err = MPG123_OUT_OF_MEM;
126 return -1;
127 }
128 fr->own_buffer = TRUE;
129 fr->buffer.fill = 0;
130 return 0;
131 }
132
133 int attribute_align_arg mpg123_replace_buffer(mpg123_handle *mh, unsigned char *data, size_t size)
134 {
135 if(data == NULL || size < mpg123_safe_buffer())
136 {
137 mh->err = MPG123_BAD_BUFFER;
138 return MPG123_ERR;
139 }
140 if(mh->own_buffer && mh->buffer.data != NULL) free(mh->buffer.data);
141 mh->own_buffer = FALSE;
142 mh->buffer.data = data;
143 mh->buffer.size = size;
144 mh->buffer.fill = 0;
145 return MPG123_OK;
146 }
147
148 #ifdef FRAME_INDEX
149 int frame_index_setup(mpg123_handle *fr)
150 {
151 int ret = MPG123_ERR;
152 if(fr->p.index_size >= 0)
153 { /* Simple fixed index. */
154 fr->index.grow_size = 0;
155 debug1("resizing index to %li", fr->p.index_size);
156 ret = fi_resize(&fr->index, (size_t)fr->p.index_size);
157 debug2("index resized... %lu at %p", (unsigned long)fr->index.size, (void*)fr->index.data);
158 }
159 else
160 { /* A growing index. We give it a start, though. */
161 fr->index.grow_size = (size_t)(- fr->p.index_size);
162 if(fr->index.size < fr->index.grow_size)
163 ret = fi_resize(&fr->index, fr->index.grow_size);
164 else
165 ret = MPG123_OK; /* We have minimal size already... and since growing is OK... */
166 }
167 debug2("set up frame index of size %lu (ret=%i)", (unsigned long)fr->index.size, ret);
168
169 return ret;
170 }
171 #endif
172
173 int frame_buffers(mpg123_handle *fr)
174 {
175 int buffssize = 0;
176 debug1("frame %p buffer", (void*)fr);
177 /*
178 the used-to-be-static buffer of the synth functions, has some subtly different types/sizes
179
180 2to1, 4to1, ntom, generic, i386: real[2][2][0x110]
181 mmx, sse: short[2][2][0x110]
182 i586(_dither): 4352 bytes; int/long[2][2][0x110]
183 i486: int[2][2][17*FIR_BUFFER_SIZE]
184 altivec: static real __attribute__ ((aligned (16))) buffs[4][4][0x110]
185
186 Huh, altivec looks like fun. Well, let it be large... then, the 16 byte alignment seems to be implicit on MacOSX malloc anyway.
187 Let's make a reasonable attempt to allocate enough memory...
188 Keep in mind: biggest ones are i486 and altivec (mutually exclusive!), then follows i586 and normal real.
189 mmx/sse use short but also real for resampling.
190 Thus, minimum is 2*2*0x110*sizeof(real).
191 */
192 if(fr->cpu_opts.type == altivec) buffssize = 4*4*0x110*sizeof(real);
193 #ifdef OPT_I486
194 else if(fr->cpu_opts.type == ivier) buffssize = 2*2*17*FIR_BUFFER_SIZE*sizeof(int);
195 #endif
196 else if(fr->cpu_opts.type == ifuenf || fr->cpu_opts.type == ifuenf_dither || fr->cpu_opts.type == dreidnow)
197 buffssize = 2*2*0x110*4; /* don't rely on type real, we need 4352 bytes */
198
199 if(2*2*0x110*sizeof(real) > buffssize)
200 buffssize = 2*2*0x110*sizeof(real);
201 buffssize += 15; /* For 16-byte alignment (SSE likes that). */
202
203 if(fr->rawbuffs != NULL && fr->rawbuffss != buffssize)
204 {
205 free(fr->rawbuffs);
206 fr->rawbuffs = NULL;
207 }
208
209 if(fr->rawbuffs == NULL) fr->rawbuffs = (unsigned char*) malloc(buffssize);
210 if(fr->rawbuffs == NULL) return -1;
211 fr->rawbuffss = buffssize;
212 fr->short_buffs[0][0] = aligned_pointer(fr->rawbuffs,short,16);
213 fr->short_buffs[0][1] = fr->short_buffs[0][0] + 0x110;
214 fr->short_buffs[1][0] = fr->short_buffs[0][1] + 0x110;
215 fr->short_buffs[1][1] = fr->short_buffs[1][0] + 0x110;
216 fr->real_buffs[0][0] = aligned_pointer(fr->rawbuffs,real,16);
217 fr->real_buffs[0][1] = fr->real_buffs[0][0] + 0x110;
218 fr->real_buffs[1][0] = fr->real_buffs[0][1] + 0x110;
219 fr->real_buffs[1][1] = fr->real_buffs[1][0] + 0x110;
220 #ifdef OPT_I486
221 if(fr->cpu_opts.type == ivier)
222 {
223 fr->int_buffs[0][0] = (int*) fr->rawbuffs;
224 fr->int_buffs[0][1] = fr->int_buffs[0][0] + 17*FIR_BUFFER_SIZE;
225 fr->int_buffs[1][0] = fr->int_buffs[0][1] + 17*FIR_BUFFER_SIZE;
226 fr->int_buffs[1][1] = fr->int_buffs[1][0] + 17*FIR_BUFFER_SIZE;
227 }
228 #endif
229 #ifdef OPT_ALTIVEC
230 if(fr->cpu_opts.type == altivec)
231 {
232 int i,j;
233 fr->areal_buffs[0][0] = (real*) fr->rawbuffs;
234 for(i=0; i<4; ++i) for(j=0; j<4; ++j)
235 fr->areal_buffs[i][j] = fr->areal_buffs[0][0] + (i*4+j)*0x110;
236 }
237 #endif
238 /* now the different decwins... all of the same size, actually */
239 /* The MMX ones want 32byte alignment, which I'll try to ensure manually */
240 {
241 int decwin_size = (512+32)*sizeof(real);
242 if(fr->rawdecwin != NULL) free(fr->rawdecwin);
243 #ifdef OPT_MMXORSSE
244 #ifdef OPT_MULTI
245 if(fr->cpu_opts.class == mmxsse)
246 {
247 #endif
248 /* decwin_mmx will share, decwins will be appended ... sizeof(float)==4 */
249 if(decwin_size < (512+32)*4) decwin_size = (512+32)*4;
250 decwin_size += (512+32)*4 + 31; /* the second window + alignment zone */
251 /* (512+32)*4/32 == 2176/32 == 68, so one decwin block retains alignment */
252 #ifdef OPT_MULTI
253 }
254 #endif
255 #endif
256 fr->rawdecwin = (unsigned char*) malloc(decwin_size);
257 if(fr->rawdecwin == NULL) return -1;
258 fr->decwin = (real*) fr->rawdecwin;
259 #ifdef OPT_MMXORSSE
260 #ifdef OPT_MULTI
261 if(fr->cpu_opts.class == mmxsse)
262 {
263 #endif
264 /* align decwin, assign that to decwin_mmx, append decwins */
265 /* I need to add to decwin what is missing to the next full 32 byte -- also I want to make gcc -pedantic happy... */
266 fr->decwin = aligned_pointer(fr->rawdecwin,real,32);
267 debug1("aligned decwin: %p", (void*)fr->decwin);
268 fr->decwin_mmx = (float*)fr->decwin;
269 fr->decwins = fr->decwin_mmx+512+32;
270 #ifdef OPT_MULTI
271 }
272 else debug("no decwins/decwin_mmx for that class");
273 #endif
274 #endif
275 }
276 frame_buffers_reset(fr);
277 debug1("frame %p buffer done", (void*)fr);
278 return 0;
279 }
280
281 int frame_buffers_reset(mpg123_handle *fr)
282 {
283 fr->buffer.fill = 0; /* hm, reset buffer fill... did we do a flush? */
284 fr->bsnum = 0;
285 /* Wondering: could it be actually _wanted_ to retain buffer contents over different files? (special gapless / cut stuff) */
286 fr->bsbuf = fr->bsspace[1];
287 fr->bsbufold = fr->bsbuf;
288 fr->bitreservoir = 0; /* Not entirely sure if this is the right place for that counter. */
289 memset(fr->bsspace, 0, 2*(MAXFRAMESIZE+512));
290 memset(fr->ssave, 0, 34);
291 memset(fr->rawbuffs, 0, fr->rawbuffss);
292 fr->hybrid_blc[0] = fr->hybrid_blc[1] = 0;
293 memset(fr->hybrid_block, 0, sizeof(real)*2*2*SBLIMIT*SSLIMIT);
294 /* Not totally, but quite, sure that decwin(s) doesn't need cleaning. */
295 return 0;
296 }
297
298 void frame_icy_reset(mpg123_handle* fr)
299 {
300 if(fr->icy.data != NULL) free(fr->icy.data);
301 fr->icy.data = NULL;
302 fr->icy.interval = 0;
303 fr->icy.next = 0;
304 }
305
306 void frame_free_toc(mpg123_handle *fr)
307 {
308 if(fr->xing_toc != NULL){ free(fr->xing_toc); fr->xing_toc = NULL; }
309 }
310
311 /* Just copy the Xing TOC over... */
312 int frame_fill_toc(mpg123_handle *fr, unsigned char* in)
313 {
314 if(fr->xing_toc == NULL) fr->xing_toc = malloc(100);
315 if(fr->xing_toc != NULL)
316 {
317 memcpy(fr->xing_toc, in, 100);
318 #ifdef DEBUG
319 debug("Got a TOC! Showing the values...");
320 {
321 int i;
322 for(i=0; i<100; ++i)
323 debug2("entry %i = %i", i, fr->xing_toc[i]);
324 }
325 #endif
326 return TRUE;
327 }
328 return FALSE;
329 }
330
331 /* Prepare the handle for a new track.
332 Reset variables, buffers... */
333 int frame_reset(mpg123_handle* fr)
334 {
335 frame_buffers_reset(fr);
336 frame_fixed_reset(fr);
337 frame_free_toc(fr);
338 #ifdef FRAME_INDEX
339 fi_reset(&fr->index);
340 #endif
341
342 return 0;
343 }
344
345 /* Reset everythign except dynamic memory. */
346 static void frame_fixed_reset(mpg123_handle *fr)
347 {
348 frame_icy_reset(fr);
349 open_bad(fr);
350 fr->to_decode = FALSE;
351 fr->to_ignore = FALSE;
352 fr->metaflags = 0;
353 fr->outblock = mpg123_safe_buffer();
354 fr->num = -1;
355 fr->accurate = TRUE;
356 fr->silent_resync = 0;
357 fr->audio_start = 0;
358 fr->clip = 0;
359 fr->oldhead = 0;
360 fr->firsthead = 0;
361 fr->vbr = MPG123_CBR;
362 fr->abr_rate = 0;
363 fr->track_frames = 0;
364 fr->track_samples = -1;
365 fr->framesize=0;
366 fr->mean_frames = 0;
367 fr->mean_framesize = 0;
368 fr->freesize = 0;
369 fr->lastscale = -1;
370 fr->rva.level[0] = -1;
371 fr->rva.level[1] = -1;
372 fr->rva.gain[0] = 0;
373 fr->rva.gain[1] = 0;
374 fr->rva.peak[0] = 0;
375 fr->rva.peak[1] = 0;
376 fr->fsizeold = 0;
377 fr->firstframe = 0;
378 fr->ignoreframe = fr->firstframe-IGNORESHIFT;
379 fr->lastframe = -1;
380 fr->fresh = 1;
381 fr->new_format = 0;
382 #ifdef GAPLESS
383 frame_gapless_init(fr,0,0);
384 fr->lastoff = 0;
385 fr->firstoff = 0;
386 #endif
387 fr->bo[0] = 1; /* the usual bo */
388 fr->bo[1] = 0; /* ditherindex */
389 #ifdef OPT_I486
390 fr->bo[0] = fr->bo[1] = FIR_SIZE-1;
391 #endif
392 reset_id3(fr);
393 reset_icy(&fr->icy);
394 /* ICY stuff should go into icy.c, eh? */
395 fr->icy.interval = 0;
396 fr->icy.next = 0;
397 fr->halfphase = 0; /* here or indeed only on first-time init? */
398 }
399
400 void frame_free_buffers(mpg123_handle *fr)
401 {
402 if(fr->rawbuffs != NULL) free(fr->rawbuffs);
403 fr->rawbuffs = NULL;
404 if(fr->rawdecwin != NULL) free(fr->rawdecwin);
405 fr->rawdecwin = NULL;
406 if(fr->conv16to8_buf != NULL) free(fr->conv16to8_buf);
407 fr->conv16to8_buf = NULL;
408 }
409
410 void frame_exit(mpg123_handle *fr)
411 {
412 if(fr->own_buffer && fr->buffer.data != NULL)
413 {
414 debug1("freeing buffer at %p", (void*)fr->buffer.data);
415 free(fr->buffer.data);
416 }
417 fr->buffer.data = NULL;
418 frame_free_buffers(fr);
419 frame_free_toc(fr);
420 #ifdef FRAME_INDEX
421 fi_exit(&fr->index);
422 #endif
423 exit_id3(fr);
424 clear_icy(&fr->icy);
425 }
426
427 int attribute_align_arg mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *mi)
428 {
429 if(mh == NULL) return MPG123_ERR;
430 if(mi == NULL)
431 {
432 mh->err = MPG123_ERR_NULL;
433 return MPG123_ERR;
434 }
435 mi->version = mh->mpeg25 ? MPG123_2_5 : (mh->lsf ? MPG123_2_0 : MPG123_1_0);
436 mi->layer = mh->lay;
437 mi->rate = frame_freq(mh);
438 switch(mh->mode)
439 {
440 case 0: mi->mode = MPG123_M_STEREO; break;
441 case 1: mi->mode = MPG123_M_JOINT; break;
442 case 2: mi->mode = MPG123_M_DUAL; break;
443 case 3: mi->mode = MPG123_M_MONO; break;
444 default: error("That mode cannot be!");
445 }
446 mi->mode_ext = mh->mode_ext;
447 mi->framesize = mh->framesize+4; /* Include header. */
448 mi->flags = 0;
449 if(mh->error_protection) mi->flags |= MPG123_CRC;
450 if(mh->copyright) mi->flags |= MPG123_COPYRIGHT;
451 if(mh->extension) mi->flags |= MPG123_PRIVATE;
452 if(mh->original) mi->flags |= MPG123_ORIGINAL;
453 mi->emphasis = mh->emphasis;
454 mi->bitrate = frame_bitrate(mh);
455 mi->abr_rate = mh->abr_rate;
456 mi->vbr = mh->vbr;
457 return MPG123_OK;
458 }
459
460
461 /*
462 Fuzzy frame offset searching (guessing).
463 When we don't have an accurate position, we may use an inaccurate one.
464 Possibilities:
465 - use approximate positions from Xing TOC (not yet parsed)
466 - guess wildly from mean framesize and offset of first frame / beginning of file.
467 */
468
469 off_t frame_fuzzy_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame)
470 {
471 /* Default is to go to the beginning. */
472 off_t ret = fr->audio_start;
473 *get_frame = 0;
474
475 /* But we try to find something better. */
476 /* Xing VBR TOC works with relative positions, both in terms of audio frames and stream bytes.
477 Thus, it only works when whe know the length of things.
478 Oh... I assume the offsets are relative to the _total_ file length. */
479 if(fr->xing_toc != NULL && fr->track_frames > 0 && fr->rdat.filelen > 0)
480 {
481 /* One could round... */
482 int toc_entry = (int) ((double)want_frame*100./fr->track_frames);
483 /* It is an index in the 100-entry table. */
484 if(toc_entry < 0) toc_entry = 0;
485 if(toc_entry > 99) toc_entry = 99;
486
487 /* Now estimate back what frame we get. */
488 *get_frame = (off_t) ((double)toc_entry/100. * fr->track_frames);
489 fr->accurate = FALSE;
490 fr->silent_resync = 1;
491 /* Question: Is the TOC for whole file size (with/without ID3) or the "real" audio data only?
492 ID3v1 info could also matter. */
493 ret = (off_t) ((double)fr->xing_toc[toc_entry]/256.* fr->rdat.filelen);
494 }
495 else if(fr->mean_framesize > 0)
496 { /* Just guess with mean framesize (may be exact with CBR files). */
497 /* Query filelen here or not? */
498 fr->accurate = FALSE; /* Fuzzy! */
499 fr->silent_resync = 1;
500 *get_frame = want_frame;
501 ret = fr->audio_start+fr->mean_framesize*want_frame;
502 }
503 debug5("fuzzy: want %li of %li, get %li at %li B of %li B",
504 (long)want_frame, (long)fr->track_frames, (long)*get_frame, (long)ret, (long)(fr->rdat.filelen-fr->audio_start));
505 return ret;
506 }
507
508 /*
509 find the best frame in index just before the wanted one, seek to there
510 then step to just before wanted one with read_frame
511 do not care tabout the stuff that was in buffer but not played back
512 everything that left the decoder is counted as played
513
514 Decide if you want low latency reaction and accurate timing info or stable long-time playback with buffer!
515 */
516
517 off_t frame_index_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame)
518 {
519 /* default is file start if no index position */
520 off_t gopos = 0;
521 *get_frame = 0;
522 #ifdef FRAME_INDEX
523 /* Possibly use VBRI index, too? I'd need an example for this... */
524 if(fr->index.fill)
525 {
526 /* find in index */
527 size_t fi;
528 /* at index fi there is frame step*fi... */
529 fi = want_frame/fr->index.step;
530 if(fi >= fr->index.fill) /* If we are beyond the end of frame index...*/
531 {
532 /* When fuzzy seek is allowed, we have some limited tolerance for the frames we want to read rather then jump over. */
533 if(fr->p.flags & MPG123_FUZZY && want_frame - (fr->index.fill-1)*fr->index.step > 10)
534 {
535 gopos = frame_fuzzy_find(fr, want_frame, get_frame);
536 if(gopos > fr->audio_start) return gopos; /* Only in that case, we have a useful guess. */
537 /* Else... just continue, fuzzyness didn't help. */
538 }
539 /* Use the last available position, slowly advancing from that one. */
540 fi = fr->index.fill - 1;
541 }
542 /* We have index position, that yields frame and byte offsets. */
543 *get_frame = fi*fr->index.step;
544 gopos = fr->index.data[fi];
545 fr->accurate = TRUE; /* When using the frame index, we are accurate. */
546 }
547 else
548 {
549 #endif
550 if(fr->p.flags & MPG123_FUZZY)
551 return frame_fuzzy_find(fr, want_frame, get_frame);
552 /* A bit hackish here... but we need to be fresh when looking for the first header again. */
553 fr->firsthead = 0;
554 fr->oldhead = 0;
555 #ifdef FRAME_INDEX
556 }
557 #endif
558 debug2("index: 0x%lx for frame %li", (unsigned long)gopos, (long) *get_frame);
559 return gopos;
560 }
561
562 off_t frame_ins2outs(mpg123_handle *fr, off_t ins)
563 {
564 off_t outs = 0;
565 switch(fr->down_sample)
566 {
567 case 0:
568 case 1:
569 case 2: outs = ins>>fr->down_sample; break;
570 case 3: outs = ntom_ins2outs(fr, ins); break;
571 default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample);
572 }
573 return outs;
574 }
575
576 off_t frame_outs(mpg123_handle *fr, off_t num)
577 {
578 off_t outs = 0;
579 switch(fr->down_sample)
580 {
581 case 0:
582 case 1:
583 case 2: outs = (spf(fr)>>fr->down_sample)*num; break;
584 case 3: outs = ntom_frmouts(fr, num); break;
585 default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample);
586 }
587 return outs;
588 }
589
590 off_t frame_offset(mpg123_handle *fr, off_t outs)
591 {
592 off_t num = 0;
593 switch(fr->down_sample)
594 {
595 case 0:
596 case 1:
597 case 2: num = outs/(spf(fr)>>fr->down_sample); break;
598 case 3: num = ntom_frameoff(fr, outs); break;
599 default: error("Bad down_sample ... should not be possible!!");
600 }
601 return num;
602 }
603
604 #ifdef GAPLESS
605 /* input in _input_ samples */
606 void frame_gapless_init(mpg123_handle *fr, off_t b, off_t e)
607 {
608 fr->begin_s = b;
609 fr->end_s = e;
610 /* These will get proper values later, from above plus resampling info. */
611 fr->begin_os = 0;
612 fr->end_os = 0;
613 debug2("frame_gapless_init: from %lu to %lu samples", (long unsigned)fr->begin_s, (long unsigned)fr->end_s);
614 }
615
616 void frame_gapless_realinit(mpg123_handle *fr)
617 {
618 fr->begin_os = frame_ins2outs(fr, fr->begin_s);
619 fr->end_os = frame_ins2outs(fr, fr->end_s);
620 debug2("frame_gapless_realinit: from %lu to %lu samples", (long unsigned)fr->begin_os, (long unsigned)fr->end_os);
621 }
622 #endif
623
624 /* The frame seek... This is not simply the seek to fe*spf(fr) samples in output because we think of _input_ frames here.
625 Seek to frame offset 1 may be just seek to 200 samples offset in output since the beginning of first frame is delay/padding.
626 Hm, is that right? OK for the padding stuff, but actually, should the decoder delay be better totally hidden or not?
627 With gapless, even the whole frame position could be advanced further than requested (since Homey don't play dat). */
628 void frame_set_frameseek(mpg123_handle *fr, off_t fe)
629 {
630 fr->firstframe = fe;
631 #ifdef GAPLESS
632 if(fr->p.flags & MPG123_GAPLESS)
633 {
634 /* Take care of the beginning... */
635 off_t beg_f = frame_offset(fr, fr->begin_os);
636 if(fe <= beg_f)
637 {
638 fr->firstframe = beg_f;
639 fr->firstoff = fr->begin_os - frame_outs(fr, beg_f);
640 }
641 else fr->firstoff = 0;
642 /* The end is set once for a track at least, on the frame_set_frameseek called in get_next_frame() */
643 if(fr->end_os > 0)
644 {
645 fr->lastframe = frame_offset(fr,fr->end_os);
646 fr->lastoff = fr->end_os - frame_outs(fr, fr->lastframe);
647 } else fr->lastoff = 0;
648 } else { fr->firstoff = fr->lastoff = 0; fr->lastframe = -1; }
649 #endif
650 fr->ignoreframe = fr->lay == 3 ? fr->firstframe-IGNORESHIFT : fr->firstframe;
651 #ifdef GAPLESS
652 debug5("frame_set_frameseek: begin at %li frames and %li samples, end at %li and %li; ignore from %li",
653 (long) fr->firstframe, (long) fr->firstoff,
654 (long) fr->lastframe, (long) fr->lastoff, (long) fr->ignoreframe);
655 #else
656 debug3("frame_set_frameseek: begin at %li frames, end at %li; ignore from %li",
657 (long) fr->firstframe, (long) fr->lastframe, (long) fr->ignoreframe);
658 #endif
659 }
660
661 /* Sample accurate seek prepare for decoder. */
662 /* This gets unadjusted output samples and takes resampling into account */
663 void frame_set_seek(mpg123_handle *fr, off_t sp)
664 {
665 fr->firstframe = frame_offset(fr, sp);
666 fr->ignoreframe = fr->lay == 3 ? fr->firstframe-IGNORESHIFT : fr->firstframe;
667 #ifdef GAPLESS /* The sample offset is used for non-gapless mode, too! */
668 fr->firstoff = sp - frame_outs(fr, fr->firstframe);
669 debug5("frame_set_seek: begin at %li frames and %li samples, end at %li and %li; ignore from %li",
670 (long) fr->firstframe, (long) fr->firstoff,
671 (long) fr->lastframe, (long) fr->lastoff, (long) fr->ignoreframe);
672 #else
673 debug3("frame_set_seek: begin at %li frames, end at %li; ignore from %li",
674 (long) fr->firstframe, (long) fr->lastframe, (long) fr->ignoreframe);
675 #endif
676 }
677
678 /* to vanish */
679 void frame_outformat(mpg123_handle *fr, int format, int channels, long rate)
680 {
681 fr->af.encoding = format;
682 fr->af.rate = rate;
683 fr->af.channels = channels;
684 }
685
686 /* set synth functions for current frame, optimizations handled by opt_* macros */
687 int set_synth_functions(mpg123_handle *fr)
688 {
689 int ds = fr->down_sample;
690 int p8=0;
691 static func_synth funcs[2][4] = {
692 { NULL,
693 synth_2to1,
694 synth_4to1,
695 synth_ntom } ,
696 { NULL,
697 synth_2to1_8bit,
698 synth_4to1_8bit,
699 synth_ntom_8bit }
700 };
701 static func_synth_mono funcs_mono[2][2][4] = {
702 { { NULL ,
703 synth_2to1_mono2stereo ,
704 synth_4to1_mono2stereo ,
705 synth_ntom_mono2stereo } ,
706 { NULL ,
707 synth_2to1_8bit_mono2stereo ,
708 synth_4to1_8bit_mono2stereo ,
709 synth_ntom_8bit_mono2stereo } } ,
710 { { NULL ,
711 synth_2to1_mono ,
712 synth_4to1_mono ,
713 synth_ntom_mono } ,
714 { NULL ,
715 synth_2to1_8bit_mono ,
716 synth_4to1_8bit_mono ,
717 synth_ntom_8bit_mono } }
718 };
719
720 /* possibly non-constand entries filled here */
721 funcs[0][0] = (func_synth) opt_synth_1to1(fr);
722 funcs[1][0] = (func_synth) opt_synth_1to1_8bit(fr);
723 funcs_mono[0][0][0] = (func_synth_mono) opt_synth_1to1_mono2stereo(fr);
724 funcs_mono[0][1][0] = (func_synth_mono) opt_synth_1to1_8bit_mono2stereo(fr);
725 funcs_mono[1][0][0] = (func_synth_mono) opt_synth_1to1_mono(fr);
726 funcs_mono[1][1][0] = (func_synth_mono) opt_synth_1to1_8bit_mono(fr);
727
728 if(fr->af.encoding & MPG123_ENC_8) p8 = 1;
729 fr->synth = funcs[p8][ds];
730 fr->synth_mono = funcs_mono[fr->af.channels==2 ? 0 : 1][p8][ds];
731
732 if(p8)
733 {
734 if(make_conv16to8_table(fr) != 0)
735 {
736 /* it's a bit more work to get proper error propagation up */
737 return -1;
738 }
739 }
740 return 0;
741 }
742
743 int attribute_align_arg mpg123_volume_change(mpg123_handle *mh, double change)
744 {
745 if(mh == NULL) return MPG123_ERR;
746 return mpg123_volume(mh, change + (double) mh->p.outscale / MAXOUTBURST);
747 }
748
749 int attribute_align_arg mpg123_volume(mpg123_handle *mh, double vol)
750 {
751 if(mh == NULL) return MPG123_ERR;
752 if(vol >= 0) mh->p.outscale = (double) MAXOUTBURST * vol;
753 do_rva(mh);
754 return MPG123_OK;
755 }
756
757 static int get_rva(mpg123_handle *fr, double *peak, double *gain)
758 {
759 double p = -1;
760 double g = 0;
761 int ret = 0;
762 if(fr->p.rva)
763 {
764 int rt = 0;
765 /* Should one assume a zero RVA as no RVA? */
766 if(fr->p.rva == 2 && fr->rva.level[1] != -1) rt = 1;
767 if(fr->rva.level[rt] != -1)
768 {
769 p = fr->rva.peak[rt];
770 g = fr->rva.gain[rt];
771 ret = 1; /* Success. */
772 }
773 }
774 if(peak != NULL) *peak = p;
775 if(gain != NULL) *gain = g;
776 return ret;
777 }
778
779 /* adjust the volume, taking both fr->outscale and rva values into account */
780 void do_rva(mpg123_handle *fr)
781 {
782 double peak = 0;
783 double gain = 0;
784 scale_t newscale;
785 double rvafact = 1;
786 if(get_rva(fr, &peak, &gain))
787 {
788 if(NOQUIET && fr->p.verbose > 1) fprintf(stderr, "Note: doing RVA with gain %f\n", gain);
789 rvafact = pow(10,gain/20);
790 }
791
792 newscale = fr->p.outscale*rvafact;
793
794 /* if peak is unknown (== 0) this check won't hurt */
795 if((peak*newscale) > MAXOUTBURST)
796 {
797 newscale = (scale_t) ((double) MAXOUTBURST/peak);
798 #ifdef FLOATOUT
799 warning2("limiting scale value to %f to prevent clipping with indicated peak factor of %f", newscale, peak);
800 #else
801 warning2("limiting scale value to %li to prevent clipping with indicated peak factor of %f", newscale, peak);
802 #endif
803 }
804 /* first rva setting is forced with fr->lastscale < 0 */
805 if(newscale != fr->lastscale)
806 {
807 #ifdef FLOATOUT
808 debug3("changing scale value from %f to %f (peak estimated to %f)", fr->lastscale != -1 ? fr->lastscale : fr->p.outscale, newscale, (double) (newscale*peak));
809 #else
810 debug3("changing scale value from %li to %li (peak estimated to %li)", fr->lastscale != -1 ? fr->lastscale : fr->p.outscale, newscale, (long) (newscale*peak));
811 #endif
812 fr->lastscale = newscale;
813 opt_make_decode_tables(fr); /* the actual work */
814 }
815 }
816
817 int attribute_align_arg mpg123_getvolume(mpg123_handle *mh, double *base, double *really, double *rva_db)
818 {
819 if(mh == NULL) return MPG123_ERR;
820 if(base) *base = (double)mh->p.outscale/MAXOUTBURST;
821 if(really) *really = (double)mh->lastscale/MAXOUTBURST;
822 get_rva(mh, NULL, rva_db);
823 return MPG123_OK;
824 }
825
826 int frame_cpu_opt(mpg123_handle *fr, const char* cpu)
827 {
828 char* chosen = ""; /* the chosed decoder opt as string */
829 int auto_choose = 0;
830 int done = 0;
831 if( (cpu == NULL)
832 || (cpu[0] == 0)
833 || !strcasecmp(cpu, "auto") )
834 auto_choose = 1;
835 #ifndef OPT_MULTI
836 {
837 char **sd = mpg123_decoders(); /* this contains _one_ decoder */
838 if(!auto_choose && strcasecmp(cpu, sd[0])) done = 0;
839 else
840 {
841 chosen = sd[0];
842 done = 1;
843 }
844 }
845 #else
846 fr->cpu_opts.type = nodec;
847 /* covers any i386+ cpu; they actually differ only in the synth_1to1 function... */
848 #ifdef OPT_X86
849
850 #ifdef OPT_MMXORSSE
851 fr->cpu_opts.make_decode_tables = make_decode_tables;
852 fr->cpu_opts.init_layer3_gainpow2 = init_layer3_gainpow2;
853 fr->cpu_opts.init_layer2_table = init_layer2_table;
854 #endif
855 #ifdef OPT_3DNOW
856 fr->cpu_opts.dct36 = dct36;
857 #endif
858 #ifdef OPT_3DNOWEXT
859 fr->cpu_opts.dct36 = dct36;
860 #endif
861
862 if(cpu_i586(cpu_flags))
863 {
864 debug2("standard flags: 0x%08x\textended flags: 0x%08x", cpu_flags.std, cpu_flags.ext);
865 #ifdef OPT_3DNOWEXT
866 if( !done && (auto_choose || !strcasecmp(cpu, "3dnowext"))
867 && cpu_3dnow(cpu_flags)
868 && cpu_3dnowext(cpu_flags)
869 && cpu_mmx(cpu_flags) )
870 {
871 int go = 1;
872 if(fr->p.force_rate)
873 {
874 #if defined(K6_FALLBACK) || defined(PENTIUM_FALLBACK)
875 if(!auto_choose){ if(NOQUIET) error("I refuse to choose 3DNowExt as this will screw up with forced rate!"); }
876 else if(VERBOSE) fprintf(stderr, "Note: Not choosing 3DNowExt because flexible rate not supported.\n");
877
878 go = 0;
879 #else
880 if(NOQUIET) error("You will hear some awful sound because of flexible rate being chosen with 3DNowExt decoder!");
881 #endif
882 }
883 if(go){ /* temporary hack for flexible rate bug, not going indent this - fix it instead! */
884 chosen = "3DNowExt";
885 fr->cpu_opts.type = dreidnowext;
886 fr->cpu_opts.class = mmxsse;
887 fr->cpu_opts.dct36 = dct36_3dnowext;
888 fr->cpu_opts.synth_1to1 = synth_1to1_3dnowext;
889 fr->cpu_opts.dct64 = dct64_mmx; /* only use the 3dnow version in the synth_1to1_sse */
890 fr->cpu_opts.make_decode_tables = make_decode_tables_mmx;
891 fr->cpu_opts.init_layer3_gainpow2 = init_layer3_gainpow2_mmx;
892 fr->cpu_opts.init_layer2_table = init_layer2_table_mmx;
893 fr->cpu_opts.mpl_dct64 = dct64_3dnowext;
894 done = 1;
895 }
896 }
897 #endif
898 #ifdef OPT_SSE
899 if( !done && (auto_choose || !strcasecmp(cpu, "sse"))
900 && cpu_sse(cpu_flags) && cpu_mmx(cpu_flags) )
901 {
902 int go = 1;
903 if(fr->p.force_rate)
904 {
905 #ifdef PENTIUM_FALLBACK
906 if(!auto_choose){ if(NOQUIET) error("I refuse to choose SSE as this will screw up with forced rate!"); }
907 else if(VERBOSE) fprintf(stderr, "Note: Not choosing SSE because flexible rate not supported.\n");
908
909 go = 0;
910 #else
911 if(NOQUIET) error("You will hear some awful sound because of flexible rate being chosen with SSE decoder!");
912 #endif
913 }
914 if(go){ /* temporary hack for flexible rate bug, not going indent this - fix it instead! */
915 chosen = "SSE";
916 fr->cpu_opts.type = sse;
917 fr->cpu_opts.class = mmxsse;
918 fr->cpu_opts.synth_1to1 = synth_1to1_sse;
919 fr->cpu_opts.dct64 = dct64_mmx; /* only use the sse version in the synth_1to1_sse */
920 fr->cpu_opts.make_decode_tables = make_decode_tables_mmx;
921 fr->cpu_opts.init_layer3_gainpow2 = init_layer3_gainpow2_mmx;
922 fr->cpu_opts.init_layer2_table = init_layer2_table_mmx;
923 fr->cpu_opts.mpl_dct64 = dct64_sse;
924 done = 1;
925 }
926 }
927 #endif
928 #ifdef OPT_3DNOW
929 fr->cpu_opts.dct36 = dct36;
930 /* TODO: make autodetection for _all_ x86 optimizations (maybe just for i586+ and keep separate 486 build?) */
931 /* check cpuflags bit 31 (3DNow!) and 23 (MMX) */
932 if( !done && (auto_choose || !strcasecmp(cpu, "3dnow"))
933 && cpu_3dnow(cpu_flags) && cpu_mmx(cpu_flags) )
934 {
935 chosen = "3DNow";
936 fr->cpu_opts.type = dreidnow;
937 fr->cpu_opts.dct36 = dct36_3dnow; /* 3DNow! optimized dct36() */
938 fr->cpu_opts.synth_1to1 = synth_1to1_3dnow;
939 fr->cpu_opts.dct64 = dct64_i386; /* use the 3dnow one? */
940 done = 1;
941 }
942 #endif
943 #ifdef OPT_MMX
944 if( !done && (auto_choose || !strcasecmp(cpu, "mmx"))
945 && cpu_mmx(cpu_flags) )
946 {
947 int go = 1;
948 if(fr->p.force_rate)
949 {
950 #ifdef PENTIUM_FALLBACK
951 if(!auto_choose){ if(NOQUIET) error("I refuse to choose MMX as this will screw up with forced rate!"); }
952 else if(VERBOSE) fprintf(stderr, "Note: Not choosing MMX because flexible rate not supported.\n");
953
954 go = 0;
955 #else
956 error("You will hear some awful sound because of flexible rate being chosen with MMX decoder!");
957 #endif
958 }
959 if(go){ /* temporary hack for flexible rate bug, not going indent this - fix it instead! */
960 chosen = "MMX";
961 fr->cpu_opts.type = mmx;
962 fr->cpu_opts.class = mmxsse;
963 fr->cpu_opts.synth_1to1 = synth_1to1_mmx;
964 fr->cpu_opts.dct64 = dct64_mmx;
965 fr->cpu_opts.make_decode_tables = make_decode_tables_mmx;
966 fr->cpu_opts.init_layer3_gainpow2 = init_layer3_gainpow2_mmx;
967 fr->cpu_opts.init_layer2_table = init_layer2_table_mmx;
968 done = 1;
969 }
970 }
971 #endif
972 #ifdef OPT_I586
973 if(!done && (auto_choose || !strcasecmp(cpu, "i586")))
974 {
975 chosen = "i586/pentium";
976 fr->cpu_opts.type = ifuenf;
977 fr->cpu_opts.synth_1to1 = synth_1to1_i586;
978 fr->cpu_opts.synth_1to1_i586_asm = synth_1to1_i586_asm;
979 fr->cpu_opts.dct64 = dct64_i386;
980 done = 1;
981 }
982 #endif
983 #ifdef OPT_I586_DITHER
984 if(!done && (auto_choose || !strcasecmp(cpu, "i586_dither")))
985 {
986 chosen = "dithered i586/pentium";
987 fr->cpu_opts.type = ifuenf_dither;
988 fr->cpu_opts.synth_1to1 = synth_1to1_i586;
989 fr->cpu_opts.dct64 = dct64_i386;
990 fr->cpu_opts.synth_1to1_i586_asm = synth_1to1_i586_asm_dither;
991 done = 1;
992 }
993 #endif
994 }
995 #ifdef OPT_I486 /* that won't cooperate nicely in multi opt mode - forcing i486 in layer3.c */
996 if(!done && (auto_choose || !strcasecmp(cpu, "i486")))
997 {
998 chosen = "i486";
999 fr->cpu_opts.type = ivier;
1000 fr->cpu_opts.synth_1to1 = synth_1to1_i386; /* i486 function is special */
1001 fr->cpu_opts.dct64 = dct64_i386;
1002 done = 1;
1003 }
1004 #endif
1005 #ifdef OPT_I386
1006 if(!done && (auto_choose || !strcasecmp(cpu, "i386")))
1007 {
1008 chosen = "i386";
1009 fr->cpu_opts.type = idrei;
1010 fr->cpu_opts.synth_1to1 = synth_1to1_i386;
1011 fr->cpu_opts.dct64 = dct64_i386;
1012 done = 1;
1013 }
1014 #endif
1015
1016 if(done) /* set common x86 functions */
1017 {
1018 fr->cpu_opts.synth_1to1_mono = synth_1to1_mono_i386;
1019 fr->cpu_opts.synth_1to1_mono2stereo = synth_1to1_mono2stereo_i386;
1020 fr->cpu_opts.synth_1to1_8bit = synth_1to1_8bit_i386;
1021 fr->cpu_opts.synth_1to1_8bit_mono = synth_1to1_8bit_mono_i386;
1022 fr->cpu_opts.synth_1to1_8bit_mono2stereo = synth_1to1_8bit_mono2stereo_i386;
1023 }
1024 #endif /* OPT_X86 */
1025
1026 #ifdef OPT_ALTIVEC
1027 if(!done && (auto_choose || !strcasecmp(cpu, "altivec")))
1028 {
1029 chosen = "AltiVec";
1030 fr->cpu_opts.type = altivec;
1031 fr->cpu_opts.dct64 = dct64_altivec;
1032 fr->cpu_opts.synth_1to1 = synth_1to1_altivec;
1033 fr->cpu_opts.synth_1to1_mono = synth_1to1_mono_altivec;
1034 fr->cpu_opts.synth_1to1_mono2stereo = synth_1to1_mono2stereo_altivec;
1035 fr->cpu_opts.synth_1to1_8bit = synth_1to1_8bit_altivec;
1036 fr->cpu_opts.synth_1to1_8bit_mono = synth_1to1_8bit_mono_altivec;
1037 fr->cpu_opts.synth_1to1_8bit_mono2stereo = synth_1to1_8bit_mono2stereo_altivec;
1038 done = 1;
1039 }
1040 #endif
1041
1042 #ifdef OPT_GENERIC
1043 if(!done && (auto_choose || !strcasecmp(cpu, "generic")))
1044 {
1045 chosen = "generic";
1046 fr->cpu_opts.type = generic;
1047 fr->cpu_opts.dct64 = dct64;
1048 fr->cpu_opts.synth_1to1 = synth_1to1;
1049 fr->cpu_opts.synth_1to1_mono = synth_1to1_mono;
1050 fr->cpu_opts.synth_1to1_mono2stereo = synth_1to1_mono2stereo;
1051 fr->cpu_opts.synth_1to1_8bit = synth_1to1_8bit;
1052 fr->cpu_opts.synth_1to1_8bit_mono = synth_1to1_8bit_mono;
1053 fr->cpu_opts.synth_1to1_8bit_mono2stereo = synth_1to1_8bit_mono2stereo;
1054 done = 1;
1055 }
1056 #endif
1057 #endif
1058 if(done)
1059 {
1060 if(VERBOSE) fprintf(stderr, "Decoder: %s\n", chosen);
1061 return 1;
1062 }
1063 else
1064 {
1065 if(NOQUIET) error("Could not set optimization!");
1066 return 0;
1067 }
1068 }
1069
1070 enum optdec dectype(const char* decoder)
1071 {
1072 if(decoder == NULL) return autodec;
1073 if(!strcasecmp(decoder, "3dnowext")) return dreidnowext;
1074 if(!strcasecmp(decoder, "3dnow")) return dreidnow;
1075 if(!strcasecmp(decoder, "sse")) return sse;
1076 if(!strcasecmp(decoder, "mmx")) return mmx;
1077 if(!strcasecmp(decoder, "generic")) return generic;
1078 if(!strcasecmp(decoder, "altivec")) return altivec;
1079 if(!strcasecmp(decoder, "i386")) return idrei;
1080 if(!strcasecmp(decoder, "i486")) return ivier;
1081 if(!strcasecmp(decoder, "i586")) return ifuenf;
1082 if(!strcasecmp(decoder, "i586_dither")) return ifuenf_dither;
1083 return nodec;
1084 }
1085