Mercurial > SDL_sound_CoreAudio
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 |