Subversion Repositories Kolibri OS

Rev

Rev 1905 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1905 Rev 3960
Line 1... Line 1...
1
/*
1
/*
2
	frame: Heap of routines dealing with the core mpg123 data structure.
2
	frame: Heap of routines dealing with the core mpg123 data structure.
Line 3... Line 3...
3
 
3
 
4
	copyright 2008-9 by the mpg123 project - free software under the terms of the LGPL 2.1
4
	copyright 2008-2010 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
5
	see COPYING and AUTHORS files in distribution or http://mpg123.org
6
	initially written by Thomas Orgis
6
	initially written by Thomas Orgis
Line 7... Line 7...
7
*/
7
*/
Line 12... Line 12...
12
 
12
 
Line 13... Line 13...
13
static void frame_fixed_reset(mpg123_handle *fr);
13
static void frame_fixed_reset(mpg123_handle *fr);
14
 
14
 
-
 
15
/* that's doubled in decode_ntom.c */
15
/* that's doubled in decode_ntom.c */
16
#define NTOM_MUL (32768)
-
 
17
 
-
 
18
#define aligned_pointer(p, type, alignment) align_the_pointer(p, alignment)
-
 
19
static void *align_the_pointer(void *base, unsigned int alignment)
-
 
20
{
-
 
21
	/*
-
 
22
		Work in unsigned integer realm, explicitly.
-
 
23
		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.
-
 
24
		I try to do it "properly" here: Casting only to uintptr_t and no artihmethic with void*.
16
#define NTOM_MUL (32768)
25
	*/
-
 
26
	uintptr_t baseval = (uintptr_t)(char*)base;
-
 
27
	uintptr_t aoff = baseval % alignment;
-
 
28
 
-
 
29
	debug3("align_the_pointer: pointer %p is off by %u from %u",
17
#define aligned_pointer(p,type,alignment) \
30
	       base, (unsigned int)aoff, alignment);
18
	(((char*)(p)-(char*)NULL) % (alignment)) \
31
 
-
 
32
	if(aoff) return (char*)base+alignment-aoff;
-
 
33
	else     return base;
19
	? (type*)((char*)(p) + (alignment) - (((char*)(p)-(char*)NULL) % (alignment))) \
34
}
20
	: (type*)(p)
35
 
21
void frame_default_pars(mpg123_pars *mp)
36
static void frame_default_pars(mpg123_pars *mp)
22
{
-
 
23
	mp->outscale = 1.0;
-
 
24
#ifdef GAPLESS
-
 
25
	mp->flags = MPG123_GAPLESS;
37
{
-
 
38
	mp->outscale = 1.0;
-
 
39
	mp->flags = 0;
26
#else
40
#ifdef GAPLESS
-
 
41
	mp->flags |= MPG123_GAPLESS;
27
	mp->flags = 0;
42
#endif
28
#endif
43
	mp->flags |= MPG123_AUTO_RESAMPLE;
29
#ifndef NO_NTOM
44
#ifndef NO_NTOM
30
	mp->force_rate = 0;
45
	mp->force_rate = 0;
31
#endif
46
#endif
Line 35... Line 50...
35
	mp->doublespeed = 0;
50
	mp->doublespeed = 0;
36
	mp->verbose = 0;
51
	mp->verbose = 0;
37
#ifndef NO_ICY
52
#ifndef NO_ICY
38
	mp->icy_interval = 0;
53
	mp->icy_interval = 0;
39
#endif
54
#endif
40
#ifndef WIN32
-
 
41
	mp->timeout = 0;
55
	mp->timeout = 0;
42
#endif
-
 
43
	mp->resync_limit = 1024;
56
	mp->resync_limit = 1024;
44
#ifdef FRAME_INDEX
57
#ifdef FRAME_INDEX
45
	mp->index_size = INDEX_SIZE;
58
	mp->index_size = INDEX_SIZE;
46
#endif
59
#endif
47
	mp->preframes = 4; /* That's good  for layer 3 ISO compliance bitstream. */
60
	mp->preframes = 4; /* That's good  for layer 3 ISO compliance bitstream. */
48
	mpg123_fmt_all(mp);
61
	mpg123_fmt_all(mp);
-
 
62
	/* Default of keeping some 4K buffers at hand, should cover the "usual" use case (using 16K pipe buffers as role model). */
-
 
63
#ifndef NO_FEEDER
-
 
64
	mp->feedpool = 5; 
-
 
65
	mp->feedbuffer = 4096;
-
 
66
#endif
49
}
67
}
Line 50... Line 68...
50
 
68
 
51
void frame_init(mpg123_handle *fr)
69
void frame_init(mpg123_handle *fr)
52
{
70
{
53
	frame_init_par(fr, NULL);
71
	frame_init_par(fr, NULL);
Line 54... Line 72...
54
}
72
}
55
 
73
 
56
void frame_init_par(mpg123_handle *fr, mpg123_pars *mp)
74
void frame_init_par(mpg123_handle *fr, mpg123_pars *mp)
57
{
75
{
-
 
76
	fr->own_buffer = TRUE;
-
 
77
	fr->buffer.data = NULL;
-
 
78
	fr->buffer.rdata = NULL;
58
	fr->own_buffer = FALSE;
79
	fr->buffer.fill = 0;
59
	fr->buffer.data = NULL;
80
	fr->buffer.size = 0;
60
	fr->rawbuffs = NULL;
81
	fr->rawbuffs = NULL;
61
	fr->rawbuffss = 0;
82
	fr->rawbuffss = 0;
62
	fr->rawdecwin = NULL;
83
	fr->rawdecwin = NULL;
63
	fr->rawdecwins = 0;
84
	fr->rawdecwins = 0;
64
#ifndef NO_8BIT
85
#ifndef NO_8BIT
65
	fr->conv16to8_buf = NULL;
86
	fr->conv16to8_buf = NULL;
66
#endif
87
#endif
67
#ifdef OPT_DITHER
88
#ifdef OPT_DITHER
-
 
89
	fr->dithernoise = NULL;
68
	fr->dithernoise = NULL;
90
#endif
69
#endif
91
	fr->layerscratch = NULL;
70
	fr->xing_toc = NULL;
92
	fr->xing_toc = NULL;
71
	fr->cpu_opts.type = defdec();
93
	fr->cpu_opts.type = defdec();
72
	fr->cpu_opts.class = decclass(fr->cpu_opts.type);
94
	fr->cpu_opts.class = decclass(fr->cpu_opts.type);
Line 84... Line 106...
84
	/* frame_buffers is missing... that one needs cpu opt setting! */
106
	/* frame_buffers is missing... that one needs cpu opt setting! */
85
	/* after these... frame_reset is needed before starting full decode */
107
	/* after these... frame_reset is needed before starting full decode */
86
	invalidate_format(&fr->af);
108
	invalidate_format(&fr->af);
87
	fr->rdat.r_read = NULL;
109
	fr->rdat.r_read = NULL;
88
	fr->rdat.r_lseek = NULL;
110
	fr->rdat.r_lseek = NULL;
-
 
111
	fr->rdat.iohandle = NULL;
-
 
112
	fr->rdat.r_read_handle = NULL;
-
 
113
	fr->rdat.r_lseek_handle = NULL;
-
 
114
	fr->rdat.cleanup_handle = NULL;
-
 
115
	fr->wrapperdata = NULL;
-
 
116
	fr->wrapperclean = NULL;
89
	fr->decoder_change = 1;
117
	fr->decoder_change = 1;
90
	fr->err = MPG123_OK;
118
	fr->err = MPG123_OK;
91
	if(mp == NULL) frame_default_pars(&fr->p);
119
	if(mp == NULL) frame_default_pars(&fr->p);
92
	else memcpy(&fr->p, mp, sizeof(struct mpg123_pars_struct));
120
	else memcpy(&fr->p, mp, sizeof(struct mpg123_pars_struct));
Line -... Line 121...
-
 
121
 
-
 
122
#ifndef NO_FEEDER
-
 
123
	bc_prepare(&fr->rdat.buffer, fr->p.feedpool, fr->p.feedbuffer);
-
 
124
#endif
93
 
125
 
94
	fr->down_sample = 0; /* Initialize to silence harmless errors when debugging. */
126
	fr->down_sample = 0; /* Initialize to silence harmless errors when debugging. */
95
	frame_fixed_reset(fr); /* Reset only the fixed data, dynamic buffers are not there yet! */
127
	frame_fixed_reset(fr); /* Reset only the fixed data, dynamic buffers are not there yet! */
96
	fr->synth = NULL;
128
	fr->synth = NULL;
97
	fr->synth_mono = NULL;
129
	fr->synth_mono = NULL;
Line 141... Line 173...
141
	return MPG123_OK;
173
	return MPG123_OK;
142
}
174
}
Line 143... Line 175...
143
 
175
 
144
int frame_outbuffer(mpg123_handle *fr)
176
int frame_outbuffer(mpg123_handle *fr)
145
{
177
{
146
	size_t size = mpg123_safe_buffer()*AUDIOBUFSIZE;
178
	size_t size = fr->outblock;
147
	if(!fr->own_buffer) fr->buffer.data = NULL;
-
 
148
	if(fr->buffer.data != NULL && fr->buffer.size != size)
179
	if(!fr->own_buffer)
-
 
180
	{
-
 
181
		if(fr->buffer.size < size)
-
 
182
		{
-
 
183
			fr->err = MPG123_BAD_BUFFER;
-
 
184
			if(NOQUIET) error2("have external buffer of size %"SIZE_P", need %"SIZE_P, (size_p)fr->buffer.size, size);
-
 
185
 
-
 
186
			return MPG123_ERR;
-
 
187
		}
-
 
188
	}
-
 
189
 
-
 
190
	debug1("need frame buffer of %"SIZE_P, (size_p)size);
-
 
191
	if(fr->buffer.rdata != NULL && fr->buffer.size != size)
149
	{
192
	{
150
		free(fr->buffer.data);
193
		free(fr->buffer.rdata);
151
		fr->buffer.data = NULL;
194
		fr->buffer.rdata = NULL;
152
	}
195
	}
-
 
196
	fr->buffer.size = size;
-
 
197
	fr->buffer.data = NULL;
153
	fr->buffer.size = size;
198
	/* be generous: use 16 byte alignment */
154
	if(fr->buffer.data == NULL) fr->buffer.data = (unsigned char*) malloc(fr->buffer.size);
199
	if(fr->buffer.rdata == NULL) fr->buffer.rdata = (unsigned char*) malloc(fr->buffer.size+15);
155
	if(fr->buffer.data == NULL)
200
	if(fr->buffer.rdata == NULL)
156
	{
201
	{
157
		fr->err = MPG123_OUT_OF_MEM;
202
		fr->err = MPG123_OUT_OF_MEM;
158
		return -1;
203
		return MPG123_ERR;
-
 
204
	}
159
	}
205
	fr->buffer.data = aligned_pointer(fr->buffer.rdata, unsigned char*, 16);
160
	fr->own_buffer = TRUE;
206
	fr->own_buffer = TRUE;
161
	fr->buffer.fill = 0;
207
	fr->buffer.fill = 0;
162
	return 0;
208
	return MPG123_OK;
Line 163... Line 209...
163
}
209
}
164
 
210
 
-
 
211
int attribute_align_arg mpg123_replace_buffer(mpg123_handle *mh, unsigned char *data, size_t size)
165
int attribute_align_arg mpg123_replace_buffer(mpg123_handle *mh, unsigned char *data, size_t size)
212
{
-
 
213
	debug2("replace buffer with %p size %"SIZE_P, data, (size_p)size);
166
{
214
	/* Will accept any size, the error comes later... */
167
	if(data == NULL || size < mpg123_safe_buffer())
215
	if(data == NULL)
168
	{
216
	{
169
		mh->err = MPG123_BAD_BUFFER;
217
		mh->err = MPG123_BAD_BUFFER;
170
		return MPG123_ERR;
218
		return MPG123_ERR;
171
	}
219
	}
-
 
220
	if(mh->buffer.rdata != NULL) free(mh->buffer.rdata);
172
	if(mh->own_buffer && mh->buffer.data != NULL) free(mh->buffer.data);
221
	mh->own_buffer = FALSE;
173
	mh->own_buffer = FALSE;
222
	mh->buffer.rdata = NULL;
174
	mh->buffer.data = data;
223
	mh->buffer.data = data;
175
	mh->buffer.size = size;
224
	mh->buffer.size = size;
176
	mh->buffer.fill = 0;
225
	mh->buffer.fill = 0;
Line 291... Line 340...
291
#ifdef OPT_MULTI
340
#ifdef OPT_MULTI
292
		}
341
		}
293
#endif
342
#endif
294
#endif
343
#endif
295
#if defined(OPT_ALTIVEC) || defined(OPT_ARM) 
344
#if defined(OPT_ALTIVEC) || defined(OPT_ARM) 
-
 
345
		/* sizeof(real) >= 4 ... yes, it could be 8, for example.
296
		if(decwin_size < (512+32)*4) decwin_size = (512+32)*4;
346
		   We got it intialized to at least (512+32)*sizeof(real).*/
297
		decwin_size += 512*4;
347
		decwin_size += 512*sizeof(real);
298
#endif
348
#endif
299
		/* Hm, that's basically realloc() ... */
349
		/* Hm, that's basically realloc() ... */
300
		if(fr->rawdecwin != NULL && fr->rawdecwins != decwin_size)
350
		if(fr->rawdecwin != NULL && fr->rawdecwins != decwin_size)
301
		{
351
		{
302
			free(fr->rawdecwin);
352
			free(fr->rawdecwin);
Line 325... Line 375...
325
		}
375
		}
326
		else debug("no decwins/decwin_mmx for that class");
376
		else debug("no decwins/decwin_mmx for that class");
327
#endif
377
#endif
328
#endif
378
#endif
329
	}
379
	}
-
 
380
 
-
 
381
	/* Layer scratch buffers are of compile-time fixed size, so allocate only once. */
-
 
382
	if(fr->layerscratch == NULL)
-
 
383
	{
-
 
384
		/* Allocate specific layer1/2/3 buffers, so that we know they'll work for SSE. */
-
 
385
		size_t scratchsize = 0;
-
 
386
		real *scratcher;
-
 
387
#ifndef NO_LAYER1
-
 
388
		scratchsize += sizeof(real) * 2 * SBLIMIT;
-
 
389
#endif
-
 
390
#ifndef NO_LAYER2
-
 
391
		scratchsize += sizeof(real) * 2 * 4 * SBLIMIT;
-
 
392
#endif
-
 
393
#ifndef NO_LAYER3
-
 
394
		scratchsize += sizeof(real) * 2 * SBLIMIT * SSLIMIT; /* hybrid_in */
-
 
395
		scratchsize += sizeof(real) * 2 * SSLIMIT * SBLIMIT; /* hybrid_out */
-
 
396
#endif
-
 
397
		/*
-
 
398
			Now figure out correct alignment:
-
 
399
			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).
-
 
400
		*/
-
 
401
		fr->layerscratch = malloc(scratchsize+63);
-
 
402
		if(fr->layerscratch == NULL) return -1;
-
 
403
 
-
 
404
		/* Get aligned part of the memory, then divide it up. */
-
 
405
		scratcher = aligned_pointer(fr->layerscratch,real,64);
-
 
406
		/* Those funky pointer casts silence compilers...
-
 
407
		   One might change the code at hand to really just use 1D arrays, but in practice, that would not make a (positive) difference. */
-
 
408
#ifndef NO_LAYER1
-
 
409
		fr->layer1.fraction = (real(*)[SBLIMIT])scratcher;
-
 
410
		scratcher += 2 * SBLIMIT;
-
 
411
#endif
-
 
412
#ifndef NO_LAYER2
-
 
413
		fr->layer2.fraction = (real(*)[4][SBLIMIT])scratcher;
-
 
414
		scratcher += 2 * 4 * SBLIMIT;
-
 
415
#endif
-
 
416
#ifndef NO_LAYER3
-
 
417
		fr->layer3.hybrid_in = (real(*)[SBLIMIT][SSLIMIT])scratcher;
-
 
418
		scratcher += 2 * SBLIMIT * SSLIMIT;
-
 
419
		fr->layer3.hybrid_out = (real(*)[SSLIMIT][SBLIMIT])scratcher;
-
 
420
		scratcher += 2 * SSLIMIT * SBLIMIT;
-
 
421
#endif
-
 
422
		/* Note: These buffers don't need resetting here. */
-
 
423
	}
-
 
424
 
330
	/* Only reset the buffers we created just now. */
425
	/* Only reset the buffers we created just now. */
331
	frame_decode_buffers_reset(fr);
426
	frame_decode_buffers_reset(fr);
Line 332... Line 427...
332
 
427
 
333
	debug1("frame %p buffer done", (void*)fr);
428
	debug1("frame %p buffer done", (void*)fr);
Line 339... Line 434...
339
	fr->buffer.fill = 0; /* hm, reset buffer fill... did we do a flush? */
434
	fr->buffer.fill = 0; /* hm, reset buffer fill... did we do a flush? */
340
	fr->bsnum = 0;
435
	fr->bsnum = 0;
341
	/* Wondering: could it be actually _wanted_ to retain buffer contents over different files? (special gapless / cut stuff) */
436
	/* Wondering: could it be actually _wanted_ to retain buffer contents over different files? (special gapless / cut stuff) */
342
	fr->bsbuf = fr->bsspace[1];
437
	fr->bsbuf = fr->bsspace[1];
343
	fr->bsbufold = fr->bsbuf;
438
	fr->bsbufold = fr->bsbuf;
344
	fr->bitreservoir = 0; /* Not entirely sure if this is the right place for that counter. */
439
	fr->bitreservoir = 0;
345
	frame_decode_buffers_reset(fr);
440
	frame_decode_buffers_reset(fr);
346
	memset(fr->bsspace, 0, 2*(MAXFRAMESIZE+512));
441
	memset(fr->bsspace, 0, 2*(MAXFRAMESIZE+512));
347
	memset(fr->ssave, 0, 34);
442
	memset(fr->ssave, 0, 34);
348
	fr->hybrid_blc[0] = fr->hybrid_blc[1] = 0;
443
	fr->hybrid_blc[0] = fr->hybrid_blc[1] = 0;
349
	memset(fr->hybrid_block, 0, sizeof(real)*2*2*SBLIMIT*SSLIMIT);
444
	memset(fr->hybrid_block, 0, sizeof(real)*2*2*SBLIMIT*SSLIMIT);
350
	return 0;
445
	return 0;
351
}
446
}
Line 352... Line 447...
352
 
447
 
353
void frame_icy_reset(mpg123_handle* fr)
448
static void frame_icy_reset(mpg123_handle* fr)
354
{
449
{
355
#ifndef NO_ICY
450
#ifndef NO_ICY
356
	if(fr->icy.data != NULL) free(fr->icy.data);
451
	if(fr->icy.data != NULL) free(fr->icy.data);
357
	fr->icy.data = NULL;
452
	fr->icy.data = NULL;
358
	fr->icy.interval = 0;
453
	fr->icy.interval = 0;
359
	fr->icy.next = 0;
454
	fr->icy.next = 0;
360
#endif
455
#endif
Line 361... Line 456...
361
}
456
}
362
 
457
 
363
void frame_free_toc(mpg123_handle *fr)
458
static void frame_free_toc(mpg123_handle *fr)
364
{
459
{
Line 365... Line 460...
365
	if(fr->xing_toc != NULL){ free(fr->xing_toc); fr->xing_toc = NULL; }
460
	if(fr->xing_toc != NULL){ free(fr->xing_toc); fr->xing_toc = NULL; }
Line 405... Line 500...
405
	frame_icy_reset(fr);
500
	frame_icy_reset(fr);
406
	open_bad(fr);
501
	open_bad(fr);
407
	fr->to_decode = FALSE;
502
	fr->to_decode = FALSE;
408
	fr->to_ignore = FALSE;
503
	fr->to_ignore = FALSE;
409
	fr->metaflags = 0;
504
	fr->metaflags = 0;
410
	fr->outblock = mpg123_safe_buffer();
505
	fr->outblock = 0; /* This will be set before decoding! */
411
	fr->num = -1;
506
	fr->num = -1;
-
 
507
	fr->input_offset = -1;
412
	fr->playnum = -1;
508
	fr->playnum = -1;
413
	fr->accurate = TRUE;
509
	fr->state_flags = FRAME_ACCURATE;
414
	fr->silent_resync = 0;
510
	fr->silent_resync = 0;
415
	fr->audio_start = 0;
511
	fr->audio_start = 0;
416
	fr->clip = 0;
512
	fr->clip = 0;
417
	fr->oldhead = 0;
513
	fr->oldhead = 0;
418
	fr->firsthead = 0;
514
	fr->firsthead = 0;
Line 436... Line 532...
436
	fr->ignoreframe = fr->firstframe-fr->p.preframes;
532
	fr->ignoreframe = fr->firstframe-fr->p.preframes;
437
	fr->lastframe = -1;
533
	fr->lastframe = -1;
438
	fr->fresh = 1;
534
	fr->fresh = 1;
439
	fr->new_format = 0;
535
	fr->new_format = 0;
440
#ifdef GAPLESS
536
#ifdef GAPLESS
441
	frame_gapless_init(fr,0,0);
537
	frame_gapless_init(fr,-1,0,0);
442
	fr->lastoff = 0;
538
	fr->lastoff = 0;
443
	fr->firstoff = 0;
539
	fr->firstoff = 0;
444
#endif
540
#endif
445
#ifdef OPT_I486
541
#ifdef OPT_I486
446
	fr->i486bo[0] = fr->i486bo[1] = FIR_SIZE-1;
542
	fr->i486bo[0] = fr->i486bo[1] = FIR_SIZE-1;
Line 459... Line 555...
459
	fr->halfphase = 0; /* here or indeed only on first-time init? */
555
	fr->halfphase = 0; /* here or indeed only on first-time init? */
460
	fr->error_protection = 0;
556
	fr->error_protection = 0;
461
	fr->freeformat_framesize = -1;
557
	fr->freeformat_framesize = -1;
462
}
558
}
Line 463... Line 559...
463
 
559
 
464
void frame_free_buffers(mpg123_handle *fr)
560
static void frame_free_buffers(mpg123_handle *fr)
465
{
561
{
466
	if(fr->rawbuffs != NULL) free(fr->rawbuffs);
562
	if(fr->rawbuffs != NULL) free(fr->rawbuffs);
467
	fr->rawbuffs = NULL;
563
	fr->rawbuffs = NULL;
468
	fr->rawbuffss = 0;
564
	fr->rawbuffss = 0;
Line 471... Line 567...
471
	fr->rawdecwins = 0;
567
	fr->rawdecwins = 0;
472
#ifndef NO_8BIT
568
#ifndef NO_8BIT
473
	if(fr->conv16to8_buf != NULL) free(fr->conv16to8_buf);
569
	if(fr->conv16to8_buf != NULL) free(fr->conv16to8_buf);
474
	fr->conv16to8_buf = NULL;
570
	fr->conv16to8_buf = NULL;
475
#endif
571
#endif
-
 
572
	if(fr->layerscratch != NULL) free(fr->layerscratch);
476
}
573
}
Line 477... Line 574...
477
 
574
 
478
void frame_exit(mpg123_handle *fr)
575
void frame_exit(mpg123_handle *fr)
479
{
576
{
480
	if(fr->own_buffer && fr->buffer.data != NULL)
577
	if(fr->buffer.rdata != NULL)
481
	{
578
	{
482
		debug1("freeing buffer at %p", (void*)fr->buffer.data);
579
		debug1("freeing buffer at %p", (void*)fr->buffer.rdata);
483
		free(fr->buffer.data);
580
		free(fr->buffer.rdata);
484
	}
581
	}
485
	fr->buffer.data = NULL;
582
	fr->buffer.rdata = NULL;
486
	frame_free_buffers(fr);
583
	frame_free_buffers(fr);
487
	frame_free_toc(fr);
584
	frame_free_toc(fr);
488
#ifdef FRAME_INDEX
585
#ifdef FRAME_INDEX
489
	fi_exit(&fr->index);
586
	fi_exit(&fr->index);
Line 495... Line 592...
495
		fr->dithernoise = NULL;
592
		fr->dithernoise = NULL;
496
	}
593
	}
497
#endif
594
#endif
498
	exit_id3(fr);
595
	exit_id3(fr);
499
	clear_icy(&fr->icy);
596
	clear_icy(&fr->icy);
-
 
597
	/* Clean up possible mess from LFS wrapper. */
-
 
598
	if(fr->wrapperclean != NULL)
-
 
599
	{
-
 
600
		fr->wrapperclean(fr->wrapperdata);
-
 
601
		fr->wrapperdata = NULL;
-
 
602
	}
-
 
603
#ifndef NO_FEEDER
-
 
604
	bc_cleanup(&fr->rdat.buffer);
-
 
605
#endif
500
}
606
}
Line 501... Line 607...
501
 
607
 
502
int attribute_align_arg mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *mi)
608
int attribute_align_arg mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *mi)
503
{
609
{
Line 530... Line 636...
530
	mi->abr_rate = mh->abr_rate;
636
	mi->abr_rate = mh->abr_rate;
531
	mi->vbr = mh->vbr;
637
	mi->vbr = mh->vbr;
532
	return MPG123_OK;
638
	return MPG123_OK;
533
}
639
}
Line -... Line 640...
-
 
640
 
-
 
641
int attribute_align_arg mpg123_framedata(mpg123_handle *mh, unsigned long *header, unsigned char **bodydata, size_t *bodybytes)
-
 
642
{
-
 
643
	if(mh == NULL)     return MPG123_ERR;
-
 
644
	if(!mh->to_decode) return MPG123_ERR;
-
 
645
 
-
 
646
	if(header    != NULL) *header    = mh->oldhead;
-
 
647
	if(bodydata  != NULL) *bodydata  = mh->bsbuf;
-
 
648
	if(bodybytes != NULL) *bodybytes = mh->framesize;
-
 
649
 
-
 
650
	return MPG123_OK;
Line 534... Line 651...
534
 
651
}
535
 
652
 
536
/*
653
/*
537
	Fuzzy frame offset searching (guessing).
654
	Fuzzy frame offset searching (guessing).
538
	When we don't have an accurate position, we may use an inaccurate one.
655
	When we don't have an accurate position, we may use an inaccurate one.
539
	Possibilities:
656
	Possibilities:
540
		- use approximate positions from Xing TOC (not yet parsed)
657
		- use approximate positions from Xing TOC (not yet parsed)
Line 541... Line 658...
541
		- guess wildly from mean framesize and offset of first frame / beginning of file.
658
		- guess wildly from mean framesize and offset of first frame / beginning of file.
542
*/
659
*/
543
 
660
 
544
off_t frame_fuzzy_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame)
661
static off_t frame_fuzzy_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame)
545
{
662
{
Line 559... Line 676...
559
		if(toc_entry < 0)  toc_entry = 0;
676
		if(toc_entry < 0)  toc_entry = 0;
560
		if(toc_entry > 99) toc_entry = 99;
677
		if(toc_entry > 99) toc_entry = 99;
Line 561... Line 678...
561
 
678
 
562
		/* Now estimate back what frame we get. */
679
		/* Now estimate back what frame we get. */
563
		*get_frame = (off_t) ((double)toc_entry/100. * fr->track_frames);
680
		*get_frame = (off_t) ((double)toc_entry/100. * fr->track_frames);
564
		fr->accurate = FALSE;
681
		fr->state_flags &= ~FRAME_ACCURATE;
565
		fr->silent_resync = 1;
682
		fr->silent_resync = 1;
566
		/* Question: Is the TOC for whole file size (with/without ID3) or the "real" audio data only?
683
		/* Question: Is the TOC for whole file size (with/without ID3) or the "real" audio data only?
567
		   ID3v1 info could also matter. */
684
		   ID3v1 info could also matter. */
568
		ret = (off_t) ((double)fr->xing_toc[toc_entry]/256.* fr->rdat.filelen);
685
		ret = (off_t) ((double)fr->xing_toc[toc_entry]/256.* fr->rdat.filelen);
569
	}
686
	}
570
	else if(fr->mean_framesize > 0)
687
	else if(fr->mean_framesize > 0)
571
	{	/* Just guess with mean framesize (may be exact with CBR files). */
688
	{	/* Just guess with mean framesize (may be exact with CBR files). */
572
		/* Query filelen here or not? */
689
		/* Query filelen here or not? */
573
		fr->accurate = FALSE; /* Fuzzy! */
690
		fr->state_flags &= ~FRAME_ACCURATE; /* Fuzzy! */
574
		fr->silent_resync = 1;
691
		fr->silent_resync = 1;
575
		*get_frame = want_frame;
692
		*get_frame = want_frame;
576
		ret = (off_t) (fr->audio_start+fr->mean_framesize*want_frame);
693
		ret = (off_t) (fr->audio_start+fr->mean_framesize*want_frame);
577
	}
694
	}
Line 615... Line 732...
615
			fi = fr->index.fill - 1;
732
			fi = fr->index.fill - 1;
616
		}
733
		}
617
		/* We have index position, that yields frame and byte offsets. */
734
		/* We have index position, that yields frame and byte offsets. */
618
		*get_frame = fi*fr->index.step;
735
		*get_frame = fi*fr->index.step;
619
		gopos = fr->index.data[fi];
736
		gopos = fr->index.data[fi];
620
		fr->accurate = TRUE; /* When using the frame index, we are accurate. */
737
		fr->state_flags |= FRAME_ACCURATE; /* When using the frame index, we are accurate. */
621
	}
738
	}
622
	else
739
	else
623
	{
740
	{
624
#endif
741
#endif
625
		if(fr->p.flags & MPG123_FUZZY)
742
		if(fr->p.flags & MPG123_FUZZY)
Line 672... Line 789...
672
		default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample);
789
		default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample);
673
	}
790
	}
674
	return outs;
791
	return outs;
675
}
792
}
Line -... Line 793...
-
 
793
 
-
 
794
/* Compute the number of output samples we expect from this frame.
-
 
795
   This is either simple spf() or a tad more elaborate for ntom. */
-
 
796
off_t frame_expect_outsamples(mpg123_handle *fr)
-
 
797
{
-
 
798
	off_t outs = 0;
-
 
799
	switch(fr->down_sample)
-
 
800
	{
-
 
801
		case 0:
-
 
802
#		ifndef NO_DOWNSAMPLE
-
 
803
		case 1:
-
 
804
		case 2:
-
 
805
#		endif
-
 
806
			outs = spf(fr)>>fr->down_sample;
-
 
807
		break;
-
 
808
#ifndef NO_NTOM
-
 
809
		case 3: outs = ntom_frame_outsamples(fr); break;
-
 
810
#endif
-
 
811
		default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample);
-
 
812
	}
-
 
813
	return outs;
-
 
814
}
676
 
815
 
677
off_t frame_offset(mpg123_handle *fr, off_t outs)
816
off_t frame_offset(mpg123_handle *fr, off_t outs)
678
{
817
{
679
	off_t num = 0;
818
	off_t num = 0;
680
	switch(fr->down_sample)
819
	switch(fr->down_sample)
Line 694... Line 833...
694
	return num;
833
	return num;
695
}
834
}
Line 696... Line 835...
696
 
835
 
697
#ifdef GAPLESS
836
#ifdef GAPLESS
698
/* input in _input_ samples */
837
/* input in _input_ samples */
-
 
838
void frame_gapless_init(mpg123_handle *fr, off_t framecount, off_t bskip, off_t eskip)
-
 
839
{
-
 
840
	debug3("frame_gaples_init: given %"OFF_P" frames, skip %"OFF_P" and %"OFF_P, (off_p)framecount, (off_p)bskip, (off_p)eskip);
-
 
841
	fr->gapless_frames = framecount;
699
void frame_gapless_init(mpg123_handle *fr, off_t b, off_t e)
842
	if(fr->gapless_frames > 0)
700
{
843
	{
-
 
844
		fr->begin_s = bskip+GAPLESS_DELAY;
-
 
845
		fr->end_s = framecount*spf(fr)-eskip+GAPLESS_DELAY;
701
	fr->begin_s = b;
846
	}
702
	fr->end_s = e;
847
	else fr->begin_s = fr->end_s = 0;
703
	/* These will get proper values later, from above plus resampling info. */
848
	/* These will get proper values later, from above plus resampling info. */
704
	fr->begin_os = 0;
849
	fr->begin_os = 0;
-
 
850
	fr->end_os = 0;
705
	fr->end_os = 0;
851
	fr->fullend_os = 0;
706
	debug2("frame_gapless_init: from %lu to %lu samples", (long unsigned)fr->begin_s, (long unsigned)fr->end_s);
852
	debug2("frame_gapless_init: from %"OFF_P" to %"OFF_P" samples", (off_p)fr->begin_s, (off_p)fr->end_s);
Line 707... Line 853...
707
}
853
}
708
 
854
 
709
void frame_gapless_realinit(mpg123_handle *fr)
855
void frame_gapless_realinit(mpg123_handle *fr)
710
{
856
{
-
 
857
	fr->begin_os = frame_ins2outs(fr, fr->begin_s);
711
	fr->begin_os = frame_ins2outs(fr, fr->begin_s);
858
	fr->end_os   = frame_ins2outs(fr, fr->end_s);
712
	fr->end_os   = frame_ins2outs(fr, fr->end_s);
859
	fr->fullend_os = frame_ins2outs(fr, fr->gapless_frames*spf(fr));
Line 713... Line 860...
713
	debug2("frame_gapless_realinit: from %lu to %lu samples", (long unsigned)fr->begin_os, (long unsigned)fr->end_os);
860
	debug2("frame_gapless_realinit: from %"OFF_P" to %"OFF_P" samples", (off_p)fr->begin_os, (off_p)fr->end_os);
714
}
861
}
715
 
862
 
-
 
863
/* At least note when there is trouble... */
-
 
864
void frame_gapless_update(mpg123_handle *fr, off_t total_samples)
-
 
865
{
-
 
866
	off_t gapless_samples = fr->gapless_frames*spf(fr);
-
 
867
	debug2("gapless update with new sample count %"OFF_P" as opposed to known %"OFF_P, total_samples, gapless_samples);
716
/* When we got a new sample count, update the gaplessness. */
868
	if(NOQUIET && total_samples != gapless_samples)
717
void frame_gapless_update(mpg123_handle *fr, off_t total_samples)
869
	fprintf(stderr, "\nWarning: Real sample count differs from given gapless sample count. Frankenstein stream?\n");
-
 
870
 
-
 
871
	if(gapless_samples > total_samples)
718
{
872
	{
719
	if(fr->end_s < 1)
873
		if(NOQUIET) error2("End sample count smaller than gapless end! (%"OFF_P" < %"OFF_P"). Disabling gapless mode from now on.", (off_p)total_samples, (off_p)fr->end_s);
720
	{
-
 
721
		fr->end_s = total_samples;
874
		/* This invalidates the current position... but what should I do? */
722
		frame_gapless_realinit(fr);
-
 
723
	}
-
 
724
	else if(fr->end_s > total_samples)
875
		frame_gapless_init(fr, -1, 0, 0);
725
	{
876
		frame_gapless_realinit(fr);
726
		if(NOQUIET) error2("end sample count smaller than gapless end! (%"OFF_P" < %"OFF_P").", (off_p)total_samples, (off_p)fr->end_s);
877
		fr->lastframe = -1;
Line 727... Line 878...
727
		fr->end_s = total_samples;
878
		fr->lastoff = 0;
Line 748... Line 899...
748
   With gapless, even the whole frame position could be advanced further than requested (since Homey don't play dat). */
899
   With gapless, even the whole frame position could be advanced further than requested (since Homey don't play dat). */
749
void frame_set_frameseek(mpg123_handle *fr, off_t fe)
900
void frame_set_frameseek(mpg123_handle *fr, off_t fe)
750
{
901
{
751
	fr->firstframe = fe;
902
	fr->firstframe = fe;
752
#ifdef GAPLESS
903
#ifdef GAPLESS
753
	if(fr->p.flags & MPG123_GAPLESS)
904
	if(fr->p.flags & MPG123_GAPLESS && fr->gapless_frames > 0)
754
	{
905
	{
755
		/* Take care of the beginning... */
906
		/* Take care of the beginning... */
756
		off_t beg_f = frame_offset(fr, fr->begin_os);
907
		off_t beg_f = frame_offset(fr, fr->begin_os);
757
		if(fe <= beg_f)
908
		if(fe <= beg_f)
758
		{
909
		{
Line 763... Line 914...
763
		/* The end is set once for a track at least, on the frame_set_frameseek called in get_next_frame() */
914
		/* The end is set once for a track at least, on the frame_set_frameseek called in get_next_frame() */
764
		if(fr->end_os > 0)
915
		if(fr->end_os > 0)
765
		{
916
		{
766
			fr->lastframe  = frame_offset(fr,fr->end_os);
917
			fr->lastframe  = frame_offset(fr,fr->end_os);
767
			fr->lastoff    = fr->end_os - frame_outs(fr, fr->lastframe);
918
			fr->lastoff    = fr->end_os - frame_outs(fr, fr->lastframe);
768
		} else fr->lastoff = 0;
919
		} else {fr->lastframe = -1; fr->lastoff = 0; }
769
	} else { fr->firstoff = fr->lastoff = 0; fr->lastframe = -1; }
920
	} else { fr->firstoff = fr->lastoff = 0; fr->lastframe = -1; }
770
#endif
921
#endif
771
	fr->ignoreframe = ignoreframe(fr);
922
	fr->ignoreframe = ignoreframe(fr);
772
#ifdef GAPLESS
923
#ifdef GAPLESS
773
	debug5("frame_set_frameseek: begin at %li frames and %li samples, end at %li and %li; ignore from %li",
924
	debug5("frame_set_frameseek: begin at %li frames and %li samples, end at %li and %li; ignore from %li",
Line 789... Line 940...
789
/* Sample accurate seek prepare for decoder. */
940
/* Sample accurate seek prepare for decoder. */
790
/* This gets unadjusted output samples and takes resampling into account */
941
/* This gets unadjusted output samples and takes resampling into account */
791
void frame_set_seek(mpg123_handle *fr, off_t sp)
942
void frame_set_seek(mpg123_handle *fr, off_t sp)
792
{
943
{
793
	fr->firstframe = frame_offset(fr, sp);
944
	fr->firstframe = frame_offset(fr, sp);
-
 
945
	debug1("frame_set_seek: from %"OFF_P, fr->num);
794
#ifndef NO_NTOM
946
#ifndef NO_NTOM
795
	if(fr->down_sample == 3) ntom_set_ntom(fr, fr->firstframe);
947
	if(fr->down_sample == 3) ntom_set_ntom(fr, fr->firstframe);
796
#endif
948
#endif
797
	fr->ignoreframe = ignoreframe(fr);
949
	fr->ignoreframe = ignoreframe(fr);
798
#ifdef GAPLESS /* The sample offset is used for non-gapless mode, too! */
950
#ifdef GAPLESS /* The sample offset is used for non-gapless mode, too! */
Line 884... Line 1036...
884
	if(really) *really = mh->lastscale;
1036
	if(really) *really = mh->lastscale;
885
	get_rva(mh, NULL, rva_db);
1037
	get_rva(mh, NULL, rva_db);
886
	return MPG123_OK;
1038
	return MPG123_OK;
887
}
1039
}
Line -... Line 1040...
-
 
1040
 
-
 
1041
off_t attribute_align_arg mpg123_framepos(mpg123_handle *mh)
-
 
1042
{
-
 
1043
	if(mh == NULL) return MPG123_ERR;
-
 
1044
 
-
 
1045
	return mh->input_offset;