ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

format.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.