OSDN Git Service

wwww
[proj16/16.git] / src / lib / doslib / ext / lame / util.c
1 /*
2  *      lame utility library source file
3  *
4  *      Copyright (c) 1999 Albert L Faber
5  *      Copyright (c) 2000-2005 Alexander Leidinger
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /* $Id: util.c,v 1.154 2011/10/18 21:51:20 robert Exp $ */
24
25 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28
29 #include "lame.h"
30 #include "machine.h"
31 #include "encoder.h"
32 #include "util.h"
33 #include "tables.h"
34
35 #define PRECOMPUTE
36 #if defined(__FreeBSD__) && !defined(__alpha__)
37 # include <machine/floatingpoint.h>
38 #endif
39
40
41 /***********************************************************************
42 *
43 *  Global Function Definitions
44 *
45 ***********************************************************************/
46 /*empty and close mallocs in gfc */
47
48 void
49 free_id3tag(lame_internal_flags * const gfc)
50 {
51     if (gfc->tag_spec.title != 0) {
52         free(gfc->tag_spec.title);
53         gfc->tag_spec.title = 0;
54     }
55     if (gfc->tag_spec.artist != 0) {
56         free(gfc->tag_spec.artist);
57         gfc->tag_spec.artist = 0;
58     }
59     if (gfc->tag_spec.album != 0) {
60         free(gfc->tag_spec.album);
61         gfc->tag_spec.album = 0;
62     }
63     if (gfc->tag_spec.comment != 0) {
64         free(gfc->tag_spec.comment);
65         gfc->tag_spec.comment = 0;
66     }
67
68     if (gfc->tag_spec.albumart != 0) {
69         free(gfc->tag_spec.albumart);
70         gfc->tag_spec.albumart = 0;
71         gfc->tag_spec.albumart_size = 0;
72         gfc->tag_spec.albumart_mimetype = MIMETYPE_NONE;
73     }
74     if (gfc->tag_spec.values != 0) {
75         unsigned int i;
76         for (i = 0; i < gfc->tag_spec.num_values; ++i) {
77             free(gfc->tag_spec.values[i]);
78         }
79         free(gfc->tag_spec.values);
80         gfc->tag_spec.values = 0;
81         gfc->tag_spec.num_values = 0;
82     }
83     if (gfc->tag_spec.v2_head != 0) {
84         FrameDataNode *node = gfc->tag_spec.v2_head;
85         do {
86             void   *p = node->dsc.ptr.b;
87             void   *q = node->txt.ptr.b;
88             void   *r = node;
89             node = node->nxt;
90             free(p);
91             free(q);
92             free(r);
93         } while (node != 0);
94         gfc->tag_spec.v2_head = 0;
95         gfc->tag_spec.v2_tail = 0;
96     }
97 }
98
99
100 static void
101 free_global_data(lame_internal_flags * gfc)
102 {
103     if (gfc && gfc->cd_psy) {
104         if (gfc->cd_psy->l.s3) {
105             /* XXX allocated in psymodel_init() */
106             free(gfc->cd_psy->l.s3);
107         }
108         if (gfc->cd_psy->s.s3) {
109             /* XXX allocated in psymodel_init() */
110             free(gfc->cd_psy->s.s3);
111         }
112         free(gfc->cd_psy);
113         gfc->cd_psy = 0;
114     }
115 }
116
117
118 void
119 freegfc(lame_internal_flags * const gfc)
120 {                       /* bit stream structure */
121     int     i;
122
123
124     for (i = 0; i <= 2 * BPC; i++)
125         if (gfc->sv_enc.blackfilt[i] != NULL) {
126             free(gfc->sv_enc.blackfilt[i]);
127             gfc->sv_enc.blackfilt[i] = NULL;
128         }
129     if (gfc->sv_enc.inbuf_old[0]) {
130         free(gfc->sv_enc.inbuf_old[0]);
131         gfc->sv_enc.inbuf_old[0] = NULL;
132     }
133     if (gfc->sv_enc.inbuf_old[1]) {
134         free(gfc->sv_enc.inbuf_old[1]);
135         gfc->sv_enc.inbuf_old[1] = NULL;
136     }
137
138     if (gfc->bs.buf != NULL) {
139         free(gfc->bs.buf);
140         gfc->bs.buf = NULL;
141     }
142
143     if (gfc->VBR_seek_table.bag) {
144         free(gfc->VBR_seek_table.bag);
145         gfc->VBR_seek_table.bag = NULL;
146         gfc->VBR_seek_table.size = 0;
147     }
148     if (gfc->ATH) {
149         free(gfc->ATH);
150     }
151     if (gfc->sv_rpg.rgdata) {
152         free(gfc->sv_rpg.rgdata);
153     }
154     if (gfc->sv_enc.in_buffer_0) {
155         free(gfc->sv_enc.in_buffer_0);
156     }
157     if (gfc->sv_enc.in_buffer_1) {
158         free(gfc->sv_enc.in_buffer_1);
159     }
160     free_id3tag(gfc);
161
162 #ifdef DECODE_ON_THE_FLY
163     if (gfc->hip) {
164         hip_decode_exit(gfc->hip);
165         gfc->hip = 0;
166     }
167 #endif
168
169     free_global_data(gfc);
170
171     free(gfc);
172 }
173
174 /*those ATH formulas are returning
175 their minimum value for input = -1*/
176
177 static  FLOAT
178 ATHformula_GB(FLOAT f, FLOAT value, FLOAT f_min, FLOAT f_max)
179 {
180     /* from Painter & Spanias
181        modified by Gabriel Bouvigne to better fit the reality
182        ath =    3.640 * pow(f,-0.8)
183        - 6.800 * exp(-0.6*pow(f-3.4,2.0))
184        + 6.000 * exp(-0.15*pow(f-8.7,2.0))
185        + 0.6* 0.001 * pow(f,4.0);
186
187
188        In the past LAME was using the Painter &Spanias formula.
189        But we had some recurrent problems with HF content.
190        We measured real ATH values, and found the older formula
191        to be inacurate in the higher part. So we made this new
192        formula and this solved most of HF problematic testcases.
193        The tradeoff is that in VBR mode it increases a lot the
194        bitrate. */
195
196
197 /*this curve can be udjusted according to the VBR scale:
198 it adjusts from something close to Painter & Spanias
199 on V9 up to Bouvigne's formula for V0. This way the VBR
200 bitrate is more balanced according to the -V value.*/
201
202     FLOAT   ath;
203
204     /* the following Hack allows to ask for the lowest value */
205     if (f < -.3)
206         f = 3410;
207
208     f /= 1000;          /* convert to khz */
209     f = Max(f_min, f);
210     f = Min(f_max, f);
211
212     ath = 3.640 * pow(f, -0.8)
213         - 6.800 * exp(-0.6 * pow(f - 3.4, 2.0))
214         + 6.000 * exp(-0.15 * pow(f - 8.7, 2.0))
215         + (0.6 + 0.04 * value) * 0.001 * pow(f, 4.0);
216     return ath;
217 }
218
219
220
221 FLOAT
222 ATHformula(SessionConfig_t const *cfg, FLOAT f)
223 {
224     FLOAT   ath;
225     switch (cfg->ATHtype) {
226     case 0:
227         ath = ATHformula_GB(f, 9, 0.1f, 24.0f);
228         break;
229     case 1:
230         ath = ATHformula_GB(f, -1, 0.1f, 24.0f); /*over sensitive, should probably be removed */
231         break;
232     case 2:
233         ath = ATHformula_GB(f, 0, 0.1f, 24.0f);
234         break;
235     case 3:
236         ath = ATHformula_GB(f, 1, 0.1f, 24.0f) + 6; /*modification of GB formula by Roel */
237         break;
238     case 4:
239         ath = ATHformula_GB(f, cfg->ATHcurve, 0.1f, 24.0f);
240         break;
241     case 5:
242         ath = ATHformula_GB(f, cfg->ATHcurve, 3.41f, 16.1f);
243         break;
244     default:
245         ath = ATHformula_GB(f, 0, 0.1f, 24.0f);
246         break;
247     }
248     return ath;
249 }
250
251 /* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */
252 FLOAT
253 freq2bark(FLOAT freq)
254 {
255     /* input: freq in hz  output: barks */
256     if (freq < 0)
257         freq = 0;
258     freq = freq * 0.001;
259     return 13.0 * atan(.76 * freq) + 3.5 * atan(freq * freq / (7.5 * 7.5));
260 }
261
262 #if 0
263 extern FLOAT freq2cbw(FLOAT freq);
264
265 /* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */
266 FLOAT
267 freq2cbw(FLOAT freq)
268 {
269     /* input: freq in hz  output: critical band width */
270     freq = freq * 0.001;
271     return 25 + 75 * pow(1 + 1.4 * (freq * freq), 0.69);
272 }
273
274 #endif
275
276
277
278
279 #define ABS(A) (((A)>0) ? (A) : -(A))
280
281 int
282 FindNearestBitrate(int bRate, /* legal rates from 8 to 320 */
283                    int version, int samplerate)
284 {                       /* MPEG-1 or MPEG-2 LSF */
285     int     bitrate;
286     int     i;
287
288     if (samplerate < 16000)
289         version = 2;
290
291     bitrate = bitrate_table[version][1];
292
293     for (i = 2; i <= 14; i++) {
294         if (bitrate_table[version][i] > 0) {
295             if (ABS(bitrate_table[version][i] - bRate) < ABS(bitrate - bRate))
296                 bitrate = bitrate_table[version][i];
297         }
298     }
299     return bitrate;
300 }
301
302
303
304
305
306 #ifndef Min
307 #define         Min(A, B)       ((A) < (B) ? (A) : (B))
308 #endif
309 #ifndef Max
310 #define         Max(A, B)       ((A) > (B) ? (A) : (B))
311 #endif
312
313
314 /* Used to find table index when
315  * we need bitrate-based values
316  * determined using tables
317  *
318  * bitrate in kbps
319  *
320  * Gabriel Bouvigne 2002-11-03
321  */
322 int
323 nearestBitrateFullIndex(uint16_t bitrate)
324 {
325     /* borrowed from DM abr presets */
326
327     const int full_bitrate_table[] =
328         { 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 };
329
330
331     int     lower_range = 0, lower_range_kbps = 0, upper_range = 0, upper_range_kbps = 0;
332
333
334     int     b;
335
336
337     /* We assume specified bitrate will be 320kbps */
338     upper_range_kbps = full_bitrate_table[16];
339     upper_range = 16;
340     lower_range_kbps = full_bitrate_table[16];
341     lower_range = 16;
342
343     /* Determine which significant bitrates the value specified falls between,
344      * if loop ends without breaking then we were correct above that the value was 320
345      */
346     for (b = 0; b < 16; b++) {
347         if ((Max(bitrate, full_bitrate_table[b + 1])) != bitrate) {
348             upper_range_kbps = full_bitrate_table[b + 1];
349             upper_range = b + 1;
350             lower_range_kbps = full_bitrate_table[b];
351             lower_range = (b);
352             break;      /* We found upper range */
353         }
354     }
355
356     /* Determine which range the value specified is closer to */
357     if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps)) {
358         return lower_range;
359     }
360     return upper_range;
361 }
362
363
364
365
366
367 /* map frequency to a valid MP3 sample frequency
368  *
369  * Robert Hegemann 2000-07-01
370  */
371 int
372 map2MP3Frequency(int freq)
373 {
374     if (freq <= 8000)
375         return 8000;
376     if (freq <= 11025)
377         return 11025;
378     if (freq <= 12000)
379         return 12000;
380     if (freq <= 16000)
381         return 16000;
382     if (freq <= 22050)
383         return 22050;
384     if (freq <= 24000)
385         return 24000;
386     if (freq <= 32000)
387         return 32000;
388     if (freq <= 44100)
389         return 44100;
390
391     return 48000;
392 }
393
394 int
395 BitrateIndex(int bRate,      /* legal rates from 32 to 448 kbps */
396              int version,    /* MPEG-1 or MPEG-2/2.5 LSF */
397              int samplerate)
398 {                       /* convert bitrate in kbps to index */
399     int     i;
400     if (samplerate < 16000)
401         version = 2;
402     for (i = 0; i <= 14; i++) {
403         if (bitrate_table[version][i] > 0) {
404             if (bitrate_table[version][i] == bRate) {
405                 return i;
406             }
407         }
408     }
409     return -1;
410 }
411
412 /* convert samp freq in Hz to index */
413
414 int
415 SmpFrqIndex(int sample_freq, int *const version)
416 {
417     switch (sample_freq) {
418     case 44100:
419         *version = 1;
420         return 0;
421     case 48000:
422         *version = 1;
423         return 1;
424     case 32000:
425         *version = 1;
426         return 2;
427     case 22050:
428         *version = 0;
429         return 0;
430     case 24000:
431         *version = 0;
432         return 1;
433     case 16000:
434         *version = 0;
435         return 2;
436     case 11025:
437         *version = 0;
438         return 0;
439     case 12000:
440         *version = 0;
441         return 1;
442     case 8000:
443         *version = 0;
444         return 2;
445     default:
446         *version = 0;
447         return -1;
448     }
449 }
450
451
452 /*****************************************************************************
453 *
454 *  End of bit_stream.c package
455 *
456 *****************************************************************************/
457
458
459
460
461
462
463
464
465
466
467 /* resampling via FIR filter, blackman window */
468 inline static FLOAT
469 blackman(FLOAT x, FLOAT fcn, int l)
470 {
471     /* This algorithm from:
472        SIGNAL PROCESSING ALGORITHMS IN FORTRAN AND C
473        S.D. Stearns and R.A. David, Prentice-Hall, 1992
474      */
475     FLOAT   bkwn, x2;
476     FLOAT const wcn = (PI * fcn);
477
478     x /= l;
479     if (x < 0)
480         x = 0;
481     if (x > 1)
482         x = 1;
483     x2 = x - .5;
484
485     bkwn = 0.42 - 0.5 * cos(2 * x * PI) + 0.08 * cos(4 * x * PI);
486     if (fabs(x2) < 1e-9)
487         return wcn / PI;
488     else
489         return (bkwn * sin(l * wcn * x2) / (PI * l * x2));
490
491
492 }
493
494
495
496
497 /* gcd - greatest common divisor */
498 /* Joint work of Euclid and M. Hendry */
499
500 static int
501 gcd(int i, int j)
502 {
503     /*    assert ( i > 0  &&  j > 0 ); */
504     return j ? gcd(j, i % j) : i;
505 }
506
507
508
509 static int
510 fill_buffer_resample(lame_internal_flags * gfc,
511                      sample_t * outbuf,
512                      int desired_len, sample_t const *inbuf, int len, int *num_used, int ch)
513 {
514     SessionConfig_t const *const cfg = &gfc->cfg;
515     EncStateVar_t *esv = &gfc->sv_enc;
516     double  resample_ratio = (double)cfg->samplerate_in / (double)cfg->samplerate_out;
517     int     BLACKSIZE;
518     FLOAT   offset, xvalue;
519     int     i, j = 0, k;
520     int     filter_l;
521     FLOAT   fcn, intratio;
522     FLOAT  *inbuf_old;
523     int     bpc;             /* number of convolution functions to pre-compute */
524     bpc = cfg->samplerate_out / gcd(cfg->samplerate_out, cfg->samplerate_in);
525     if (bpc > BPC)
526         bpc = BPC;
527
528     intratio = (fabs(resample_ratio - floor(.5 + resample_ratio)) < .0001);
529     fcn = 1.00 / resample_ratio;
530     if (fcn > 1.00)
531         fcn = 1.00;
532     filter_l = 31;     /* must be odd */
533     filter_l += intratio; /* unless resample_ratio=int, it must be even */
534
535
536     BLACKSIZE = filter_l + 1; /* size of data needed for FIR */
537
538     if (gfc->fill_buffer_resample_init == 0) {
539         esv->inbuf_old[0] = calloc(BLACKSIZE, sizeof(esv->inbuf_old[0][0]));
540         esv->inbuf_old[1] = calloc(BLACKSIZE, sizeof(esv->inbuf_old[0][0]));
541         for (i = 0; i <= 2 * bpc; ++i)
542             esv->blackfilt[i] = calloc(BLACKSIZE, sizeof(esv->blackfilt[0][0]));
543
544         esv->itime[0] = 0;
545         esv->itime[1] = 0;
546
547         /* precompute blackman filter coefficients */
548         for (j = 0; j <= 2 * bpc; j++) {
549             FLOAT   sum = 0.;
550             offset = (j - bpc) / (2. * bpc);
551             for (i = 0; i <= filter_l; i++)
552                 sum += esv->blackfilt[j][i] = blackman(i - offset, fcn, filter_l);
553             for (i = 0; i <= filter_l; i++)
554                 esv->blackfilt[j][i] /= sum;
555         }
556         gfc->fill_buffer_resample_init = 1;
557     }
558
559     inbuf_old = esv->inbuf_old[ch];
560
561     /* time of j'th element in inbuf = itime + j/ifreq; */
562     /* time of k'th element in outbuf   =  j/ofreq */
563     for (k = 0; k < desired_len; k++) {
564         double  time0 = k * resample_ratio; /* time of k'th output sample */
565         int     joff;
566
567         j = floor(time0 - esv->itime[ch]);
568
569         /* check if we need more input data */
570         if ((filter_l + j - filter_l / 2) >= len)
571             break;
572
573         /* blackman filter.  by default, window centered at j+.5(filter_l%2) */
574         /* but we want a window centered at time0.   */
575         offset = (time0 - esv->itime[ch] - (j + .5 * (filter_l % 2)));
576         assert(fabs(offset) <= .501);
577
578         /* find the closest precomputed window for this offset: */
579         joff = floor((offset * 2 * bpc) + bpc + .5);
580
581         xvalue = 0.;
582         for (i = 0; i <= filter_l; ++i) {
583             int const j2 = i + j - filter_l / 2;
584             sample_t y;
585             assert(j2 < len);
586             assert(j2 + BLACKSIZE >= 0);
587             y = (j2 < 0) ? inbuf_old[BLACKSIZE + j2] : inbuf[j2];
588 #ifdef PRECOMPUTE
589             xvalue += y * esv->blackfilt[joff][i];
590 #else
591             xvalue += y * blackman(i - offset, fcn, filter_l); /* very slow! */
592 #endif
593         }
594         outbuf[k] = xvalue;
595     }
596
597
598     /* k = number of samples added to outbuf */
599     /* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2]  */
600
601     /* how many samples of input data were used:  */
602     *num_used = Min(len, filter_l + j - filter_l / 2);
603
604     /* adjust our input time counter.  Incriment by the number of samples used,
605      * then normalize so that next output sample is at time 0, next
606      * input buffer is at time itime[ch] */
607     esv->itime[ch] += *num_used - k * resample_ratio;
608
609     /* save the last BLACKSIZE samples into the inbuf_old buffer */
610     if (*num_used >= BLACKSIZE) {
611         for (i = 0; i < BLACKSIZE; i++)
612             inbuf_old[i] = inbuf[*num_used + i - BLACKSIZE];
613     }
614     else {
615         /* shift in *num_used samples into inbuf_old  */
616         int const n_shift = BLACKSIZE - *num_used; /* number of samples to shift */
617
618         /* shift n_shift samples by *num_used, to make room for the
619          * num_used new samples */
620         for (i = 0; i < n_shift; ++i)
621             inbuf_old[i] = inbuf_old[i + *num_used];
622
623         /* shift in the *num_used samples */
624         for (j = 0; i < BLACKSIZE; ++i, ++j)
625             inbuf_old[i] = inbuf[j];
626
627         assert(j == *num_used);
628     }
629     return k;           /* return the number samples created at the new samplerate */
630 }
631
632 int
633 isResamplingNecessary(SessionConfig_t const* cfg)
634 {
635     int const l = cfg->samplerate_out * 0.9995f;
636     int const h = cfg->samplerate_out * 1.0005f;
637     return (cfg->samplerate_in < l) || (h < cfg->samplerate_in) ? 1 : 0;
638 }
639
640 /* copy in new samples from in_buffer into mfbuf, with resampling
641    if necessary.  n_in = number of samples from the input buffer that
642    were used.  n_out = number of samples copied into mfbuf  */
643
644 void
645 fill_buffer(lame_internal_flags * gfc,
646             sample_t * const mfbuf[2], sample_t const * const in_buffer[2], int nsamples, int *n_in, int *n_out)
647 {
648     SessionConfig_t const *const cfg = &gfc->cfg;
649     int     mf_size = gfc->sv_enc.mf_size;
650     int     framesize = 576 * cfg->mode_gr;
651     int     nout, ch = 0;
652     int     nch = cfg->channels_out;
653
654     /* copy in new samples into mfbuf, with resampling if necessary */
655     if (isResamplingNecessary(cfg)) {
656         do {
657             nout =
658                 fill_buffer_resample(gfc, mfbuf[ch]+mf_size,
659                                      framesize, in_buffer[ch], nsamples, n_in, ch);
660         } while (++ch < nch);
661         *n_out = nout;
662     }
663     else {
664         nout = Min(framesize, nsamples);
665         do {
666             memcpy(mfbuf[ch]+mf_size,in_buffer[ch],sizeof(sample_t) * nout);
667         } while (++ch < nch);
668         *n_out = nout;
669         *n_in = nout;
670     }
671 }
672
673
674
675
676
677
678
679 /***********************************************************************
680 *
681 *  Message Output
682 *
683 ***********************************************************************/
684
685 void
686 lame_report_def(const char *format, va_list args)
687 {
688     (void) vfprintf(stderr, format, args);
689     fflush(stderr); /* an debug function should flush immediately */
690 }
691
692 void 
693 lame_report_fnc(lame_report_function print_f, const char *format, ...)
694 {
695     if (print_f) {
696         va_list args;
697         va_start(args, format);
698         print_f(format, args);
699         va_end(args);
700     }
701 }
702
703
704 void
705 lame_debugf(const lame_internal_flags* gfc, const char *format, ...)
706 {
707     if (gfc && gfc->report_dbg) {
708         va_list args;
709         va_start(args, format);
710         gfc->report_dbg(format, args);
711         va_end(args);
712     }
713 }
714
715
716 void
717 lame_msgf(const lame_internal_flags* gfc, const char *format, ...)
718 {
719     if (gfc && gfc->report_msg) {
720         va_list args;
721         va_start(args, format);
722         gfc->report_msg(format, args);
723         va_end(args);
724     }
725 }
726
727
728 void
729 lame_errorf(const lame_internal_flags* gfc, const char *format, ...)
730 {
731     if (gfc && gfc->report_err) {
732         va_list args;
733         va_start(args, format);
734         gfc->report_err(format, args);
735         va_end(args);
736     }
737 }
738
739
740
741 /***********************************************************************
742  *
743  *      routines to detect CPU specific features like 3DNow, MMX, SSE
744  *
745  *  donated by Frank Klemm
746  *  added Robert Hegemann 2000-10-10
747  *
748  ***********************************************************************/
749
750 #ifdef HAVE_NASM
751 extern int has_MMX_nasm(void);
752 extern int has_3DNow_nasm(void);
753 extern int has_SSE_nasm(void);
754 extern int has_SSE2_nasm(void);
755 #endif
756
757 int
758 has_MMX(void)
759 {
760 #ifdef HAVE_NASM
761     return has_MMX_nasm();
762 #else
763     return 0;           /* don't know, assume not */
764 #endif
765 }
766
767 int
768 has_3DNow(void)
769 {
770 #ifdef HAVE_NASM
771     return has_3DNow_nasm();
772 #else
773     return 0;           /* don't know, assume not */
774 #endif
775 }
776
777 int
778 has_SSE(void)
779 {
780 #ifdef HAVE_NASM
781     return has_SSE_nasm();
782 #else
783 #if defined( _M_X64 ) || defined( MIN_ARCH_SSE )
784     return 1;
785 #else
786     return 0;           /* don't know, assume not */
787 #endif
788 #endif
789 }
790
791 int
792 has_SSE2(void)
793 {
794 #ifdef HAVE_NASM
795     return has_SSE2_nasm();
796 #else
797 #if defined( _M_X64 ) || defined( MIN_ARCH_SSE )
798     return 1;
799 #else
800     return 0;           /* don't know, assume not */
801 #endif
802 #endif
803 }
804
805 void
806 disable_FPE(void)
807 {
808 /* extremly system dependent stuff, move to a lib to make the code readable */
809 /*==========================================================================*/
810
811
812
813     /*
814      *  Disable floating point exceptions
815      */
816
817
818
819
820 #if defined(__FreeBSD__) && !defined(__alpha__)
821     {
822         /* seet floating point mask to the Linux default */
823         fp_except_t mask;
824         mask = fpgetmask();
825         /* if bit is set, we get SIGFPE on that error! */
826         fpsetmask(mask & ~(FP_X_INV | FP_X_DZ));
827         /*  DEBUGF("FreeBSD mask is 0x%x\n",mask); */
828     }
829 #endif
830
831 #if defined(__riscos__) && !defined(ABORTFP)
832     /* Disable FPE's under RISC OS */
833     /* if bit is set, we disable trapping that error! */
834     /*   _FPE_IVO : invalid operation */
835     /*   _FPE_DVZ : divide by zero */
836     /*   _FPE_OFL : overflow */
837     /*   _FPE_UFL : underflow */
838     /*   _FPE_INX : inexact */
839     DisableFPETraps(_FPE_IVO | _FPE_DVZ | _FPE_OFL);
840 #endif
841
842     /*
843      *  Debugging stuff
844      *  The default is to ignore FPE's, unless compiled with -DABORTFP
845      *  so add code below to ENABLE FPE's.
846      */
847
848 #if defined(ABORTFP)
849 #if defined(_MSC_VER)
850     {
851 #if 0
852         /* rh 061207
853            the following fix seems to be a workaround for a problem in the
854            parent process calling LAME. It would be better to fix the broken
855            application => code disabled.
856          */
857
858         /* set affinity to a single CPU.  Fix for EAC/lame on SMP systems from
859            "Todd Richmond" <todd.richmond@openwave.com> */
860         SYSTEM_INFO si;
861         GetSystemInfo(&si);
862         SetProcessAffinityMask(GetCurrentProcess(), si.dwActiveProcessorMask);
863 #endif
864 #include <float.h>
865         unsigned int mask;
866         mask = _controlfp(0, 0);
867         mask &= ~(_EM_OVERFLOW | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_INVALID);
868         mask = _controlfp(mask, _MCW_EM);
869     }
870 #elif defined(__CYGWIN__)
871 #  define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
872 #  define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
873
874 #  define _EM_INEXACT     0x00000020 /* inexact (precision) */
875 #  define _EM_UNDERFLOW   0x00000010 /* underflow */
876 #  define _EM_OVERFLOW    0x00000008 /* overflow */
877 #  define _EM_ZERODIVIDE  0x00000004 /* zero divide */
878 #  define _EM_INVALID     0x00000001 /* invalid */
879     {
880         unsigned int mask;
881         _FPU_GETCW(mask);
882         /* Set the FPU control word to abort on most FPEs */
883         mask &= ~(_EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID);
884         _FPU_SETCW(mask);
885     }
886 # elif defined(__linux__)
887     {
888
889 #  include <fpu_control.h>
890 #  ifndef _FPU_GETCW
891 #  define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
892 #  endif
893 #  ifndef _FPU_SETCW
894 #  define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
895 #  endif
896
897         /* 
898          * Set the Linux mask to abort on most FPE's
899          * if bit is set, we _mask_ SIGFPE on that error!
900          *  mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM );
901          */
902
903         unsigned int mask;
904         _FPU_GETCW(mask);
905         mask &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
906         _FPU_SETCW(mask);
907     }
908 #endif
909 #endif /* ABORTFP */
910 }
911
912
913
914
915
916 #ifdef USE_FAST_LOG
917 /***********************************************************************
918  *
919  * Fast Log Approximation for log2, used to approximate every other log
920  * (log10 and log)
921  * maximum absolute error for log10 is around 10-6
922  * maximum *relative* error can be high when x is almost 1 because error/log10(x) tends toward x/e
923  *
924  * use it if typical RESULT values are > 1e-5 (for example if x>1.00001 or x<0.99999)
925  * or if the relative precision in the domain around 1 is not important (result in 1 is exact and 0)
926  *
927  ***********************************************************************/
928
929
930 #define LOG2_SIZE       (512)
931 #define LOG2_SIZE_L2    (9)
932
933 static ieee754_float32_t log_table[LOG2_SIZE + 1];
934
935
936
937 void
938 init_log_table(void)
939 {
940     int     j;
941     static int init = 0;
942
943     /* Range for log2(x) over [1,2[ is [0,1[ */
944     assert((1 << LOG2_SIZE_L2) == LOG2_SIZE);
945
946     if (!init) {
947         for (j = 0; j < LOG2_SIZE + 1; j++)
948             log_table[j] = log(1.0f + j / (ieee754_float32_t) LOG2_SIZE) / log(2.0f);
949     }
950     init = 1;
951 }
952
953
954
955 ieee754_float32_t
956 fast_log2(ieee754_float32_t x)
957 {
958     ieee754_float32_t log2val, partial;
959     union {
960         ieee754_float32_t f;
961         int     i;
962     } fi;
963     int     mantisse;
964     fi.f = x;
965     mantisse = fi.i & 0x7fffff;
966     log2val = ((fi.i >> 23) & 0xFF) - 0x7f;
967     partial = (mantisse & ((1 << (23 - LOG2_SIZE_L2)) - 1));
968     partial *= 1.0f / ((1 << (23 - LOG2_SIZE_L2)));
969
970
971     mantisse >>= (23 - LOG2_SIZE_L2);
972
973     /* log2val += log_table[mantisse];  without interpolation the results are not good */
974     log2val += log_table[mantisse] * (1.0f - partial) + log_table[mantisse + 1] * partial;
975
976     return log2val;
977 }
978
979 #else /* Don't use FAST_LOG */
980
981
982 void
983 init_log_table(void)
984 {
985 }
986
987
988 #endif
989
990 /* end of util.c */