Rev 1905 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1905 | Rev 3960 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | format:routines to deal with audio (output) format |
2 | format:routines to deal with audio (output) format |
3 | 3 | ||
4 | copyright 2008-9 by the mpg123 project - free software under the terms of the LGPL 2.1 |
4 | copyright 2008-9 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, starting with parts of the old audio.c, with only faintly manage to show now |
6 | initially written by Thomas Orgis, starting with parts of the old audio.c, with only faintly manage to show now |
7 | */ |
7 | */ |
8 | 8 | ||
9 | #include "mpg123lib_intern.h" |
9 | #include "mpg123lib_intern.h" |
10 | #include "debug.h" |
10 | #include "debug.h" |
11 | 11 | ||
12 | /* static int chans[NUM_CHANNELS] = { 1 , 2 }; */ |
12 | /* static int chans[NUM_CHANNELS] = { 1 , 2 }; */ |
13 | static const long my_rates[MPG123_RATES] = /* only the standard rates */ |
13 | static const long my_rates[MPG123_RATES] = /* only the standard rates */ |
14 | { |
14 | { |
15 | 8000, 11025, 12000, |
15 | 8000, 11025, 12000, |
16 | 16000, 22050, 24000, |
16 | 16000, 22050, 24000, |
17 | 32000, 44100, 48000, |
17 | 32000, 44100, 48000, |
18 | }; |
18 | }; |
19 | 19 | ||
20 | static const int my_encodings[MPG123_ENCODINGS] = |
20 | static const int my_encodings[MPG123_ENCODINGS] = |
21 | { |
21 | { |
22 | MPG123_ENC_SIGNED_16, |
22 | MPG123_ENC_SIGNED_16, |
23 | MPG123_ENC_UNSIGNED_16, |
23 | MPG123_ENC_UNSIGNED_16, |
24 | MPG123_ENC_SIGNED_32, |
24 | MPG123_ENC_SIGNED_32, |
25 | MPG123_ENC_UNSIGNED_32, |
25 | MPG123_ENC_UNSIGNED_32, |
- | 26 | MPG123_ENC_SIGNED_24, |
|
- | 27 | MPG123_ENC_UNSIGNED_24, |
|
- | 28 | /* Floating point range, see below. */ |
|
26 | MPG123_ENC_FLOAT_32, |
29 | MPG123_ENC_FLOAT_32, |
27 | MPG123_ENC_FLOAT_64, |
30 | MPG123_ENC_FLOAT_64, |
- | 31 | /* 8 bit range, see below. */ |
|
28 | MPG123_ENC_SIGNED_8, |
32 | MPG123_ENC_SIGNED_8, |
29 | MPG123_ENC_UNSIGNED_8, |
33 | MPG123_ENC_UNSIGNED_8, |
30 | MPG123_ENC_ULAW_8, |
34 | MPG123_ENC_ULAW_8, |
31 | MPG123_ENC_ALAW_8 |
35 | MPG123_ENC_ALAW_8 |
32 | }; |
36 | }; |
- | 37 | ||
- | 38 | /* Make that match the above table. |
|
- | 39 | And yes, I still don't like this kludgy stuff. */ |
|
- | 40 | /* range[0] <= i < range[1] for forced floating point */ |
|
- | 41 | static const int enc_float_range[2] = { 6, 8 }; |
|
- | 42 | /* same for 8 bit encodings */ |
|
- | 43 | static const int enc_8bit_range[2] = { 8, 12 }; |
|
33 | 44 | ||
34 | /* Only one type of float is supported. */ |
45 | /* Only one type of float is supported. */ |
35 | # ifdef REAL_IS_FLOAT |
46 | # ifdef REAL_IS_FLOAT |
36 | # define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_32 |
47 | # define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_32 |
37 | # else |
48 | # else |
38 | # define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_64 |
49 | # define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_64 |
39 | # endif |
50 | # endif |
40 | 51 | ||
41 | /* The list of actually possible encodings. */ |
52 | /* The list of actually possible encodings. */ |
42 | static const int good_encodings[] = |
53 | static const int good_encodings[] = |
43 | { |
54 | { |
44 | #ifndef NO_16BIT |
55 | #ifndef NO_16BIT |
45 | MPG123_ENC_SIGNED_16, |
56 | MPG123_ENC_SIGNED_16, |
46 | MPG123_ENC_UNSIGNED_16, |
57 | MPG123_ENC_UNSIGNED_16, |
47 | #endif |
58 | #endif |
48 | #ifndef NO_32BIT |
59 | #ifndef NO_32BIT |
49 | MPG123_ENC_SIGNED_32, |
60 | MPG123_ENC_SIGNED_32, |
50 | MPG123_ENC_UNSIGNED_32, |
61 | MPG123_ENC_UNSIGNED_32, |
- | 62 | MPG123_ENC_SIGNED_24, |
|
- | 63 | MPG123_ENC_UNSIGNED_24, |
|
51 | #endif |
64 | #endif |
52 | #ifndef NO_REAL |
65 | #ifndef NO_REAL |
53 | MPG123_FLOAT_ENC, |
66 | MPG123_FLOAT_ENC, |
54 | #endif |
67 | #endif |
55 | #ifndef NO_8BIT |
68 | #ifndef NO_8BIT |
56 | MPG123_ENC_SIGNED_8, |
69 | MPG123_ENC_SIGNED_8, |
57 | MPG123_ENC_UNSIGNED_8, |
70 | MPG123_ENC_UNSIGNED_8, |
58 | MPG123_ENC_ULAW_8, |
71 | MPG123_ENC_ULAW_8, |
59 | MPG123_ENC_ALAW_8 |
72 | MPG123_ENC_ALAW_8 |
60 | #endif |
73 | #endif |
61 | }; |
74 | }; |
62 | 75 | ||
63 | /* Check if encoding is a valid one in this build. |
76 | /* Check if encoding is a valid one in this build. |
64 | ...lazy programming: linear search. */ |
77 | ...lazy programming: linear search. */ |
65 | static int good_enc(const int enc) |
78 | static int good_enc(const int enc) |
66 | { |
79 | { |
67 | size_t i; |
80 | size_t i; |
68 | for(i=0; i |
81 | for(i=0; i |
69 | if(enc == good_encodings[i]) return TRUE; |
82 | if(enc == good_encodings[i]) return TRUE; |
70 | 83 | ||
71 | return FALSE; |
84 | return FALSE; |
72 | } |
85 | } |
73 | 86 | ||
74 | void attribute_align_arg mpg123_rates(const long **list, size_t *number) |
87 | void attribute_align_arg mpg123_rates(const long **list, size_t *number) |
75 | { |
88 | { |
76 | if(list != NULL) *list = my_rates; |
89 | if(list != NULL) *list = my_rates; |
77 | if(number != NULL) *number = sizeof(my_rates)/sizeof(long); |
90 | if(number != NULL) *number = sizeof(my_rates)/sizeof(long); |
78 | } |
91 | } |
79 | 92 | ||
80 | /* Now that's a bit tricky... One build of the library knows only a subset of the encodings. */ |
93 | /* Now that's a bit tricky... One build of the library knows only a subset of the encodings. */ |
81 | void attribute_align_arg mpg123_encodings(const int **list, size_t *number) |
94 | void attribute_align_arg mpg123_encodings(const int **list, size_t *number) |
82 | { |
95 | { |
83 | if(list != NULL) *list = good_encodings; |
96 | if(list != NULL) *list = good_encodings; |
84 | if(number != NULL) *number = sizeof(good_encodings)/sizeof(int); |
97 | if(number != NULL) *number = sizeof(good_encodings)/sizeof(int); |
85 | } |
98 | } |
- | 99 | ||
- | 100 | int attribute_align_arg mpg123_encsize(int encoding) |
|
- | 101 | { |
|
- | 102 | if(encoding & MPG123_ENC_8) |
|
- | 103 | return 1; |
|
- | 104 | else if(encoding & MPG123_ENC_16) |
|
- | 105 | return 2; |
|
- | 106 | else if(encoding & MPG123_ENC_24) |
|
- | 107 | return 3; |
|
- | 108 | else if(encoding & MPG123_ENC_32 || encoding == MPG123_ENC_FLOAT_32) |
|
- | 109 | return 4; |
|
- | 110 | else if(encoding == MPG123_ENC_FLOAT_64) |
|
- | 111 | return 8; |
|
- | 112 | else |
|
- | 113 | return 0; |
|
- | 114 | } |
|
86 | 115 | ||
87 | /* char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS]; */ |
116 | /* char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS]; */ |
88 | 117 | ||
89 | static int rate2num(mpg123_pars *mp, long r) |
118 | static int rate2num(mpg123_pars *mp, long r) |
90 | { |
119 | { |
91 | int i; |
120 | int i; |
92 | for(i=0;i |
121 | for(i=0;i |
93 | #ifndef NO_NTOM |
122 | #ifndef NO_NTOM |
94 | if(mp && mp->force_rate != 0 && mp->force_rate == r) return MPG123_RATES; |
123 | if(mp && mp->force_rate != 0 && mp->force_rate == r) return MPG123_RATES; |
95 | #endif |
124 | #endif |
96 | 125 | ||
97 | return -1; |
126 | return -1; |
98 | } |
127 | } |
99 | 128 | ||
100 | static int enc2num(int encoding) |
129 | static int enc2num(int encoding) |
101 | { |
130 | { |
102 | int i; |
131 | int i; |
103 | for(i=0;i |
132 | for(i=0;i |
104 | if(my_encodings[i] == encoding) return i; |
133 | if(my_encodings[i] == encoding) return i; |
105 | 134 | ||
106 | return -1; |
135 | return -1; |
107 | } |
136 | } |
108 | 137 | ||
109 | static int cap_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2) |
138 | static int cap_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2) |
110 | { |
139 | { |
111 | int i; |
140 | int i; |
112 | int c = nf->channels-1; |
141 | int c = nf->channels-1; |
113 | int rn = rate2num(&fr->p, nf->rate); |
142 | int rn = rate2num(&fr->p, nf->rate); |
114 | if(rn >= 0) for(i=f0;i |
143 | if(rn >= 0) for(i=f0;i |
115 | { |
144 | { |
116 | if(fr->p.audio_caps[c][rn][i]) |
145 | if(fr->p.audio_caps[c][rn][i]) |
117 | { |
146 | { |
118 | nf->encoding = my_encodings[i]; |
147 | nf->encoding = my_encodings[i]; |
119 | return 1; |
148 | return 1; |
120 | } |
149 | } |
121 | } |
150 | } |
122 | return 0; |
151 | return 0; |
123 | } |
152 | } |
124 | 153 | ||
125 | static int freq_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2) |
154 | static int freq_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2) |
126 | { |
155 | { |
127 | nf->rate = frame_freq(fr)>>fr->p.down_sample; |
156 | nf->rate = frame_freq(fr)>>fr->p.down_sample; |
128 | if(cap_fit(fr,nf,f0,f2)) return 1; |
157 | if(cap_fit(fr,nf,f0,f2)) return 1; |
- | 158 | if(fr->p.flags & MPG123_AUTO_RESAMPLE) |
|
- | 159 | { |
|
129 | nf->rate>>=1; |
160 | nf->rate>>=1; |
130 | if(cap_fit(fr,nf,f0,f2)) return 1; |
161 | if(cap_fit(fr,nf,f0,f2)) return 1; |
131 | nf->rate>>=1; |
162 | nf->rate>>=1; |
132 | if(cap_fit(fr,nf,f0,f2)) return 1; |
163 | if(cap_fit(fr,nf,f0,f2)) return 1; |
- | 164 | } |
|
133 | #ifndef NO_NTOM |
165 | #ifndef NO_NTOM |
134 | /* If nothing worked, try the other rates, only without constrains from user. |
166 | /* If nothing worked, try the other rates, only without constrains from user. |
135 | In case you didn't guess: We enable flexible resampling if we find a working rate. */ |
167 | In case you didn't guess: We enable flexible resampling if we find a working rate. */ |
- | 168 | if( fr->p.flags & MPG123_AUTO_RESAMPLE && |
|
136 | if(!fr->p.force_rate && fr->p.down_sample == 0) |
169 | !fr->p.force_rate && fr->p.down_sample == 0) |
137 | { |
170 | { |
138 | int i; |
171 | int i; |
139 | int c = nf->channels-1; |
172 | int c = nf->channels-1; |
140 | int rn = rate2num(&fr->p, frame_freq(fr)); |
173 | int rn = rate2num(&fr->p, frame_freq(fr)); |
141 | int rrn; |
174 | int rrn; |
142 | if(rn < 0) return 0; |
175 | if(rn < 0) return 0; |
143 | /* Try higher rates first. */ |
176 | /* Try higher rates first. */ |
144 | for(i=f0;i |
177 | for(i=f0;i |
145 | if(fr->p.audio_caps[c][rrn][i]) |
178 | if(fr->p.audio_caps[c][rrn][i]) |
146 | { |
179 | { |
147 | nf->rate = my_rates[rrn]; |
180 | nf->rate = my_rates[rrn]; |
148 | nf->encoding = my_encodings[i]; |
181 | nf->encoding = my_encodings[i]; |
149 | return 1; |
182 | return 1; |
150 | } |
183 | } |
151 | /* Then lower rates. */ |
184 | /* Then lower rates. */ |
152 | for(i=f0;i |
185 | for(i=f0;i |
153 | if(fr->p.audio_caps[c][rrn][i]) |
186 | if(fr->p.audio_caps[c][rrn][i]) |
154 | { |
187 | { |
155 | nf->rate = my_rates[rrn]; |
188 | nf->rate = my_rates[rrn]; |
156 | nf->encoding = my_encodings[i]; |
189 | nf->encoding = my_encodings[i]; |
157 | return 1; |
190 | return 1; |
158 | } |
191 | } |
159 | } |
192 | } |
160 | #endif |
193 | #endif |
161 | 194 | ||
162 | return 0; |
195 | return 0; |
163 | } |
196 | } |
164 | 197 | ||
165 | /* match constraints against supported audio formats, store possible setup in frame |
198 | /* match constraints against supported audio formats, store possible setup in frame |
166 | return: -1: error; 0: no format change; 1: format change */ |
199 | return: -1: error; 0: no format change; 1: format change */ |
167 | int frame_output_format(mpg123_handle *fr) |
200 | int frame_output_format(mpg123_handle *fr) |
168 | { |
201 | { |
169 | struct audioformat nf; |
202 | struct audioformat nf; |
170 | int f0=0; |
203 | int f0=0; |
171 | int f2=MPG123_ENCODINGS; /* Omit the 32bit and float encodings. */ |
204 | int f2=MPG123_ENCODINGS; /* Omit the 32bit and float encodings. */ |
172 | mpg123_pars *p = &fr->p; |
205 | mpg123_pars *p = &fr->p; |
173 | /* initialize new format, encoding comes later */ |
206 | /* initialize new format, encoding comes later */ |
174 | nf.channels = fr->stereo; |
207 | nf.channels = fr->stereo; |
175 | 208 | ||
176 | /* All this forcing should be removed in favour of the capabilities table... */ |
209 | /* All this forcing should be removed in favour of the capabilities table... */ |
177 | if(p->flags & MPG123_FORCE_8BIT) |
210 | if(p->flags & MPG123_FORCE_8BIT) |
178 | { |
211 | { |
179 | f0 = 6; |
212 | f0 = enc_8bit_range[0]; |
180 | f2 = 10; |
213 | f2 = enc_8bit_range[1]; |
181 | } |
214 | } |
182 | if(p->flags & MPG123_FORCE_FLOAT) |
215 | if(p->flags & MPG123_FORCE_FLOAT) |
183 | { |
216 | { |
184 | f0 = 4; |
217 | f0 = enc_float_range[0]; |
185 | f2 = 6; |
218 | f2 = enc_float_range[1]; |
186 | } |
219 | } |
187 | 220 | ||
188 | /* force stereo is stronger */ |
221 | /* force stereo is stronger */ |
189 | if(p->flags & MPG123_FORCE_MONO) nf.channels = 1; |
222 | if(p->flags & MPG123_FORCE_MONO) nf.channels = 1; |
190 | if(p->flags & MPG123_FORCE_STEREO) nf.channels = 2; |
223 | if(p->flags & MPG123_FORCE_STEREO) nf.channels = 2; |
191 | 224 | ||
192 | #ifndef NO_NTOM |
225 | #ifndef NO_NTOM |
193 | if(p->force_rate) |
226 | if(p->force_rate) |
194 | { |
227 | { |
195 | nf.rate = p->force_rate; |
228 | nf.rate = p->force_rate; |
196 | if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */ |
229 | if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */ |
197 | if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */ |
230 | if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */ |
198 | 231 | ||
199 | /* try again with different stereoness */ |
232 | /* try again with different stereoness */ |
200 | if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1; |
233 | if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1; |
201 | else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2; |
234 | else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2; |
202 | 235 | ||
203 | if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */ |
236 | if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */ |
204 | if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */ |
237 | if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */ |
205 | 238 | ||
206 | if(NOQUIET) |
239 | if(NOQUIET) |
207 | error3( "Unable to set up output format! Constraints: %s%s%liHz.", |
240 | error3( "Unable to set up output format! Constraints: %s%s%liHz.", |
208 | ( p->flags & MPG123_FORCE_STEREO ? "stereo, " : |
241 | ( p->flags & MPG123_FORCE_STEREO ? "stereo, " : |
209 | (p->flags & MPG123_FORCE_MONO ? "mono, " : "") ), |
242 | (p->flags & MPG123_FORCE_MONO ? "mono, " : "") ), |
210 | (p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""), |
243 | (p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""), |
211 | p->force_rate ); |
244 | p->force_rate ); |
212 | /* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */ |
245 | /* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */ |
213 | 246 | ||
214 | fr->err = MPG123_BAD_OUTFORMAT; |
247 | fr->err = MPG123_BAD_OUTFORMAT; |
215 | return -1; |
248 | return -1; |
216 | } |
249 | } |
217 | #endif |
250 | #endif |
218 | 251 | ||
219 | if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */ |
252 | if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */ |
220 | if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */ |
253 | if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */ |
221 | 254 | ||
222 | /* try again with different stereoness */ |
255 | /* try again with different stereoness */ |
223 | if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1; |
256 | if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1; |
224 | else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2; |
257 | else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2; |
225 | 258 | ||
226 | if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */ |
259 | if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */ |
227 | if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */ |
260 | if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */ |
228 | 261 | ||
229 | /* Here is the _bad_ end. */ |
262 | /* Here is the _bad_ end. */ |
230 | if(NOQUIET) |
263 | if(NOQUIET) |
231 | { |
264 | { |
232 | error5( "Unable to set up output format! Constraints: %s%s%li, %li or %liHz.", |
265 | error5( "Unable to set up output format! Constraints: %s%s%li, %li or %liHz.", |
233 | ( p->flags & MPG123_FORCE_STEREO ? "stereo, " : |
266 | ( p->flags & MPG123_FORCE_STEREO ? "stereo, " : |
234 | (p->flags & MPG123_FORCE_MONO ? "mono, " : "") ), |
267 | (p->flags & MPG123_FORCE_MONO ? "mono, " : "") ), |
235 | (p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""), |
268 | (p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""), |
236 | frame_freq(fr), frame_freq(fr)>>1, frame_freq(fr)>>2 ); |
269 | frame_freq(fr), frame_freq(fr)>>1, frame_freq(fr)>>2 ); |
237 | } |
270 | } |
238 | /* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */ |
271 | /* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */ |
239 | 272 | ||
240 | fr->err = MPG123_BAD_OUTFORMAT; |
273 | fr->err = MPG123_BAD_OUTFORMAT; |
241 | return -1; |
274 | return -1; |
242 | 275 | ||
243 | end: /* Here is the _good_ end. */ |
276 | end: /* Here is the _good_ end. */ |
244 | /* we had a successful match, now see if there's a change */ |
277 | /* we had a successful match, now see if there's a change */ |
245 | if(nf.rate == fr->af.rate && nf.channels == fr->af.channels && nf.encoding == fr->af.encoding) |
278 | if(nf.rate == fr->af.rate && nf.channels == fr->af.channels && nf.encoding == fr->af.encoding) |
246 | { |
279 | { |
247 | debug2("Old format with %i channels, and FORCE_MONO=%li", nf.channels, p->flags & MPG123_FORCE_MONO); |
280 | debug2("Old format with %i channels, and FORCE_MONO=%li", nf.channels, p->flags & MPG123_FORCE_MONO); |
248 | return 0; /* the same format as before */ |
281 | return 0; /* the same format as before */ |
249 | } |
282 | } |
250 | else /* a new format */ |
283 | else /* a new format */ |
251 | { |
284 | { |
252 | debug1("New format with %i channels!", nf.channels); |
285 | debug1("New format with %i channels!", nf.channels); |
253 | fr->af.rate = nf.rate; |
286 | fr->af.rate = nf.rate; |
254 | fr->af.channels = nf.channels; |
287 | fr->af.channels = nf.channels; |
255 | fr->af.encoding = nf.encoding; |
288 | fr->af.encoding = nf.encoding; |
256 | /* Cache the size of one sample in bytes, for ease of use. */ |
289 | /* Cache the size of one sample in bytes, for ease of use. */ |
257 | if(fr->af.encoding & MPG123_ENC_8) |
- | |
258 | fr->af.encsize = 1; |
- | |
259 | else if(fr->af.encoding & MPG123_ENC_16) |
- | |
260 | fr->af.encsize = 2; |
- | |
261 | else if(fr->af.encoding & MPG123_ENC_32 || fr->af.encoding == MPG123_ENC_FLOAT_32) |
290 | fr->af.encsize = mpg123_encsize(fr->af.encoding); |
262 | fr->af.encsize = 4; |
- | |
263 | else if(fr->af.encoding == MPG123_ENC_FLOAT_64) |
- | |
264 | fr->af.encsize = 8; |
291 | if(fr->af.encsize < 1) |
265 | else |
- | |
266 | { |
292 | { |
267 | if(NOQUIET) error1("Some unknown encoding??? (%i)", fr->af.encoding); |
293 | if(NOQUIET) error1("Some unknown encoding??? (%i)", fr->af.encoding); |
268 | 294 | ||
269 | fr->err = MPG123_BAD_OUTFORMAT; |
295 | fr->err = MPG123_BAD_OUTFORMAT; |
270 | return -1; |
296 | return -1; |
271 | } |
297 | } |
272 | return 1; |
298 | return 1; |
273 | } |
299 | } |
274 | } |
300 | } |
275 | 301 | ||
276 | int attribute_align_arg mpg123_format_none(mpg123_handle *mh) |
302 | int attribute_align_arg mpg123_format_none(mpg123_handle *mh) |
277 | { |
303 | { |
278 | int r; |
304 | int r; |
279 | if(mh == NULL) return MPG123_ERR; |
305 | if(mh == NULL) return MPG123_ERR; |
280 | 306 | ||
281 | r = mpg123_fmt_none(&mh->p); |
307 | r = mpg123_fmt_none(&mh->p); |
282 | if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; } |
308 | if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; } |
283 | 309 | ||
284 | return r; |
310 | return r; |
285 | } |
311 | } |
286 | 312 | ||
287 | int attribute_align_arg mpg123_fmt_none(mpg123_pars *mp) |
313 | int attribute_align_arg mpg123_fmt_none(mpg123_pars *mp) |
288 | { |
314 | { |
289 | if(mp == NULL) return MPG123_BAD_PARS; |
315 | if(mp == NULL) return MPG123_BAD_PARS; |
290 | 316 | ||
291 | if(PVERB(mp,3)) fprintf(stderr, "Note: Disabling all formats.\n"); |
317 | if(PVERB(mp,3)) fprintf(stderr, "Note: Disabling all formats.\n"); |
292 | 318 | ||
293 | memset(mp->audio_caps,0,sizeof(mp->audio_caps)); |
319 | memset(mp->audio_caps,0,sizeof(mp->audio_caps)); |
294 | return MPG123_OK; |
320 | return MPG123_OK; |
295 | } |
321 | } |
296 | 322 | ||
297 | int attribute_align_arg mpg123_format_all(mpg123_handle *mh) |
323 | int attribute_align_arg mpg123_format_all(mpg123_handle *mh) |
298 | { |
324 | { |
299 | int r; |
325 | int r; |
300 | if(mh == NULL) return MPG123_ERR; |
326 | if(mh == NULL) return MPG123_ERR; |
301 | 327 | ||
302 | r = mpg123_fmt_all(&mh->p); |
328 | r = mpg123_fmt_all(&mh->p); |
303 | if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; } |
329 | if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; } |
304 | 330 | ||
305 | return r; |
331 | return r; |
306 | } |
332 | } |
307 | 333 | ||
308 | int attribute_align_arg mpg123_fmt_all(mpg123_pars *mp) |
334 | int attribute_align_arg mpg123_fmt_all(mpg123_pars *mp) |
309 | { |
335 | { |
310 | size_t rate, ch, enc; |
336 | size_t rate, ch, enc; |
311 | if(mp == NULL) return MPG123_BAD_PARS; |
337 | if(mp == NULL) return MPG123_BAD_PARS; |
312 | 338 | ||
313 | if(PVERB(mp,3)) fprintf(stderr, "Note: Enabling all formats.\n"); |
339 | if(PVERB(mp,3)) fprintf(stderr, "Note: Enabling all formats.\n"); |
314 | 340 | ||
315 | for(ch=0; ch < NUM_CHANNELS; ++ch) |
341 | for(ch=0; ch < NUM_CHANNELS; ++ch) |
316 | for(rate=0; rate < MPG123_RATES+1; ++rate) |
342 | for(rate=0; rate < MPG123_RATES+1; ++rate) |
317 | for(enc=0; enc < MPG123_ENCODINGS; ++enc) |
343 | for(enc=0; enc < MPG123_ENCODINGS; ++enc) |
318 | mp->audio_caps[ch][rate][enc] = good_enc(my_encodings[enc]) ? 1 : 0; |
344 | mp->audio_caps[ch][rate][enc] = good_enc(my_encodings[enc]) ? 1 : 0; |
319 | 345 | ||
320 | return MPG123_OK; |
346 | return MPG123_OK; |
321 | } |
347 | } |
322 | 348 | ||
323 | int attribute_align_arg mpg123_format(mpg123_handle *mh, long rate, int channels, int encodings) |
349 | int attribute_align_arg mpg123_format(mpg123_handle *mh, long rate, int channels, int encodings) |
324 | { |
350 | { |
325 | int r; |
351 | int r; |
326 | if(mh == NULL) return MPG123_ERR; |
352 | if(mh == NULL) return MPG123_ERR; |
327 | r = mpg123_fmt(&mh->p, rate, channels, encodings); |
353 | r = mpg123_fmt(&mh->p, rate, channels, encodings); |
328 | if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; } |
354 | if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; } |
329 | 355 | ||
330 | return r; |
356 | return r; |
331 | } |
357 | } |
332 | 358 | ||
333 | int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int encodings) |
359 | int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int encodings) |
334 | { |
360 | { |
335 | int ie, ic, ratei; |
361 | int ie, ic, ratei; |
336 | int ch[2] = {0, 1}; |
362 | int ch[2] = {0, 1}; |
337 | if(mp == NULL) return MPG123_BAD_PARS; |
363 | if(mp == NULL) return MPG123_BAD_PARS; |
338 | if(!(channels & (MPG123_MONO|MPG123_STEREO))) return MPG123_BAD_CHANNEL; |
364 | if(!(channels & (MPG123_MONO|MPG123_STEREO))) return MPG123_BAD_CHANNEL; |
339 | 365 | ||
340 | if(PVERB(mp,3)) fprintf(stderr, "Note: Want to enable format %li/%i for encodings 0x%x.\n", rate, channels, encodings); |
366 | if(PVERB(mp,3)) fprintf(stderr, "Note: Want to enable format %li/%i for encodings 0x%x.\n", rate, channels, encodings); |
341 | 367 | ||
342 | if(!(channels & MPG123_STEREO)) ch[1] = 0; /* {0,0} */ |
368 | if(!(channels & MPG123_STEREO)) ch[1] = 0; /* {0,0} */ |
343 | else if(!(channels & MPG123_MONO)) ch[0] = 1; /* {1,1} */ |
369 | else if(!(channels & MPG123_MONO)) ch[0] = 1; /* {1,1} */ |
344 | ratei = rate2num(mp, rate); |
370 | ratei = rate2num(mp, rate); |
345 | if(ratei < 0) return MPG123_BAD_RATE; |
371 | if(ratei < 0) return MPG123_BAD_RATE; |
346 | 372 | ||
347 | /* now match the encodings */ |
373 | /* now match the encodings */ |
348 | for(ic = 0; ic < 2; ++ic) |
374 | for(ic = 0; ic < 2; ++ic) |
349 | { |
375 | { |
350 | for(ie = 0; ie < MPG123_ENCODINGS; ++ie) |
376 | for(ie = 0; ie < MPG123_ENCODINGS; ++ie) |
351 | if(good_enc(my_encodings[ie]) && ((my_encodings[ie] & encodings) == my_encodings[ie])) |
377 | if(good_enc(my_encodings[ie]) && ((my_encodings[ie] & encodings) == my_encodings[ie])) |
352 | mp->audio_caps[ch[ic]][ratei][ie] = 1; |
378 | mp->audio_caps[ch[ic]][ratei][ie] = 1; |
353 | 379 | ||
354 | if(ch[0] == ch[1]) break; /* no need to do it again */ |
380 | if(ch[0] == ch[1]) break; /* no need to do it again */ |
355 | } |
381 | } |
356 | 382 | ||
357 | return MPG123_OK; |
383 | return MPG123_OK; |
358 | } |
384 | } |
359 | 385 | ||
360 | int attribute_align_arg mpg123_format_support(mpg123_handle *mh, long rate, int encoding) |
386 | int attribute_align_arg mpg123_format_support(mpg123_handle *mh, long rate, int encoding) |
361 | { |
387 | { |
362 | if(mh == NULL) return 0; |
388 | if(mh == NULL) return 0; |
363 | else return mpg123_fmt_support(&mh->p, rate, encoding); |
389 | else return mpg123_fmt_support(&mh->p, rate, encoding); |
364 | } |
390 | } |
365 | 391 | ||
366 | int attribute_align_arg mpg123_fmt_support(mpg123_pars *mp, long rate, int encoding) |
392 | int attribute_align_arg mpg123_fmt_support(mpg123_pars *mp, long rate, int encoding) |
367 | { |
393 | { |
368 | int ch = 0; |
394 | int ch = 0; |
369 | int ratei, enci; |
395 | int ratei, enci; |
370 | ratei = rate2num(mp, rate); |
396 | ratei = rate2num(mp, rate); |
371 | enci = enc2num(encoding); |
397 | enci = enc2num(encoding); |
372 | if(mp == NULL || ratei < 0 || enci < 0) return 0; |
398 | if(mp == NULL || ratei < 0 || enci < 0) return 0; |
373 | if(mp->audio_caps[0][ratei][enci]) ch |= MPG123_MONO; |
399 | if(mp->audio_caps[0][ratei][enci]) ch |= MPG123_MONO; |
374 | if(mp->audio_caps[1][ratei][enci]) ch |= MPG123_STEREO; |
400 | if(mp->audio_caps[1][ratei][enci]) ch |= MPG123_STEREO; |
375 | return ch; |
401 | return ch; |
376 | } |
402 | } |
377 | 403 | ||
378 | /* Call this one to ensure that any valid format will be something different than this. */ |
404 | /* Call this one to ensure that any valid format will be something different than this. */ |
379 | void invalidate_format(struct audioformat *af) |
405 | void invalidate_format(struct audioformat *af) |
380 | { |
406 | { |
381 | af->encoding = 0; |
407 | af->encoding = 0; |
382 | af->rate = 0; |
408 | af->rate = 0; |
383 | af->channels = 0; |
409 | af->channels = 0; |
384 | } |
410 | } |
- | 411 | ||
- | 412 | /* Consider 24bit output needing 32bit output as temporary storage. */ |
|
- | 413 | off_t samples_to_storage(mpg123_handle *fr, off_t s) |
|
- | 414 | { |
|
- | 415 | if(fr->af.encoding & MPG123_ENC_24) |
|
- | 416 | return s*4*fr->af.channels; /* 4 bytes per sample */ |
|
- | 417 | else |
|
- | 418 | return samples_to_bytes(fr, s); |
|
- | 419 | } |
|
385 | 420 | ||
386 | /* take into account: channels, bytes per sample -- NOT resampling!*/ |
421 | /* take into account: channels, bytes per sample -- NOT resampling!*/ |
387 | off_t samples_to_bytes(mpg123_handle *fr , off_t s) |
422 | off_t samples_to_bytes(mpg123_handle *fr , off_t s) |
388 | { |
423 | { |
389 | return s * fr->af.encsize * fr->af.channels; |
424 | return s * fr->af.encsize * fr->af.channels; |
390 | } |
425 | } |
391 | 426 | ||
392 | off_t bytes_to_samples(mpg123_handle *fr , off_t b) |
427 | off_t bytes_to_samples(mpg123_handle *fr , off_t b) |
393 | { |
428 | { |
394 | return b / fr->af.encsize / fr->af.channels; |
429 | return b / fr->af.encsize / fr->af.channels; |
395 | }>>>>>>>>=>=2>=2>=>=2>=2>> |
430 | } |
- | 431 | ||
- | 432 | ||
- | 433 | #ifndef NO_32BIT |
|
- | 434 | /* Remove every fourth byte, facilitating conversion from 32 bit to 24 bit integers. |
|
- | 435 | This has to be aware of endianness, of course. */ |
|
- | 436 | static void chop_fourth_byte(struct outbuffer *buf) |
|
- | 437 | { |
|
- | 438 | unsigned char *wpos = buf->data; |
|
- | 439 | unsigned char *rpos = buf->data; |
|
- | 440 | #ifdef WORDS_BIGENDIAN |
|
- | 441 | while((size_t) (rpos - buf->data + 4) <= buf->fill) |
|
- | 442 | { |
|
- | 443 | /* Really stupid: Copy, increment. Byte per byte. */ |
|
- | 444 | *wpos = *rpos; |
|
- | 445 | wpos++; rpos++; |
|
- | 446 | *wpos = *rpos; |
|
- | 447 | wpos++; rpos++; |
|
- | 448 | *wpos = *rpos; |
|
- | 449 | wpos++; rpos++; |
|
- | 450 | rpos++; /* Skip the lowest byte (last). */ |
|
- | 451 | } |
|
- | 452 | #else |
|
- | 453 | while((size_t) (rpos - buf->data + 4) <= buf->fill) |
|
- | 454 | { |
|
- | 455 | /* Really stupid: Copy, increment. Byte per byte. */ |
|
- | 456 | rpos++; /* Skip the lowest byte (first). */ |
|
- | 457 | *wpos = *rpos; |
|
- | 458 | wpos++; rpos++; |
|
- | 459 | *wpos = *rpos; |
|
- | 460 | wpos++; rpos++; |
|
- | 461 | *wpos = *rpos; |
|
- | 462 | wpos++; rpos++; |
|
- | 463 | } |
|
- | 464 | #endif |
|
- | 465 | buf->fill = wpos-buf->data; |
|
- | 466 | } |
|
- | 467 | #endif |
|
- | 468 | ||
- | 469 | void postprocess_buffer(mpg123_handle *fr) |
|
- | 470 | { |
|
- | 471 | /* Handle unsigned output formats via reshifting after decode here. |
|
- | 472 | Also handle conversion to 24 bit. */ |
|
- | 473 | #ifndef NO_32BIT |
|
- | 474 | if(fr->af.encoding == MPG123_ENC_UNSIGNED_32 || fr->af.encoding == MPG123_ENC_UNSIGNED_24) |
|
- | 475 | { /* 32bit signed -> unsigned */ |
|
- | 476 | size_t i; |
|
- | 477 | int32_t *ssamples; |
|
- | 478 | uint32_t *usamples; |
|
- | 479 | ssamples = (int32_t*)fr->buffer.data; |
|
- | 480 | usamples = (uint32_t*)fr->buffer.data; |
|
- | 481 | debug("converting output to unsigned 32 bit integer"); |
|
- | 482 | for(i=0; i |
|
- | 483 | { |
|
- | 484 | /* Different strategy since we don't have a larger type at hand. |
|
- | 485 | Also watch out for silly +-1 fun because integer constants are signed in C90! */ |
|
- | 486 | if(ssamples[i] >= 0) |
|
- | 487 | usamples[i] = (uint32_t)ssamples[i] + 2147483647+1; |
|
- | 488 | /* The smalles value goes zero. */ |
|
- | 489 | else if(ssamples[i] == ((int32_t)-2147483647-1)) |
|
- | 490 | usamples[i] = 0; |
|
- | 491 | /* Now -value is in the positive range of signed int ... so it's a possible value at all. */ |
|
- | 492 | else |
|
- | 493 | usamples[i] = (uint32_t)2147483647+1 - (uint32_t)(-ssamples[i]); |
|
- | 494 | } |
|
- | 495 | /* Dumb brute force: A second pass for hacking off the last byte. */ |
|
- | 496 | if(fr->af.encoding == MPG123_ENC_UNSIGNED_24) |
|
- | 497 | chop_fourth_byte(&fr->buffer); |
|
- | 498 | } |
|
- | 499 | else if(fr->af.encoding == MPG123_ENC_SIGNED_24) |
|
- | 500 | { |
|
- | 501 | /* We got 32 bit signed ... chop off for 24 bit signed. */ |
|
- | 502 | chop_fourth_byte(&fr->buffer); |
|
- | 503 | } |
|
- | 504 | #endif |
|
- | 505 | #ifndef NO_16BIT |
|
- | 506 | if(fr->af.encoding == MPG123_ENC_UNSIGNED_16) |
|
- | 507 | { |
|
- | 508 | size_t i; |
|
- | 509 | short *ssamples; |
|
- | 510 | unsigned short *usamples; |
|
- | 511 | ssamples = (short*)fr->buffer.data; |
|
- | 512 | usamples = (unsigned short*)fr->buffer.data; |
|
- | 513 | debug("converting output to unsigned 16 bit integer"); |
|
- | 514 | for(i=0; i |
|
- | 515 | { |
|
- | 516 | long tmp = (long)ssamples[i]+32768; |
|
- | 517 | usamples[i] = (unsigned short)tmp; |
|
- | 518 | } |
|
- | 519 | } |
|
- | 520 | #endif |
|
- | 521 | }=>=>>>>>>>>>>=>=2>=2>=>=2>=2>> |
|
396 | > |
522 | > |
397 | > |
523 | >>=> |