Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/mpg123/src/libmpg123/frame.c
4394 views
1
/*
2
frame: Heap of routines dealing with the core mpg123 data structure.
3
4
copyright 2008-2023 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
#define WANT_GETCPUFLAGS
10
#include "mpg123lib_intern.h"
11
#include "getcpuflags.h"
12
#include "../common/debug.h"
13
14
static void frame_fixed_reset(mpg123_handle *fr);
15
16
/* that's doubled in decode_ntom.c */
17
#define NTOM_MUL (32768)
18
19
#define aligned_pointer(p, type, alignment) align_the_pointer(p, alignment)
20
static void *align_the_pointer(void *base, unsigned int alignment)
21
{
22
/*
23
Work in unsigned integer realm, explicitly.
24
Tricking the compiler into integer operations like % by invoking base-NULL is dangerous: It results into ptrdiff_t, which gets negative on big addresses. Big screw up, that.
25
I try to do it "properly" here: Casting only to uintptr_t and no artihmethic with void*.
26
*/
27
uintptr_t baseval = (uintptr_t)(char*)base;
28
uintptr_t aoff = baseval % alignment;
29
30
debug3("align_the_pointer: pointer %p is off by %u from %u",
31
base, (unsigned int)aoff, alignment);
32
33
if(aoff) return (char*)base+alignment-aoff;
34
else return base;
35
}
36
37
static void frame_default_pars(mpg123_pars *mp)
38
{
39
mp->outscale = 1.0;
40
mp->flags = 0;
41
#ifdef GAPLESS
42
mp->flags |= MPG123_GAPLESS;
43
#endif
44
mp->flags |= MPG123_AUTO_RESAMPLE|MPG123_FLOAT_FALLBACK;
45
#ifndef NO_NTOM
46
mp->force_rate = 0;
47
#endif
48
mp->down_sample = 0;
49
mp->rva = 0;
50
mp->halfspeed = 0;
51
mp->doublespeed = 0;
52
mp->verbose = 0;
53
#ifndef NO_ICY
54
mp->icy_interval = 0;
55
#endif
56
mp->timeout = 0;
57
mp->resync_limit = 1024;
58
#ifdef FRAME_INDEX
59
mp->index_size = INDEX_SIZE;
60
#endif
61
mp->preframes = 4; /* That's good for layer 3 ISO compliance bitstream. */
62
mpg123_fmt_all(mp);
63
/* Default of keeping some 4K buffers at hand, should cover the "usual" use case (using 16K pipe buffers as role model). */
64
#ifndef NO_FEEDER
65
mp->feedpool = 5;
66
mp->feedbuffer = 4096;
67
#endif
68
mp->freeformat_framesize = -1;
69
}
70
71
void INT123_frame_init(mpg123_handle *fr)
72
{
73
INT123_frame_init_par(fr, NULL);
74
}
75
76
void INT123_frame_init_par(mpg123_handle *fr, mpg123_pars *mp)
77
{
78
fr->own_buffer = TRUE;
79
fr->buffer.data = NULL;
80
fr->buffer.rdata = NULL;
81
fr->buffer.fill = 0;
82
fr->buffer.size = 0;
83
fr->rawbuffs = NULL;
84
fr->rawbuffss = 0;
85
fr->rawdecwin = NULL;
86
fr->rawdecwins = 0;
87
#ifdef REAL_IS_FIXED
88
fr->gainpow2 = NULL; // At least crash early if I get it wrong.
89
#endif
90
#ifndef NO_8BIT
91
fr->conv16to8_buf = NULL;
92
#endif
93
#ifdef OPT_DITHER
94
fr->dithernoise = NULL;
95
#endif
96
fr->layerscratch = NULL;
97
fr->xing_toc = NULL;
98
#ifdef OPT_CPU_FLAGS
99
wrap_getcpuflags(&(fr->cpu_flags));
100
#endif
101
fr->cpu_opts.type = INT123_defdec();
102
fr->cpu_opts.class = INT123_decclass(fr->cpu_opts.type);
103
#ifndef NO_NTOM
104
/* these two look unnecessary, check guarantee for INT123_synth_ntom_set_step (in control_generic, even)! */
105
fr->INT123_ntom_val[0] = NTOM_MUL>>1;
106
fr->INT123_ntom_val[1] = NTOM_MUL>>1;
107
fr->ntom_step = NTOM_MUL;
108
#endif
109
/* unnecessary: fr->buffer.size = fr->buffer.fill = 0; */
110
mpg123_reset_eq(fr);
111
INT123_init_icy(&fr->icy);
112
INT123_init_id3(fr);
113
/* INT123_frame_outbuffer is missing... */
114
/* INT123_frame_buffers is missing... that one needs cpu opt setting! */
115
/* after these... INT123_frame_reset is needed before starting full decode */
116
INT123_invalidate_format(&fr->af);
117
fr->rdat.iohandle = NULL;
118
fr->rdat.r_read64 = NULL;
119
fr->rdat.r_lseek64 = NULL;
120
fr->rdat.cleanup_handle = NULL;
121
fr->wrapperdata = NULL;
122
fr->decoder_change = 1;
123
fr->err = MPG123_OK;
124
if(mp == NULL) frame_default_pars(&fr->p);
125
else memcpy(&fr->p, mp, sizeof(struct mpg123_pars_struct));
126
127
#ifndef NO_FEEDER
128
INT123_bc_prepare(&fr->rdat.buffer, fr->p.feedpool, fr->p.feedbuffer);
129
#endif
130
131
fr->down_sample = 0; /* Initialize to silence harmless errors when debugging. */
132
fr->id3v2_raw = NULL;
133
frame_fixed_reset(fr); /* Reset only the fixed data, dynamic buffers are not there yet! */
134
fr->synth = NULL;
135
fr->synth_mono = NULL;
136
fr->INT123_make_decode_tables = NULL;
137
#ifdef FRAME_INDEX
138
INT123_fi_init(&fr->index);
139
INT123_frame_index_setup(fr); /* Apply the size setting. */
140
#endif
141
#ifndef NO_MOREINFO
142
fr->pinfo = NULL;
143
#endif
144
}
145
146
#ifdef OPT_DITHER
147
/* Also, only allocate the memory for the table on demand.
148
In future, one could create special noise for different sampling frequencies(?). */
149
int INT123_frame_dither_init(mpg123_handle *fr)
150
{
151
/* run-time dither noise table generation */
152
if(fr->dithernoise == NULL)
153
{
154
fr->dithernoise = malloc(sizeof(float)*DITHERSIZE);
155
if(fr->dithernoise == NULL) return 0;
156
157
INT123_dither_table_init(fr->dithernoise);
158
}
159
return 1;
160
}
161
#endif
162
163
mpg123_pars attribute_align_arg *mpg123_new_pars(int *error)
164
{
165
mpg123_pars *mp = malloc(sizeof(struct mpg123_pars_struct));
166
if(mp != NULL){ frame_default_pars(mp); if(error != NULL) *error = MPG123_OK; }
167
else if(error != NULL) *error = MPG123_OUT_OF_MEM;
168
return mp;
169
}
170
171
void attribute_align_arg mpg123_delete_pars(mpg123_pars* mp)
172
{
173
if(mp != NULL) free(mp);
174
}
175
176
int attribute_align_arg mpg123_reset_eq(mpg123_handle *mh)
177
{
178
if(mh == NULL) return MPG123_BAD_HANDLE;
179
#ifndef NO_EQUALIZER
180
int i;
181
mh->have_eq_settings = 0;
182
for(i=0; i < 32; ++i) mh->equalizer[0][i] = mh->equalizer[1][i] = DOUBLE_TO_REAL(1.0);
183
#endif
184
return MPG123_OK;
185
}
186
187
int INT123_frame_outbuffer(mpg123_handle *fr)
188
{
189
size_t size = fr->outblock;
190
if(!fr->own_buffer)
191
{
192
if(fr->buffer.size < size)
193
{
194
fr->err = MPG123_BAD_BUFFER;
195
if(NOQUIET)
196
merror("have external buffer of size %zu, need %zu", fr->buffer.size, size);
197
return MPG123_ERR;
198
}
199
}
200
201
debug1("need frame buffer of %zu", size);
202
if(fr->buffer.rdata != NULL && fr->buffer.size != size)
203
{
204
free(fr->buffer.rdata);
205
fr->buffer.rdata = NULL;
206
}
207
fr->buffer.size = size;
208
fr->buffer.data = NULL;
209
/* be generous: use 16 byte alignment */
210
if(fr->buffer.rdata == NULL) fr->buffer.rdata = (unsigned char*) malloc(fr->buffer.size+15);
211
if(fr->buffer.rdata == NULL)
212
{
213
fr->err = MPG123_OUT_OF_MEM;
214
return MPG123_ERR;
215
}
216
fr->buffer.data = aligned_pointer(fr->buffer.rdata, unsigned char*, 16);
217
fr->own_buffer = TRUE;
218
fr->buffer.fill = 0;
219
return MPG123_OK;
220
}
221
222
int attribute_align_arg mpg123_replace_buffer(mpg123_handle *mh, void *data, size_t size)
223
{
224
debug2("replace buffer with %p size %zu", data, size);
225
if(mh == NULL) return MPG123_BAD_HANDLE;
226
/* Will accept any size, the error comes later... */
227
if(data == NULL)
228
{
229
mh->err = MPG123_BAD_BUFFER;
230
return MPG123_ERR;
231
}
232
if(mh->buffer.rdata != NULL) free(mh->buffer.rdata);
233
mh->own_buffer = FALSE;
234
mh->buffer.rdata = NULL;
235
mh->buffer.data = data;
236
mh->buffer.size = size;
237
mh->buffer.fill = 0;
238
return MPG123_OK;
239
}
240
241
#ifdef FRAME_INDEX
242
int INT123_frame_index_setup(mpg123_handle *fr)
243
{
244
int ret = MPG123_ERR;
245
if(fr->p.index_size >= 0)
246
{ /* Simple fixed index. */
247
fr->index.grow_size = 0;
248
ret = INT123_fi_resize(&fr->index, (size_t)fr->p.index_size);
249
}
250
else
251
{ /* A growing index. We give it a start, though. */
252
fr->index.grow_size = (size_t)(- fr->p.index_size);
253
if(fr->index.size < fr->index.grow_size)
254
ret = INT123_fi_resize(&fr->index, fr->index.grow_size);
255
else
256
ret = MPG123_OK; /* We have minimal size already... and since growing is OK... */
257
}
258
debug2("set up frame index of size %lu (ret=%i)", (unsigned long)fr->index.size, ret);
259
if(ret && NOQUIET)
260
error("frame index setup (initial resize) failed");
261
return ret;
262
}
263
#endif
264
265
static void frame_decode_buffers_reset(mpg123_handle *fr)
266
{
267
if(fr->rawbuffs) /* memset(NULL, 0, 0) not desired */
268
memset(fr->rawbuffs, 0, fr->rawbuffss);
269
}
270
271
int INT123_frame_buffers(mpg123_handle *fr)
272
{
273
int buffssize = 0;
274
debug1("frame %p buffer", (void*)fr);
275
/*
276
the used-to-be-static buffer of the synth functions, has some subtly different types/sizes
277
278
2to1, 4to1, ntom, generic, i386: real[2][2][0x110]
279
mmx, sse: short[2][2][0x110]
280
i586(_dither): 4352 bytes; int/long[2][2][0x110]
281
i486: int[2][2][17*FIR_BUFFER_SIZE]
282
altivec: static real __attribute__ ((aligned (16))) buffs[4][4][0x110]
283
284
Huh, altivec looks like fun. Well, let it be large... then, the 16 byte alignment seems to be implicit on MacOSX malloc anyway.
285
Let's make a reasonable attempt to allocate enough memory...
286
Keep in mind: biggest ones are i486 and altivec (mutually exclusive!), then follows i586 and normal real.
287
mmx/sse use short but also real for resampling.
288
Thus, minimum is 2*2*0x110*sizeof(real).
289
*/
290
if(fr->cpu_opts.type == altivec) buffssize = 4*4*0x110*sizeof(real);
291
#ifdef OPT_I486
292
else if(fr->cpu_opts.type == ivier) buffssize = 2*2*17*FIR_BUFFER_SIZE*sizeof(int);
293
#endif
294
else if(fr->cpu_opts.type == ifuenf || fr->cpu_opts.type == ifuenf_dither || fr->cpu_opts.type == dreidnow)
295
buffssize = 2*2*0x110*4; /* don't rely on type real, we need 4352 bytes */
296
297
if(2*2*0x110*sizeof(real) > buffssize)
298
buffssize = 2*2*0x110*sizeof(real);
299
buffssize += 15; /* For 16-byte alignment (SSE likes that). */
300
301
if(fr->rawbuffs != NULL && fr->rawbuffss != buffssize)
302
{
303
free(fr->rawbuffs);
304
fr->rawbuffs = NULL;
305
}
306
307
if(fr->rawbuffs == NULL) fr->rawbuffs = (unsigned char*) malloc(buffssize);
308
if(fr->rawbuffs == NULL) return -1;
309
fr->rawbuffss = buffssize;
310
fr->short_buffs[0][0] = aligned_pointer(fr->rawbuffs,short,16);
311
fr->short_buffs[0][1] = fr->short_buffs[0][0] + 0x110;
312
fr->short_buffs[1][0] = fr->short_buffs[0][1] + 0x110;
313
fr->short_buffs[1][1] = fr->short_buffs[1][0] + 0x110;
314
fr->real_buffs[0][0] = aligned_pointer(fr->rawbuffs,real,16);
315
fr->real_buffs[0][1] = fr->real_buffs[0][0] + 0x110;
316
fr->real_buffs[1][0] = fr->real_buffs[0][1] + 0x110;
317
fr->real_buffs[1][1] = fr->real_buffs[1][0] + 0x110;
318
#ifdef OPT_I486
319
if(fr->cpu_opts.type == ivier)
320
{
321
fr->int_buffs[0][0] = (int*) fr->rawbuffs;
322
fr->int_buffs[0][1] = fr->int_buffs[0][0] + 17*FIR_BUFFER_SIZE;
323
fr->int_buffs[1][0] = fr->int_buffs[0][1] + 17*FIR_BUFFER_SIZE;
324
fr->int_buffs[1][1] = fr->int_buffs[1][0] + 17*FIR_BUFFER_SIZE;
325
}
326
#endif
327
#ifdef OPT_ALTIVEC
328
if(fr->cpu_opts.type == altivec)
329
{
330
int i,j;
331
fr->areal_buffs[0][0] = (real*) fr->rawbuffs;
332
for(i=0; i<4; ++i) for(j=0; j<4; ++j)
333
fr->areal_buffs[i][j] = fr->areal_buffs[0][0] + (i*4+j)*0x110;
334
}
335
#endif
336
/* now the different decwins... all of the same size, actually */
337
/* The MMX ones want 32byte alignment, which I'll try to ensure manually */
338
{
339
int decwin_size = (512+32)*sizeof(real);
340
#ifdef OPT_MMXORSSE
341
#ifdef OPT_MULTI
342
if(fr->cpu_opts.class == mmxsse)
343
{
344
#endif
345
/* decwin_mmx will share, decwins will be appended ... sizeof(float)==4 */
346
if(decwin_size < (512+32)*4) decwin_size = (512+32)*4;
347
348
/* the second window + alignment zone -- we align for 32 bytes for SSE as
349
requirement, 64 byte for matching cache line size (that matters!) */
350
decwin_size += (512+32)*4 + 63;
351
/* (512+32)*4/32 == 2176/32 == 68, so one decwin block retains alignment for 32 or 64 bytes */
352
#ifdef OPT_MULTI
353
}
354
#endif
355
#endif
356
#if defined(OPT_ALTIVEC) || defined(OPT_ARM)
357
/* sizeof(real) >= 4 ... yes, it could be 8, for example.
358
We got it intialized to at least (512+32)*sizeof(real).*/
359
decwin_size += 512*sizeof(real);
360
#endif
361
/* Hm, that's basically realloc() ... */
362
if(fr->rawdecwin != NULL && fr->rawdecwins != decwin_size)
363
{
364
free(fr->rawdecwin);
365
fr->rawdecwin = NULL;
366
}
367
368
if(fr->rawdecwin == NULL)
369
fr->rawdecwin = (unsigned char*) malloc(decwin_size);
370
371
if(fr->rawdecwin == NULL) return -1;
372
373
fr->rawdecwins = decwin_size;
374
fr->decwin = (real*) fr->rawdecwin;
375
#ifdef OPT_MMXORSSE
376
#ifdef OPT_MULTI
377
if(fr->cpu_opts.class == mmxsse)
378
{
379
#endif
380
/* align decwin, assign that to decwin_mmx, append decwins */
381
/* I need to add to decwin what is missing to the next full 64 byte -- also I want to make gcc -pedantic happy... */
382
fr->decwin = aligned_pointer(fr->rawdecwin,real,64);
383
debug1("aligned decwin: %p", (void*)fr->decwin);
384
fr->decwin_mmx = (float*)fr->decwin;
385
fr->decwins = fr->decwin_mmx+512+32;
386
#ifdef OPT_MULTI
387
}
388
else debug("no decwins/decwin_mmx for that class");
389
#endif
390
#endif
391
}
392
393
/* Layer scratch buffers are of compile-time fixed size, so allocate only once. */
394
if(fr->layerscratch == NULL)
395
{
396
/* Allocate specific layer1/2/3 buffers, so that we know they'll work for SSE. */
397
size_t scratchsize = 0;
398
real *scratcher;
399
#ifndef NO_LAYER1
400
scratchsize += sizeof(real) * 2 * SBLIMIT;
401
#endif
402
#ifndef NO_LAYER2
403
scratchsize += sizeof(real) * 2 * 4 * SBLIMIT;
404
#endif
405
#ifndef NO_LAYER3
406
scratchsize += sizeof(real) * 2 * SBLIMIT * SSLIMIT; /* hybrid_in */
407
scratchsize += sizeof(real) * 2 * SSLIMIT * SBLIMIT; /* hybrid_out */
408
#endif
409
/*
410
Now figure out correct alignment:
411
We need 16 byte minimum, smallest unit of the blocks is 2*SBLIMIT*sizeof(real), which is 64*4=256. Let's do 64bytes as heuristic for cache line (as proven useful in buffs above).
412
*/
413
fr->layerscratch = malloc(scratchsize+63);
414
if(fr->layerscratch == NULL) return -1;
415
416
/* Get aligned part of the memory, then divide it up. */
417
scratcher = aligned_pointer(fr->layerscratch,real,64);
418
/* Those funky pointer casts silence compilers...
419
One might change the code at hand to really just use 1D arrays, but in practice, that would not make a (positive) difference. */
420
#ifndef NO_LAYER1
421
fr->layer1.fraction = (real(*)[SBLIMIT])scratcher;
422
scratcher += 2 * SBLIMIT;
423
#endif
424
#ifndef NO_LAYER2
425
fr->layer2.fraction = (real(*)[4][SBLIMIT])scratcher;
426
scratcher += 2 * 4 * SBLIMIT;
427
#endif
428
#ifndef NO_LAYER3
429
fr->layer3.hybrid_in = (real(*)[SBLIMIT][SSLIMIT])scratcher;
430
scratcher += 2 * SBLIMIT * SSLIMIT;
431
fr->layer3.hybrid_out = (real(*)[SSLIMIT][SBLIMIT])scratcher;
432
scratcher += 2 * SSLIMIT * SBLIMIT;
433
#endif
434
/* Note: These buffers don't need resetting here. */
435
}
436
437
/* Only reset the buffers we created just now. */
438
frame_decode_buffers_reset(fr);
439
440
debug1("frame %p buffer done", (void*)fr);
441
return 0;
442
}
443
444
int INT123_frame_buffers_reset(mpg123_handle *fr)
445
{
446
fr->buffer.fill = 0; /* hm, reset buffer fill... did we do a flush? */
447
fr->bsnum = 0;
448
/* Wondering: could it be actually _wanted_ to retain buffer contents over different files? (special gapless / cut stuff) */
449
fr->bsbuf = fr->bsspace[1];
450
fr->bsbufold = fr->bsbuf;
451
fr->bitreservoir = 0;
452
frame_decode_buffers_reset(fr);
453
memset(fr->bsspace, 0, 2*(MAXFRAMESIZE+512));
454
memset(fr->ssave, 0, 34);
455
fr->hybrid_blc[0] = fr->hybrid_blc[1] = 0;
456
memset(fr->hybrid_block, 0, sizeof(real)*2*2*SBLIMIT*SSLIMIT);
457
return 0;
458
}
459
460
static void frame_icy_reset(mpg123_handle* fr)
461
{
462
#ifndef NO_ICY
463
if(fr->icy.data != NULL) free(fr->icy.data);
464
fr->icy.data = NULL;
465
fr->icy.interval = 0;
466
fr->icy.next = 0;
467
#endif
468
}
469
470
static void frame_free_toc(mpg123_handle *fr)
471
{
472
if(fr->xing_toc != NULL){ free(fr->xing_toc); fr->xing_toc = NULL; }
473
}
474
475
/* Just copy the Xing TOC over... */
476
int INT123_frame_fill_toc(mpg123_handle *fr, unsigned char* in)
477
{
478
if(fr->xing_toc == NULL) fr->xing_toc = malloc(100);
479
if(fr->xing_toc != NULL)
480
{
481
memcpy(fr->xing_toc, in, 100);
482
#ifdef DEBUG
483
debug("Got a TOC! Showing the values...");
484
{
485
int i;
486
for(i=0; i<100; ++i)
487
debug2("entry %i = %i", i, fr->xing_toc[i]);
488
}
489
#endif
490
return TRUE;
491
}
492
return FALSE;
493
}
494
495
/* Prepare the handle for a new track.
496
Reset variables, buffers... */
497
int INT123_frame_reset(mpg123_handle* fr)
498
{
499
INT123_frame_buffers_reset(fr);
500
frame_fixed_reset(fr);
501
frame_free_toc(fr);
502
#ifdef FRAME_INDEX
503
INT123_fi_reset(&fr->index);
504
#endif
505
506
return 0;
507
}
508
509
/* Reset everythign except dynamic memory. */
510
static void frame_fixed_reset(mpg123_handle *fr)
511
{
512
frame_icy_reset(fr);
513
INT123_open_bad(fr);
514
memset(&(fr->hdr), 0, sizeof(fr->hdr));
515
fr->to_decode = FALSE;
516
fr->to_ignore = FALSE;
517
fr->metaflags = 0;
518
fr->outblock = 0; /* This will be set before decoding! */
519
fr->num = -1;
520
fr->input_offset = -1;
521
fr->playnum = -1;
522
fr->state_flags = FRAME_ACCURATE;
523
fr->silent_resync = 0;
524
fr->audio_start = 0;
525
fr->clip = 0;
526
fr->oldhead = 0;
527
fr->firsthead = 0;
528
fr->vbr = MPG123_CBR;
529
fr->abr_rate = 0;
530
fr->track_frames = 0;
531
fr->track_samples = -1;
532
fr->mean_frames = 0;
533
fr->mean_framesize = 0;
534
fr->lastscale = -1;
535
fr->rva.level[0] = -1;
536
fr->rva.level[1] = -1;
537
fr->rva.gain[0] = 0;
538
fr->rva.gain[1] = 0;
539
fr->rva.peak[0] = 0;
540
fr->rva.peak[1] = 0;
541
fr->fsizeold = 0;
542
fr->firstframe = 0;
543
fr->ignoreframe = fr->firstframe-fr->p.preframes;
544
fr->header_change = 0;
545
fr->lastframe = -1;
546
fr->fresh = 1;
547
fr->new_format = 0;
548
#ifdef GAPLESS
549
INT123_frame_gapless_init(fr,-1,0,0);
550
fr->lastoff = 0;
551
fr->firstoff = 0;
552
#endif
553
#ifdef OPT_I486
554
fr->i486bo[0] = fr->i486bo[1] = FIR_SIZE-1;
555
#endif
556
fr->bo = 1; /* the usual bo */
557
#ifdef OPT_DITHER
558
fr->ditherindex = 0;
559
#endif
560
INT123_reset_id3(fr);
561
INT123_reset_icy(&fr->icy);
562
/* ICY stuff should go into icy.c, eh? */
563
#ifndef NO_ICY
564
fr->icy.interval = 0;
565
fr->icy.next = 0;
566
#endif
567
fr->halfphase = 0; /* here or indeed only on first-time init? */
568
fr->hdr.freeformat_framesize = fr->p.freeformat_framesize;
569
fr->enc_delay = -1;
570
fr->enc_padding = -1;
571
memset(fr->id3buf, 0, sizeof(fr->id3buf));
572
if(fr->id3v2_raw)
573
free(fr->id3v2_raw);
574
fr->id3v2_raw = NULL;
575
fr->id3v2_size = 0;
576
}
577
578
static void frame_free_buffers(mpg123_handle *fr)
579
{
580
if(fr->rawbuffs != NULL) free(fr->rawbuffs);
581
fr->rawbuffs = NULL;
582
fr->rawbuffss = 0;
583
if(fr->rawdecwin != NULL) free(fr->rawdecwin);
584
fr->rawdecwin = NULL;
585
fr->rawdecwins = 0;
586
#ifndef NO_8BIT
587
if(fr->conv16to8_buf != NULL) free(fr->conv16to8_buf);
588
fr->conv16to8_buf = NULL;
589
#endif
590
if(fr->layerscratch != NULL) free(fr->layerscratch);
591
}
592
593
void INT123_frame_exit(mpg123_handle *fr)
594
{
595
if(fr->buffer.rdata != NULL)
596
{
597
debug1("freeing buffer at %p", (void*)fr->buffer.rdata);
598
free(fr->buffer.rdata);
599
}
600
fr->buffer.rdata = NULL;
601
frame_free_buffers(fr);
602
frame_free_toc(fr);
603
#ifdef FRAME_INDEX
604
INT123_fi_exit(&fr->index);
605
#endif
606
#ifdef OPT_DITHER
607
if(fr->dithernoise != NULL)
608
{
609
free(fr->dithernoise);
610
fr->dithernoise = NULL;
611
}
612
#endif
613
INT123_exit_id3(fr);
614
INT123_clear_icy(&fr->icy);
615
#ifndef NO_FEEDER
616
INT123_bc_cleanup(&fr->rdat.buffer);
617
#endif
618
}
619
620
int attribute_align_arg mpg123_framedata(mpg123_handle *mh, unsigned long *header, unsigned char **bodydata, size_t *bodybytes)
621
{
622
if(mh == NULL) return MPG123_BAD_HANDLE;
623
if(!mh->to_decode) return MPG123_ERR;
624
625
if(header != NULL) *header = mh->oldhead;
626
if(bodydata != NULL) *bodydata = mh->bsbuf;
627
if(bodybytes != NULL) *bodybytes = mh->hdr.framesize;
628
629
return MPG123_OK;
630
}
631
632
int attribute_align_arg mpg123_set_moreinfo( mpg123_handle *mh
633
, struct mpg123_moreinfo *mi)
634
{
635
#ifndef NO_MOREINFO
636
mh->pinfo = mi;
637
return MPG123_OK;
638
#else
639
mh->err = MPG123_MISSING_FEATURE;
640
return MPG123_ERR;
641
#endif
642
}
643
644
/*
645
Fuzzy frame offset searching (guessing).
646
When we don't have an accurate position, we may use an inaccurate one.
647
Possibilities:
648
- use approximate positions from Xing TOC (not yet parsed)
649
- guess wildly from mean framesize and offset of first frame / beginning of file.
650
*/
651
652
static int64_t frame_fuzzy_find(mpg123_handle *fr, int64_t want_frame, int64_t* get_frame)
653
{
654
/* Default is to go to the beginning. */
655
int64_t ret = fr->audio_start;
656
*get_frame = 0;
657
658
/* But we try to find something better. */
659
/* Xing VBR TOC works with relative positions, both in terms of audio frames and stream bytes.
660
Thus, it only works when whe know the length of things.
661
Oh... I assume the offsets are relative to the _total_ file length. */
662
if(fr->xing_toc != NULL && fr->track_frames > 0 && fr->rdat.filelen > 0)
663
{
664
/* One could round... */
665
int toc_entry = (int) ((double)want_frame*100./fr->track_frames);
666
/* It is an index in the 100-entry table. */
667
if(toc_entry < 0) toc_entry = 0;
668
if(toc_entry > 99) toc_entry = 99;
669
670
/* Now estimate back what frame we get. */
671
*get_frame = (int64_t) ((double)toc_entry/100. * fr->track_frames);
672
fr->state_flags &= ~FRAME_ACCURATE;
673
fr->silent_resync = 1;
674
/* Question: Is the TOC for whole file size (with/without ID3) or the "real" audio data only?
675
ID3v1 info could also matter. */
676
ret = (int64_t) ((double)fr->xing_toc[toc_entry]/256.* fr->rdat.filelen);
677
}
678
else if(fr->mean_framesize > 0)
679
{ /* Just guess with mean framesize (may be exact with CBR files). */
680
/* Query filelen here or not? */
681
fr->state_flags &= ~FRAME_ACCURATE; /* Fuzzy! */
682
fr->silent_resync = 1;
683
*get_frame = want_frame;
684
ret = (int64_t) (fr->audio_start+fr->mean_framesize*want_frame);
685
}
686
debug5("fuzzy: want %" PRIi64 " of %" PRIi64
687
", get %" PRIi64 " at %" PRIi64 " B of %" PRIi64 " B"
688
, want_frame, fr->track_frames, *get_frame, ret
689
, (fr->rdat.filelen-fr->audio_start));
690
return ret;
691
}
692
693
/*
694
find the best frame in index just before the wanted one, seek to there
695
then step to just before wanted one with INT123_read_frame
696
do not care tabout the stuff that was in buffer but not played back
697
everything that left the decoder is counted as played
698
699
Decide if you want low latency reaction and accurate timing info or stable long-time playback with buffer!
700
*/
701
702
int64_t INT123_frame_index_find(mpg123_handle *fr, int64_t want_frame, int64_t* get_frame)
703
{
704
/* default is file start if no index position */
705
int64_t gopos = 0;
706
*get_frame = 0;
707
#ifdef FRAME_INDEX
708
/* Possibly use VBRI index, too? I'd need an example for this... */
709
if(fr->index.fill)
710
{
711
/* find in index */
712
size_t fi;
713
/* at index fi there is frame step*fi... */
714
fi = want_frame/fr->index.step;
715
if(fi >= fr->index.fill) /* If we are beyond the end of frame index...*/
716
{
717
/* When fuzzy seek is allowed, we have some limited tolerance for the frames we want to read rather then jump over. */
718
if(fr->p.flags & MPG123_FUZZY && want_frame - (fr->index.fill-1)*fr->index.step > 10)
719
{
720
gopos = frame_fuzzy_find(fr, want_frame, get_frame);
721
if(gopos > fr->audio_start) return gopos; /* Only in that case, we have a useful guess. */
722
/* Else... just continue, fuzzyness didn't help. */
723
}
724
/* Use the last available position, slowly advancing from that one. */
725
fi = fr->index.fill - 1;
726
}
727
/* We have index position, that yields frame and byte offsets. */
728
*get_frame = fi*fr->index.step;
729
gopos = fr->index.data[fi];
730
fr->state_flags |= FRAME_ACCURATE; /* When using the frame index, we are accurate. */
731
}
732
else
733
{
734
#endif
735
if(fr->p.flags & MPG123_FUZZY)
736
return frame_fuzzy_find(fr, want_frame, get_frame);
737
/* A bit hackish here... but we need to be fresh when looking for the first header again. */
738
fr->firsthead = 0;
739
fr->oldhead = 0;
740
#ifdef FRAME_INDEX
741
}
742
#endif
743
debug2("index: 0x%" PRIx64 " for frame %" PRIi64, (uint64_t)gopos, *get_frame);
744
return gopos;
745
}
746
747
int64_t INT123_frame_ins2outs(mpg123_handle *fr, int64_t ins)
748
{
749
int64_t outs = 0;
750
switch(fr->down_sample)
751
{
752
case 0:
753
# ifndef NO_DOWNSAMPLE
754
case 1:
755
case 2:
756
# endif
757
outs = ins>>fr->down_sample;
758
break;
759
# ifndef NO_NTOM
760
case 3: outs = INT123_ntom_ins2outs(fr, ins); break;
761
# endif
762
default: if(NOQUIET)
763
merror( "Bad down_sample (%i) ... should not be possible!!"
764
, fr->down_sample );
765
}
766
return outs;
767
}
768
769
int64_t INT123_frame_outs(mpg123_handle *fr, int64_t num)
770
{
771
int64_t outs = 0;
772
switch(fr->down_sample)
773
{
774
case 0:
775
# ifndef NO_DOWNSAMPLE
776
case 1:
777
case 2:
778
# endif
779
outs = (fr->spf>>fr->down_sample)*num;
780
break;
781
#ifndef NO_NTOM
782
case 3: outs = INT123_ntom_frmouts(fr, num); break;
783
#endif
784
default: if(NOQUIET)
785
merror( "Bad down_sample (%i) ... should not be possible!!"
786
, fr->down_sample );
787
}
788
return outs;
789
}
790
791
/* Compute the number of output samples we expect from this frame.
792
This is either simple spf() or a tad more elaborate for ntom. */
793
int64_t INT123_frame_expect_outsamples(mpg123_handle *fr)
794
{
795
int64_t outs = 0;
796
switch(fr->down_sample)
797
{
798
case 0:
799
# ifndef NO_DOWNSAMPLE
800
case 1:
801
case 2:
802
# endif
803
outs = fr->spf>>fr->down_sample;
804
break;
805
#ifndef NO_NTOM
806
case 3: outs = INT123_ntom_frame_outsamples(fr); break;
807
#endif
808
default: if(NOQUIET)
809
merror( "Bad down_sample (%i) ... should not be possible!!"
810
, fr->down_sample );
811
}
812
return outs;
813
}
814
815
int64_t INT123_frame_offset(mpg123_handle *fr, int64_t outs)
816
{
817
int64_t num = 0;
818
switch(fr->down_sample)
819
{
820
case 0:
821
# ifndef NO_DOWNSAMPLE
822
case 1:
823
case 2:
824
# endif
825
num = outs/(fr->spf>>fr->down_sample);
826
break;
827
#ifndef NO_NTOM
828
case 3: num = INT123_ntom_frameoff(fr, outs); break;
829
#endif
830
default: if(NOQUIET)
831
error("Bad down_sample ... should not be possible!!");
832
}
833
return num;
834
}
835
836
#ifdef GAPLESS
837
/* input in _input_ samples */
838
void INT123_frame_gapless_init(mpg123_handle *fr, int64_t framecount, int64_t bskip, int64_t eskip)
839
{
840
debug3("INT123_frame_gapless_init: given %"PRIi64" frames, skip %"PRIi64" and %"PRIi64, framecount, bskip, eskip);
841
fr->gapless_frames = framecount;
842
if(fr->gapless_frames > 0 && bskip >=0 && eskip >= 0)
843
{
844
fr->begin_s = bskip+GAPLESS_DELAY;
845
fr->end_s = framecount*fr->spf-eskip+GAPLESS_DELAY;
846
}
847
else fr->begin_s = fr->end_s = 0;
848
/* These will get proper values later, from above plus resampling info. */
849
fr->begin_os = 0;
850
fr->end_os = 0;
851
fr->fullend_os = 0;
852
debug2("INT123_frame_gapless_init: from %"PRIi64" to %"PRIi64" samples", fr->begin_s, fr->end_s);
853
}
854
855
void INT123_frame_gapless_realinit(mpg123_handle *fr)
856
{
857
fr->begin_os = INT123_frame_ins2outs(fr, fr->begin_s);
858
fr->end_os = INT123_frame_ins2outs(fr, fr->end_s);
859
if(fr->gapless_frames > 0)
860
fr->fullend_os = INT123_frame_ins2outs(fr, fr->gapless_frames*fr->spf);
861
else fr->fullend_os = 0;
862
863
debug4("INT123_frame_gapless_realinit: from %"PRIi64" to %"PRIi64" samples (%"PRIi64", %"PRIi64")"
864
, fr->begin_os, fr->end_os, fr->fullend_os, fr->gapless_frames);
865
}
866
867
/* At least note when there is trouble... */
868
void INT123_frame_gapless_update(mpg123_handle *fr, int64_t total_samples)
869
{
870
int64_t gapless_samples = fr->gapless_frames*fr->spf;
871
if(fr->gapless_frames < 1) return;
872
873
debug2("gapless update with new sample count %"PRIi64" as opposed to known %"PRIi64, total_samples, gapless_samples);
874
if(NOQUIET && total_samples != gapless_samples)
875
fprintf(stderr, "\nWarning: Real sample count %" PRIi64
876
" differs from given gapless sample count %" PRIi64
877
". Frankenstein stream?\n", total_samples, gapless_samples);
878
879
if(gapless_samples > total_samples)
880
{
881
if(NOQUIET)
882
merror( "End sample count smaller than gapless end! (%" PRIi64
883
" < %"PRIi64"). Disabling gapless mode from now on."
884
, total_samples, fr->end_s );
885
/* This invalidates the current position... but what should I do? */
886
INT123_frame_gapless_init(fr, -1, 0, 0);
887
INT123_frame_gapless_realinit(fr);
888
fr->lastframe = -1;
889
fr->lastoff = 0;
890
}
891
}
892
893
#endif
894
895
/* Compute the needed frame to ignore from, for getting accurate/consistent output for intended firstframe. */
896
static int64_t ignoreframe(mpg123_handle *fr)
897
{
898
int64_t preshift = fr->p.preframes;
899
/* Layer 3 _really_ needs at least one frame before. */
900
if(fr->hdr.lay==3 && preshift < 1) preshift = 1;
901
/* Layer 1 & 2 reall do not need more than 2. */
902
if(fr->hdr.lay!=3 && preshift > 2) preshift = 2;
903
904
return fr->firstframe - preshift;
905
}
906
907
/* The frame seek... This is not simply the seek to fe*fr->spf samples in output because we think of _input_ frames here.
908
Seek to frame offset 1 may be just seek to 200 samples offset in output since the beginning of first frame is delay/padding.
909
Hm, is that right? OK for the padding stuff, but actually, should the decoder delay be better totally hidden or not?
910
With gapless, even the whole frame position could be advanced further than requested (since Homey don't play dat). */
911
void INT123_frame_set_frameseek(mpg123_handle *fr, int64_t fe)
912
{
913
fr->firstframe = fe;
914
#ifdef GAPLESS
915
if(fr->p.flags & MPG123_GAPLESS && fr->gapless_frames > 0)
916
{
917
/* Take care of the beginning... */
918
int64_t beg_f = INT123_frame_offset(fr, fr->begin_os);
919
if(fe <= beg_f)
920
{
921
fr->firstframe = beg_f;
922
fr->firstoff = fr->begin_os - INT123_frame_outs(fr, beg_f);
923
}
924
else fr->firstoff = 0;
925
/* The end is set once for a track at least, on the INT123_frame_set_frameseek called in get_next_frame() */
926
if(fr->end_os > 0)
927
{
928
fr->lastframe = INT123_frame_offset(fr,fr->end_os);
929
fr->lastoff = fr->end_os - INT123_frame_outs(fr, fr->lastframe);
930
} else {fr->lastframe = -1; fr->lastoff = 0; }
931
} else { fr->firstoff = fr->lastoff = 0; fr->lastframe = -1; }
932
#endif
933
fr->ignoreframe = ignoreframe(fr);
934
#ifdef GAPLESS
935
debug5("INT123_frame_set_frameseek: begin at %" PRIi64 " frames and %" PRIi64
936
" samples, end at %" PRIi64 " and %" PRIi64 "; ignore from %" PRIi64,
937
fr->firstframe, fr->firstoff
938
, fr->lastframe, fr->lastoff, fr->ignoreframe);
939
#else
940
debug3("INT123_frame_set_frameseek: begin at %" PRIi64 " frames, end at %" PRIi64
941
"; ignore from %" PRIi64
942
, fr->firstframe, fr->lastframe, fr->ignoreframe);
943
#endif
944
}
945
946
void INT123_frame_skip(mpg123_handle *fr)
947
{
948
#ifndef NO_LAYER3
949
if(fr->hdr.lay == 3) INT123_set_pointer(fr, 1, 512);
950
#endif
951
}
952
953
/* Sample accurate seek prepare for decoder. */
954
/* This gets unadjusted output samples and takes resampling into account */
955
void INT123_frame_set_seek(mpg123_handle *fr, int64_t sp)
956
{
957
fr->firstframe = INT123_frame_offset(fr, sp);
958
debug1("INT123_frame_set_seek: from %" PRIi64, fr->num);
959
#ifndef NO_NTOM
960
if(fr->down_sample == 3) INT123_ntom_set_ntom(fr, fr->firstframe);
961
#endif
962
fr->ignoreframe = ignoreframe(fr);
963
#ifdef GAPLESS /* The sample offset is used for non-gapless mode, too! */
964
fr->firstoff = sp - INT123_frame_outs(fr, fr->firstframe);
965
debug5("INT123_frame_set_seek: begin at %" PRIi64 " frames and %" PRIi64
966
" samples, end at %" PRIi64 " and %" PRIi64 "; ignore from %" PRIi64,
967
fr->firstframe, fr->firstoff
968
, fr->lastframe, fr->lastoff, fr->ignoreframe);
969
#else
970
debug3("INT123_frame_set_seek: begin at %" PRIi64 " frames, end at %" PRIi64
971
"; ignore from %" PRIi64
972
, fr->firstframe, fr->lastframe, fr->ignoreframe);
973
#endif
974
}
975
976
int attribute_align_arg mpg123_volume_change(mpg123_handle *mh, double change)
977
{
978
if(mh == NULL) return MPG123_ERR;
979
return mpg123_volume(mh, change + (double) mh->p.outscale);
980
}
981
982
int attribute_align_arg mpg123_volume_change_db(mpg123_handle *mh, double change)
983
{
984
if(mh == NULL) return MPG123_ERR;
985
return mpg123_volume(mh, dbchange(mh->p.outscale, change));
986
}
987
988
int attribute_align_arg mpg123_volume(mpg123_handle *mh, double vol)
989
{
990
if(mh == NULL) return MPG123_ERR;
991
992
if(vol >= 0) mh->p.outscale = vol;
993
else mh->p.outscale = 0.;
994
995
INT123_do_rva(mh);
996
return MPG123_OK;
997
}
998
999
static int get_rva(mpg123_handle *fr, double *peak, double *gain)
1000
{
1001
double p = -1;
1002
double g = 0;
1003
int ret = 0;
1004
if(fr->p.rva)
1005
{
1006
int rt = 0;
1007
/* Should one assume a zero RVA as no RVA? */
1008
if(fr->p.rva == 2 && fr->rva.level[1] != -1) rt = 1;
1009
if(fr->rva.level[rt] != -1)
1010
{
1011
p = fr->rva.peak[rt];
1012
g = fr->rva.gain[rt];
1013
ret = 1; /* Success. */
1014
}
1015
}
1016
if(peak != NULL) *peak = p;
1017
if(gain != NULL) *gain = g;
1018
return ret;
1019
}
1020
1021
/* adjust the volume, taking both fr->outscale and rva values into account */
1022
void INT123_do_rva(mpg123_handle *fr)
1023
{
1024
double peak = 0;
1025
double gain = 0;
1026
double newscale;
1027
double rvafact = 1;
1028
if(get_rva(fr, &peak, &gain))
1029
{
1030
if(NOQUIET && fr->p.verbose > 1) fprintf(stderr, "Note: doing RVA with gain %f\n", gain);
1031
rvafact = pow(10,gain/20);
1032
}
1033
1034
newscale = fr->p.outscale*rvafact;
1035
1036
/* if peak is unknown (== 0) this check won't hurt */
1037
if((peak*newscale) > 1.0)
1038
{
1039
newscale = 1.0/peak;
1040
warning2("limiting scale value to %f to prevent clipping with indicated peak factor of %f", newscale, peak);
1041
}
1042
/* first rva setting is forced with fr->lastscale < 0 */
1043
if(newscale != fr->lastscale || fr->decoder_change)
1044
{
1045
debug3("changing scale value from %f to %f (peak estimated to %f)", fr->lastscale != -1 ? fr->lastscale : fr->p.outscale, newscale, (double) (newscale*peak));
1046
fr->lastscale = newscale;
1047
/* It may be too early, actually. */
1048
if(fr->INT123_make_decode_tables != NULL) fr->INT123_make_decode_tables(fr); /* the actual work */
1049
}
1050
}
1051
1052
1053
int attribute_align_arg mpg123_getvolume(mpg123_handle *mh, double *base, double *really, double *rva_db)
1054
{
1055
if(mh == NULL) return MPG123_ERR;
1056
if(base) *base = mh->p.outscale;
1057
if(really) *really = mh->lastscale;
1058
get_rva(mh, NULL, rva_db);
1059
return MPG123_OK;
1060
}
1061
1062
int64_t attribute_align_arg mpg123_framepos64(mpg123_handle *mh)
1063
{
1064
if(mh == NULL) return MPG123_ERR;
1065
1066
return mh->input_offset;
1067
}
1068
1069