util.c

Go to the documentation of this file.
00001 /*
00002  *      lame utility library source file
00003  *
00004  *      Copyright (c) 1999 Albert L Faber
00005  *      Copyright (c) 2000-2005 Alexander Leidinger
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the
00019  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020  * Boston, MA 02111-1307, USA.
00021  */
00022 
00023 /* $Id: util.c,v 1.134 2007/07/24 17:46:12 bouvigne Exp $ */
00024 
00025 #ifdef HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028 
00029 #include "lame.h"
00030 #include "machine.h"
00031 #include "encoder.h"
00032 #include "util.h"
00033 #include "lame_global_flags.h"
00034 
00035 #define PRECOMPUTE
00036 #if defined(__FreeBSD__) && !defined(__alpha__)
00037 # include <machine/floatingpoint.h>
00038 #endif
00039 
00040 
00041 /***********************************************************************
00042 *
00043 *  Global Function Definitions
00044 *
00045 ***********************************************************************/
00046 /*empty and close mallocs in gfc */
00047 
00048 void
00049 free_id3tag(lame_internal_flags * const gfc)
00050 {
00051     if (gfc->tag_spec.title != 0) {
00052         free(gfc->tag_spec.title);
00053         gfc->tag_spec.title = 0;
00054     }
00055     if (gfc->tag_spec.artist != 0) {
00056         free(gfc->tag_spec.artist);
00057         gfc->tag_spec.artist = 0;
00058     }
00059     if (gfc->tag_spec.album != 0) {
00060         free(gfc->tag_spec.album);
00061         gfc->tag_spec.album = 0;
00062     }
00063     if (gfc->tag_spec.comment != 0) {
00064         free(gfc->tag_spec.comment);
00065         gfc->tag_spec.comment = 0;
00066     }
00067     if (gfc->tag_spec.track_id3v2 != 0) {
00068         free(gfc->tag_spec.track_id3v2);
00069         gfc->tag_spec.track_id3v2 = 0;
00070     }
00071     if (gfc->tag_spec.genre_id3v2 != 0) {
00072         free(gfc->tag_spec.genre_id3v2);
00073         gfc->tag_spec.genre_id3v2 = 0;
00074     }
00075 
00076     if (gfc->tag_spec.albumart != 0) {
00077         free(gfc->tag_spec.albumart);
00078         gfc->tag_spec.albumart = 0;
00079         gfc->tag_spec.albumart_size = 0;
00080         gfc->tag_spec.albumart_mimetype = MIMETYPE_NONE;
00081     }
00082     if (gfc->tag_spec.values != 0) {
00083         int i;
00084         for (i = 0; i < gfc->tag_spec.num_values; ++i) {
00085             free(gfc->tag_spec.values[i]);
00086         }
00087         free(gfc->tag_spec.values);
00088         gfc->tag_spec.values = 0;
00089         gfc->tag_spec.num_values = 0;
00090     }
00091 }
00092 
00093 
00094 void
00095 freegfc(lame_internal_flags * const gfc)
00096 {                       /* bit stream structure */
00097     int     i;
00098 
00099 
00100     for (i = 0; i <= 2 * BPC; i++)
00101         if (gfc->blackfilt[i] != NULL) {
00102             free(gfc->blackfilt[i]);
00103             gfc->blackfilt[i] = NULL;
00104         }
00105     if (gfc->inbuf_old[0]) {
00106         free(gfc->inbuf_old[0]);
00107         gfc->inbuf_old[0] = NULL;
00108     }
00109     if (gfc->inbuf_old[1]) {
00110         free(gfc->inbuf_old[1]);
00111         gfc->inbuf_old[1] = NULL;
00112     }
00113 
00114     if (gfc->bs.buf != NULL) {
00115         free(gfc->bs.buf);
00116         gfc->bs.buf = NULL;
00117     }
00118 
00119     if (gfc->VBR_seek_table.bag) {
00120         free(gfc->VBR_seek_table.bag);
00121         gfc->VBR_seek_table.bag = NULL;
00122         gfc->VBR_seek_table.size = 0;
00123     }
00124     if (gfc->ATH) {
00125         free(gfc->ATH);
00126     }
00127     if (gfc->PSY) {
00128         free(gfc->PSY);
00129     }
00130     if (gfc->rgdata) {
00131         free(gfc->rgdata);
00132     }
00133     if (gfc->s3_ll) {
00134         /* XXX allocated in psymodel_init() */
00135         free(gfc->s3_ll);
00136     }
00137     if (gfc->s3_ss) {
00138         /* XXX allocated in psymodel_init() */
00139         free(gfc->s3_ss);
00140     }
00141     if (gfc->in_buffer_0) {
00142         free(gfc->in_buffer_0);
00143     }
00144     if (gfc->in_buffer_1) {
00145         free(gfc->in_buffer_1);
00146     }
00147     free_id3tag(gfc);
00148     free(gfc);
00149 }
00150 
00151 void
00152 malloc_aligned(aligned_pointer_t * ptr, unsigned int size, unsigned int bytes)
00153 {
00154     if (ptr) {
00155         if (!ptr->pointer) {
00156             ptr->pointer = malloc(size + bytes);
00157             if (bytes > 0) {
00158                 ptr->aligned = (void *) ((( (size_t)ptr->pointer + bytes - 1) / bytes) * bytes);
00159             }
00160             else {
00161                 ptr->aligned = ptr->pointer;
00162             }
00163         }
00164     }
00165 }
00166 
00167 void
00168 free_aligned(aligned_pointer_t * ptr)
00169 {
00170     if (ptr) {
00171         if (ptr->pointer) {
00172             free(ptr->pointer);
00173             ptr->pointer = 0;
00174             ptr->aligned = 0;
00175         }
00176     }
00177 }
00178 
00179 /*those ATH formulas are returning
00180 their minimum value for input = -1*/
00181 
00182 FLOAT
00183 ATHformula_GB(FLOAT f, FLOAT value)
00184 {
00185     /* from Painter & Spanias
00186        modified by Gabriel Bouvigne to better fit the reality
00187        ath =    3.640 * pow(f,-0.8)
00188        - 6.800 * exp(-0.6*pow(f-3.4,2.0))
00189        + 6.000 * exp(-0.15*pow(f-8.7,2.0))
00190        + 0.6* 0.001 * pow(f,4.0);
00191 
00192 
00193        In the past LAME was using the Painter &Spanias formula.
00194        But we had some recurrent problems with HF content.
00195        We measured real ATH values, and found the older formula
00196        to be inacurate in the higher part. So we made this new
00197        formula and this solved most of HF problematic testcases.
00198        The tradeoff is that in VBR mode it increases a lot the
00199        bitrate. */
00200 
00201 
00202 /*this curve can be udjusted according to the VBR scale:
00203 it adjusts from something close to Painter & Spanias
00204 on V9 up to Bouvigne's formula for V0. This way the VBR
00205 bitrate is more balanced according to the -V value.*/
00206 
00207     FLOAT   ath;
00208 
00209     if (f < -.3)
00210         f = 3410;
00211 
00212     f /= 1000;          /* convert to khz */
00213     f = Max(0.01, f);
00214 /*  f  = Min(21.0, f);
00215 */
00216     ath = 3.640 * pow(f, -0.8)
00217         - 6.800 * exp(-0.6 * pow(f - 3.4, 2.0))
00218         + 6.000 * exp(-0.15 * pow(f - 8.7, 2.0))
00219         + (0.6 + 0.04 * value) * 0.001 * pow(f, 4.0);
00220     return ath;
00221 }
00222 
00223 
00224 
00225 FLOAT
00226 ATHformula(FLOAT f, lame_global_flags const *gfp)
00227 {
00228     switch (gfp->ATHtype) {
00229     case 0:
00230         return ATHformula_GB(f, 9);
00231     case 1:
00232         return ATHformula_GB(f, -1); /*over sensitive, should probably be removed */
00233     case 2:
00234         return ATHformula_GB(f, 0);
00235     case 3:
00236         return ATHformula_GB(f, 1) + 6; /*modification of GB formula by Roel */
00237     case 4:
00238         return ATHformula_GB(f, gfp->ATHcurve);
00239     default:
00240         break;
00241     }
00242 
00243     return ATHformula_GB(f, 0);
00244 }
00245 
00246 /* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */
00247 FLOAT
00248 freq2bark(FLOAT freq)
00249 {
00250     /* input: freq in hz  output: barks */
00251     if (freq < 0)
00252         freq = 0;
00253     freq = freq * 0.001;
00254     return 13.0 * atan(.76 * freq) + 3.5 * atan(freq * freq / (7.5 * 7.5));
00255 }
00256 
00257 /* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */
00258 FLOAT
00259 freq2cbw(FLOAT freq)
00260 {
00261     /* input: freq in hz  output: critical band width */
00262     freq = freq * 0.001;
00263     return 25 + 75 * pow(1 + 1.4 * (freq * freq), 0.69);
00264 }
00265 
00266 
00267 
00268 
00269 
00270 
00271 #define ABS(A) (((A)>0) ? (A) : -(A))
00272 
00273 int
00274 FindNearestBitrate(int bRate, /* legal rates from 8 to 320 */
00275                    int version,
00276                    int samplerate)
00277 {                       /* MPEG-1 or MPEG-2 LSF */
00278     int     bitrate;
00279     int     i;
00280 
00281     if (samplerate < 16000)
00282         version = 2;
00283     
00284     bitrate = bitrate_table[version][1];
00285 
00286     for (i = 2; i <= 14; i++) {
00287         if (bitrate_table[version][i] > 0) {
00288             if (ABS(bitrate_table[version][i] - bRate) < ABS(bitrate - bRate))
00289                 bitrate = bitrate_table[version][i];
00290         }
00291     }
00292     return bitrate;
00293 }
00294 
00295 
00296 
00297 
00298 
00299 #ifndef Min
00300 #define         Min(A, B)       ((A) < (B) ? (A) : (B))
00301 #endif
00302 #ifndef Max
00303 #define         Max(A, B)       ((A) > (B) ? (A) : (B))
00304 #endif
00305 
00306 
00307 /* Used to find table index when
00308  * we need bitrate-based values
00309  * determined using tables
00310  *
00311  * bitrate in kbps
00312  *
00313  * Gabriel Bouvigne 2002-11-03
00314  */
00315 int
00316 nearestBitrateFullIndex(const int bitrate)
00317 {
00318     /* borrowed from DM abr presets */
00319 
00320     int     index;           /* resolved range */
00321 
00322     const int bitrate_table[] =
00323         { 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 };
00324 
00325 
00326     int     lower_range = 0, lower_range_kbps = 0, upper_range = 0, upper_range_kbps = 0;
00327 
00328 
00329     int     b;
00330 
00331 
00332     /* We assume specified bitrate will be 320kbps */
00333     upper_range_kbps = bitrate_table[16];
00334     upper_range = 16;
00335     lower_range_kbps = bitrate_table[16];
00336     lower_range = 16;
00337 
00338     /* Determine which significant bitrates the value specified falls between,
00339      * if loop ends without breaking then we were correct above that the value was 320
00340      */
00341     for (b = 0; b < 16; b++) {
00342         if ((Max(bitrate, bitrate_table[b + 1])) != bitrate) {
00343             upper_range_kbps = bitrate_table[b + 1];
00344             upper_range = b + 1;
00345             lower_range_kbps = bitrate_table[b];
00346             lower_range = (b);
00347             break;      /* We found upper range */
00348         }
00349     }
00350 
00351     /* Determine which range the value specified is closer to */
00352     if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps))
00353         index = lower_range;
00354     else
00355         index = upper_range;
00356 
00357     return index;
00358 }
00359 
00360 
00361 
00362 
00363 
00364 /* map frequency to a valid MP3 sample frequency
00365  *
00366  * Robert Hegemann 2000-07-01
00367  */
00368 int
00369 map2MP3Frequency(int freq)
00370 {
00371     if (freq <= 8000)
00372         return 8000;
00373     if (freq <= 11025)
00374         return 11025;
00375     if (freq <= 12000)
00376         return 12000;
00377     if (freq <= 16000)
00378         return 16000;
00379     if (freq <= 22050)
00380         return 22050;
00381     if (freq <= 24000)
00382         return 24000;
00383     if (freq <= 32000)
00384         return 32000;
00385     if (freq <= 44100)
00386         return 44100;
00387 
00388     return 48000;
00389 }
00390 
00391 int
00392 BitrateIndex(int bRate,      /* legal rates from 32 to 448 kbps */
00393              int version,    /* MPEG-1 or MPEG-2/2.5 LSF */
00394              int samplerate)
00395 {                       /* convert bitrate in kbps to index */
00396     int     i;
00397     if (samplerate < 16000)
00398         version = 2;
00399     for (i = 0; i <= 14; i++) {
00400         if (bitrate_table[version][i] > 0) {
00401             if (bitrate_table[version][i] == bRate) {
00402                 return i;
00403             }
00404         }
00405     }
00406     return -1;
00407 }
00408 
00409 /* convert samp freq in Hz to index */
00410 
00411 int
00412 SmpFrqIndex(int sample_freq, int *const version)
00413 {
00414     switch (sample_freq) {
00415     case 44100:
00416         *version = 1;
00417         return 0;
00418     case 48000:
00419         *version = 1;
00420         return 1;
00421     case 32000:
00422         *version = 1;
00423         return 2;
00424     case 22050:
00425         *version = 0;
00426         return 0;
00427     case 24000:
00428         *version = 0;
00429         return 1;
00430     case 16000:
00431         *version = 0;
00432         return 2;
00433     case 11025:
00434         *version = 0;
00435         return 0;
00436     case 12000:
00437         *version = 0;
00438         return 1;
00439     case 8000:
00440         *version = 0;
00441         return 2;
00442     default:
00443         *version = 0;
00444         return -1;
00445     }
00446 }
00447 
00448 
00449 /*****************************************************************************
00450 *
00451 *  End of bit_stream.c package
00452 *
00453 *****************************************************************************/
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 /* resampling via FIR filter, blackman window */
00465 inline static FLOAT
00466 blackman(FLOAT x, FLOAT fcn, int l)
00467 {
00468     /* This algorithm from:
00469        SIGNAL PROCESSING ALGORITHMS IN FORTRAN AND C
00470        S.D. Stearns and R.A. David, Prentice-Hall, 1992
00471      */
00472     FLOAT   bkwn, x2;
00473     FLOAT const wcn = (PI * fcn);
00474 
00475     x /= l;
00476     if (x < 0)
00477         x = 0;
00478     if (x > 1)
00479         x = 1;
00480     x2 = x - .5;
00481 
00482     bkwn = 0.42 - 0.5 * cos(2 * x * PI) + 0.08 * cos(4 * x * PI);
00483     if (fabs(x2) < 1e-9)
00484         return wcn / PI;
00485     else
00486         return (bkwn * sin(l * wcn * x2) / (PI * l * x2));
00487 
00488 
00489 }
00490 
00491 /* gcd - greatest common divisor */
00492 /* Joint work of Euclid and M. Hendry */
00493 
00494 int
00495 gcd(int i, int j)
00496 {
00497 /*    assert ( i > 0  &&  j > 0 ); */
00498     return j ? gcd(j, i % j) : i;
00499 }
00500 
00501 
00502 
00503 /* copy in new samples from in_buffer into mfbuf, with resampling
00504    if necessary.  n_in = number of samples from the input buffer that
00505    were used.  n_out = number of samples copied into mfbuf  */
00506 
00507 void
00508 fill_buffer(lame_global_flags const *gfp,
00509             sample_t * mfbuf[2], sample_t const *in_buffer[2], int nsamples, int *n_in, int *n_out)
00510 {
00511     lame_internal_flags const *const gfc = gfp->internal_flags;
00512     int     ch, i;
00513 
00514     /* copy in new samples into mfbuf, with resampling if necessary */
00515     if ((gfc->resample_ratio < .9999) || (gfc->resample_ratio > 1.0001)) {
00516         for (ch = 0; ch < gfc->channels_out; ch++) {
00517             *n_out =
00518                 fill_buffer_resample(gfp, &mfbuf[ch][gfc->mf_size],
00519                                      gfp->framesize, in_buffer[ch], nsamples, n_in, ch);
00520         }
00521     }
00522     else {
00523         *n_out = Min(gfp->framesize, nsamples);
00524         *n_in = *n_out;
00525         for (i = 0; i < *n_out; ++i) {
00526             mfbuf[0][gfc->mf_size + i] = in_buffer[0][i];
00527             if (gfc->channels_out == 2)
00528                 mfbuf[1][gfc->mf_size + i] = in_buffer[1][i];
00529         }
00530     }
00531 }
00532 
00533 
00534 
00535 
00536 int
00537 fill_buffer_resample(lame_global_flags const *gfp,
00538                      sample_t * outbuf,
00539                      int desired_len, sample_t const *inbuf, int len, int *num_used, int ch)
00540 {
00541 
00542 
00543     lame_internal_flags *const gfc = gfp->internal_flags;
00544     int     BLACKSIZE;
00545     FLOAT   offset, xvalue;
00546     int     i, j = 0, k;
00547     int     filter_l;
00548     FLOAT   fcn, intratio;
00549     FLOAT  *inbuf_old;
00550     int     bpc;             /* number of convolution functions to pre-compute */
00551     bpc = gfp->out_samplerate / gcd(gfp->out_samplerate, gfp->in_samplerate);
00552     if (bpc > BPC)
00553         bpc = BPC;
00554 
00555     intratio = (fabs(gfc->resample_ratio - floor(.5 + gfc->resample_ratio)) < .0001);
00556     fcn = 1.00 / gfc->resample_ratio;
00557     if (fcn > 1.00)
00558         fcn = 1.00;
00559     filter_l = gfp->quality < 7 ? 31 : 7;
00560     filter_l = 31;
00561     if (0 == filter_l % 2)
00562         --filter_l;     /* must be odd */
00563     filter_l += intratio; /* unless resample_ratio=int, it must be even */
00564 
00565 
00566     BLACKSIZE = filter_l + 1; /* size of data needed for FIR */
00567 
00568     if (gfc->fill_buffer_resample_init == 0) {
00569         gfc->inbuf_old[0] = calloc(BLACKSIZE, sizeof(gfc->inbuf_old[0][0]));
00570         gfc->inbuf_old[1] = calloc(BLACKSIZE, sizeof(gfc->inbuf_old[0][0]));
00571         for (i = 0; i <= 2 * bpc; ++i)
00572             gfc->blackfilt[i] = calloc(BLACKSIZE, sizeof(gfc->blackfilt[0][0]));
00573 
00574         gfc->itime[0] = 0;
00575         gfc->itime[1] = 0;
00576 
00577         /* precompute blackman filter coefficients */
00578         for (j = 0; j <= 2 * bpc; j++) {
00579             FLOAT   sum = 0.;
00580             offset = (j - bpc) / (2. * bpc);
00581             for (i = 0; i <= filter_l; i++)
00582                 sum += gfc->blackfilt[j][i] = blackman(i - offset, fcn, filter_l);
00583             for (i = 0; i <= filter_l; i++)
00584                 gfc->blackfilt[j][i] /= sum;
00585         }
00586         gfc->fill_buffer_resample_init = 1;
00587     }
00588 
00589     inbuf_old = gfc->inbuf_old[ch];
00590 
00591     /* time of j'th element in inbuf = itime + j/ifreq; */
00592     /* time of k'th element in outbuf   =  j/ofreq */
00593     for (k = 0; k < desired_len; k++) {
00594         FLOAT   time0;
00595         int     joff;
00596 
00597         time0 = k * gfc->resample_ratio; /* time of k'th output sample */
00598         j = floor(time0 - gfc->itime[ch]);
00599 
00600         /* check if we need more input data */
00601         if ((filter_l + j - filter_l / 2) >= len)
00602             break;
00603 
00604         /* blackman filter.  by default, window centered at j+.5(filter_l%2) */
00605         /* but we want a window centered at time0.   */
00606         offset = (time0 - gfc->itime[ch] - (j + .5 * (filter_l % 2)));
00607         assert(fabs(offset) <= .501);
00608 
00609         /* find the closest precomputed window for this offset: */
00610         joff = floor((offset * 2 * bpc) + bpc + .5);
00611 
00612         xvalue = 0.;
00613         for (i = 0; i <= filter_l; ++i) {
00614             int const j2 = i + j - filter_l / 2;
00615             sample_t y;
00616             assert(j2 < len);
00617             assert(j2 + BLACKSIZE >= 0);
00618             y = (j2 < 0) ? inbuf_old[BLACKSIZE + j2] : inbuf[j2];
00619 #ifdef PRECOMPUTE
00620             xvalue += y * gfc->blackfilt[joff][i];
00621 #else
00622             xvalue += y * blackman(i - offset, fcn, filter_l); /* very slow! */
00623 #endif
00624         }
00625         outbuf[k] = xvalue;
00626     }
00627 
00628 
00629     /* k = number of samples added to outbuf */
00630     /* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2]  */
00631 
00632     /* how many samples of input data were used:  */
00633     *num_used = Min(len, filter_l + j - filter_l / 2);
00634 
00635     /* adjust our input time counter.  Incriment by the number of samples used,
00636      * then normalize so that next output sample is at time 0, next
00637      * input buffer is at time itime[ch] */
00638     gfc->itime[ch] += *num_used - k * gfc->resample_ratio;
00639 
00640     /* save the last BLACKSIZE samples into the inbuf_old buffer */
00641     if (*num_used >= BLACKSIZE) {
00642         for (i = 0; i < BLACKSIZE; i++)
00643             inbuf_old[i] = inbuf[*num_used + i - BLACKSIZE];
00644     }
00645     else {
00646         /* shift in *num_used samples into inbuf_old  */
00647         int const n_shift = BLACKSIZE - *num_used; /* number of samples to shift */
00648 
00649         /* shift n_shift samples by *num_used, to make room for the
00650          * num_used new samples */
00651         for (i = 0; i < n_shift; ++i)
00652             inbuf_old[i] = inbuf_old[i + *num_used];
00653 
00654         /* shift in the *num_used samples */
00655         for (j = 0; i < BLACKSIZE; ++i, ++j)
00656             inbuf_old[i] = inbuf[j];
00657 
00658         assert(j == *num_used);
00659     }
00660     return k;           /* return the number samples created at the new samplerate */
00661 }
00662 
00663 
00664 
00665 
00666 
00667 /***********************************************************************
00668 *
00669 *  Message Output
00670 *
00671 ***********************************************************************/
00672 void
00673 lame_debugf(const lame_internal_flags * gfc, const char *format, ...)
00674 {
00675     va_list args;
00676 
00677     va_start(args, format);
00678 
00679     if (gfc->report.debugf != NULL) {
00680         gfc->report.debugf(format, args);
00681     }
00682     else {
00683         (void) vfprintf(stderr, format, args);
00684         fflush(stderr); /* an debug function should flush immediately */
00685     }
00686 
00687     va_end(args);
00688 }
00689 
00690 
00691 void
00692 lame_msgf(const lame_internal_flags * gfc, const char *format, ...)
00693 {
00694     va_list args;
00695 
00696     va_start(args, format);
00697 
00698     if (gfc->report.msgf != NULL) {
00699         gfc->report.msgf(format, args);
00700     }
00701     else {
00702         (void) vfprintf(stderr, format, args);
00703         fflush(stderr); /* we print to stderr, so me may want to flush */
00704     }
00705 
00706     va_end(args);
00707 }
00708 
00709 
00710 void
00711 lame_errorf(const lame_internal_flags * gfc, const char *format, ...)
00712 {
00713     va_list args;
00714 
00715     va_start(args, format);
00716 
00717     if (gfc->report.errorf != NULL) {
00718         gfc->report.errorf(format, args);
00719     }
00720     else {
00721         (void) vfprintf(stderr, format, args);
00722         fflush(stderr); /* an error function should flush immediately */
00723     }
00724 
00725     va_end(args);
00726 }
00727 
00728 
00729 
00730 /***********************************************************************
00731  *
00732  *      routines to detect CPU specific features like 3DNow, MMX, SSE
00733  *
00734  *  donated by Frank Klemm
00735  *  added Robert Hegemann 2000-10-10
00736  *
00737  ***********************************************************************/
00738 
00739 
00740 int
00741 has_MMX(void)
00742 {
00743 #ifdef HAVE_NASM
00744     extern int has_MMX_nasm(void);
00745     return has_MMX_nasm();
00746 #else
00747     return 0;           /* don't know, assume not */
00748 #endif
00749 }
00750 
00751 int
00752 has_3DNow(void)
00753 {
00754 #ifdef HAVE_NASM
00755     extern int has_3DNow_nasm(void);
00756     return has_3DNow_nasm();
00757 #else
00758     return 0;           /* don't know, assume not */
00759 #endif
00760 }
00761 
00762 int
00763 has_SSE(void)
00764 {
00765 #ifdef HAVE_NASM
00766     extern int has_SSE_nasm(void);
00767     return has_SSE_nasm();
00768 #else
00769 #ifdef _M_X64
00770         return 1;
00771 #else
00772         return 0;           /* don't know, assume not */
00773 #endif
00774 #endif
00775 }
00776 
00777 int
00778 has_SSE2(void)
00779 {
00780 #ifdef HAVE_NASM
00781     extern int has_SSE2_nasm(void);
00782     return has_SSE2_nasm();
00783 #else
00784 #ifdef _M_X64
00785         return 1;
00786 #else
00787         return 0;           /* don't know, assume not */
00788 #endif
00789 #endif
00790 }
00791 
00792 void
00793 disable_FPE(void)
00794 {
00795 /* extremly system dependent stuff, move to a lib to make the code readable */
00796 /*==========================================================================*/
00797 
00798 
00799 
00800     /*
00801      *  Disable floating point exceptions
00802      */
00803 
00804 
00805 
00806 
00807 #if defined(__FreeBSD__) && !defined(__alpha__)
00808     {
00809         /* seet floating point mask to the Linux default */
00810         fp_except_t mask;
00811         mask = fpgetmask();
00812         /* if bit is set, we get SIGFPE on that error! */
00813         fpsetmask(mask & ~(FP_X_INV | FP_X_DZ));
00814         /*  DEBUGF("FreeBSD mask is 0x%x\n",mask); */
00815     }
00816 #endif
00817 
00818 #if defined(__riscos__) && !defined(ABORTFP)
00819     /* Disable FPE's under RISC OS */
00820     /* if bit is set, we disable trapping that error! */
00821     /*   _FPE_IVO : invalid operation */
00822     /*   _FPE_DVZ : divide by zero */
00823     /*   _FPE_OFL : overflow */
00824     /*   _FPE_UFL : underflow */
00825     /*   _FPE_INX : inexact */
00826     DisableFPETraps(_FPE_IVO | _FPE_DVZ | _FPE_OFL);
00827 #endif
00828 
00829     /*
00830      *  Debugging stuff
00831      *  The default is to ignore FPE's, unless compiled with -DABORTFP
00832      *  so add code below to ENABLE FPE's.
00833      */
00834 
00835 #if defined(ABORTFP)
00836 #if defined(_MSC_VER)
00837     {
00838 #if 0
00839     /* rh 061207
00840        the following fix seems to be a workaround for a problem in the
00841        parent process calling LAME. It would be better to fix the broken
00842        application => code disabled.
00843      */
00844 
00845         /* set affinity to a single CPU.  Fix for EAC/lame on SMP systems from
00846            "Todd Richmond" <todd.richmond@openwave.com> */
00847         SYSTEM_INFO si;
00848         GetSystemInfo(&si);
00849         SetProcessAffinityMask(GetCurrentProcess(), si.dwActiveProcessorMask);
00850 #endif
00851 #include <float.h>
00852         unsigned int mask;
00853         mask = _controlfp(0, 0);
00854         mask &= ~(_EM_OVERFLOW | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_INVALID);
00855         mask = _controlfp(mask, _MCW_EM);
00856     }
00857 #elif defined(__CYGWIN__)
00858 #  define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
00859 #  define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
00860 
00861 #  define _EM_INEXACT     0x00000020 /* inexact (precision) */
00862 #  define _EM_UNDERFLOW   0x00000010 /* underflow */
00863 #  define _EM_OVERFLOW    0x00000008 /* overflow */
00864 #  define _EM_ZERODIVIDE  0x00000004 /* zero divide */
00865 #  define _EM_INVALID     0x00000001 /* invalid */
00866     {
00867         unsigned int mask;
00868         _FPU_GETCW(mask);
00869         /* Set the FPU control word to abort on most FPEs */
00870         mask &= ~(_EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID);
00871         _FPU_SETCW(mask);
00872     }
00873 # elif defined(__linux__)
00874     {
00875 
00876 #  include <fpu_control.h>
00877 #  ifndef _FPU_GETCW
00878 #  define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
00879 #  endif
00880 #  ifndef _FPU_SETCW
00881 #  define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
00882 #  endif
00883 
00884         /* 
00885          * Set the Linux mask to abort on most FPE's
00886          * if bit is set, we _mask_ SIGFPE on that error!
00887          *  mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM );
00888          */
00889 
00890         unsigned int mask;
00891         _FPU_GETCW(mask);
00892         mask &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
00893         _FPU_SETCW(mask);
00894     }
00895 #endif
00896 #endif /* ABORTFP */
00897 }
00898 
00899 
00900 
00901 
00902 
00903 #ifdef USE_FAST_LOG
00904 /***********************************************************************
00905  *
00906  * Fast Log Approximation for log2, used to approximate every other log
00907  * (log10 and log)
00908  * maximum absolute error for log10 is around 10-6
00909  * maximum *relative* error can be high when x is almost 1 because error/log10(x) tends toward x/e
00910  *
00911  * use it if typical RESULT values are > 1e-5 (for example if x>1.00001 or x<0.99999)
00912  * or if the relative precision in the domain around 1 is not important (result in 1 is exact and 0)
00913  *
00914  ***********************************************************************/
00915 
00916 
00917 #define LOG2_SIZE       (512)
00918 #define LOG2_SIZE_L2    (9)
00919 
00920 static ieee754_float32_t log_table[LOG2_SIZE + 1];
00921 
00922 
00923 
00924 void
00925 init_log_table(void)
00926 {
00927     int     j;
00928     static int init = 0;
00929 
00930     /* Range for log2(x) over [1,2[ is [0,1[ */
00931     assert((1 << LOG2_SIZE_L2) == LOG2_SIZE);
00932 
00933     if (!init) {
00934         for (j = 0; j < LOG2_SIZE + 1; j++)
00935             log_table[j] = log(1.0f + j / (ieee754_float32_t) LOG2_SIZE) / log(2.0f);
00936     }
00937     init = 1;
00938 }
00939 
00940 
00941 
00942 ieee754_float32_t
00943 fast_log2(ieee754_float32_t x)
00944 {
00945     ieee754_float32_t log2val, partial;
00946     union {
00947         ieee754_float32_t f;
00948         int     i;
00949     } fi;
00950     int     mantisse;
00951     fi.f = x;
00952     mantisse = fi.i & 0x7fffff;
00953     log2val = ((fi.i >> 23) & 0xFF) - 0x7f;
00954     partial = (mantisse & ((1 << (23 - LOG2_SIZE_L2)) - 1));
00955     partial *= 1.0f / ((1 << (23 - LOG2_SIZE_L2)));
00956 
00957 
00958     mantisse >>= (23 - LOG2_SIZE_L2);
00959 
00960     /* log2val += log_table[mantisse];  without interpolation the results are not good */
00961     log2val += log_table[mantisse] * (1.0f - partial) + log_table[mantisse + 1] * partial;
00962 
00963     return log2val;
00964 }
00965 
00966 #else /* Don't use FAST_LOG */
00967 
00968 
00969 void
00970 init_log_table(void)
00971 {
00972 }
00973 
00974 
00975 #endif
00976 
00977 /* end of util.c */

Generated on Sun Dec 2 11:34:20 2007 for LAME by  doxygen 1.5.2