Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenformat.c
Go to the documentation of this file.
00001 /* 00002 format:routines to deal with audio (output) format 00003 00004 copyright 2008-9 by the mpg123 project - free software under the terms of the LGPL 2.1 00005 see COPYING and AUTHORS files in distribution or http://mpg123.org 00006 initially written by Thomas Orgis, starting with parts of the old audio.c, with only faintly manage to show now 00007 */ 00008 00009 #include "mpg123lib_intern.h" 00010 #include "debug.h" 00011 00012 /* static int chans[NUM_CHANNELS] = { 1 , 2 }; */ 00013 static const long my_rates[MPG123_RATES] = /* only the standard rates */ 00014 { 00015 8000, 11025, 12000, 00016 16000, 22050, 24000, 00017 32000, 44100, 48000, 00018 }; 00019 00020 static const int my_encodings[MPG123_ENCODINGS] = 00021 { 00022 MPG123_ENC_SIGNED_16, 00023 MPG123_ENC_UNSIGNED_16, 00024 MPG123_ENC_SIGNED_32, 00025 MPG123_ENC_UNSIGNED_32, 00026 MPG123_ENC_FLOAT_32, 00027 MPG123_ENC_FLOAT_64, 00028 MPG123_ENC_SIGNED_8, 00029 MPG123_ENC_UNSIGNED_8, 00030 MPG123_ENC_ULAW_8, 00031 MPG123_ENC_ALAW_8 00032 }; 00033 00034 /* Only one type of float is supported. */ 00035 # ifdef REAL_IS_FLOAT 00036 # define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_32 00037 # else 00038 # define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_64 00039 # endif 00040 00041 /* The list of actually possible encodings. */ 00042 static const int good_encodings[] = 00043 { 00044 #ifndef NO_16BIT 00045 MPG123_ENC_SIGNED_16, 00046 MPG123_ENC_UNSIGNED_16, 00047 #endif 00048 #ifndef NO_32BIT 00049 MPG123_ENC_SIGNED_32, 00050 MPG123_ENC_UNSIGNED_32, 00051 #endif 00052 #ifndef NO_REAL 00053 MPG123_FLOAT_ENC, 00054 #endif 00055 #ifndef NO_8BIT 00056 MPG123_ENC_SIGNED_8, 00057 MPG123_ENC_UNSIGNED_8, 00058 MPG123_ENC_ULAW_8, 00059 MPG123_ENC_ALAW_8 00060 #endif 00061 }; 00062 00063 /* Check if encoding is a valid one in this build. 00064 ...lazy programming: linear search. */ 00065 static int good_enc(const int enc) 00066 { 00067 size_t i; 00068 for(i=0; i<sizeof(good_encodings)/sizeof(int); ++i) 00069 if(enc == good_encodings[i]) return TRUE; 00070 00071 return FALSE; 00072 } 00073 00074 void attribute_align_arg mpg123_rates(const long **list, size_t *number) 00075 { 00076 if(list != NULL) *list = my_rates; 00077 if(number != NULL) *number = sizeof(my_rates)/sizeof(long); 00078 } 00079 00080 /* Now that's a bit tricky... One build of the library knows only a subset of the encodings. */ 00081 void attribute_align_arg mpg123_encodings(const int **list, size_t *number) 00082 { 00083 if(list != NULL) *list = good_encodings; 00084 if(number != NULL) *number = sizeof(good_encodings)/sizeof(int); 00085 } 00086 00087 /* char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS]; */ 00088 00089 static int rate2num(mpg123_pars *mp, long r) 00090 { 00091 int i; 00092 for(i=0;i<MPG123_RATES;i++) if(my_rates[i] == r) return i; 00093 #ifndef NO_NTOM 00094 if(mp && mp->force_rate != 0 && mp->force_rate == r) return MPG123_RATES; 00095 #endif 00096 00097 return -1; 00098 } 00099 00100 static int enc2num(int encoding) 00101 { 00102 int i; 00103 for(i=0;i<MPG123_ENCODINGS;++i) 00104 if(my_encodings[i] == encoding) return i; 00105 00106 return -1; 00107 } 00108 00109 static int cap_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2) 00110 { 00111 int i; 00112 int c = nf->channels-1; 00113 int rn = rate2num(&fr->p, nf->rate); 00114 if(rn >= 0) for(i=f0;i<f2;i++) 00115 { 00116 if(fr->p.audio_caps[c][rn][i]) 00117 { 00118 nf->encoding = my_encodings[i]; 00119 return 1; 00120 } 00121 } 00122 return 0; 00123 } 00124 00125 static int freq_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2) 00126 { 00127 nf->rate = frame_freq(fr)>>fr->p.down_sample; 00128 if(cap_fit(fr,nf,f0,f2)) return 1; 00129 nf->rate>>=1; 00130 if(cap_fit(fr,nf,f0,f2)) return 1; 00131 nf->rate>>=1; 00132 if(cap_fit(fr,nf,f0,f2)) return 1; 00133 #ifndef NO_NTOM 00134 /* If nothing worked, try the other rates, only without constrains from user. 00135 In case you didn't guess: We enable flexible resampling if we find a working rate. */ 00136 if(!fr->p.force_rate && fr->p.down_sample == 0) 00137 { 00138 int i; 00139 int c = nf->channels-1; 00140 int rn = rate2num(&fr->p, frame_freq(fr)); 00141 int rrn; 00142 if(rn < 0) return 0; 00143 /* Try higher rates first. */ 00144 for(i=f0;i<f2;i++) for(rrn=rn+1; rrn<MPG123_RATES; ++rrn) 00145 if(fr->p.audio_caps[c][rrn][i]) 00146 { 00147 nf->rate = my_rates[rrn]; 00148 nf->encoding = my_encodings[i]; 00149 return 1; 00150 } 00151 /* Then lower rates. */ 00152 for(i=f0;i<f2;i++) for(rrn=rn-1; rrn>=0; --rrn) 00153 if(fr->p.audio_caps[c][rrn][i]) 00154 { 00155 nf->rate = my_rates[rrn]; 00156 nf->encoding = my_encodings[i]; 00157 return 1; 00158 } 00159 } 00160 #endif 00161 00162 return 0; 00163 } 00164 00165 /* match constraints against supported audio formats, store possible setup in frame 00166 return: -1: error; 0: no format change; 1: format change */ 00167 int frame_output_format(mpg123_handle *fr) 00168 { 00169 struct audioformat nf; 00170 int f0=0; 00171 int f2=MPG123_ENCODINGS; /* Omit the 32bit and float encodings. */ 00172 mpg123_pars *p = &fr->p; 00173 /* initialize new format, encoding comes later */ 00174 nf.channels = fr->stereo; 00175 00176 /* All this forcing should be removed in favour of the capabilities table... */ 00177 if(p->flags & MPG123_FORCE_8BIT) 00178 { 00179 f0 = 6; 00180 f2 = 10; 00181 } 00182 if(p->flags & MPG123_FORCE_FLOAT) 00183 { 00184 f0 = 4; 00185 f2 = 6; 00186 } 00187 00188 /* force stereo is stronger */ 00189 if(p->flags & MPG123_FORCE_MONO) nf.channels = 1; 00190 if(p->flags & MPG123_FORCE_STEREO) nf.channels = 2; 00191 00192 #ifndef NO_NTOM 00193 if(p->force_rate) 00194 { 00195 nf.rate = p->force_rate; 00196 if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */ 00197 if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */ 00198 00199 /* try again with different stereoness */ 00200 if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1; 00201 else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2; 00202 00203 if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */ 00204 if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */ 00205 00206 if(NOQUIET) 00207 error3( "Unable to set up output format! Constraints: %s%s%liHz.", 00208 ( p->flags & MPG123_FORCE_STEREO ? "stereo, " : 00209 (p->flags & MPG123_FORCE_MONO ? "mono, " : "") ), 00210 (p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""), 00211 p->force_rate ); 00212 /* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */ 00213 00214 fr->err = MPG123_BAD_OUTFORMAT; 00215 return -1; 00216 } 00217 #endif 00218 00219 if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */ 00220 if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */ 00221 00222 /* try again with different stereoness */ 00223 if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1; 00224 else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2; 00225 00226 if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */ 00227 if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */ 00228 00229 /* Here is the _bad_ end. */ 00230 if(NOQUIET) 00231 { 00232 error5( "Unable to set up output format! Constraints: %s%s%li, %li or %liHz.", 00233 ( p->flags & MPG123_FORCE_STEREO ? "stereo, " : 00234 (p->flags & MPG123_FORCE_MONO ? "mono, " : "") ), 00235 (p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""), 00236 frame_freq(fr), frame_freq(fr)>>1, frame_freq(fr)>>2 ); 00237 } 00238 /* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */ 00239 00240 fr->err = MPG123_BAD_OUTFORMAT; 00241 return -1; 00242 00243 end: /* Here is the _good_ end. */ 00244 /* we had a successful match, now see if there's a change */ 00245 if(nf.rate == fr->af.rate && nf.channels == fr->af.channels && nf.encoding == fr->af.encoding) 00246 { 00247 debug2("Old format with %i channels, and FORCE_MONO=%li", nf.channels, p->flags & MPG123_FORCE_MONO); 00248 return 0; /* the same format as before */ 00249 } 00250 else /* a new format */ 00251 { 00252 debug1("New format with %i channels!", nf.channels); 00253 fr->af.rate = nf.rate; 00254 fr->af.channels = nf.channels; 00255 fr->af.encoding = nf.encoding; 00256 /* Cache the size of one sample in bytes, for ease of use. */ 00257 if(fr->af.encoding & MPG123_ENC_8) 00258 fr->af.encsize = 1; 00259 else if(fr->af.encoding & MPG123_ENC_16) 00260 fr->af.encsize = 2; 00261 else if(fr->af.encoding & MPG123_ENC_32 || fr->af.encoding == MPG123_ENC_FLOAT_32) 00262 fr->af.encsize = 4; 00263 else if(fr->af.encoding == MPG123_ENC_FLOAT_64) 00264 fr->af.encsize = 8; 00265 else 00266 { 00267 if(NOQUIET) error1("Some unknown encoding??? (%i)", fr->af.encoding); 00268 00269 fr->err = MPG123_BAD_OUTFORMAT; 00270 return -1; 00271 } 00272 return 1; 00273 } 00274 } 00275 00276 int attribute_align_arg mpg123_format_none(mpg123_handle *mh) 00277 { 00278 int r; 00279 if(mh == NULL) return MPG123_ERR; 00280 00281 r = mpg123_fmt_none(&mh->p); 00282 if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; } 00283 00284 return r; 00285 } 00286 00287 int attribute_align_arg mpg123_fmt_none(mpg123_pars *mp) 00288 { 00289 if(mp == NULL) return MPG123_BAD_PARS; 00290 00291 if(PVERB(mp,3)) fprintf(stderr, "Note: Disabling all formats.\n"); 00292 00293 memset(mp->audio_caps,0,sizeof(mp->audio_caps)); 00294 return MPG123_OK; 00295 } 00296 00297 int attribute_align_arg mpg123_format_all(mpg123_handle *mh) 00298 { 00299 int r; 00300 if(mh == NULL) return MPG123_ERR; 00301 00302 r = mpg123_fmt_all(&mh->p); 00303 if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; } 00304 00305 return r; 00306 } 00307 00308 int attribute_align_arg mpg123_fmt_all(mpg123_pars *mp) 00309 { 00310 size_t rate, ch, enc; 00311 if(mp == NULL) return MPG123_BAD_PARS; 00312 00313 if(PVERB(mp,3)) fprintf(stderr, "Note: Enabling all formats.\n"); 00314 00315 for(ch=0; ch < NUM_CHANNELS; ++ch) 00316 for(rate=0; rate < MPG123_RATES+1; ++rate) 00317 for(enc=0; enc < MPG123_ENCODINGS; ++enc) 00318 mp->audio_caps[ch][rate][enc] = good_enc(my_encodings[enc]) ? 1 : 0; 00319 00320 return MPG123_OK; 00321 } 00322 00323 int attribute_align_arg mpg123_format(mpg123_handle *mh, long rate, int channels, int encodings) 00324 { 00325 int r; 00326 if(mh == NULL) return MPG123_ERR; 00327 r = mpg123_fmt(&mh->p, rate, channels, encodings); 00328 if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; } 00329 00330 return r; 00331 } 00332 00333 int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int encodings) 00334 { 00335 int ie, ic, ratei; 00336 int ch[2] = {0, 1}; 00337 if(mp == NULL) return MPG123_BAD_PARS; 00338 if(!(channels & (MPG123_MONO|MPG123_STEREO))) return MPG123_BAD_CHANNEL; 00339 00340 if(PVERB(mp,3)) fprintf(stderr, "Note: Want to enable format %li/%i for encodings 0x%x.\n", rate, channels, encodings); 00341 00342 if(!(channels & MPG123_STEREO)) ch[1] = 0; /* {0,0} */ 00343 else if(!(channels & MPG123_MONO)) ch[0] = 1; /* {1,1} */ 00344 ratei = rate2num(mp, rate); 00345 if(ratei < 0) return MPG123_BAD_RATE; 00346 00347 /* now match the encodings */ 00348 for(ic = 0; ic < 2; ++ic) 00349 { 00350 for(ie = 0; ie < MPG123_ENCODINGS; ++ie) 00351 if(good_enc(my_encodings[ie]) && ((my_encodings[ie] & encodings) == my_encodings[ie])) 00352 mp->audio_caps[ch[ic]][ratei][ie] = 1; 00353 00354 if(ch[0] == ch[1]) break; /* no need to do it again */ 00355 } 00356 00357 return MPG123_OK; 00358 } 00359 00360 int attribute_align_arg mpg123_format_support(mpg123_handle *mh, long rate, int encoding) 00361 { 00362 if(mh == NULL) return 0; 00363 else return mpg123_fmt_support(&mh->p, rate, encoding); 00364 } 00365 00366 int attribute_align_arg mpg123_fmt_support(mpg123_pars *mp, long rate, int encoding) 00367 { 00368 int ch = 0; 00369 int ratei, enci; 00370 ratei = rate2num(mp, rate); 00371 enci = enc2num(encoding); 00372 if(mp == NULL || ratei < 0 || enci < 0) return 0; 00373 if(mp->audio_caps[0][ratei][enci]) ch |= MPG123_MONO; 00374 if(mp->audio_caps[1][ratei][enci]) ch |= MPG123_STEREO; 00375 return ch; 00376 } 00377 00378 /* Call this one to ensure that any valid format will be something different than this. */ 00379 void invalidate_format(struct audioformat *af) 00380 { 00381 af->encoding = 0; 00382 af->rate = 0; 00383 af->channels = 0; 00384 } 00385 00386 /* take into account: channels, bytes per sample -- NOT resampling!*/ 00387 off_t samples_to_bytes(mpg123_handle *fr , off_t s) 00388 { 00389 return s * fr->af.encsize * fr->af.channels; 00390 } 00391 00392 off_t bytes_to_samples(mpg123_handle *fr , off_t b) 00393 { 00394 return b / fr->af.encsize / fr->af.channels; 00395 } Generated on Sat May 26 2012 04:16:53 for ReactOS by
1.7.6.1
|