Subversion Repositories Kolibri OS

Rev

Rev 1905 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1905 Rev 3960
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.
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
7
*/
7
*/
8
 
8
 
9
#include "mpg123lib_intern.h"
9
#include "mpg123lib_intern.h"
10
#include "getcpuflags.h"
10
#include "getcpuflags.h"
11
#include "debug.h"
11
#include "debug.h"
12
 
12
 
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)
16
#define NTOM_MUL (32768)
-
 
17
 
17
#define aligned_pointer(p,type,alignment) \
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*.
-
 
25
	*/
-
 
26
	uintptr_t baseval = (uintptr_t)(char*)base;
18
	(((char*)(p)-(char*)NULL) % (alignment)) \
27
	uintptr_t aoff = baseval % alignment;
-
 
28
 
-
 
29
	debug3("align_the_pointer: pointer %p is off by %u from %u",
-
 
30
	       base, (unsigned int)aoff, alignment);
-
 
31
 
19
	? (type*)((char*)(p) + (alignment) - (((char*)(p)-(char*)NULL) % (alignment))) \
32
	if(aoff) return (char*)base+alignment-aoff;
20
	: (type*)(p)
33
	else     return base;
-
 
34
}
-
 
35
 
21
void frame_default_pars(mpg123_pars *mp)
36
static void frame_default_pars(mpg123_pars *mp)
22
{
37
{
23
	mp->outscale = 1.0;
38
	mp->outscale = 1.0;
24
#ifdef GAPLESS
-
 
25
	mp->flags = MPG123_GAPLESS;
-
 
26
#else
-
 
27
	mp->flags = 0;
39
	mp->flags = 0;
-
 
40
#ifdef GAPLESS
-
 
41
	mp->flags |= MPG123_GAPLESS;
28
#endif
42
#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
32
	mp->down_sample = 0;
47
	mp->down_sample = 0;
33
	mp->rva = 0;
48
	mp->rva = 0;
34
	mp->halfspeed = 0;
49
	mp->halfspeed = 0;
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
}
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);
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
{
58
	fr->own_buffer = FALSE;
76
	fr->own_buffer = TRUE;
59
	fr->buffer.data = NULL;
77
	fr->buffer.data = NULL;
-
 
78
	fr->buffer.rdata = NULL;
-
 
79
	fr->buffer.fill = 0;
-
 
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
68
	fr->dithernoise = NULL;
89
	fr->dithernoise = NULL;
69
#endif
90
#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);
73
#ifndef NO_NTOM
95
#ifndef NO_NTOM
74
	/* these two look unnecessary, check guarantee for synth_ntom_set_step (in control_generic, even)! */
96
	/* these two look unnecessary, check guarantee for synth_ntom_set_step (in control_generic, even)! */
75
	fr->ntom_val[0] = NTOM_MUL>>1;
97
	fr->ntom_val[0] = NTOM_MUL>>1;
76
	fr->ntom_val[1] = NTOM_MUL>>1;
98
	fr->ntom_val[1] = NTOM_MUL>>1;
77
	fr->ntom_step = NTOM_MUL;
99
	fr->ntom_step = NTOM_MUL;
78
#endif
100
#endif
79
	/* unnecessary: fr->buffer.size = fr->buffer.fill = 0; */
101
	/* unnecessary: fr->buffer.size = fr->buffer.fill = 0; */
80
	mpg123_reset_eq(fr);
102
	mpg123_reset_eq(fr);
81
	init_icy(&fr->icy);
103
	init_icy(&fr->icy);
82
	init_id3(fr);
104
	init_id3(fr);
83
	/* frame_outbuffer is missing... */
105
	/* frame_outbuffer is missing... */
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));
-
 
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;
98
	fr->make_decode_tables = NULL;
130
	fr->make_decode_tables = NULL;
99
#ifdef FRAME_INDEX
131
#ifdef FRAME_INDEX
100
	fi_init(&fr->index);
132
	fi_init(&fr->index);
101
	frame_index_setup(fr); /* Apply the size setting. */
133
	frame_index_setup(fr); /* Apply the size setting. */
102
#endif
134
#endif
103
}
135
}
104
 
136
 
105
#ifdef OPT_DITHER
137
#ifdef OPT_DITHER
106
/* Also, only allocate the memory for the table on demand.
138
/* Also, only allocate the memory for the table on demand.
107
   In future, one could create special noise for different sampling frequencies(?). */
139
   In future, one could create special noise for different sampling frequencies(?). */
108
int frame_dither_init(mpg123_handle *fr)
140
int frame_dither_init(mpg123_handle *fr)
109
{
141
{
110
	/* run-time dither noise table generation */
142
	/* run-time dither noise table generation */
111
	if(fr->dithernoise == NULL)
143
	if(fr->dithernoise == NULL)
112
	{
144
	{
113
		fr->dithernoise = malloc(sizeof(float)*DITHERSIZE);
145
		fr->dithernoise = malloc(sizeof(float)*DITHERSIZE);
114
		if(fr->dithernoise == NULL) return 0;
146
		if(fr->dithernoise == NULL) return 0;
115
 
147
 
116
		dither_table_init(fr->dithernoise);
148
		dither_table_init(fr->dithernoise);
117
	}
149
	}
118
	return 1;
150
	return 1;
119
}
151
}
120
#endif
152
#endif
121
 
153
 
122
mpg123_pars attribute_align_arg *mpg123_new_pars(int *error)
154
mpg123_pars attribute_align_arg *mpg123_new_pars(int *error)
123
{
155
{
124
	mpg123_pars *mp = malloc(sizeof(struct mpg123_pars_struct));
156
	mpg123_pars *mp = malloc(sizeof(struct mpg123_pars_struct));
125
	if(mp != NULL){ frame_default_pars(mp); if(error != NULL) *error = MPG123_OK; }
157
	if(mp != NULL){ frame_default_pars(mp); if(error != NULL) *error = MPG123_OK; }
126
	else if(error != NULL) *error = MPG123_OUT_OF_MEM;
158
	else if(error != NULL) *error = MPG123_OUT_OF_MEM;
127
	return mp;
159
	return mp;
128
}
160
}
129
 
161
 
130
void attribute_align_arg mpg123_delete_pars(mpg123_pars* mp)
162
void attribute_align_arg mpg123_delete_pars(mpg123_pars* mp)
131
{
163
{
132
	if(mp != NULL) free(mp);
164
	if(mp != NULL) free(mp);
133
}
165
}
134
 
166
 
135
int attribute_align_arg mpg123_reset_eq(mpg123_handle *mh)
167
int attribute_align_arg mpg123_reset_eq(mpg123_handle *mh)
136
{
168
{
137
	int i;
169
	int i;
138
	mh->have_eq_settings = 0;
170
	mh->have_eq_settings = 0;
139
	for(i=0; i < 32; ++i) mh->equalizer[0][i] = mh->equalizer[1][i] = DOUBLE_TO_REAL(1.0);
171
	for(i=0; i < 32; ++i) mh->equalizer[0][i] = mh->equalizer[1][i] = DOUBLE_TO_REAL(1.0);
140
 
172
 
141
	return MPG123_OK;
173
	return MPG123_OK;
142
}
174
}
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;
179
	if(!fr->own_buffer)
148
	if(fr->buffer.data != NULL && fr->buffer.size != size)
-
 
149
	{
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)
-
 
192
	{
150
		free(fr->buffer.data);
193
		free(fr->buffer.rdata);
151
		fr->buffer.data = NULL;
194
		fr->buffer.rdata = NULL;
152
	}
195
	}
153
	fr->buffer.size = size;
196
	fr->buffer.size = size;
-
 
197
	fr->buffer.data = NULL;
-
 
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;
159
	}
204
	}
-
 
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;
163
}
209
}
164
 
210
 
165
int attribute_align_arg mpg123_replace_buffer(mpg123_handle *mh, unsigned char *data, size_t size)
211
int attribute_align_arg mpg123_replace_buffer(mpg123_handle *mh, unsigned char *data, size_t size)
166
{
212
{
-
 
213
	debug2("replace buffer with %p size %"SIZE_P, data, (size_p)size);
167
	if(data == NULL || size < mpg123_safe_buffer())
214
	/* Will accept any size, the error comes later... */
-
 
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
	}
172
	if(mh->own_buffer && mh->buffer.data != NULL) free(mh->buffer.data);
220
	if(mh->buffer.rdata != NULL) free(mh->buffer.rdata);
173
	mh->own_buffer = FALSE;
221
	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;
177
	return MPG123_OK;
226
	return MPG123_OK;
178
}
227
}
179
 
228
 
180
#ifdef FRAME_INDEX
229
#ifdef FRAME_INDEX
181
int frame_index_setup(mpg123_handle *fr)
230
int frame_index_setup(mpg123_handle *fr)
182
{
231
{
183
	int ret = MPG123_ERR;
232
	int ret = MPG123_ERR;
184
	if(fr->p.index_size >= 0)
233
	if(fr->p.index_size >= 0)
185
	{ /* Simple fixed index. */
234
	{ /* Simple fixed index. */
186
		fr->index.grow_size = 0;
235
		fr->index.grow_size = 0;
187
		debug1("resizing index to %li", fr->p.index_size);
236
		debug1("resizing index to %li", fr->p.index_size);
188
		ret = fi_resize(&fr->index, (size_t)fr->p.index_size);
237
		ret = fi_resize(&fr->index, (size_t)fr->p.index_size);
189
		debug2("index resized... %lu at %p", (unsigned long)fr->index.size, (void*)fr->index.data);
238
		debug2("index resized... %lu at %p", (unsigned long)fr->index.size, (void*)fr->index.data);
190
	}
239
	}
191
	else
240
	else
192
	{ /* A growing index. We give it a start, though. */
241
	{ /* A growing index. We give it a start, though. */
193
		fr->index.grow_size = (size_t)(- fr->p.index_size);
242
		fr->index.grow_size = (size_t)(- fr->p.index_size);
194
		if(fr->index.size < fr->index.grow_size)
243
		if(fr->index.size < fr->index.grow_size)
195
		ret = fi_resize(&fr->index, fr->index.grow_size);
244
		ret = fi_resize(&fr->index, fr->index.grow_size);
196
		else
245
		else
197
		ret = MPG123_OK; /* We have minimal size already... and since growing is OK... */
246
		ret = MPG123_OK; /* We have minimal size already... and since growing is OK... */
198
	}
247
	}
199
	debug2("set up frame index of size %lu (ret=%i)", (unsigned long)fr->index.size, ret);
248
	debug2("set up frame index of size %lu (ret=%i)", (unsigned long)fr->index.size, ret);
200
 
249
 
201
	return ret;
250
	return ret;
202
}
251
}
203
#endif
252
#endif
204
 
253
 
205
static void frame_decode_buffers_reset(mpg123_handle *fr)
254
static void frame_decode_buffers_reset(mpg123_handle *fr)
206
{
255
{
207
	memset(fr->rawbuffs, 0, fr->rawbuffss);
256
	memset(fr->rawbuffs, 0, fr->rawbuffss);
208
}
257
}
209
 
258
 
210
int frame_buffers(mpg123_handle *fr)
259
int frame_buffers(mpg123_handle *fr)
211
{
260
{
212
	int buffssize = 0;
261
	int buffssize = 0;
213
	debug1("frame %p buffer", (void*)fr);
262
	debug1("frame %p buffer", (void*)fr);
214
/*
263
/*
215
	the used-to-be-static buffer of the synth functions, has some subtly different types/sizes
264
	the used-to-be-static buffer of the synth functions, has some subtly different types/sizes
216
 
265
 
217
	2to1, 4to1, ntom, generic, i386: real[2][2][0x110]
266
	2to1, 4to1, ntom, generic, i386: real[2][2][0x110]
218
	mmx, sse: short[2][2][0x110]
267
	mmx, sse: short[2][2][0x110]
219
	i586(_dither): 4352 bytes; int/long[2][2][0x110]
268
	i586(_dither): 4352 bytes; int/long[2][2][0x110]
220
	i486: int[2][2][17*FIR_BUFFER_SIZE]
269
	i486: int[2][2][17*FIR_BUFFER_SIZE]
221
	altivec: static real __attribute__ ((aligned (16))) buffs[4][4][0x110]
270
	altivec: static real __attribute__ ((aligned (16))) buffs[4][4][0x110]
222
 
271
 
223
	Huh, altivec looks like fun. Well, let it be large... then, the 16 byte alignment seems to be implicit on MacOSX malloc anyway.
272
	Huh, altivec looks like fun. Well, let it be large... then, the 16 byte alignment seems to be implicit on MacOSX malloc anyway.
224
	Let's make a reasonable attempt to allocate enough memory...
273
	Let's make a reasonable attempt to allocate enough memory...
225
	Keep in mind: biggest ones are i486 and altivec (mutually exclusive!), then follows i586 and normal real.
274
	Keep in mind: biggest ones are i486 and altivec (mutually exclusive!), then follows i586 and normal real.
226
	mmx/sse use short but also real for resampling.
275
	mmx/sse use short but also real for resampling.
227
	Thus, minimum is 2*2*0x110*sizeof(real).
276
	Thus, minimum is 2*2*0x110*sizeof(real).
228
*/
277
*/
229
	if(fr->cpu_opts.type == altivec) buffssize = 4*4*0x110*sizeof(real);
278
	if(fr->cpu_opts.type == altivec) buffssize = 4*4*0x110*sizeof(real);
230
#ifdef OPT_I486
279
#ifdef OPT_I486
231
	else if(fr->cpu_opts.type == ivier) buffssize = 2*2*17*FIR_BUFFER_SIZE*sizeof(int);
280
	else if(fr->cpu_opts.type == ivier) buffssize = 2*2*17*FIR_BUFFER_SIZE*sizeof(int);
232
#endif
281
#endif
233
	else if(fr->cpu_opts.type == ifuenf || fr->cpu_opts.type == ifuenf_dither || fr->cpu_opts.type == dreidnow)
282
	else if(fr->cpu_opts.type == ifuenf || fr->cpu_opts.type == ifuenf_dither || fr->cpu_opts.type == dreidnow)
234
	buffssize = 2*2*0x110*4; /* don't rely on type real, we need 4352 bytes */
283
	buffssize = 2*2*0x110*4; /* don't rely on type real, we need 4352 bytes */
235
 
284
 
236
	if(2*2*0x110*sizeof(real) > buffssize)
285
	if(2*2*0x110*sizeof(real) > buffssize)
237
	buffssize = 2*2*0x110*sizeof(real);
286
	buffssize = 2*2*0x110*sizeof(real);
238
	buffssize += 15; /* For 16-byte alignment (SSE likes that). */
287
	buffssize += 15; /* For 16-byte alignment (SSE likes that). */
239
 
288
 
240
	if(fr->rawbuffs != NULL && fr->rawbuffss != buffssize)
289
	if(fr->rawbuffs != NULL && fr->rawbuffss != buffssize)
241
	{
290
	{
242
		free(fr->rawbuffs);
291
		free(fr->rawbuffs);
243
		fr->rawbuffs = NULL;
292
		fr->rawbuffs = NULL;
244
	}
293
	}
245
 
294
 
246
	if(fr->rawbuffs == NULL) fr->rawbuffs = (unsigned char*) malloc(buffssize);
295
	if(fr->rawbuffs == NULL) fr->rawbuffs = (unsigned char*) malloc(buffssize);
247
	if(fr->rawbuffs == NULL) return -1;
296
	if(fr->rawbuffs == NULL) return -1;
248
	fr->rawbuffss = buffssize;
297
	fr->rawbuffss = buffssize;
249
	fr->short_buffs[0][0] = aligned_pointer(fr->rawbuffs,short,16);
298
	fr->short_buffs[0][0] = aligned_pointer(fr->rawbuffs,short,16);
250
	fr->short_buffs[0][1] = fr->short_buffs[0][0] + 0x110;
299
	fr->short_buffs[0][1] = fr->short_buffs[0][0] + 0x110;
251
	fr->short_buffs[1][0] = fr->short_buffs[0][1] + 0x110;
300
	fr->short_buffs[1][0] = fr->short_buffs[0][1] + 0x110;
252
	fr->short_buffs[1][1] = fr->short_buffs[1][0] + 0x110;
301
	fr->short_buffs[1][1] = fr->short_buffs[1][0] + 0x110;
253
	fr->real_buffs[0][0] = aligned_pointer(fr->rawbuffs,real,16);
302
	fr->real_buffs[0][0] = aligned_pointer(fr->rawbuffs,real,16);
254
	fr->real_buffs[0][1] = fr->real_buffs[0][0] + 0x110;
303
	fr->real_buffs[0][1] = fr->real_buffs[0][0] + 0x110;
255
	fr->real_buffs[1][0] = fr->real_buffs[0][1] + 0x110;
304
	fr->real_buffs[1][0] = fr->real_buffs[0][1] + 0x110;
256
	fr->real_buffs[1][1] = fr->real_buffs[1][0] + 0x110;
305
	fr->real_buffs[1][1] = fr->real_buffs[1][0] + 0x110;
257
#ifdef OPT_I486
306
#ifdef OPT_I486
258
	if(fr->cpu_opts.type == ivier)
307
	if(fr->cpu_opts.type == ivier)
259
	{
308
	{
260
		fr->int_buffs[0][0] = (int*) fr->rawbuffs;
309
		fr->int_buffs[0][0] = (int*) fr->rawbuffs;
261
		fr->int_buffs[0][1] = fr->int_buffs[0][0] + 17*FIR_BUFFER_SIZE;
310
		fr->int_buffs[0][1] = fr->int_buffs[0][0] + 17*FIR_BUFFER_SIZE;
262
		fr->int_buffs[1][0] = fr->int_buffs[0][1] + 17*FIR_BUFFER_SIZE;
311
		fr->int_buffs[1][0] = fr->int_buffs[0][1] + 17*FIR_BUFFER_SIZE;
263
		fr->int_buffs[1][1] = fr->int_buffs[1][0] + 17*FIR_BUFFER_SIZE;
312
		fr->int_buffs[1][1] = fr->int_buffs[1][0] + 17*FIR_BUFFER_SIZE;
264
	}
313
	}
265
#endif
314
#endif
266
#ifdef OPT_ALTIVEC
315
#ifdef OPT_ALTIVEC
267
	if(fr->cpu_opts.type == altivec)
316
	if(fr->cpu_opts.type == altivec)
268
	{
317
	{
269
		int i,j;
318
		int i,j;
270
		fr->areal_buffs[0][0] = (real*) fr->rawbuffs;
319
		fr->areal_buffs[0][0] = (real*) fr->rawbuffs;
271
		for(i=0; i<4; ++i) for(j=0; j<4; ++j)
320
		for(i=0; i<4; ++i) for(j=0; j<4; ++j)
272
		fr->areal_buffs[i][j] = fr->areal_buffs[0][0] + (i*4+j)*0x110;
321
		fr->areal_buffs[i][j] = fr->areal_buffs[0][0] + (i*4+j)*0x110;
273
	}
322
	}
274
#endif
323
#endif
275
	/* now the different decwins... all of the same size, actually */
324
	/* now the different decwins... all of the same size, actually */
276
	/* The MMX ones want 32byte alignment, which I'll try to ensure manually */
325
	/* The MMX ones want 32byte alignment, which I'll try to ensure manually */
277
	{
326
	{
278
		int decwin_size = (512+32)*sizeof(real);
327
		int decwin_size = (512+32)*sizeof(real);
279
#ifdef OPT_MMXORSSE
328
#ifdef OPT_MMXORSSE
280
#ifdef OPT_MULTI
329
#ifdef OPT_MULTI
281
		if(fr->cpu_opts.class == mmxsse)
330
		if(fr->cpu_opts.class == mmxsse)
282
		{
331
		{
283
#endif
332
#endif
284
			/* decwin_mmx will share, decwins will be appended ... sizeof(float)==4 */
333
			/* decwin_mmx will share, decwins will be appended ... sizeof(float)==4 */
285
			if(decwin_size < (512+32)*4) decwin_size = (512+32)*4;
334
			if(decwin_size < (512+32)*4) decwin_size = (512+32)*4;
286
 
335
 
287
			/* the second window + alignment zone -- we align for 32 bytes for SSE as
336
			/* the second window + alignment zone -- we align for 32 bytes for SSE as
288
			   requirement, 64 byte for matching cache line size (that matters!) */
337
			   requirement, 64 byte for matching cache line size (that matters!) */
289
			decwin_size += (512+32)*4 + 63;
338
			decwin_size += (512+32)*4 + 63;
290
			/* (512+32)*4/32 == 2176/32 == 68, so one decwin block retains alignment for 32 or 64 bytes */
339
			/* (512+32)*4/32 == 2176/32 == 68, so one decwin block retains alignment for 32 or 64 bytes */
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);
303
			fr->rawdecwin = NULL;
353
			fr->rawdecwin = NULL;
304
		}
354
		}
305
 
355
 
306
		if(fr->rawdecwin == NULL)
356
		if(fr->rawdecwin == NULL)
307
		fr->rawdecwin = (unsigned char*) malloc(decwin_size);
357
		fr->rawdecwin = (unsigned char*) malloc(decwin_size);
308
 
358
 
309
		if(fr->rawdecwin == NULL) return -1;
359
		if(fr->rawdecwin == NULL) return -1;
310
 
360
 
311
		fr->rawdecwins = decwin_size;
361
		fr->rawdecwins = decwin_size;
312
		fr->decwin = (real*) fr->rawdecwin;
362
		fr->decwin = (real*) fr->rawdecwin;
313
#ifdef OPT_MMXORSSE
363
#ifdef OPT_MMXORSSE
314
#ifdef OPT_MULTI
364
#ifdef OPT_MULTI
315
		if(fr->cpu_opts.class == mmxsse)
365
		if(fr->cpu_opts.class == mmxsse)
316
		{
366
		{
317
#endif
367
#endif
318
			/* align decwin, assign that to decwin_mmx, append decwins */
368
			/* align decwin, assign that to decwin_mmx, append decwins */
319
			/* I need to add to decwin what is missing to the next full 64 byte -- also I want to make gcc -pedantic happy... */
369
			/* I need to add to decwin what is missing to the next full 64 byte -- also I want to make gcc -pedantic happy... */
320
			fr->decwin = aligned_pointer(fr->rawdecwin,real,64);
370
			fr->decwin = aligned_pointer(fr->rawdecwin,real,64);
321
			debug1("aligned decwin: %p", (void*)fr->decwin);
371
			debug1("aligned decwin: %p", (void*)fr->decwin);
322
			fr->decwin_mmx = (float*)fr->decwin;
372
			fr->decwin_mmx = (float*)fr->decwin;
323
			fr->decwins = fr->decwin_mmx+512+32;
373
			fr->decwins = fr->decwin_mmx+512+32;
324
#ifdef OPT_MULTI
374
#ifdef OPT_MULTI
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);
332
 
427
 
333
	debug1("frame %p buffer done", (void*)fr);
428
	debug1("frame %p buffer done", (void*)fr);
334
	return 0;
429
	return 0;
335
}
430
}
336
 
431
 
337
int frame_buffers_reset(mpg123_handle *fr)
432
int frame_buffers_reset(mpg123_handle *fr)
338
{
433
{
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
}
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
361
}
456
}
362
 
457
 
363
void frame_free_toc(mpg123_handle *fr)
458
static void frame_free_toc(mpg123_handle *fr)
364
{
459
{
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; }
366
}
461
}
367
 
462
 
368
/* Just copy the Xing TOC over... */
463
/* Just copy the Xing TOC over... */
369
int frame_fill_toc(mpg123_handle *fr, unsigned char* in)
464
int frame_fill_toc(mpg123_handle *fr, unsigned char* in)
370
{
465
{
371
	if(fr->xing_toc == NULL) fr->xing_toc = malloc(100);
466
	if(fr->xing_toc == NULL) fr->xing_toc = malloc(100);
372
	if(fr->xing_toc != NULL)
467
	if(fr->xing_toc != NULL)
373
	{
468
	{
374
		memcpy(fr->xing_toc, in, 100);
469
		memcpy(fr->xing_toc, in, 100);
375
#ifdef DEBUG
470
#ifdef DEBUG
376
		debug("Got a TOC! Showing the values...");
471
		debug("Got a TOC! Showing the values...");
377
		{
472
		{
378
			int i;
473
			int i;
379
			for(i=0; i<100; ++i)
474
			for(i=0; i<100; ++i)
380
			debug2("entry %i = %i", i, fr->xing_toc[i]);
475
			debug2("entry %i = %i", i, fr->xing_toc[i]);
381
		}
476
		}
382
#endif
477
#endif
383
		return TRUE;
478
		return TRUE;
384
	}
479
	}
385
	return FALSE;
480
	return FALSE;
386
}
481
}
387
 
482
 
388
/* Prepare the handle for a new track.
483
/* Prepare the handle for a new track.
389
   Reset variables, buffers... */
484
   Reset variables, buffers... */
390
int frame_reset(mpg123_handle* fr)
485
int frame_reset(mpg123_handle* fr)
391
{
486
{
392
	frame_buffers_reset(fr);
487
	frame_buffers_reset(fr);
393
	frame_fixed_reset(fr);
488
	frame_fixed_reset(fr);
394
	frame_free_toc(fr);
489
	frame_free_toc(fr);
395
#ifdef FRAME_INDEX
490
#ifdef FRAME_INDEX
396
	fi_reset(&fr->index);
491
	fi_reset(&fr->index);
397
#endif
492
#endif
398
 
493
 
399
	return 0;
494
	return 0;
400
}
495
}
401
 
496
 
402
/* Reset everythign except dynamic memory. */
497
/* Reset everythign except dynamic memory. */
403
static void frame_fixed_reset(mpg123_handle *fr)
498
static void frame_fixed_reset(mpg123_handle *fr)
404
{
499
{
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;
419
	fr->vbr = MPG123_CBR;
515
	fr->vbr = MPG123_CBR;
420
	fr->abr_rate = 0;
516
	fr->abr_rate = 0;
421
	fr->track_frames = 0;
517
	fr->track_frames = 0;
422
	fr->track_samples = -1;
518
	fr->track_samples = -1;
423
	fr->framesize=0; 
519
	fr->framesize=0; 
424
	fr->mean_frames = 0;
520
	fr->mean_frames = 0;
425
	fr->mean_framesize = 0;
521
	fr->mean_framesize = 0;
426
	fr->freesize = 0;
522
	fr->freesize = 0;
427
	fr->lastscale = -1;
523
	fr->lastscale = -1;
428
	fr->rva.level[0] = -1;
524
	fr->rva.level[0] = -1;
429
	fr->rva.level[1] = -1;
525
	fr->rva.level[1] = -1;
430
	fr->rva.gain[0] = 0;
526
	fr->rva.gain[0] = 0;
431
	fr->rva.gain[1] = 0;
527
	fr->rva.gain[1] = 0;
432
	fr->rva.peak[0] = 0;
528
	fr->rva.peak[0] = 0;
433
	fr->rva.peak[1] = 0;
529
	fr->rva.peak[1] = 0;
434
	fr->fsizeold = 0;
530
	fr->fsizeold = 0;
435
	fr->firstframe = 0;
531
	fr->firstframe = 0;
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;
447
#endif
543
#endif
448
	fr->bo = 1; /* the usual bo */
544
	fr->bo = 1; /* the usual bo */
449
#ifdef OPT_DITHER
545
#ifdef OPT_DITHER
450
	fr->ditherindex = 0;
546
	fr->ditherindex = 0;
451
#endif
547
#endif
452
	reset_id3(fr);
548
	reset_id3(fr);
453
	reset_icy(&fr->icy);
549
	reset_icy(&fr->icy);
454
	/* ICY stuff should go into icy.c, eh? */
550
	/* ICY stuff should go into icy.c, eh? */
455
#ifndef NO_ICY
551
#ifndef NO_ICY
456
	fr->icy.interval = 0;
552
	fr->icy.interval = 0;
457
	fr->icy.next = 0;
553
	fr->icy.next = 0;
458
#endif
554
#endif
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
}
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;
469
	if(fr->rawdecwin != NULL) free(fr->rawdecwin);
565
	if(fr->rawdecwin != NULL) free(fr->rawdecwin);
470
	fr->rawdecwin = NULL;
566
	fr->rawdecwin = NULL;
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
}
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);
490
#endif
587
#endif
491
#ifdef OPT_DITHER
588
#ifdef OPT_DITHER
492
	if(fr->dithernoise != NULL)
589
	if(fr->dithernoise != NULL)
493
	{
590
	{
494
		free(fr->dithernoise);
591
		free(fr->dithernoise);
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
}
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
{
504
	if(mh == NULL) return MPG123_ERR;
610
	if(mh == NULL) return MPG123_ERR;
505
	if(mi == NULL)
611
	if(mi == NULL)
506
	{
612
	{
507
		mh->err = MPG123_ERR_NULL;
613
		mh->err = MPG123_ERR_NULL;
508
		return MPG123_ERR;
614
		return MPG123_ERR;
509
	}
615
	}
510
	mi->version = mh->mpeg25 ? MPG123_2_5 : (mh->lsf ? MPG123_2_0 : MPG123_1_0);
616
	mi->version = mh->mpeg25 ? MPG123_2_5 : (mh->lsf ? MPG123_2_0 : MPG123_1_0);
511
	mi->layer = mh->lay;
617
	mi->layer = mh->lay;
512
	mi->rate = frame_freq(mh);
618
	mi->rate = frame_freq(mh);
513
	switch(mh->mode)
619
	switch(mh->mode)
514
	{
620
	{
515
		case 0: mi->mode = MPG123_M_STEREO; break;
621
		case 0: mi->mode = MPG123_M_STEREO; break;
516
		case 1: mi->mode = MPG123_M_JOINT;  break;
622
		case 1: mi->mode = MPG123_M_JOINT;  break;
517
		case 2: mi->mode = MPG123_M_DUAL;   break;
623
		case 2: mi->mode = MPG123_M_DUAL;   break;
518
		case 3: mi->mode = MPG123_M_MONO;   break;
624
		case 3: mi->mode = MPG123_M_MONO;   break;
519
		default: error("That mode cannot be!");
625
		default: error("That mode cannot be!");
520
	}
626
	}
521
	mi->mode_ext = mh->mode_ext;
627
	mi->mode_ext = mh->mode_ext;
522
	mi->framesize = mh->framesize+4; /* Include header. */
628
	mi->framesize = mh->framesize+4; /* Include header. */
523
	mi->flags = 0;
629
	mi->flags = 0;
524
	if(mh->error_protection) mi->flags |= MPG123_CRC;
630
	if(mh->error_protection) mi->flags |= MPG123_CRC;
525
	if(mh->copyright)        mi->flags |= MPG123_COPYRIGHT;
631
	if(mh->copyright)        mi->flags |= MPG123_COPYRIGHT;
526
	if(mh->extension)        mi->flags |= MPG123_PRIVATE;
632
	if(mh->extension)        mi->flags |= MPG123_PRIVATE;
527
	if(mh->original)         mi->flags |= MPG123_ORIGINAL;
633
	if(mh->original)         mi->flags |= MPG123_ORIGINAL;
528
	mi->emphasis = mh->emphasis;
634
	mi->emphasis = mh->emphasis;
529
	mi->bitrate  = frame_bitrate(mh);
635
	mi->bitrate  = frame_bitrate(mh);
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
}
-
 
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;
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)
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
{
546
	/* Default is to go to the beginning. */
663
	/* Default is to go to the beginning. */
547
	off_t ret = fr->audio_start;
664
	off_t ret = fr->audio_start;
548
	*get_frame = 0;
665
	*get_frame = 0;
549
 
666
 
550
	/* But we try to find something better. */
667
	/* But we try to find something better. */
551
	/* Xing VBR TOC works with relative positions, both in terms of audio frames and stream bytes.
668
	/* Xing VBR TOC works with relative positions, both in terms of audio frames and stream bytes.
552
	   Thus, it only works when whe know the length of things.
669
	   Thus, it only works when whe know the length of things.
553
	   Oh... I assume the offsets are relative to the _total_ file length. */
670
	   Oh... I assume the offsets are relative to the _total_ file length. */
554
	if(fr->xing_toc != NULL && fr->track_frames > 0 && fr->rdat.filelen > 0)
671
	if(fr->xing_toc != NULL && fr->track_frames > 0 && fr->rdat.filelen > 0)
555
	{
672
	{
556
		/* One could round... */
673
		/* One could round... */
557
		int toc_entry = (int) ((double)want_frame*100./fr->track_frames);
674
		int toc_entry = (int) ((double)want_frame*100./fr->track_frames);
558
		/* It is an index in the 100-entry table. */
675
		/* It is an index in the 100-entry table. */
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;
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
	}
578
	debug5("fuzzy: want %li of %li, get %li at %li B of %li B",
695
	debug5("fuzzy: want %li of %li, get %li at %li B of %li B",
579
		(long)want_frame, (long)fr->track_frames, (long)*get_frame, (long)ret, (long)(fr->rdat.filelen-fr->audio_start));
696
		(long)want_frame, (long)fr->track_frames, (long)*get_frame, (long)ret, (long)(fr->rdat.filelen-fr->audio_start));
580
	return ret;
697
	return ret;
581
}
698
}
582
 
699
 
583
/*
700
/*
584
	find the best frame in index just before the wanted one, seek to there
701
	find the best frame in index just before the wanted one, seek to there
585
	then step to just before wanted one with read_frame
702
	then step to just before wanted one with read_frame
586
	do not care tabout the stuff that was in buffer but not played back
703
	do not care tabout the stuff that was in buffer but not played back
587
	everything that left the decoder is counted as played
704
	everything that left the decoder is counted as played
588
	
705
	
589
	Decide if you want low latency reaction and accurate timing info or stable long-time playback with buffer!
706
	Decide if you want low latency reaction and accurate timing info or stable long-time playback with buffer!
590
*/
707
*/
591
 
708
 
592
off_t frame_index_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame)
709
off_t frame_index_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame)
593
{
710
{
594
	/* default is file start if no index position */
711
	/* default is file start if no index position */
595
	off_t gopos = 0;
712
	off_t gopos = 0;
596
	*get_frame = 0;
713
	*get_frame = 0;
597
#ifdef FRAME_INDEX
714
#ifdef FRAME_INDEX
598
	/* Possibly use VBRI index, too? I'd need an example for this... */
715
	/* Possibly use VBRI index, too? I'd need an example for this... */
599
	if(fr->index.fill)
716
	if(fr->index.fill)
600
	{
717
	{
601
		/* find in index */
718
		/* find in index */
602
		size_t fi;
719
		size_t fi;
603
		/* at index fi there is frame step*fi... */
720
		/* at index fi there is frame step*fi... */
604
		fi = want_frame/fr->index.step;
721
		fi = want_frame/fr->index.step;
605
		if(fi >= fr->index.fill) /* If we are beyond the end of frame index...*/
722
		if(fi >= fr->index.fill) /* If we are beyond the end of frame index...*/
606
		{
723
		{
607
			/* When fuzzy seek is allowed, we have some limited tolerance for the frames we want to read rather then jump over. */
724
			/* When fuzzy seek is allowed, we have some limited tolerance for the frames we want to read rather then jump over. */
608
			if(fr->p.flags & MPG123_FUZZY && want_frame - (fr->index.fill-1)*fr->index.step > 10)
725
			if(fr->p.flags & MPG123_FUZZY && want_frame - (fr->index.fill-1)*fr->index.step > 10)
609
			{
726
			{
610
				gopos = frame_fuzzy_find(fr, want_frame, get_frame);
727
				gopos = frame_fuzzy_find(fr, want_frame, get_frame);
611
				if(gopos > fr->audio_start) return gopos; /* Only in that case, we have a useful guess. */
728
				if(gopos > fr->audio_start) return gopos; /* Only in that case, we have a useful guess. */
612
				/* Else... just continue, fuzzyness didn't help. */
729
				/* Else... just continue, fuzzyness didn't help. */
613
			}
730
			}
614
			/* Use the last available position, slowly advancing from that one. */
731
			/* Use the last available position, slowly advancing from that one. */
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)
626
		return frame_fuzzy_find(fr, want_frame, get_frame);
743
		return frame_fuzzy_find(fr, want_frame, get_frame);
627
		/* A bit hackish here... but we need to be fresh when looking for the first header again. */
744
		/* A bit hackish here... but we need to be fresh when looking for the first header again. */
628
		fr->firsthead = 0;
745
		fr->firsthead = 0;
629
		fr->oldhead = 0;
746
		fr->oldhead = 0;
630
#ifdef FRAME_INDEX
747
#ifdef FRAME_INDEX
631
	}
748
	}
632
#endif
749
#endif
633
	debug2("index: 0x%lx for frame %li", (unsigned long)gopos, (long) *get_frame);
750
	debug2("index: 0x%lx for frame %li", (unsigned long)gopos, (long) *get_frame);
634
	return gopos;
751
	return gopos;
635
}
752
}
636
 
753
 
637
off_t frame_ins2outs(mpg123_handle *fr, off_t ins)
754
off_t frame_ins2outs(mpg123_handle *fr, off_t ins)
638
{	
755
{	
639
	off_t outs = 0;
756
	off_t outs = 0;
640
	switch(fr->down_sample)
757
	switch(fr->down_sample)
641
	{
758
	{
642
		case 0:
759
		case 0:
643
#		ifndef NO_DOWNSAMPLE
760
#		ifndef NO_DOWNSAMPLE
644
		case 1:
761
		case 1:
645
		case 2:
762
		case 2:
646
#		endif
763
#		endif
647
			outs = ins>>fr->down_sample;
764
			outs = ins>>fr->down_sample;
648
		break;
765
		break;
649
#		ifndef NO_NTOM
766
#		ifndef NO_NTOM
650
		case 3: outs = ntom_ins2outs(fr, ins); break;
767
		case 3: outs = ntom_ins2outs(fr, ins); break;
651
#		endif
768
#		endif
652
		default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample);
769
		default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample);
653
	}
770
	}
654
	return outs;
771
	return outs;
655
}
772
}
656
 
773
 
657
off_t frame_outs(mpg123_handle *fr, off_t num)
774
off_t frame_outs(mpg123_handle *fr, off_t num)
658
{
775
{
659
	off_t outs = 0;
776
	off_t outs = 0;
660
	switch(fr->down_sample)
777
	switch(fr->down_sample)
661
	{
778
	{
662
		case 0:
779
		case 0:
663
#		ifndef NO_DOWNSAMPLE
780
#		ifndef NO_DOWNSAMPLE
664
		case 1:
781
		case 1:
665
		case 2:
782
		case 2:
666
#		endif
783
#		endif
667
			outs = (spf(fr)>>fr->down_sample)*num;
784
			outs = (spf(fr)>>fr->down_sample)*num;
668
		break;
785
		break;
669
#ifndef NO_NTOM
786
#ifndef NO_NTOM
670
		case 3: outs = ntom_frmouts(fr, num); break;
787
		case 3: outs = ntom_frmouts(fr, num); break;
671
#endif
788
#endif
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
}
-
 
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)
681
	{
820
	{
682
		case 0:
821
		case 0:
683
#		ifndef NO_DOWNSAMPLE
822
#		ifndef NO_DOWNSAMPLE
684
		case 1:
823
		case 1:
685
		case 2:
824
		case 2:
686
#		endif
825
#		endif
687
			num = outs/(spf(fr)>>fr->down_sample);
826
			num = outs/(spf(fr)>>fr->down_sample);
688
		break;
827
		break;
689
#ifndef NO_NTOM
828
#ifndef NO_NTOM
690
		case 3: num = ntom_frameoff(fr, outs); break;
829
		case 3: num = ntom_frameoff(fr, outs); break;
691
#endif
830
#endif
692
		default: error("Bad down_sample ... should not be possible!!");
831
		default: error("Bad down_sample ... should not be possible!!");
693
	}
832
	}
694
	return num;
833
	return num;
695
}
834
}
696
 
835
 
697
#ifdef GAPLESS
836
#ifdef GAPLESS
698
/* input in _input_ samples */
837
/* input in _input_ samples */
699
void frame_gapless_init(mpg123_handle *fr, off_t b, off_t e)
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;
-
 
842
	if(fr->gapless_frames > 0)
700
{
843
	{
701
	fr->begin_s = b;
844
		fr->begin_s = bskip+GAPLESS_DELAY;
-
 
845
		fr->end_s = framecount*spf(fr)-eskip+GAPLESS_DELAY;
-
 
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;
705
	fr->end_os = 0;
850
	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);
707
}
853
}
708
 
854
 
709
void frame_gapless_realinit(mpg123_handle *fr)
855
void frame_gapless_realinit(mpg123_handle *fr)
710
{
856
{
711
	fr->begin_os = frame_ins2outs(fr, fr->begin_s);
857
	fr->begin_os = frame_ins2outs(fr, fr->begin_s);
712
	fr->end_os   = frame_ins2outs(fr, fr->end_s);
858
	fr->end_os   = frame_ins2outs(fr, fr->end_s);
-
 
859
	fr->fullend_os = frame_ins2outs(fr, fr->gapless_frames*spf(fr));
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
 
716
/* When we got a new sample count, update the gaplessness. */
863
/* At least note when there is trouble... */
717
void frame_gapless_update(mpg123_handle *fr, off_t total_samples)
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);
-
 
868
	if(NOQUIET && total_samples != gapless_samples)
-
 
869
	fprintf(stderr, "\nWarning: Real sample count differs from given gapless sample count. Frankenstein stream?\n");
718
{
870
 
719
	if(fr->end_s < 1)
871
	if(gapless_samples > total_samples)
-
 
872
	{
-
 
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
	{
874
		/* This invalidates the current position... but what should I do? */
721
		fr->end_s = total_samples;
875
		frame_gapless_init(fr, -1, 0, 0);
722
		frame_gapless_realinit(fr);
-
 
723
	}
876
		frame_gapless_realinit(fr);
724
	else if(fr->end_s > total_samples)
-
 
725
	{
-
 
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;
727
		fr->end_s = total_samples;
878
		fr->lastoff = 0;
728
	}
879
	}
729
}
880
}
730
 
881
 
731
#endif
882
#endif
732
 
883
 
733
/* Compute the needed frame to ignore from, for getting accurate/consistent output for intended firstframe. */
884
/* Compute the needed frame to ignore from, for getting accurate/consistent output for intended firstframe. */
734
static off_t ignoreframe(mpg123_handle *fr)
885
static off_t ignoreframe(mpg123_handle *fr)
735
{
886
{
736
	off_t preshift = fr->p.preframes;
887
	off_t preshift = fr->p.preframes;
737
	/* Layer 3 _really_ needs at least one frame before. */
888
	/* Layer 3 _really_ needs at least one frame before. */
738
	if(fr->lay==3 && preshift < 1) preshift = 1;
889
	if(fr->lay==3 && preshift < 1) preshift = 1;
739
	/* Layer 1 & 2 reall do not need more than 2. */
890
	/* Layer 1 & 2 reall do not need more than 2. */
740
	if(fr->lay!=3 && preshift > 2) preshift = 2;
891
	if(fr->lay!=3 && preshift > 2) preshift = 2;
741
 
892
 
742
	return fr->firstframe - preshift;
893
	return fr->firstframe - preshift;
743
}
894
}
744
 
895
 
745
/* The frame seek... This is not simply the seek to fe*spf(fr) samples in output because we think of _input_ frames here.
896
/* The frame seek... This is not simply the seek to fe*spf(fr) samples in output because we think of _input_ frames here.
746
   Seek to frame offset 1 may be just seek to 200 samples offset in output since the beginning of first frame is delay/padding.
897
   Seek to frame offset 1 may be just seek to 200 samples offset in output since the beginning of first frame is delay/padding.
747
   Hm, is that right? OK for the padding stuff, but actually, should the decoder delay be better totally hidden or not?
898
   Hm, is that right? OK for the padding stuff, but actually, should the decoder delay be better totally hidden or not?
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
		{
759
			fr->firstframe = beg_f;
910
			fr->firstframe = beg_f;
760
			fr->firstoff   = fr->begin_os - frame_outs(fr, beg_f);
911
			fr->firstoff   = fr->begin_os - frame_outs(fr, beg_f);
761
		}
912
		}
762
		else fr->firstoff = 0;
913
		else fr->firstoff = 0;
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",
774
	       (long) fr->firstframe, (long) fr->firstoff,
925
	       (long) fr->firstframe, (long) fr->firstoff,
775
	       (long) fr->lastframe,  (long) fr->lastoff, (long) fr->ignoreframe);
926
	       (long) fr->lastframe,  (long) fr->lastoff, (long) fr->ignoreframe);
776
#else
927
#else
777
	debug3("frame_set_frameseek: begin at %li frames, end at %li; ignore from %li",
928
	debug3("frame_set_frameseek: begin at %li frames, end at %li; ignore from %li",
778
	       (long) fr->firstframe, (long) fr->lastframe, (long) fr->ignoreframe);
929
	       (long) fr->firstframe, (long) fr->lastframe, (long) fr->ignoreframe);
779
#endif
930
#endif
780
}
931
}
781
 
932
 
782
void frame_skip(mpg123_handle *fr)
933
void frame_skip(mpg123_handle *fr)
783
{
934
{
784
#ifndef NO_LAYER3
935
#ifndef NO_LAYER3
785
	if(fr->lay == 3) set_pointer(fr, 512);
936
	if(fr->lay == 3) set_pointer(fr, 512);
786
#endif
937
#endif
787
}
938
}
788
 
939
 
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! */
799
	fr->firstoff = sp - frame_outs(fr, fr->firstframe);
951
	fr->firstoff = sp - frame_outs(fr, fr->firstframe);
800
	debug5("frame_set_seek: begin at %li frames and %li samples, end at %li and %li; ignore from %li",
952
	debug5("frame_set_seek: begin at %li frames and %li samples, end at %li and %li; ignore from %li",
801
	       (long) fr->firstframe, (long) fr->firstoff,
953
	       (long) fr->firstframe, (long) fr->firstoff,
802
	       (long) fr->lastframe,  (long) fr->lastoff, (long) fr->ignoreframe);
954
	       (long) fr->lastframe,  (long) fr->lastoff, (long) fr->ignoreframe);
803
#else
955
#else
804
	debug3("frame_set_seek: begin at %li frames, end at %li; ignore from %li",
956
	debug3("frame_set_seek: begin at %li frames, end at %li; ignore from %li",
805
	       (long) fr->firstframe, (long) fr->lastframe, (long) fr->ignoreframe);
957
	       (long) fr->firstframe, (long) fr->lastframe, (long) fr->ignoreframe);
806
#endif
958
#endif
807
}
959
}
808
 
960
 
809
int attribute_align_arg mpg123_volume_change(mpg123_handle *mh, double change)
961
int attribute_align_arg mpg123_volume_change(mpg123_handle *mh, double change)
810
{
962
{
811
	if(mh == NULL) return MPG123_ERR;
963
	if(mh == NULL) return MPG123_ERR;
812
	return mpg123_volume(mh, change + (double) mh->p.outscale);
964
	return mpg123_volume(mh, change + (double) mh->p.outscale);
813
}
965
}
814
 
966
 
815
int attribute_align_arg mpg123_volume(mpg123_handle *mh, double vol)
967
int attribute_align_arg mpg123_volume(mpg123_handle *mh, double vol)
816
{
968
{
817
	if(mh == NULL) return MPG123_ERR;
969
	if(mh == NULL) return MPG123_ERR;
818
 
970
 
819
	if(vol >= 0) mh->p.outscale = vol;
971
	if(vol >= 0) mh->p.outscale = vol;
820
	else mh->p.outscale = 0.;
972
	else mh->p.outscale = 0.;
821
 
973
 
822
	do_rva(mh);
974
	do_rva(mh);
823
	return MPG123_OK;
975
	return MPG123_OK;
824
}
976
}
825
 
977
 
826
static int get_rva(mpg123_handle *fr, double *peak, double *gain)
978
static int get_rva(mpg123_handle *fr, double *peak, double *gain)
827
{
979
{
828
	double p = -1;
980
	double p = -1;
829
	double g = 0;
981
	double g = 0;
830
	int ret = 0;
982
	int ret = 0;
831
	if(fr->p.rva)
983
	if(fr->p.rva)
832
	{
984
	{
833
		int rt = 0;
985
		int rt = 0;
834
		/* Should one assume a zero RVA as no RVA? */
986
		/* Should one assume a zero RVA as no RVA? */
835
		if(fr->p.rva == 2 && fr->rva.level[1] != -1) rt = 1;
987
		if(fr->p.rva == 2 && fr->rva.level[1] != -1) rt = 1;
836
		if(fr->rva.level[rt] != -1)
988
		if(fr->rva.level[rt] != -1)
837
		{
989
		{
838
			p = fr->rva.peak[rt];
990
			p = fr->rva.peak[rt];
839
			g = fr->rva.gain[rt];
991
			g = fr->rva.gain[rt];
840
			ret = 1; /* Success. */
992
			ret = 1; /* Success. */
841
		}
993
		}
842
	}
994
	}
843
	if(peak != NULL) *peak = p;
995
	if(peak != NULL) *peak = p;
844
	if(gain != NULL) *gain = g;
996
	if(gain != NULL) *gain = g;
845
	return ret;
997
	return ret;
846
}
998
}
847
 
999
 
848
/* adjust the volume, taking both fr->outscale and rva values into account */
1000
/* adjust the volume, taking both fr->outscale and rva values into account */
849
void do_rva(mpg123_handle *fr)
1001
void do_rva(mpg123_handle *fr)
850
{
1002
{
851
	double peak = 0;
1003
	double peak = 0;
852
	double gain = 0;
1004
	double gain = 0;
853
	double newscale;
1005
	double newscale;
854
	double rvafact = 1;
1006
	double rvafact = 1;
855
	if(get_rva(fr, &peak, &gain))
1007
	if(get_rva(fr, &peak, &gain))
856
	{
1008
	{
857
		if(NOQUIET && fr->p.verbose > 1) fprintf(stderr, "Note: doing RVA with gain %f\n", gain);
1009
		if(NOQUIET && fr->p.verbose > 1) fprintf(stderr, "Note: doing RVA with gain %f\n", gain);
858
		rvafact = pow(10,gain/20);
1010
		rvafact = pow(10,gain/20);
859
	}
1011
	}
860
 
1012
 
861
	newscale = fr->p.outscale*rvafact;
1013
	newscale = fr->p.outscale*rvafact;
862
 
1014
 
863
	/* if peak is unknown (== 0) this check won't hurt */
1015
	/* if peak is unknown (== 0) this check won't hurt */
864
	if((peak*newscale) > 1.0)
1016
	if((peak*newscale) > 1.0)
865
	{
1017
	{
866
		newscale = 1.0/peak;
1018
		newscale = 1.0/peak;
867
		warning2("limiting scale value to %f to prevent clipping with indicated peak factor of %f", newscale, peak);
1019
		warning2("limiting scale value to %f to prevent clipping with indicated peak factor of %f", newscale, peak);
868
	}
1020
	}
869
	/* first rva setting is forced with fr->lastscale < 0 */
1021
	/* first rva setting is forced with fr->lastscale < 0 */
870
	if(newscale != fr->lastscale || fr->decoder_change)
1022
	if(newscale != fr->lastscale || fr->decoder_change)
871
	{
1023
	{
872
		debug3("changing scale value from %f to %f (peak estimated to %f)", fr->lastscale != -1 ? fr->lastscale : fr->p.outscale, newscale, (double) (newscale*peak));
1024
		debug3("changing scale value from %f to %f (peak estimated to %f)", fr->lastscale != -1 ? fr->lastscale : fr->p.outscale, newscale, (double) (newscale*peak));
873
		fr->lastscale = newscale;
1025
		fr->lastscale = newscale;
874
		/* It may be too early, actually. */
1026
		/* It may be too early, actually. */
875
		if(fr->make_decode_tables != NULL) fr->make_decode_tables(fr); /* the actual work */
1027
		if(fr->make_decode_tables != NULL) fr->make_decode_tables(fr); /* the actual work */
876
	}
1028
	}
877
}
1029
}
878
 
1030
 
879
 
1031
 
880
int attribute_align_arg mpg123_getvolume(mpg123_handle *mh, double *base, double *really, double *rva_db)
1032
int attribute_align_arg mpg123_getvolume(mpg123_handle *mh, double *base, double *really, double *rva_db)
881
{
1033
{
882
	if(mh == NULL) return MPG123_ERR;
1034
	if(mh == NULL) return MPG123_ERR;
883
	if(base)   *base   = mh->p.outscale;
1035
	if(base)   *base   = mh->p.outscale;
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
}
-
 
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;
-
 
1046
}