comparison decoders/libmpg123/format.c @ 562:7e08477b0fc1

MP3 decoder upgrade work. Ripped out SMPEG and mpglib support, replaced it with "mpg123.c" and libmpg123. libmpg123 is a much better version of mpglib, so it should solve all the problems about MP3's not seeking, or most modern MP3's not playing at all, etc. Since you no longer have to make a tradeoff with SMPEG for features, and SMPEG is basically rotting, I removed it from the project. There is still work to be done with libmpg123...there are MMX, 3DNow, SSE, Altivec, etc decoders which we don't have enabled at the moment, and the build system could use some work to make this compile more cleanly, etc. Still: huge win.
author Ryan C. Gordon <icculus@icculus.org>
date Fri, 30 Jan 2009 02:44:47 -0500
parents
children
comparison
equal deleted inserted replaced
561:f2985e08589c 562:7e08477b0fc1
1 /*
2 format:routines to deal with audio (output) format
3
4 copyright 2008 by the mpg123 project - free software under the terms of the LGPL 2.1
5 see COPYING and AUTHORS files in distribution or http://mpg123.org
6 initially written by Thomas Orgis, starting with parts of the old audio.c, with only faintly manage to show now
7 */
8
9 #include "mpg123lib_intern.h"
10 #include "debug.h"
11
12 /* static int chans[NUM_CHANNELS] = { 1 , 2 }; */
13 static const long my_rates[MPG123_RATES] = /* only the standard rates */
14 {
15 8000, 11025, 12000,
16 16000, 22050, 24000,
17 32000, 44100, 48000,
18 };
19 static const int my_encodings[MPG123_ENCODINGS] =
20 {
21 MPG123_ENC_SIGNED_16,
22 MPG123_ENC_UNSIGNED_16,
23 MPG123_ENC_UNSIGNED_8,
24 MPG123_ENC_SIGNED_8,
25 MPG123_ENC_ULAW_8,
26 MPG123_ENC_ALAW_8,
27 MPG123_ENC_SIGNED_32,
28 MPG123_ENC_UNSIGNED_32,
29 MPG123_ENC_FLOAT_32,
30 MPG123_ENC_FLOAT_64
31 };
32
33 /* Check if encoding (mask) is a valid one in this build. */
34 static int good_enc(int enc)
35 {
36 if(!(enc & MPG123_ENC_ANY)) return FALSE;
37 #ifdef FLOATOUT
38 #ifdef REAL_IS_FLOAT /* we know only 32bit*/
39 if(enc != MPG123_ENC_FLOAT_32) return FALSE;
40 #else
41 if(enc != MPG123_ENC_FLOAT_64) return FALSE;
42 #endif
43 #else
44 if(enc & MPG123_ENC_FLOAT) return FALSE;
45 #endif
46 if(enc & MPG123_ENC_32) return FALSE; /* Not supported yet. */
47 if(enc == MPG123_ENC_UNSIGNED_16) return FALSE; /* Not supported yet... ever? */
48
49 return TRUE;
50 }
51
52 void attribute_align_arg mpg123_rates(const long **list, size_t *number)
53 {
54 if(list != NULL) *list = my_rates;
55 if(number != NULL) *number = sizeof(my_rates)/sizeof(long);
56 }
57
58 /* Now that's a bit tricky... One build of the library knows only a subset of the encodings. */
59 void attribute_align_arg mpg123_encodings(const int **list, size_t *number)
60 {
61 size_t offset = 0;
62 size_t n = sizeof(my_encodings)/sizeof(int)-4; /* The last 4 are special. */
63 #ifdef FLOATOUT /* Skip integer encodings. */
64 n = 1;
65 #ifdef REAL_IS_FLOAT /* we know only 32bit*/
66 offset = 8; /* Only 32bit float */
67 #else
68 offset = 9; /* Only 64bit float */
69 #endif
70 #endif /* There should be a branch for 32bit integer; but that's not anywhere now. */
71 if(list != NULL) *list = my_encodings+offset;
72 if(number != NULL) *number = n;
73 }
74
75 /* char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS]; */
76
77 static int rate2num(mpg123_pars *mp, long r)
78 {
79 int i;
80 for(i=0;i<MPG123_RATES;i++) if(my_rates[i] == r) return i;
81 if(mp && mp->force_rate != 0 && mp->force_rate == r) return MPG123_RATES;
82
83 return -1;
84 }
85
86 static int enc2num(int encoding)
87 {
88 int i;
89 for(i=0;i<MPG123_ENCODINGS;++i)
90 if(my_encodings[i] == encoding) return i;
91
92 return -1;
93 }
94
95 static int cap_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
96 {
97 int i;
98 int c = nf->channels-1;
99 int rn = rate2num(&fr->p, nf->rate);
100 if(rn >= 0) for(i=f0;i<f2;i++)
101 {
102 if(fr->p.audio_caps[c][rn][i])
103 {
104 nf->encoding = my_encodings[i];
105 return 1;
106 }
107 }
108 return 0;
109 }
110
111 static int freq_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
112 {
113 nf->rate = frame_freq(fr)>>fr->p.down_sample;
114 if(cap_fit(fr,nf,f0,f2)) return 1;
115 nf->rate>>=1;
116 if(cap_fit(fr,nf,f0,f2)) return 1;
117 nf->rate>>=1;
118 if(cap_fit(fr,nf,f0,f2)) return 1;
119 return 0;
120 }
121
122 /* match constraints against supported audio formats, store possible setup in frame
123 return: -1: error; 0: no format change; 1: format change */
124 int frame_output_format(mpg123_handle *fr)
125 {
126 struct audioformat nf;
127 int f0=0;
128 int f2=MPG123_ENCODINGS-4; /* Omit the 32bit and float encodings. */
129 mpg123_pars *p = &fr->p;
130 /* initialize new format, encoding comes later */
131 nf.channels = fr->stereo;
132
133 #ifdef FLOATOUT /* Skip integer encodings. */
134 #ifdef REAL_IS_FLOAT /* we know only 32bit*/
135 f0 = 8; /* Only 32bit float */
136 #else
137 f0 = 9; /* Only 64bit float */
138 #endif
139 f2 = f0+1; /* Only one encoding to try... */
140 #else
141 if(p->flags & MPG123_FORCE_8BIT) f0 = 2; /* skip the 16bit encodings */
142 #endif /* There should be a branch for 32bit integer; but that's not anywhere now. */
143
144 /* force stereo is stronger */
145 if(p->flags & MPG123_FORCE_MONO) nf.channels = 1;
146 if(p->flags & MPG123_FORCE_STEREO) nf.channels = 2;
147
148 if(p->force_rate)
149 {
150 nf.rate = p->force_rate;
151 if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */
152 if(cap_fit(fr,&nf,2,f2)) goto end; /* 8bit encodings */
153
154 /* try again with different stereoness */
155 if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
156 else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
157
158 if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */
159 if(cap_fit(fr,&nf,2,f2)) goto end; /* 8bit encodings */
160
161 if(NOQUIET)
162 error3( "Unable to set up output format! Constraints: %s%s%liHz.",
163 ( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
164 (p->flags & MPG123_FORCE_MONO ? "mono, " : "") ),
165 (p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""),
166 p->force_rate );
167 /* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
168
169 fr->err = MPG123_BAD_OUTFORMAT;
170 return -1;
171 }
172
173 if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */
174 if(freq_fit(fr, &nf, 2, f2)) goto end; /* ... 8bit */
175
176 /* try again with different stereoness */
177 if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
178 else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
179
180 if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */
181 if(freq_fit(fr, &nf, 2, f2)) goto end; /* ... 8bit */
182
183 /* Here is the _bad_ end. */
184 if(NOQUIET)
185 error5( "Unable to set up output format! Constraints: %s%s%li, %li or %liHz.",
186 ( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
187 (p->flags & MPG123_FORCE_MONO ? "mono, " : "") ),
188 (p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""),
189 frame_freq(fr), frame_freq(fr)>>1, frame_freq(fr)>>2 );
190 /* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
191
192 fr->err = MPG123_BAD_OUTFORMAT;
193 return -1;
194
195 end: /* Here is the _good_ end. */
196 /* we had a successful match, now see if there's a change */
197 if(nf.rate == fr->af.rate && nf.channels == fr->af.channels && nf.encoding == fr->af.encoding)
198 {
199 debug("Old format!");
200 return 0; /* the same format as before */
201 }
202 else /* a new format */
203 {
204 debug("New format!");
205 fr->af.rate = nf.rate;
206 fr->af.channels = nf.channels;
207 fr->af.encoding = nf.encoding;
208 return 1;
209 }
210 }
211
212 int attribute_align_arg mpg123_format_none(mpg123_handle *mh)
213 {
214 int r;
215 if(mh == NULL) return MPG123_ERR;
216
217 r = mpg123_fmt_none(&mh->p);
218 if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
219
220 return r;
221 }
222
223 int attribute_align_arg mpg123_fmt_none(mpg123_pars *mp)
224 {
225 if(mp == NULL) return MPG123_BAD_PARS;
226
227 if(PVERB(mp,3)) fprintf(stderr, "Note: Disabling all formats.\n");
228
229 memset(mp->audio_caps,0,sizeof(mp->audio_caps));
230 return MPG123_OK;
231 }
232
233 int attribute_align_arg mpg123_format_all(mpg123_handle *mh)
234 {
235 int r;
236 if(mh == NULL) return MPG123_ERR;
237
238 r = mpg123_fmt_all(&mh->p);
239 if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
240
241 return r;
242 }
243
244 int attribute_align_arg mpg123_fmt_all(mpg123_pars *mp)
245 {
246 size_t rate, ch, enc;
247 if(mp == NULL) return MPG123_BAD_PARS;
248
249 if(PVERB(mp,3)) fprintf(stderr, "Note: Enabling all formats.\n");
250
251 for(ch=0; ch < NUM_CHANNELS; ++ch)
252 for(rate=0; rate < MPG123_RATES+1; ++rate)
253 for(enc=0; enc < MPG123_ENCODINGS; ++enc)
254 mp->audio_caps[ch][rate][enc] = good_enc(my_encodings[enc]) ? 1 : 0;
255
256 return MPG123_OK;
257 }
258
259 int attribute_align_arg mpg123_format(mpg123_handle *mh, long rate, int channels, int encodings)
260 {
261 int r;
262 if(mh == NULL) return MPG123_ERR;
263 r = mpg123_fmt(&mh->p, rate, channels, encodings);
264 if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
265
266 return r;
267 }
268
269 int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int encodings)
270 {
271 int ie, ic, ratei;
272 int ch[2] = {0, 1};
273 if(mp == NULL) return MPG123_BAD_PARS;
274 if(!(channels & (MPG123_MONO|MPG123_STEREO))) return MPG123_BAD_CHANNEL;
275
276 if(PVERB(mp,3)) fprintf(stderr, "Note: Want to enable format %li/%i for encodings 0x%x.\n", rate, channels, encodings);
277
278 if(!(channels & MPG123_STEREO)) ch[1] = 0; /* {0,0} */
279 else if(!(channels & MPG123_MONO)) ch[0] = 1; /* {1,1} */
280 ratei = rate2num(mp, rate);
281 if(ratei < 0) return MPG123_BAD_RATE;
282
283 /* now match the encodings */
284 for(ic = 0; ic < 2; ++ic)
285 {
286 for(ie = 0; ie < MPG123_ENCODINGS; ++ie)
287 if(good_enc(my_encodings[ie]) && ((my_encodings[ie] & encodings) == my_encodings[ie]))
288 mp->audio_caps[ch[ic]][ratei][ie] = 1;
289
290 if(ch[0] == ch[1]) break; /* no need to do it again */
291 }
292
293 return MPG123_OK;
294 }
295
296 int attribute_align_arg mpg123_format_support(mpg123_handle *mh, long rate, int encoding)
297 {
298 if(mh == NULL) return 0;
299 else return mpg123_fmt_support(&mh->p, rate, encoding);
300 }
301
302 int attribute_align_arg mpg123_fmt_support(mpg123_pars *mp, long rate, int encoding)
303 {
304 int ch = 0;
305 int ratei, enci;
306 ratei = rate2num(mp, rate);
307 enci = enc2num(encoding);
308 if(mp == NULL || ratei < 0 || enci < 0) return 0;
309 if(mp->audio_caps[0][ratei][enci]) ch |= MPG123_MONO;
310 if(mp->audio_caps[1][ratei][enci]) ch |= MPG123_STEREO;
311 return ch;
312 }
313
314 /* Call this one to ensure that any valid format will be something different than this. */
315 void invalidate_format(struct audioformat *af)
316 {
317 af->encoding = 0;
318 af->rate = 0;
319 af->channels = 0;
320 }
321