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
	libmpg123: MPEG Audio Decoder library
2
	libmpg123: MPEG Audio Decoder library
Line 3... Line 3...
3
 
3
 
4
	copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
4
	copyright 1995-2012 by the mpg123 project - free software under the terms of the LGPL 2.1
Line 5... Line 5...
5
	see COPYING and AUTHORS files in distribution or http://mpg123.org
5
	see COPYING and AUTHORS files in distribution or http://mpg123.org
Line 6... Line 6...
6
 
6
 
7
*/
7
*/
8
 
8
 
Line 9... Line 9...
9
#include "mpg123lib_intern.h"
9
#include "mpg123lib_intern.h"
10
#include "icy2utf8.h"
-
 
11
#include "debug.h"
-
 
12
 
-
 
13
#ifdef GAPLESS
-
 
14
#define SAMPLE_ADJUST(x)   ((x) - ((mh->p.flags & MPG123_GAPLESS) ? mh->begin_os : 0))
-
 
15
#define SAMPLE_UNADJUST(x) ((x) + ((mh->p.flags & MPG123_GAPLESS) ? mh->begin_os : 0))
-
 
Line 16... Line 10...
16
#else
10
#include "icy2utf8.h"
Line 17... Line 11...
17
#define SAMPLE_ADJUST(x)   (x)
11
#include "debug.h"
Line 18... Line -...
18
#define SAMPLE_UNADJUST(x) (x)
-
 
19
#endif
-
 
20
 
-
 
21
#define SEEKFRAME(mh) ((mh)->ignoreframe < 0 ? 0 : (mh)->ignoreframe)
-
 
22
 
-
 
23
static int initialized = 0;
-
 
24
 
-
 
25
#define ALIGNCHECK(mh)
-
 
26
#define ALIGNCHECKK
-
 
27
/* On compilers that support data alignment but not the automatic stack realignment.
-
 
28
   We check for properly aligned stack before risking a crash because of badly compiled
-
 
29
   client program. */
-
 
30
#if (defined CCALIGN) && (defined NEED_ALIGNCHECK) && ((defined DEBUG) || (defined CHECK_ALIGN))
-
 
31
 
-
 
32
/* Common building block. */
-
 
33
#define ALIGNMAINPART \
-
 
34
	/* minimum size of 16 bytes, not all compilers would align a smaller piece of data */ \
-
 
35
	double ALIGNED(16) altest[2]; \
-
 
36
	debug2("testing alignment, with %lu %% 16 = %lu", \
-
 
37
		(unsigned long)altest, (unsigned long)((size_t)altest % 16)); \
-
 
38
	if((size_t)altest % 16 != 0)
-
 
39
 
-
 
40
#undef ALIGNCHECK
-
 
41
#define ALIGNCHECK(mh) \
-
 
42
	ALIGNMAINPART \
-
 
43
	{ \
-
 
44
		error("Stack variable is not aligned! Your combination of compiler/library is dangerous!"); \
-
 
45
		if(mh != NULL) mh->err = MPG123_BAD_ALIGN; \
-
 
46
\
-
 
47
		return MPG123_ERR; \
-
 
48
	}
-
 
49
#undef ALIGNCHECKK
-
 
50
#define ALIGNCHECKK \
-
 
51
	ALIGNMAINPART \
-
 
52
	{ \
-
 
53
		error("Stack variable is not aligned! Your combination of compiler/library is dangerous!"); \
-
 
54
		return MPG123_BAD_ALIGN; \
-
 
55
	}
-
 
56
 
-
 
57
#endif
-
 
58
 
-
 
59
#ifdef GAPLESS
-
 
60
/*
-
 
61
	Take the buffer after a frame decode (strictly: it is the data from frame fr->num!) and cut samples out.
-
 
62
	fr->buffer.fill may then be smaller than before...
-
 
63
*/
-
 
64
static void frame_buffercheck(mpg123_handle *fr)
-
 
65
{
-
 
66
	/* When we have no accurate position, gapless code does not make sense. */
-
 
67
	if(!fr->accurate) return;
-
 
68
 
-
 
69
	/* The first interesting frame: Skip some leading samples. */
-
 
70
	if(fr->firstoff && fr->num == fr->firstframe)
-
 
71
	{
-
 
72
		off_t byteoff = samples_to_bytes(fr, fr->firstoff);
-
 
73
		if((off_t)fr->buffer.fill > byteoff)
-
 
74
		{
-
 
75
			fr->buffer.fill -= byteoff;
-
 
76
			/* buffer.p != buffer.data only for own buffer */
-
 
77
			debug6("cutting %li samples/%li bytes on begin, own_buffer=%i at %p=%p, buf[1]=%i",
-
 
78
			        (long)fr->firstoff, (long)byteoff, fr->own_buffer, (void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]);
-
 
79
			if(fr->own_buffer) fr->buffer.p = fr->buffer.data + byteoff;
-
 
80
			else memmove(fr->buffer.data, fr->buffer.data + byteoff, fr->buffer.fill);
-
 
81
			debug3("done cutting, buffer at %p =? %p, buf[1]=%i",
-
 
82
			        (void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]);
-
 
83
		}
-
 
84
		else fr->buffer.fill = 0;
-
 
85
		fr->firstoff = 0; /* Only enter here once... when you seek, firstoff should be reset. */
-
 
86
	}
-
 
87
	/* The last interesting (planned) frame: Only use some leading samples. */
-
 
88
	if(fr->lastoff && fr->num == fr->lastframe)
-
 
89
	{
-
 
90
		off_t byteoff = samples_to_bytes(fr, fr->lastoff);
-
 
91
		if((off_t)fr->buffer.fill > byteoff)
-
 
92
		{
-
 
93
			fr->buffer.fill = byteoff;
12
 
94
		}
13
#include "gapless.h"
95
		fr->lastoff = 0; /* Only enter here once... when you seek, lastoff should be reset. */
-
 
96
	}
14
 
Line 97... Line 15...
97
}
15
#define SEEKFRAME(mh) ((mh)->ignoreframe < 0 ? 0 : (mh)->ignoreframe)
Line 98... Line 16...
98
#endif
16
 
Line 130... Line 48...
130
/* ...the full routine with optional initial parameters to override defaults. */
48
/* ...the full routine with optional initial parameters to override defaults. */
131
mpg123_handle attribute_align_arg *mpg123_parnew(mpg123_pars *mp, const char* decoder, int *error)
49
mpg123_handle attribute_align_arg *mpg123_parnew(mpg123_pars *mp, const char* decoder, int *error)
132
{
50
{
133
	mpg123_handle *fr = NULL;
51
	mpg123_handle *fr = NULL;
134
	int err = MPG123_OK;
52
	int err = MPG123_OK;
135
#if (defined CCALIGN) && (defined NEED_ALIGNCHECK) && ((defined DEBUG) || (defined CHECK_ALIGN))
-
 
136
#ifdef CCALIGN
-
 
137
	double ALIGNED(16) altest[4];
-
 
138
	if(((size_t)altest) % 16 != 0)
-
 
139
	{
53
 
140
		error("Stack variable is not aligned! Your combination of compiler/library is dangerous!");
-
 
141
		*error = MPG123_BAD_ALIGN;
-
 
142
		return NULL;
-
 
143
	}
-
 
144
#endif
-
 
145
#endif
-
 
146
	if(initialized) fr = (mpg123_handle*) malloc(sizeof(mpg123_handle));
54
	if(initialized) fr = (mpg123_handle*) malloc(sizeof(mpg123_handle));
147
	else err = MPG123_NOT_INITIALIZED;
55
	else err = MPG123_NOT_INITIALIZED;
148
	if(fr != NULL)
56
	if(fr != NULL)
149
	{
57
	{
150
		frame_init_par(fr, mp);
58
		frame_init_par(fr, mp);
Line 157... Line 65...
157
			fr = NULL;
65
			fr = NULL;
158
		}
66
		}
159
	}
67
	}
160
	if(fr != NULL)
68
	if(fr != NULL)
161
	{
69
	{
162
		/* Cleanup that mess! ... use mpg123_decoder / decode_update! */
-
 
163
		if(frame_outbuffer(fr) != 0)
-
 
164
		{
-
 
165
			err = MPG123_NO_BUFFERS;
-
 
166
			frame_exit(fr);
-
 
167
			free(fr);
-
 
168
			fr = NULL;
-
 
169
		}
-
 
170
		else
-
 
171
		{
-
 
172
			/* I smell cleanup here... with get_next_frame() */
-
 
173
/*			if(decode_update(fr) != 0)
-
 
174
			{
-
 
175
				err = fr->err != MPG123_OK ? fr->err : MPG123_BAD_DECODER;
-
 
176
				frame_exit(fr);
-
 
177
				free(fr);
-
 
178
				fr = NULL;
-
 
179
			}
-
 
180
			else */
-
 
181
			fr->decoder_change = 1;
70
		fr->decoder_change = 1;
182
		}
71
	}
183
	}
-
 
184
	else if(err == MPG123_OK) err = MPG123_OUT_OF_MEM;
72
	else if(err == MPG123_OK) err = MPG123_OUT_OF_MEM;
Line 185... Line 73...
185
 
73
 
186
	if(error != NULL) *error = err;
74
	if(error != NULL) *error = err;
187
	return fr;
75
	return fr;
Line 188... Line 76...
188
}
76
}
189
 
77
 
190
int attribute_align_arg mpg123_decoder(mpg123_handle *mh, const char* decoder)
78
int attribute_align_arg mpg123_decoder(mpg123_handle *mh, const char* decoder)
191
{
-
 
-
 
79
{
192
	enum optdec dt = dectype(decoder);
80
	enum optdec dt = dectype(decoder);
Line 193... Line 81...
193
	ALIGNCHECK(mh);
81
 
194
	if(mh == NULL) return MPG123_ERR;
82
	if(mh == NULL) return MPG123_ERR;
195
 
83
 
Line 215... Line 103...
215
	{
103
	{
216
		mh->err = MPG123_NO_BUFFERS;
104
		mh->err = MPG123_NO_BUFFERS;
217
		frame_exit(mh);
105
		frame_exit(mh);
218
		return MPG123_ERR;
106
		return MPG123_ERR;
219
	}
107
	}
220
	/* I smell cleanup here... with get_next_frame() */
108
	/* Do _not_ call decode_update here! That is only allowed after a first MPEG frame has been met. */
221
	decode_update(mh);
-
 
222
	mh->decoder_change = 1;
109
	mh->decoder_change = 1;
223
	return MPG123_OK;
110
	return MPG123_OK;
224
}
111
}
Line 225... Line 112...
225
 
112
 
226
int attribute_align_arg mpg123_param(mpg123_handle *mh, enum mpg123_parms key, long val, double fval)
113
int attribute_align_arg mpg123_param(mpg123_handle *mh, enum mpg123_parms key, long val, double fval)
227
{
114
{
228
	int r;
-
 
-
 
115
	int r;
229
	ALIGNCHECK(mh);
116
 
230
	if(mh == NULL) return MPG123_ERR;
117
	if(mh == NULL) return MPG123_ERR;
231
	r = mpg123_par(&mh->p, key, val, fval);
118
	r = mpg123_par(&mh->p, key, val, fval);
232
	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
119
	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
233
	else
120
	else
Line 237... Line 124...
237
		{ /* Apply frame index size and grow property on the fly. */
124
		{ /* Apply frame index size and grow property on the fly. */
238
			r = frame_index_setup(mh);
125
			r = frame_index_setup(mh);
239
			if(r != MPG123_OK) mh->err = MPG123_INDEX_FAIL;
126
			if(r != MPG123_OK) mh->err = MPG123_INDEX_FAIL;
240
		}
127
		}
241
#endif
128
#endif
-
 
129
#ifndef NO_FEEDER
-
 
130
		/* Feeder pool size is applied right away, reader will react to that. */
-
 
131
		if(key == MPG123_FEEDPOOL || key == MPG123_FEEDBUFFER)
-
 
132
		bc_poolsize(&mh->rdat.buffer, mh->p.feedpool, mh->p.feedbuffer);
-
 
133
#endif
242
	}
134
	}
243
	return r;
135
	return r;
244
}
136
}
Line 245... Line 137...
245
 
137
 
246
int attribute_align_arg mpg123_par(mpg123_pars *mp, enum mpg123_parms key, long val, double fval)
138
int attribute_align_arg mpg123_par(mpg123_pars *mp, enum mpg123_parms key, long val, double fval)
247
{
139
{
248
	int ret = MPG123_OK;
140
	int ret = MPG123_OK;
249
	ALIGNCHECKK
141
 
250
	if(mp == NULL) return MPG123_BAD_PARS;
142
	if(mp == NULL) return MPG123_BAD_PARS;
251
	switch(key)
143
	switch(key)
252
	{
144
	{
253
		case MPG123_VERBOSE:
145
		case MPG123_VERBOSE:
Line 311... Line 203...
311
			/* Choose the value that is non-zero, if any.
203
			/* Choose the value that is non-zero, if any.
312
			   Downscaling integers to 1.0 . */
204
			   Downscaling integers to 1.0 . */
313
			mp->outscale = val == 0 ? fval : (double)val/SHORT_SCALE;
205
			mp->outscale = val == 0 ? fval : (double)val/SHORT_SCALE;
314
		break;
206
		break;
315
		case MPG123_TIMEOUT:
207
		case MPG123_TIMEOUT:
316
#ifndef WIN32
208
#ifdef TIMEOUT_READ
317
			mp->timeout = val >= 0 ? val : 0;
209
			mp->timeout = val >= 0 ? val : 0;
318
#else
210
#else
319
			ret = MPG123_NO_TIMEOUT;
211
			if(val > 0) ret = MPG123_NO_TIMEOUT;
320
#endif
212
#endif
321
		break;
213
		break;
322
		case MPG123_RESYNC_LIMIT:
214
		case MPG123_RESYNC_LIMIT:
323
			mp->resync_limit = val;
215
			mp->resync_limit = val;
324
		break;
216
		break;
Line 331... Line 223...
331
		break;
223
		break;
332
		case MPG123_PREFRAMES:
224
		case MPG123_PREFRAMES:
333
			if(val >= 0) mp->preframes = val;
225
			if(val >= 0) mp->preframes = val;
334
			else ret = MPG123_BAD_VALUE;
226
			else ret = MPG123_BAD_VALUE;
335
		break;
227
		break;
-
 
228
		case MPG123_FEEDPOOL:
-
 
229
#ifndef NO_FEEDER
-
 
230
			if(val >= 0) mp->feedpool = val;
-
 
231
			else ret = MPG123_BAD_VALUE;
-
 
232
#else
-
 
233
			ret = MPG123_MISSING_FEATURE;
-
 
234
#endif
-
 
235
		break;
-
 
236
		case MPG123_FEEDBUFFER:
-
 
237
#ifndef NO_FEEDER
-
 
238
			if(val > 0) mp->feedbuffer = val;
-
 
239
			else ret = MPG123_BAD_VALUE;
-
 
240
#else
-
 
241
			ret = MPG123_MISSING_FEATURE;
-
 
242
#endif
-
 
243
		break;
336
		default:
244
		default:
337
			ret = MPG123_BAD_PARAM;
245
			ret = MPG123_BAD_PARAM;
338
	}
246
	}
339
	return ret;
247
	return ret;
340
}
248
}
Line 341... Line 249...
341
 
249
 
342
int attribute_align_arg mpg123_getparam(mpg123_handle *mh, enum mpg123_parms key, long *val, double *fval)
250
int attribute_align_arg mpg123_getparam(mpg123_handle *mh, enum mpg123_parms key, long *val, double *fval)
343
{
251
{
344
	int r;
-
 
-
 
252
	int r;
345
	ALIGNCHECK(mh);
253
 
346
	if(mh == NULL) return MPG123_ERR;
254
	if(mh == NULL) return MPG123_ERR;
347
	r = mpg123_getpar(&mh->p, key, val, fval);
255
	r = mpg123_getpar(&mh->p, key, val, fval);
348
	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
256
	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
349
	return r;
257
	return r;
Line 350... Line 258...
350
}
258
}
351
 
259
 
352
int attribute_align_arg mpg123_getpar(mpg123_pars *mp, enum mpg123_parms key, long *val, double *fval)
260
int attribute_align_arg mpg123_getpar(mpg123_pars *mp, enum mpg123_parms key, long *val, double *fval)
353
{
261
{
354
	int ret = 0;
262
	int ret = 0;
355
	ALIGNCHECKK
263
 
356
	if(mp == NULL) return MPG123_BAD_PARS;
264
	if(mp == NULL) return MPG123_BAD_PARS;
357
	switch(key)
265
	switch(key)
358
	{
266
	{
Line 406... Line 314...
406
#endif
314
#endif
407
		break;
315
		break;
408
		case MPG123_PREFRAMES:
316
		case MPG123_PREFRAMES:
409
			*val = mp->preframes;
317
			*val = mp->preframes;
410
		break;
318
		break;
-
 
319
		case MPG123_FEEDPOOL:
-
 
320
#ifndef NO_FEEDER
-
 
321
			*val = mp->feedpool;
-
 
322
#else
-
 
323
			ret = MPG123_MISSING_FEATURE;
-
 
324
#endif
-
 
325
		break;
-
 
326
		case MPG123_FEEDBUFFER:
-
 
327
#ifndef NO_FEEDER
-
 
328
			*val = mp->feedbuffer;
-
 
329
#else
-
 
330
			ret = MPG123_MISSING_FEATURE;
-
 
331
#endif
-
 
332
		break;
411
		default:
333
		default:
412
			ret = MPG123_BAD_PARAM;
334
			ret = MPG123_BAD_PARAM;
413
	}
335
	}
414
	return ret;
336
	return ret;
415
}
337
}
Line 417... Line 339...
417
int attribute_align_arg mpg123_getstate(mpg123_handle *mh, enum mpg123_state key, long *val, double *fval)
339
int attribute_align_arg mpg123_getstate(mpg123_handle *mh, enum mpg123_state key, long *val, double *fval)
418
{
340
{
419
	int ret = MPG123_OK;
341
	int ret = MPG123_OK;
420
	long theval = 0;
342
	long theval = 0;
421
	double thefval = 0.;
343
	double thefval = 0.;
422
	ALIGNCHECK(mh);
-
 
-
 
344
 
423
	if(mh == NULL) return MPG123_ERR;
345
	if(mh == NULL) return MPG123_ERR;
Line 424... Line 346...
424
 
346
 
425
	switch(key)
347
	switch(key)
426
	{
348
	{
-
 
349
		case MPG123_ACCURATE:
-
 
350
			theval = mh->state_flags & FRAME_ACCURATE;
-
 
351
		break;
-
 
352
		case MPG123_FRANKENSTEIN:
-
 
353
			theval = mh->state_flags & FRAME_FRANKENSTEIN;
-
 
354
		break;
-
 
355
		case MPG123_BUFFERFILL:
-
 
356
#ifndef NO_FEEDER
-
 
357
		{
427
		case MPG123_ACCURATE:
358
			size_t sval = bc_fill(&mh->rdat.buffer);
-
 
359
			theval = (long)sval;
-
 
360
			if((size_t)theval != sval)
-
 
361
			{
-
 
362
				mh->err = MPG123_INT_OVERFLOW;
-
 
363
				ret = MPG123_ERR;
-
 
364
			}
-
 
365
		}
-
 
366
#else
-
 
367
			mh->err = MPG123_MISSING_FEATURE;
-
 
368
			ret = MPG123_ERR;
428
			theval = mh->accurate;
369
#endif
429
		break;
370
		break;
430
		default:
371
		default:
431
			mh->err = MPG123_BAD_KEY;
372
			mh->err = MPG123_BAD_KEY;
432
			ret = MPG123_ERR;
373
			ret = MPG123_ERR;
Line 438... Line 379...
438
	return ret;
379
	return ret;
439
}
380
}
Line 440... Line 381...
440
 
381
 
441
int attribute_align_arg mpg123_eq(mpg123_handle *mh, enum mpg123_channels channel, int band, double val)
382
int attribute_align_arg mpg123_eq(mpg123_handle *mh, enum mpg123_channels channel, int band, double val)
442
{
-
 
443
	ALIGNCHECK(mh);
383
{
444
	if(mh == NULL) return MPG123_ERR;
384
	if(mh == NULL) return MPG123_ERR;
445
	if(band < 0 || band > 31){ mh->err = MPG123_BAD_BAND; return MPG123_ERR; }
385
	if(band < 0 || band > 31){ mh->err = MPG123_BAD_BAND; return MPG123_ERR; }
446
	switch(channel)
386
	switch(channel)
447
	{
387
	{
Line 459... Line 399...
459
}
399
}
Line 460... Line 400...
460
 
400
 
461
double attribute_align_arg mpg123_geteq(mpg123_handle *mh, enum mpg123_channels channel, int band)
401
double attribute_align_arg mpg123_geteq(mpg123_handle *mh, enum mpg123_channels channel, int band)
462
{
402
{
463
	double ret = 0.;
-
 
-
 
403
	double ret = 0.;
464
	ALIGNCHECK(mh);
404
 
Line 465... Line 405...
465
	if(mh == NULL) return MPG123_ERR;
405
	if(mh == NULL) return MPG123_ERR;
466
 
406
 
467
	/* Handle this gracefully. When there is no band, it has no volume. */
407
	/* Handle this gracefully. When there is no band, it has no volume. */
Line 481... Line 421...
481
 
421
 
482
 
422
 
483
/* plain file access, no http! */
423
/* plain file access, no http! */
484
int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
-
 
485
{
424
int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
Line 486... Line 425...
486
	ALIGNCHECK(mh);
425
{
487
	if(mh == NULL) return MPG123_ERR;
-
 
488
 
426
	if(mh == NULL) return MPG123_ERR;
489
	mpg123_close(mh);
427
 
Line 490... Line 428...
490
	frame_reset(mh);
428
	mpg123_close(mh);
491
	return open_stream(mh, path, -1);
429
	return open_stream(mh, path, -1);
492
}
-
 
493
 
430
}
Line 494... Line 431...
494
int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd)
431
 
495
{
-
 
496
	ALIGNCHECK(mh);
432
int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd)
497
	if(mh == NULL) return MPG123_ERR;
433
{
Line -... Line 434...
-
 
434
	if(mh == NULL) return MPG123_ERR;
-
 
435
 
-
 
436
	mpg123_close(mh);
-
 
437
	return open_stream(mh, NULL, fd);
-
 
438
}
-
 
439
 
-
 
440
int attribute_align_arg mpg123_open_handle(mpg123_handle *mh, void *iohandle)
-
 
441
{
-
 
442
	if(mh == NULL) return MPG123_ERR;
-
 
443
 
-
 
444
	mpg123_close(mh);
-
 
445
	if(mh->rdat.r_read_handle == NULL)
-
 
446
	{
498
 
447
		mh->err = MPG123_BAD_CUSTOM_IO;
499
	mpg123_close(mh);
448
		return MPG123_ERR;
500
	frame_reset(mh);
-
 
501
	return open_stream(mh, NULL, fd);
449
	}
Line 502... Line 450...
502
}
450
	return open_stream_handle(mh, iohandle);
503
 
-
 
504
int attribute_align_arg mpg123_open_feed(mpg123_handle *mh)
451
}
505
{
452
 
Line 506... Line 453...
506
	ALIGNCHECK(mh);
453
int attribute_align_arg mpg123_open_feed(mpg123_handle *mh)
507
	if(mh == NULL) return MPG123_ERR;
454
{
508
 
455
	if(mh == NULL) return MPG123_ERR;
509
	mpg123_close(mh);
456
 
510
	frame_reset(mh);
-
 
511
	return open_feed(mh);
457
	mpg123_close(mh);
-
 
458
	return open_feed(mh);
-
 
459
}
512
}
460
 
513
 
461
int attribute_align_arg mpg123_replace_reader( mpg123_handle *mh,
514
int attribute_align_arg mpg123_replace_reader( mpg123_handle *mh,
462
                           ssize_t (*r_read) (int, void *, size_t),
515
                           ssize_t (*r_read) (int, void *, size_t),
463
                           off_t   (*r_lseek)(int, off_t, int) )
Line -... Line 464...
-
 
464
{
-
 
465
	if(mh == NULL) return MPG123_ERR;
-
 
466
 
-
 
467
	mpg123_close(mh);
-
 
468
	mh->rdat.r_read = r_read;
-
 
469
	mh->rdat.r_lseek = r_lseek;
Line -... Line 470...
-
 
470
	return MPG123_OK;
-
 
471
}
-
 
472
 
-
 
473
int attribute_align_arg mpg123_replace_reader_handle( mpg123_handle *mh,
-
 
474
                           ssize_t (*r_read) (void*, void *, size_t),
-
 
475
                           off_t   (*r_lseek)(void*, off_t, int),
-
 
476
                           void    (*cleanup)(void*)  )
-
 
477
{
-
 
478
	if(mh == NULL) return MPG123_ERR;
-
 
479
 
-
 
480
	mpg123_close(mh);
516
                           off_t   (*r_lseek)(int, off_t, int) )
481
	mh->rdat.r_read_handle = r_read;
517
{
482
	mh->rdat.r_lseek_handle = r_lseek;
518
	ALIGNCHECK(mh);
483
	mh->rdat.cleanup_handle = cleanup;
519
	if(mh == NULL) return MPG123_ERR;
484
	return MPG123_OK;
-
 
485
}
520
	mh->rdat.r_read = r_read;
486
 
-
 
487
/* Update decoding engine for
-
 
488
   a) a new choice of decoder
-
 
489
   b) a changed native format of the MPEG stream
-
 
490
   ... calls are only valid after parsing some MPEG frame! */
-
 
491
int decode_update(mpg123_handle *mh)
-
 
492
{
-
 
493
	long native_rate;
521
	mh->rdat.r_lseek = r_lseek;
494
	int b;
Line 522... Line 495...
522
	return MPG123_OK;
495
 
523
}
496
	if(mh->num < 0)
Line 545... Line 518...
545
		case 0:
518
		case 0:
546
		case 1:
519
		case 1:
547
		case 2:
520
		case 2:
548
			mh->down_sample_sblimit = SBLIMIT>>(mh->down_sample);
521
			mh->down_sample_sblimit = SBLIMIT>>(mh->down_sample);
549
			/* With downsampling I get less samples per frame */
522
			/* With downsampling I get less samples per frame */
550
			mh->outblock = samples_to_bytes(mh, (spf(mh)>>mh->down_sample));
523
			mh->outblock = samples_to_storage(mh, (spf(mh)>>mh->down_sample));
551
		break;
524
		break;
552
#ifndef NO_NTOM
525
#ifndef NO_NTOM
553
		case 3:
526
		case 3:
554
		{
527
		{
555
			if(synth_ntom_set_step(mh) != 0) return -1;
528
			if(synth_ntom_set_step(mh) != 0) return -1;
Line 557... Line 530...
557
			{
530
			{
558
				mh->down_sample_sblimit = SBLIMIT * mh->af.rate;
531
				mh->down_sample_sblimit = SBLIMIT * mh->af.rate;
559
				mh->down_sample_sblimit /= frame_freq(mh);
532
				mh->down_sample_sblimit /= frame_freq(mh);
560
			}
533
			}
561
			else mh->down_sample_sblimit = SBLIMIT;
534
			else mh->down_sample_sblimit = SBLIMIT;
562
			mh->outblock = mh->af.encsize * mh->af.channels *
535
			mh->outblock = samples_to_storage(mh,
563
			               ( ( NTOM_MUL-1+spf(mh)
536
			                 ( ( NTOM_MUL-1+spf(mh)
564
			                   * (((size_t)NTOM_MUL*mh->af.rate)/frame_freq(mh))
537
			                   * (((size_t)NTOM_MUL*mh->af.rate)/frame_freq(mh))
565
			                 )/NTOM_MUL );
538
			                 )/NTOM_MUL ));
566
		}
539
		}
567
		break;
540
		break;
568
#endif
541
#endif
569
	}
542
	}
Line 574... Line 547...
574
		else mh->single = SINGLE_STEREO;
547
		else mh->single = SINGLE_STEREO;
575
	}
548
	}
576
	else mh->single = (mh->p.flags & MPG123_FORCE_MONO)-1;
549
	else mh->single = (mh->p.flags & MPG123_FORCE_MONO)-1;
577
	if(set_synth_functions(mh) != 0) return -1;;
550
	if(set_synth_functions(mh) != 0) return -1;;
Line -... Line 551...
-
 
551
 
-
 
552
	/* The needed size of output buffer may have changed. */
-
 
553
	if(frame_outbuffer(mh) != MPG123_OK) return -1;
578
 
554
 
579
	do_rva(mh);
555
	do_rva(mh);
Line 580... Line 556...
580
	debug3("done updating decoder structure with native rate %li and af.rate %li and down_sample %i", frame_freq(mh), mh->af.rate, mh->down_sample);
556
	debug3("done updating decoder structure with native rate %li and af.rate %li and down_sample %i", frame_freq(mh), mh->af.rate, mh->down_sample);
581
 
557
 
Line 582... Line 558...
582
	return 0;
558
	return 0;
583
}
559
}
584
 
560
 
585
size_t attribute_align_arg mpg123_safe_buffer()
561
size_t attribute_align_arg mpg123_safe_buffer(void)
586
{
562
{
Line 587... Line 563...
587
	/* real is the largest possible output (it's 32bit float, 32bit int or 64bit double). */
563
	/* real is the largest possible output (it's 32bit float, 32bit int or 64bit double). */
588
	return sizeof(real)*2*1152*NTOM_MAX;
564
	return sizeof(real)*2*1152*NTOM_MAX;
-
 
565
}
589
}
566
 
590
 
567
size_t attribute_align_arg mpg123_outblock(mpg123_handle *mh)
591
size_t attribute_align_arg mpg123_outblock(mpg123_handle *mh)
568
{
Line -... Line 569...
-
 
569
	/* Try to be helpful and never return zero output block size. */
-
 
570
	if(mh != NULL && mh->outblock > 0) return mh->outblock;
592
{
571
	else return mpg123_safe_buffer();
593
	if(mh != NULL) return mh->outblock;
572
}
-
 
573
 
-
 
574
/* Read in the next frame we actually want for decoding.
-
 
575
   This includes skipping/ignoring frames, in additon to skipping junk in the parser. */
594
	else return mpg123_safe_buffer();
576
static int get_next_frame(mpg123_handle *mh)
595
}
577
{
596
 
578
	/* We have some decoder ready, if the desired decoder has changed,
597
static int get_next_frame(mpg123_handle *mh)
579
	   it is OK to use the old one for ignoring frames and activating
598
{
580
	   the new one for real (decode_update()) after getting the frame. */
Line 619... Line 601...
619
		debug4("read of frame %li returned %i (to_decode=%i) at sample %li", (long)mh->num, b, mh->to_decode, (long)mpg123_tell(mh));
601
		debug4("read of frame %li returned %i (to_decode=%i) at sample %li", (long)mh->num, b, mh->to_decode, (long)mpg123_tell(mh));
620
		if(b == MPG123_NEED_MORE) return MPG123_NEED_MORE; /* need another call with data */
602
		if(b == MPG123_NEED_MORE) return MPG123_NEED_MORE; /* need another call with data */
621
		else if(b <= 0)
603
		else if(b <= 0)
622
		{
604
		{
623
			/* More sophisticated error control? */
605
			/* More sophisticated error control? */
624
			if(b==0 || mh->rdat.filepos == mh->rdat.filelen)
606
			if(b==0 || (mh->rdat.filelen >= 0 && mh->rdat.filepos == mh->rdat.filelen))
625
			{ /* We simply reached the end. */
607
			{ /* We simply reached the end. */
626
				mh->track_frames = mh->num + 1;
608
				mh->track_frames = mh->num + 1;
627
				debug("What about updating/checking gapless sample count here?");
609
				debug("What about updating/checking gapless sample count here?");
628
				return MPG123_DONE;
610
				return MPG123_DONE;
629
			}
611
			}
Line 648... Line 630...
648
			}
630
			}
649
		}
631
		}
650
		/* Or, we are finally done and have a new frame. */
632
		/* Or, we are finally done and have a new frame. */
651
		else break;
633
		else break;
652
	} while(1);
634
	} while(1);
653
	/* When we start actually using the CRC, this could move into the loop... */
-
 
654
	/* A question of semantics ... should I fold start_frame and frame_number into firstframe/lastframe? */
-
 
655
	if(mh->lastframe >= 0 && mh->num > mh->lastframe)
-
 
656
	{
635
 
657
		mh->to_decode = mh->to_ignore = FALSE;
636
	/* If we reach this point, we got a new frame ready to be decoded.
658
		return MPG123_DONE;
637
	   All other situations resulted in returns from the loop. */
659
	}
-
 
660
	if(change)
638
	if(change)
661
	{
639
	{
662
		if(decode_update(mh) < 0)  /* dito... */
640
		if(decode_update(mh) < 0)  /* dito... */
663
		return MPG123_ERR;
641
		return MPG123_ERR;
Line 664... Line 642...
664
 
642
 
Line 665... Line 643...
665
debug1("new format: %i", mh->new_format);
643
debug1("new format: %i", mh->new_format);
666
 
-
 
667
		mh->decoder_change = 0;
644
 
668
#ifdef GAPLESS
645
		mh->decoder_change = 0;
-
 
646
		if(mh->fresh)
669
		if(mh->fresh)
647
		{
670
		{
648
#ifdef GAPLESS
671
			int b=0;
649
			int b=0;
672
			/* Prepare offsets for gapless decoding. */
650
			/* Prepare offsets for gapless decoding. */
673
			debug1("preparing gapless stuff with native rate %li", frame_freq(mh));
651
			debug1("preparing gapless stuff with native rate %li", frame_freq(mh));
-
 
652
			frame_gapless_realinit(mh);
674
			frame_gapless_realinit(mh);
653
			frame_set_frameseek(mh, mh->num);
-
 
654
#endif
675
			frame_set_frameseek(mh, mh->num);
655
			mh->fresh = 0;
676
			mh->fresh = 0;
656
#ifdef GAPLESS
677
			/* Could this possibly happen? With a real big gapless offset... */
657
			/* Could this possibly happen? With a real big gapless offset... */
678
			if(mh->num < mh->firstframe) b = get_next_frame(mh);
-
 
679
			if(b < 0) return b; /* Could be error, need for more, new format... */
658
			if(mh->num < mh->firstframe) b = get_next_frame(mh);
680
		}
659
			if(b < 0) return b; /* Could be error, need for more, new format... */
-
 
660
#endif
681
#endif
661
		}
682
	}
662
	}
Line 683... Line 663...
683
	return MPG123_OK;
663
	return MPG123_OK;
-
 
664
}
684
}
665
 
685
 
666
/* Assumption: A buffer full of zero samples can be constructed by repetition of this byte.
686
/* Assumption: A buffer full of zero samples can be constructed by repetition of this byte.
667
   Oh, and it handles some format conversion.
687
   Only to be used by decode_the_frame() ... */
668
   Only to be used by decode_the_frame() ... */
688
static int zero_byte(mpg123_handle *fr)
669
static int zero_byte(mpg123_handle *fr)
Line 696... Line 677...
696
 
677
 
697
/*
678
/*
698
	Not part of the api. This just decodes the frame and fills missing bits with zeroes.
679
	Not part of the api. This just decodes the frame and fills missing bits with zeroes.
699
	There can be frames that are broken and thus make do_layer() fail.
680
	There can be frames that are broken and thus make do_layer() fail.
700
*/
681
*/
701
void decode_the_frame(mpg123_handle *fr)
682
static void decode_the_frame(mpg123_handle *fr)
702
{
683
{
703
	size_t needed_bytes = samples_to_bytes(fr, frame_outs(fr, fr->num+1)-frame_outs(fr, fr->num));
684
	size_t needed_bytes = samples_to_storage(fr, frame_expect_outsamples(fr));
704
	fr->clip += (fr->do_layer)(fr);
685
	fr->clip += (fr->do_layer)(fr);
705
	/*fprintf(stderr, "frame %"OFF_P": got %"SIZE_P" / %"SIZE_P"\n", fr->num,(size_p)fr->buffer.fill, (size_p)needed_bytes);*/
686
	/*fprintf(stderr, "frame %"OFF_P": got %"SIZE_P" / %"SIZE_P"\n", fr->num,(size_p)fr->buffer.fill, (size_p)needed_bytes);*/
706
	/* There could be less data than promised.
687
	/* There could be less data than promised.
707
	   Also, then debugging, we look out for coding errors that could result in _more_ data than expected. */
688
	   Also, then debugging, we look out for coding errors that could result in _more_ data than expected. */
Line 734... Line 715...
734
			if(NOQUIET)
715
			if(NOQUIET)
735
			error2("I got _more_ bytes than expected (%"SIZE_P" / %"SIZE_P"), that should not be possible!", (size_p)fr->buffer.fill, (size_p)needed_bytes);
716
			error2("I got _more_ bytes than expected (%"SIZE_P" / %"SIZE_P"), that should not be possible!", (size_p)fr->buffer.fill, (size_p)needed_bytes);
736
		}
717
		}
737
	}
718
	}
738
#endif
719
#endif
739
	/* Handle unsigned output formats via reshifting after decode here. */
-
 
740
#ifndef NO_32BIT
-
 
741
	if(fr->af.encoding == MPG123_ENC_UNSIGNED_32)
-
 
742
	{ /* 32bit signed -> unsigned */
-
 
743
		size_t i;
-
 
744
		int32_t *ssamples;
720
	postprocess_buffer(fr);
745
		uint32_t *usamples;
-
 
746
		ssamples = (int32_t*)fr->buffer.data;
-
 
747
		usamples = (uint32_t*)fr->buffer.data;
-
 
748
		debug("converting output to unsigned 32 bit integer");
-
 
749
		for(i=0; ibuffer.fill/sizeof(int32_t); ++i)
-
 
750
		{
-
 
751
			/* Different strategy since we don't have a larger type at hand.
-
 
752
				 Also watch out for silly +-1 fun because integer constants are signed in C90! */
-
 
753
			if(ssamples[i] >= 0)
-
 
754
			usamples[i] = (uint32_t)ssamples[i] + 2147483647+1;
-
 
755
			/* The smalles value goes zero. */
-
 
756
			else if(ssamples[i] == ((int32_t)-2147483647-1))
-
 
757
			usamples[i] = 0;
-
 
758
			/* Now -value is in the positive range of signed int ... so it's a possible value at all. */
-
 
759
			else
-
 
760
			usamples[i] = (uint32_t)2147483647+1 - (uint32_t)(-ssamples[i]);
-
 
761
		}
721
}
-
 
722
 
-
 
723
/*
-
 
724
	Decode the current frame into the frame structure's buffer, accessible at the location stored in 
-
 
725
	 will contain the last decoded frame number. This function should be called after mpg123_framebyframe_next positioned the stream at a
-
 
726
	valid mp3 frame. The buffer contents will get lost on the next call to mpg123_framebyframe_next or mpg123_framebyframe_decode.
-
 
727
	returns
-
 
728
	MPG123_OK -- successfully decoded or ignored the frame, you get your output data or in case of ignored frames 0 bytes
-
 
729
	MPG123_DONE -- decoding finished, should not happen
-
 
730
	MPG123_ERR -- some error occured.
-
 
731
	MPG123_ERR_NULL -- audio or bytes are not pointing to valid storage addresses
-
 
732
	MPG123_BAD_HANDLE -- mh has not been initialized
-
 
733
	MPG123_NO_SPACE -- not enough space in buffer for safe decoding, should not happen
-
 
734
*/
-
 
735
int attribute_align_arg mpg123_framebyframe_decode(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes)
-
 
736
{
-
 
737
	if(bytes == NULL) return MPG123_ERR_NULL;
-
 
738
	if(audio == NULL) return MPG123_ERR_NULL;
-
 
739
	if(mh == NULL) return MPG123_BAD_HANDLE;
-
 
740
	if(mh->buffer.size < mh->outblock) return MPG123_NO_SPACE;
-
 
741
 
-
 
742
	*bytes = 0;
-
 
743
	mh->buffer.fill = 0; /* always start fresh */
-
 
744
	if(!mh->to_decode) return MPG123_OK;
-
 
745
 
-
 
746
	if(num != NULL) *num = mh->num;
-
 
747
	debug("decoding");
-
 
748
	decode_the_frame(mh);
-
 
749
	mh->to_decode = mh->to_ignore = FALSE;
-
 
750
	mh->buffer.p = mh->buffer.data;
-
 
751
	FRAME_BUFFERCHECK(mh);
-
 
752
	*audio = mh->buffer.p;
-
 
753
	*bytes = mh->buffer.fill;
-
 
754
	return MPG123_OK;
762
	}
755
}
-
 
756
 
763
#endif
757
/*
-
 
758
	Find, read and parse the next mp3 frame while skipping junk and parsing id3 tags, lame headers, etc.
-
 
759
	Prepares everything for decoding using mpg123_framebyframe_decode.
764
#ifndef NO_16BIT
760
	returns
-
 
761
	MPG123_OK -- new frame was read and parsed, call mpg123_framebyframe_decode to actually decode
-
 
762
	MPG123_NEW_FORMAT -- new frame was read, it results in changed output format, call mpg123_framebyframe_decode to actually decode
765
	if(fr->af.encoding == MPG123_ENC_UNSIGNED_16)
763
	MPG123_BAD_HANDLE -- mh has not been initialized
-
 
764
	MPG123_NEED_MORE  -- more input data is needed to advance to the next frame. supply more input data using mpg123_feed
-
 
765
*/
-
 
766
int attribute_align_arg mpg123_framebyframe_next(mpg123_handle *mh)
766
	{
767
{
767
		size_t i;
768
	int b;
-
 
769
	if(mh == NULL) return MPG123_BAD_HANDLE;
-
 
770
 
-
 
771
	mh->to_decode = mh->to_ignore = FALSE;
768
		short *ssamples;
772
	mh->buffer.fill = 0;
-
 
773
 
769
		unsigned short *usamples;
774
	b = get_next_frame(mh);
770
		ssamples = (short*)fr->buffer.data;
775
	if(b < 0) return b;
771
		usamples = (unsigned short*)fr->buffer.data;
776
	debug1("got next frame, %i", mh->to_decode);
-
 
777
 
772
		debug("converting output to unsigned 16 bit integer");
778
	/* mpg123_framebyframe_decode will return MPG123_OK with 0 bytes decoded if mh->to_decode is 0 */
-
 
779
	if(!mh->to_decode)
-
 
780
		return MPG123_OK;
-
 
781
 
773
		for(i=0; ibuffer.fill/sizeof(short); ++i)
782
	if(mh->new_format)
774
		{
783
	{
775
			long tmp = (long)ssamples[i]+32768;
784
		debug("notifiying new format");
776
			usamples[i] = (unsigned short)tmp;
785
		mh->new_format = 0;
777
		}
786
		return MPG123_NEW_FORMAT;
778
	}
787
	}
-
 
788
 
779
#endif
789
	return MPG123_OK;
780
}
790
}
Line 781... Line 791...
781
 
791
 
782
/*
792
/*
783
	Put _one_ decoded frame into the frame structure's buffer, accessible at the location stored in 
793
	Put _one_ decoded frame into the frame structure's buffer, accessible at the location stored in 
Line 791... Line 801...
791
 
801
 
792
	num will be updated to the last decoded frame number (may possibly _not_ increase, p.ex. when format changed).
802
	num will be updated to the last decoded frame number (may possibly _not_ increase, p.ex. when format changed).
793
*/
803
*/
794
int attribute_align_arg mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes)
804
int attribute_align_arg mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes)
795
{
-
 
796
	ALIGNCHECK(mh);
805
{
797
	if(bytes != NULL) *bytes = 0;
806
	if(bytes != NULL) *bytes = 0;
798
	if(mh == NULL) return MPG123_ERR;
807
	if(mh == NULL) return MPG123_ERR;
799
	if(mh->buffer.size < mh->outblock) return MPG123_NO_SPACE;
808
	if(mh->buffer.size < mh->outblock) return MPG123_NO_SPACE;
800
	mh->buffer.fill = 0; /* always start fresh */
809
	mh->buffer.fill = 0; /* always start fresh */
Line 814... Line 823...
814
 
823
 
Line 815... Line 824...
815
			decode_the_frame(mh);
824
			decode_the_frame(mh);
816
 
825
 
817
			mh->to_decode = mh->to_ignore = FALSE;
-
 
818
			mh->buffer.p = mh->buffer.data;
-
 
819
#ifdef GAPLESS
826
			mh->to_decode = mh->to_ignore = FALSE;
820
			/* This checks for individual samples to skip, for gapless mode or sample-accurate seek. */
-
 
821
			frame_buffercheck(mh);
827
			mh->buffer.p = mh->buffer.data;
822
#endif
828
			FRAME_BUFFERCHECK(mh);
Line 823... Line 829...
823
			if(audio != NULL) *audio = mh->buffer.p;
829
			if(audio != NULL) *audio = mh->buffer.p;
824
			if(bytes != NULL) *bytes = mh->buffer.fill;
830
			if(bytes != NULL) *bytes = mh->buffer.fill;
Line 840... Line 846...
840
}
846
}
Line 841... Line 847...
841
 
847
 
842
int attribute_align_arg mpg123_feed(mpg123_handle *mh, const unsigned char *in, size_t size)
848
int attribute_align_arg mpg123_feed(mpg123_handle *mh, const unsigned char *in, size_t size)
843
{
849
{
-
 
850
	if(mh == NULL) return MPG123_ERR;
844
	if(mh == NULL) return MPG123_ERR;
851
#ifndef NO_FEEDER
845
	if(size > 0)
852
	if(size > 0)
846
	{
853
	{
847
		if(in != NULL)
854
		if(in != NULL)
848
		{
855
		{
-
 
856
			if(feed_more(mh, in, size) != 0) return MPG123_ERR;
-
 
857
			else
-
 
858
			{
-
 
859
				/* The need for more data might have triggered an error.
-
 
860
				   This one is outdated now with the new data. */
-
 
861
				if(mh->err == MPG123_ERR_READER) mh->err = MPG123_OK;
849
			if(feed_more(mh, in, size) != 0) return MPG123_ERR;
862
 
-
 
863
				return MPG123_OK;
850
			else return MPG123_OK;
864
			}
851
		}
865
		}
852
		else
866
		else
853
		{
867
		{
854
			mh->err = MPG123_NULL_BUFFER;
868
			mh->err = MPG123_NULL_BUFFER;
855
			return MPG123_ERR;
869
			return MPG123_ERR;
856
		}
870
		}
857
	}
871
	}
-
 
872
	return MPG123_OK;
-
 
873
#else
-
 
874
	mh->err = MPG123_MISSING_FEATURE;
-
 
875
	return MPG123_ERR;
858
	return MPG123_OK;
876
#endif
Line 859... Line 877...
859
}
877
}
860
 
878
 
861
/*
879
/*
Line 874... Line 892...
874
 
892
 
875
int attribute_align_arg mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize, unsigned char *outmemory, size_t outmemsize, size_t *done)
893
int attribute_align_arg mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize, unsigned char *outmemory, size_t outmemsize, size_t *done)
876
{
894
{
877
	int ret = MPG123_OK;
895
	int ret = MPG123_OK;
878
	size_t mdone = 0;
-
 
-
 
896
	size_t mdone = 0;
879
	ALIGNCHECK(mh);
897
 
880
	if(done != NULL) *done = 0;
898
	if(done != NULL) *done = 0;
-
 
899
	if(mh == NULL) return MPG123_ERR;
881
	if(mh == NULL) return MPG123_ERR;
900
#ifndef NO_FEEDER
882
	if(inmemsize > 0 && mpg123_feed(mh, inmemory, inmemsize) != MPG123_OK)
901
	if(inmemsize > 0 && mpg123_feed(mh, inmemory, inmemsize) != MPG123_OK)
883
	{
902
	{
884
		ret = MPG123_ERR;
903
		ret = MPG123_ERR;
885
		goto decodeend;
904
		goto decodeend;
Line 895... Line 914...
895
		{
914
		{
896
			if(mh->new_format)
915
			if(mh->new_format)
897
			{
916
			{
898
				debug("notifiying new format");
917
				debug("notifiying new format");
899
				mh->new_format = 0;
918
				mh->new_format = 0;
900
				return MPG123_NEW_FORMAT;
919
				ret = MPG123_NEW_FORMAT;
-
 
920
				goto decodeend;
901
			}
921
			}
902
			if(mh->buffer.size - mh->buffer.fill < mh->outblock)
922
			if(mh->buffer.size - mh->buffer.fill < mh->outblock)
903
			{
923
			{
904
				ret = MPG123_NO_SPACE;
924
				ret = MPG123_NO_SPACE;
905
				goto decodeend;
925
				goto decodeend;
906
			}
926
			}
907
			decode_the_frame(mh);
927
			decode_the_frame(mh);
908
			mh->to_decode = mh->to_ignore = FALSE;
928
			mh->to_decode = mh->to_ignore = FALSE;
909
			mh->buffer.p = mh->buffer.data;
929
			mh->buffer.p = mh->buffer.data;
910
			debug2("decoded frame %li, got %li samples in buffer", (long)mh->num, (long)(mh->buffer.fill / (samples_to_bytes(mh, 1))));
930
			debug2("decoded frame %li, got %li samples in buffer", (long)mh->num, (long)(mh->buffer.fill / (samples_to_bytes(mh, 1))));
911
#ifdef GAPLESS
-
 
912
			frame_buffercheck(mh); /* Seek & gapless. */
931
			FRAME_BUFFERCHECK(mh);
913
#endif
-
 
914
		}
932
		}
915
		if(mh->buffer.fill) /* Copy (part of) the decoded data to the caller's buffer. */
933
		if(mh->buffer.fill) /* Copy (part of) the decoded data to the caller's buffer. */
916
		{
934
		{
917
			/* get what is needed - or just what is there */
935
			/* get what is needed - or just what is there */
918
			int a = mh->buffer.fill > (outmemsize - mdone) ? outmemsize - mdone : mh->buffer.fill;
936
			int a = mh->buffer.fill > (outmemsize - mdone) ? outmemsize - mdone : mh->buffer.fill;
Line 932... Line 950...
932
		}
950
		}
933
	}
951
	}
934
decodeend:
952
decodeend:
935
	if(done != NULL) *done = mdone;
953
	if(done != NULL) *done = mdone;
936
	return ret;
954
	return ret;
-
 
955
#else
-
 
956
	mh->err = MPG123_MISSING_FEATURE;
-
 
957
	return MPG123_ERR;
-
 
958
#endif
937
}
959
}
Line 938... Line 960...
938
 
960
 
939
long attribute_align_arg mpg123_clip(mpg123_handle *mh)
961
long attribute_align_arg mpg123_clip(mpg123_handle *mh)
940
{
962
{
941
	long ret = 0;
-
 
-
 
963
	long ret = 0;
942
	ALIGNCHECK(mh);
964
 
943
	if(mh != NULL)
965
	if(mh != NULL)
944
	{
966
	{
945
		ret = mh->clip;
967
		ret = mh->clip;
946
		mh->clip = 0;
968
		mh->clip = 0;
947
	}
969
	}
948
	return ret;
970
	return ret;
Line -... Line 971...
-
 
971
}
949
}
972
 
Line 950... Line 973...
950
 
973
/* Simples: Track needs initializtion if no initial frame has been read yet. */
951
#define track_need_init(mh) (!(mh)->to_decode && (mh)->fresh)
974
#define track_need_init(mh) ((mh)->num < 0)
952
 
975
 
953
static int init_track(mpg123_handle *mh)
976
static int init_track(mpg123_handle *mh)
Line 961... Line 984...
961
	return 0;
984
	return 0;
962
}
985
}
Line 963... Line 986...
963
 
986
 
964
int attribute_align_arg mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
987
int attribute_align_arg mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
965
{
988
{
-
 
989
	int b;
966
	ALIGNCHECK(mh);
990
 
-
 
991
	if(mh == NULL) return MPG123_ERR;
967
	if(mh == NULL) return MPG123_ERR;
992
	b = init_track(mh);
Line 968... Line 993...
968
	if(init_track(mh) == MPG123_ERR) return MPG123_ERR;
993
	if(b < 0) return b;
969
 
994
 
970
	if(rate != NULL) *rate = mh->af.rate;
995
	if(rate != NULL) *rate = mh->af.rate;
971
	if(channels != NULL) *channels = mh->af.channels;
996
	if(channels != NULL) *channels = mh->af.channels;
Line 975... Line 1000...
975
}
1000
}
Line 976... Line 1001...
976
 
1001
 
977
off_t attribute_align_arg mpg123_timeframe(mpg123_handle *mh, double seconds)
1002
off_t attribute_align_arg mpg123_timeframe(mpg123_handle *mh, double seconds)
978
{
1003
{
979
	off_t b;
-
 
-
 
1004
	off_t b;
980
	ALIGNCHECK(mh);
1005
 
981
	if(mh == NULL) return MPG123_ERR;
1006
	if(mh == NULL) return MPG123_ERR;
982
	b = init_track(mh);
1007
	b = init_track(mh);
983
	if(b<0) return b;
1008
	if(b<0) return b;
984
	return (off_t)(seconds/mpg123_tpf(mh));
1009
	return (off_t)(seconds/mpg123_tpf(mh));
Line 992... Line 1017...
992
	Then, there is firstframe...when we didn't reach it yet, then the next data will come from there.
1017
	Then, there is firstframe...when we didn't reach it yet, then the next data will come from there.
993
	mh->num starts with -1
1018
	mh->num starts with -1
994
*/
1019
*/
995
off_t attribute_align_arg mpg123_tell(mpg123_handle *mh)
1020
off_t attribute_align_arg mpg123_tell(mpg123_handle *mh)
996
{
1021
{
997
	ALIGNCHECK(mh);
-
 
998
	if(mh == NULL) return MPG123_ERR;
1022
	if(mh == NULL) return MPG123_ERR;
999
	if(track_need_init(mh)) return 0;
1023
	if(track_need_init(mh)) return 0;
1000
	/* Now we have all the info at hand. */
1024
	/* Now we have all the info at hand. */
1001
	debug5("tell: %li/%i first %li buffer %lu; frame_outs=%li", (long)mh->num, mh->to_decode, (long)mh->firstframe, (unsigned long)mh->buffer.fill, (long)frame_outs(mh, mh->num));
1025
	debug5("tell: %li/%i first %li buffer %lu; frame_outs=%li", (long)mh->num, mh->to_decode, (long)mh->firstframe, (unsigned long)mh->buffer.fill, (long)frame_outs(mh, mh->num));
Line 1016... Line 1040...
1016
		else
1040
		else
1017
		{ /* We serve what we have in buffer and then the beginning of next frame... */
1041
		{ /* We serve what we have in buffer and then the beginning of next frame... */
1018
			pos = frame_outs(mh, mh->num+1) - bytes_to_samples(mh, mh->buffer.fill);
1042
			pos = frame_outs(mh, mh->num+1) - bytes_to_samples(mh, mh->buffer.fill);
1019
		}
1043
		}
1020
		/* Substract padding and delay from the beginning. */
1044
		/* Substract padding and delay from the beginning. */
1021
		pos = SAMPLE_ADJUST(pos);
1045
		pos = SAMPLE_ADJUST(mh,pos);
1022
		/* Negative sample offsets are not right, less than nothing is still nothing. */
1046
		/* Negative sample offsets are not right, less than nothing is still nothing. */
1023
		return pos>0 ? pos : 0;
1047
		return pos>0 ? pos : 0;
1024
	}
1048
	}
1025
}
1049
}
Line 1026... Line 1050...
1026
 
1050
 
1027
off_t attribute_align_arg mpg123_tellframe(mpg123_handle *mh)
1051
off_t attribute_align_arg mpg123_tellframe(mpg123_handle *mh)
1028
{
-
 
1029
	ALIGNCHECK(mh);
1052
{
1030
	if(mh == NULL) return MPG123_ERR;
1053
	if(mh == NULL) return MPG123_ERR;
1031
	if(mh->num < mh->firstframe) return mh->firstframe;
1054
	if(mh->num < mh->firstframe) return mh->firstframe;
1032
	if(mh->to_decode) return mh->num;
1055
	if(mh->to_decode) return mh->num;
1033
	/* Consider firstoff? */
1056
	/* Consider firstoff? */
1034
	return mh->buffer.fill ? mh->num : mh->num + 1;
1057
	return mh->buffer.fill ? mh->num : mh->num + 1;
Line 1035... Line 1058...
1035
}
1058
}
1036
 
1059
 
1037
off_t attribute_align_arg mpg123_tell_stream(mpg123_handle *mh)
-
 
1038
{
1060
off_t attribute_align_arg mpg123_tell_stream(mpg123_handle *mh)
1039
	ALIGNCHECK(mh);
1061
{
1040
	if(mh == NULL) return MPG123_ERR;
1062
	if(mh == NULL) return MPG123_ERR;
1041
	/* mh->rd is at least a bad_reader, so no worry. */
1063
	/* mh->rd is at least a bad_reader, so no worry. */
Line 1068... Line 1090...
1068
	frame_buffers_reset(mh);
1090
	frame_buffers_reset(mh);
1069
#ifndef NO_NTOM
1091
#ifndef NO_NTOM
1070
	if(mh->down_sample == 3)
1092
	if(mh->down_sample == 3)
1071
	{
1093
	{
1072
		ntom_set_ntom(mh, fnum);
1094
		ntom_set_ntom(mh, fnum);
1073
		debug3("fixed ntom for frame %"OFF_P" to %lu, num=%"OFF_P, fnum, mh->ntom_val[0], mh->num);
1095
		debug3("fixed ntom for frame %"OFF_P" to %lu, num=%"OFF_P, (off_p)fnum, mh->ntom_val[0], (off_p)mh->num);
1074
	}
1096
	}
1075
#endif
1097
#endif
1076
	b = mh->rd->seek_frame(mh, fnum);
1098
	b = mh->rd->seek_frame(mh, fnum);
1077
	debug1("seek_frame returned: %i", b);
1099
	debug1("seek_frame returned: %i", b);
1078
	if(b<0) return b;
1100
	if(b<0) return b;
Line 1085... Line 1107...
1085
 
1107
 
1086
off_t attribute_align_arg mpg123_seek(mpg123_handle *mh, off_t sampleoff, int whence)
1108
off_t attribute_align_arg mpg123_seek(mpg123_handle *mh, off_t sampleoff, int whence)
1087
{
1109
{
1088
	int b;
1110
	int b;
1089
	off_t pos;
-
 
-
 
1111
	off_t pos;
1090
	ALIGNCHECK(mh);
1112
 
1091
	pos = mpg123_tell(mh); /* adjusted samples */
1113
	pos = mpg123_tell(mh); /* adjusted samples */
1092
	/* pos < 0 also can mean that simply a former seek failed at the lower levels.
1114
	/* pos < 0 also can mean that simply a former seek failed at the lower levels.
1093
	  In that case, we only allow absolute seeks. */
1115
	  In that case, we only allow absolute seeks. */
1094
	if(pos < 0 && whence != SEEK_SET)
1116
	if(pos < 0 && whence != SEEK_SET)
Line 1103... Line 1125...
1103
		case SEEK_SET: pos  = sampleoff; break;
1125
		case SEEK_SET: pos  = sampleoff; break;
1104
		case SEEK_END:
1126
		case SEEK_END:
1105
			/* When we do not know the end already, we can try to find it. */
1127
			/* When we do not know the end already, we can try to find it. */
1106
			if(mh->track_frames < 1 && (mh->rdat.flags & READER_SEEKABLE))
1128
			if(mh->track_frames < 1 && (mh->rdat.flags & READER_SEEKABLE))
1107
			mpg123_scan(mh);
1129
			mpg123_scan(mh);
-
 
1130
			if(mh->track_frames > 0) pos = SAMPLE_ADJUST(mh,frame_outs(mh, mh->track_frames)) - sampleoff;
1108
#ifdef GAPLESS
1131
#ifdef GAPLESS
1109
			if(mh->end_os > 0) pos = SAMPLE_ADJUST(mh->end_os) - sampleoff;
1132
			else if(mh->end_os > 0) pos = SAMPLE_ADJUST(mh,mh->end_os) - sampleoff;
1110
#else
-
 
1111
			if(mh->track_frames > 0) pos = SAMPLE_ADJUST(frame_outs(mh, mh->track_frames)) - sampleoff;
-
 
1112
#endif
1133
#endif
1113
			else
1134
			else
1114
			{
1135
			{
1115
				mh->err = MPG123_NO_SEEK_FROM_END;
1136
				mh->err = MPG123_NO_SEEK_FROM_END;
1116
				return MPG123_ERR;
1137
				return MPG123_ERR;
Line 1118... Line 1139...
1118
		break;
1139
		break;
1119
		default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR;
1140
		default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR;
1120
	}
1141
	}
1121
	if(pos < 0) pos = 0;
1142
	if(pos < 0) pos = 0;
1122
	/* pos now holds the wanted sample offset in adjusted samples */
1143
	/* pos now holds the wanted sample offset in adjusted samples */
1123
	frame_set_seek(mh, SAMPLE_UNADJUST(pos));
1144
	frame_set_seek(mh, SAMPLE_UNADJUST(mh,pos));
1124
	pos = do_the_seek(mh);
1145
	pos = do_the_seek(mh);
1125
	if(pos < 0) return pos;
1146
	if(pos < 0) return pos;
Line 1126... Line 1147...
1126
 
1147
 
1127
	return mpg123_tell(mh);
1148
	return mpg123_tell(mh);
Line 1135... Line 1156...
1135
*/
1156
*/
1136
off_t attribute_align_arg mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset)
1157
off_t attribute_align_arg mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset)
1137
{
1158
{
1138
	int b;
1159
	int b;
1139
	off_t pos;
1160
	off_t pos;
1140
	ALIGNCHECK(mh);
-
 
-
 
1161
 
1141
	pos = mpg123_tell(mh); /* adjusted samples */
1162
	pos = mpg123_tell(mh); /* adjusted samples */
1142
	debug3("seek from %li to %li (whence=%i)", (long)pos, (long)sampleoff, whence);
1163
	debug3("seek from %li to %li (whence=%i)", (long)pos, (long)sampleoff, whence);
1143
	/* The special seek error handling does not apply here... there is no lowlevel I/O. */
1164
	/* The special seek error handling does not apply here... there is no lowlevel I/O. */
1144
	if(pos < 0) return pos; /* mh == NULL is covered in mpg123_tell() */
1165
	if(pos < 0) return pos; /* mh == NULL is covered in mpg123_tell() */
-
 
1166
#ifndef NO_FEEDER
1145
	if(input_offset == NULL)
1167
	if(input_offset == NULL)
1146
	{
1168
	{
1147
		mh->err = MPG123_NULL_POINTER;
1169
		mh->err = MPG123_NULL_POINTER;
1148
		return MPG123_ERR;
1170
		return MPG123_ERR;
1149
	}
1171
	}
Line 1153... Line 1175...
1153
	switch(whence)
1175
	switch(whence)
1154
	{
1176
	{
1155
		case SEEK_CUR: pos += sampleoff; break;
1177
		case SEEK_CUR: pos += sampleoff; break;
1156
		case SEEK_SET: pos  = sampleoff; break;
1178
		case SEEK_SET: pos  = sampleoff; break;
1157
		case SEEK_END:
1179
		case SEEK_END:
-
 
1180
			if(mh->track_frames > 0) pos = SAMPLE_ADJUST(mh,frame_outs(mh, mh->track_frames)) - sampleoff;
1158
#ifdef GAPLESS
1181
#ifdef GAPLESS
1159
			if(mh->end_os >= 0) pos = SAMPLE_ADJUST(mh->end_os) - sampleoff;
1182
			else if(mh->end_os >= 0) pos = SAMPLE_ADJUST(mh,mh->end_os) - sampleoff;
1160
#else
-
 
1161
			if(mh->track_frames > 0) pos = SAMPLE_ADJUST(frame_outs(mh, mh->track_frames)) - sampleoff;
-
 
1162
#endif
1183
#endif
1163
			else
1184
			else
1164
			{
1185
			{
1165
				mh->err = MPG123_NO_SEEK_FROM_END;
1186
				mh->err = MPG123_NO_SEEK_FROM_END;
1166
				return MPG123_ERR;
1187
				return MPG123_ERR;
1167
			}
1188
			}
1168
		break;
1189
		break;
1169
		default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR;
1190
		default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR;
1170
	}
1191
	}
1171
	if(pos < 0) pos = 0;
1192
	if(pos < 0) pos = 0;
1172
	frame_set_seek(mh, SAMPLE_UNADJUST(pos));
1193
	frame_set_seek(mh, SAMPLE_UNADJUST(mh,pos));
1173
	pos = SEEKFRAME(mh);
1194
	pos = SEEKFRAME(mh);
1174
	mh->buffer.fill = 0;
1195
	mh->buffer.fill = 0;
Line 1175... Line 1196...
1175
 
1196
 
1176
	/* Shortcuts without modifying input stream. */
1197
	/* Shortcuts without modifying input stream. */
Line 1183... Line 1204...
1183
	mh->num = pos-1; /* The next read frame will have num = pos. */
1204
	mh->num = pos-1; /* The next read frame will have num = pos. */
1184
	if(*input_offset < 0) return MPG123_ERR;
1205
	if(*input_offset < 0) return MPG123_ERR;
Line 1185... Line 1206...
1185
 
1206
 
1186
feedseekend:
1207
feedseekend:
-
 
1208
	return mpg123_tell(mh);
-
 
1209
#else
-
 
1210
	mh->err = MPG123_MISSING_FEATURE;
-
 
1211
	return MPG123_ERR;
1187
	return mpg123_tell(mh);
1212
#endif
Line 1188... Line 1213...
1188
}
1213
}
1189
 
1214
 
1190
off_t attribute_align_arg mpg123_seek_frame(mpg123_handle *mh, off_t offset, int whence)
1215
off_t attribute_align_arg mpg123_seek_frame(mpg123_handle *mh, off_t offset, int whence)
1191
{
1216
{
1192
	int b;
-
 
-
 
1217
	int b;
1193
	off_t pos = 0;
1218
	off_t pos = 0;
1194
	ALIGNCHECK(mh);
1219
 
Line 1195... Line 1220...
1195
	if(mh == NULL) return MPG123_ERR;
1220
	if(mh == NULL) return MPG123_ERR;
1196
	if((b=init_track(mh)) < 0) return b;
1221
	if((b=init_track(mh)) < 0) return b;
Line 1212... Line 1237...
1212
		default:
1237
		default:
1213
			mh->err = MPG123_BAD_WHENCE;
1238
			mh->err = MPG123_BAD_WHENCE;
1214
			return MPG123_ERR;
1239
			return MPG123_ERR;
1215
	}
1240
	}
1216
	if(pos < 0) pos = 0;
1241
	if(pos < 0) pos = 0;
1217
	/* Hm, do we need to seek right past the end? */
-
 
1218
	else if(mh->track_frames > 0 && pos >= mh->track_frames) pos = mh->track_frames;
1242
	/* Not limiting the possible position on end for the chance that there might be more to the stream than announced via track_frames. */
Line 1219... Line 1243...
1219
 
1243
 
1220
	frame_set_frameseek(mh, pos);
1244
	frame_set_frameseek(mh, pos);
1221
	pos = do_the_seek(mh);
1245
	pos = do_the_seek(mh);
Line 1222... Line 1246...
1222
	if(pos < 0) return pos;
1246
	if(pos < 0) return pos;
1223
 
1247
 
Line 1224... Line 1248...
1224
	return mpg123_tellframe(mh);
1248
	return mpg123_tellframe(mh);
1225
}
1249
}
1226
 
-
 
1227
int attribute_align_arg mpg123_set_filesize(mpg123_handle *mh, off_t size)
1250
 
Line 1228... Line 1251...
1228
{
1251
int attribute_align_arg mpg123_set_filesize(mpg123_handle *mh, off_t size)
1229
	ALIGNCHECK(mh);
1252
{
1230
	if(mh == NULL) return MPG123_ERR;
1253
	if(mh == NULL) return MPG123_ERR;
Line 1231... Line 1254...
1231
 
1254
 
1232
	mh->rdat.filelen = size;
1255
	mh->rdat.filelen = size;
1233
	return MPG123_OK;
1256
	return MPG123_OK;
1234
}
1257
}
1235
 
-
 
-
 
1258
 
1236
off_t attribute_align_arg mpg123_length(mpg123_handle *mh)
1259
off_t attribute_align_arg mpg123_length(mpg123_handle *mh)
1237
{
1260
{
1238
	int b;
1261
	int b;
1239
	off_t length;
1262
	off_t length;
1240
	ALIGNCHECK(mh);
1263
 
Line 1250... Line 1273...
1250
		length = (off_t)((double)(mh->rdat.filelen)/bpf*spf(mh));
1273
		length = (off_t)((double)(mh->rdat.filelen)/bpf*spf(mh));
1251
	}
1274
	}
1252
	else if(mh->rdat.filelen == 0) return mpg123_tell(mh); /* we could be in feeder mode */
1275
	else if(mh->rdat.filelen == 0) return mpg123_tell(mh); /* we could be in feeder mode */
1253
	else return MPG123_ERR; /* No length info there! */
1276
	else return MPG123_ERR; /* No length info there! */
Line -... Line 1277...
-
 
1277
 
-
 
1278
	debug1("mpg123_length: internal sample length: %"OFF_P, (off_p)length);
1254
 
1279
 
1255
	length = frame_ins2outs(mh, length);
-
 
1256
#ifdef GAPLESS
1280
	length = frame_ins2outs(mh, length);
1257
	if(mh->end_os > 0 && length > mh->end_os) length = mh->end_os;
1281
	debug1("mpg123_length: external sample length: %"OFF_P, (off_p)length);
1258
	length -= mh->begin_os;
-
 
1259
#endif
1282
	length = SAMPLE_ADJUST(mh,length);
1260
	return length;
1283
	return length;
Line 1261... Line 1284...
1261
}
1284
}
1262
 
1285
 
1263
int attribute_align_arg mpg123_scan(mpg123_handle *mh)
1286
int attribute_align_arg mpg123_scan(mpg123_handle *mh)
1264
{
1287
{
1265
	int b;
1288
	int b;
1266
	off_t backframe;
1289
	off_t oldpos;
-
 
1290
	off_t track_frames = 0;
1267
	int to_decode, to_ignore;
1291
	off_t track_samples = 0;
1268
	ALIGNCHECK(mh);
1292
 
1269
	if(mh == NULL) return MPG123_ERR;
1293
	if(mh == NULL) return MPG123_ERR;
1270
	if(!(mh->rdat.flags & READER_SEEKABLE)){ mh->err = MPG123_NO_SEEK; return MPG123_ERR; }
1294
	if(!(mh->rdat.flags & READER_SEEKABLE)){ mh->err = MPG123_NO_SEEK; return MPG123_ERR; }
1271
	/* Scan through the _whole_ file, since the current position is no count but computed assuming constant samples per frame. */
1295
	/* Scan through the _whole_ file, since the current position is no count but computed assuming constant samples per frame. */
Line 1275... Line 1299...
1275
	if(b<0)
1299
	if(b<0)
1276
	{
1300
	{
1277
		if(b == MPG123_DONE) return MPG123_OK;
1301
		if(b == MPG123_DONE) return MPG123_OK;
1278
		else return MPG123_ERR; /* Must be error here, NEED_MORE is not for seekable streams. */
1302
		else return MPG123_ERR; /* Must be error here, NEED_MORE is not for seekable streams. */
1279
	}
1303
	}
1280
	backframe = mh->num;
-
 
1281
	to_decode = mh->to_decode;
1304
	oldpos = mpg123_tell(mh);
1282
	to_ignore = mh->to_ignore;
-
 
1283
	b = mh->rd->seek_frame(mh, 0);
1305
	b = mh->rd->seek_frame(mh, 0);
1284
	if(b<0 || mh->num != 0) return MPG123_ERR;
1306
	if(b<0 || mh->num != 0) return MPG123_ERR;
1285
	/* One frame must be there now. */
1307
	/* One frame must be there now. */
1286
	mh->track_frames = 1;
1308
	track_frames = 1;
1287
	mh->track_samples = spf(mh); /* Internal samples. */
1309
	track_samples = spf(mh); /* Internal samples. */
-
 
1310
	debug("TODO: We should disable gapless code when encountering inconsistent spf(mh)!");
-
 
1311
	/* Do not increment mh->track_frames in the loop as tha would confuse Frankenstein detection. */
1288
	while(read_frame(mh) == 1)
1312
	while(read_frame(mh) == 1)
1289
	{
1313
	{
1290
		++mh->track_frames;
1314
		++track_frames;
1291
		mh->track_samples += spf(mh);
1315
		track_samples += spf(mh);
1292
	}
1316
	}
-
 
1317
	mh->track_frames = track_frames;
-
 
1318
	mh->track_samples = track_samples;
-
 
1319
	mpg123_seek_frame(mh, SEEK_SET, mh->track_frames);
-
 
1320
	debug2("Scanning yielded %"OFF_P" track samples, %"OFF_P" frames.", (off_p)mh->track_samples, (off_p)mh->track_frames);
1293
#ifdef GAPLESS
1321
#ifdef GAPLESS
1294
	/* Also, think about usefulness of that extra value track_samples ... it could be used for consistency checking. */
1322
	/* Also, think about usefulness of that extra value track_samples ... it could be used for consistency checking. */
1295
	frame_gapless_update(mh, mh->track_samples);
1323
	frame_gapless_update(mh, mh->track_samples);
1296
#endif	
1324
#endif
1297
	b = mh->rd->seek_frame(mh, backframe);
-
 
1298
	if(b<0 || mh->num != backframe) return MPG123_ERR;
1325
	return mpg123_seek(mh, oldpos, SEEK_SET) >= 0 ? MPG123_OK : MPG123_ERR;
1299
	mh->to_decode = to_decode;
-
 
1300
	mh->to_ignore = to_ignore;
-
 
1301
	return MPG123_OK;
-
 
1302
}
1326
}
Line 1303... Line 1327...
1303
 
1327
 
1304
int attribute_align_arg mpg123_meta_check(mpg123_handle *mh)
1328
int attribute_align_arg mpg123_meta_check(mpg123_handle *mh)
1305
{
1329
{
1306
	if(mh != NULL) return mh->metaflags;
1330
	if(mh != NULL) return mh->metaflags;
1307
	else return 0;
1331
	else return 0;
Line -... Line 1332...
-
 
1332
}
-
 
1333
 
-
 
1334
void attribute_align_arg mpg123_meta_free(mpg123_handle *mh)
-
 
1335
{
-
 
1336
	if(mh == NULL) return;
-
 
1337
 
-
 
1338
	reset_id3(mh);
-
 
1339
	reset_icy(&mh->icy);
1308
}
1340
}
1309
 
1341
 
1310
int attribute_align_arg mpg123_id3(mpg123_handle *mh, mpg123_id3v1 **v1, mpg123_id3v2 **v2)
-
 
1311
{
1342
int attribute_align_arg mpg123_id3(mpg123_handle *mh, mpg123_id3v1 **v1, mpg123_id3v2 **v2)
1312
	ALIGNCHECK(mh);
1343
{
1313
	if(v1 != NULL) *v1 = NULL;
1344
	if(v1 != NULL) *v1 = NULL;
Line 1314... Line 1345...
1314
	if(v2 != NULL) *v2 = NULL;
1345
	if(v2 != NULL) *v2 = NULL;
Line 1331... Line 1362...
1331
	return MPG123_OK;
1362
	return MPG123_OK;
1332
}
1363
}
Line 1333... Line 1364...
1333
 
1364
 
1334
int attribute_align_arg mpg123_icy(mpg123_handle *mh, char **icy_meta)
1365
int attribute_align_arg mpg123_icy(mpg123_handle *mh, char **icy_meta)
1335
{
-
 
1336
	ALIGNCHECK(mh);
1366
{
1337
	if(mh == NULL) return MPG123_ERR;
1367
	if(mh == NULL) return MPG123_ERR;
1338
#ifndef NO_ICY
1368
#ifndef NO_ICY
1339
	if(icy_meta == NULL)
1369
	if(icy_meta == NULL)
1340
	{
1370
	{
Line 1354... Line 1384...
1354
	mh->err = MPG123_MISSING_FEATURE;
1384
	mh->err = MPG123_MISSING_FEATURE;
1355
	return MPG123_ERR;
1385
	return MPG123_ERR;
1356
#endif
1386
#endif
1357
}
1387
}
Line 1358... Line -...
1358
 
-
 
1359
/*
-
 
1360
	Simple utility functions that do not possibly call code with extra alignment requirements do not use the ALIGNCHECK.
-
 
1361
	I am aware of the chance that the compiler could have introduced such code outside assembly functions, but such a modern compiler (gcc) can also honour attribute_align_arg.
-
 
1362
*/
-
 
1363
 
1388
 
1364
char* attribute_align_arg mpg123_icy2utf8(const char* icy_text)
1389
char* attribute_align_arg mpg123_icy2utf8(const char* icy_text)
1365
{
1390
{
1366
#ifndef NO_ICY
1391
#ifndef NO_ICY
1367
	return icy2utf8(icy_text, 0);
1392
	return icy2utf8(icy_text, 0);
Line 1433... Line 1458...
1433
}
1458
}
1434
#endif
1459
#endif
Line 1435... Line 1460...
1435
 
1460
 
1436
int attribute_align_arg mpg123_index(mpg123_handle *mh, off_t **offsets, off_t *step, size_t *fill)
1461
int attribute_align_arg mpg123_index(mpg123_handle *mh, off_t **offsets, off_t *step, size_t *fill)
1437
{
-
 
1438
	ALIGNCHECK(mh);
1462
{
1439
	if(mh == NULL) return MPG123_ERR;
1463
	if(mh == NULL) return MPG123_ERR;
1440
	if(offsets == NULL || step == NULL || fill == NULL)
1464
	if(offsets == NULL || step == NULL || fill == NULL)
1441
	{
1465
	{
1442
		mh->err = MPG123_BAD_INDEX_PAR;
1466
		mh->err = MPG123_BAD_INDEX_PAR;
Line 1452... Line 1476...
1452
	*fill    = 0;
1476
	*fill    = 0;
1453
#endif
1477
#endif
1454
	return MPG123_OK;
1478
	return MPG123_OK;
1455
}
1479
}
Line -... Line 1480...
-
 
1480
 
-
 
1481
int attribute_align_arg mpg123_set_index(mpg123_handle *mh, off_t *offsets, off_t step, size_t fill)
-
 
1482
{
-
 
1483
	if(mh == NULL) return MPG123_ERR;
-
 
1484
#ifdef FRAME_INDEX
-
 
1485
	if(step == 0)
-
 
1486
	{
-
 
1487
		mh->err = MPG123_BAD_INDEX_PAR;
-
 
1488
		return MPG123_ERR;
-
 
1489
	}
-
 
1490
	if(fi_set(&mh->index, offsets, step, fill) == -1)
-
 
1491
	{
-
 
1492
		mh->err = MPG123_OUT_OF_MEM;
-
 
1493
		return MPG123_ERR;
-
 
1494
	}
-
 
1495
	return MPG123_OK;
-
 
1496
#else
-
 
1497
	mh->err = MPG123_MISSING_FEATURE;
-
 
1498
	return MPG123_ERR;
-
 
1499
#endif
-
 
1500
}
1456
 
1501
 
1457
int attribute_align_arg mpg123_close(mpg123_handle *mh)
1502
int attribute_align_arg mpg123_close(mpg123_handle *mh)
1458
{
-
 
1459
	ALIGNCHECK(mh);
1503
{
-
 
1504
	if(mh == NULL) return MPG123_ERR;
-
 
1505
 
1460
	if(mh == NULL) return MPG123_ERR;
1506
	/* mh->rd is never NULL! */
1461
	if(mh->rd != NULL && mh->rd->close != NULL) mh->rd->close(mh);
1507
	if(mh->rd->close != NULL) mh->rd->close(mh);
1462
	mh->rd = NULL;
1508
 
1463
	if(mh->new_format)
1509
	if(mh->new_format)
1464
	{
1510
	{
1465
		debug("Hey, we are closing a track before the new format has been queried...");
1511
		debug("Hey, we are closing a track before the new format has been queried...");
1466
		invalidate_format(&mh->af);
1512
		invalidate_format(&mh->af);
1467
		mh->new_format = 0;
1513
		mh->new_format = 0;
-
 
1514
	}
-
 
1515
	/* Always reset the frame buffers on close, so we cannot forget it in funky opening routines (wrappers, even). */
1468
	}
1516
	frame_reset(mh);
1469
	return MPG123_OK;
1517
	return MPG123_OK;
Line 1470... Line 1518...
1470
}
1518
}
1471
 
1519
 
Line 1520... Line 1568...
1520
	"Frame index operation failed.",
1568
	"Frame index operation failed.",
1521
	"Decoder setup failed (invalid combination of settings?)",
1569
	"Decoder setup failed (invalid combination of settings?)",
1522
	"Feature not in this build."
1570
	"Feature not in this build."
1523
	,"Some bad value has been provided."
1571
	,"Some bad value has been provided."
1524
	,"Low-level seeking has failed (call to lseek(), usually)."
1572
	,"Low-level seeking has failed (call to lseek(), usually)."
-
 
1573
	,"Custom I/O obviously not prepared."
-
 
1574
	,"Overflow in LFS (large file support) conversion."
-
 
1575
	,"Overflow in integer conversion."
1525
};
1576
};
Line 1526... Line 1577...
1526
 
1577
 
1527
const char* attribute_align_arg mpg123_plain_strerror(int errcode)
1578
const char* attribute_align_arg mpg123_plain_strerror(int errcode)
1528
{
1579
{