00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00044
00045
00046
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 {
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
00135 free(gfc->s3_ll);
00136 }
00137 if (gfc->s3_ss) {
00138
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
00180
00181
00182 FLOAT
00183 ATHformula_GB(FLOAT f, FLOAT value)
00184 {
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 FLOAT ath;
00208
00209 if (f < -.3)
00210 f = 3410;
00211
00212 f /= 1000;
00213 f = Max(0.01, f);
00214
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);
00233 case 2:
00234 return ATHformula_GB(f, 0);
00235 case 3:
00236 return ATHformula_GB(f, 1) + 6;
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
00247 FLOAT
00248 freq2bark(FLOAT freq)
00249 {
00250
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
00258 FLOAT
00259 freq2cbw(FLOAT freq)
00260 {
00261
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,
00275 int version,
00276 int samplerate)
00277 {
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
00308
00309
00310
00311
00312
00313
00314
00315 int
00316 nearestBitrateFullIndex(const int bitrate)
00317 {
00318
00319
00320 int index;
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
00333 upper_range_kbps = bitrate_table[16];
00334 upper_range = 16;
00335 lower_range_kbps = bitrate_table[16];
00336 lower_range = 16;
00337
00338
00339
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;
00348 }
00349 }
00350
00351
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
00365
00366
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,
00393 int version,
00394 int samplerate)
00395 {
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
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
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 inline static FLOAT
00466 blackman(FLOAT x, FLOAT fcn, int l)
00467 {
00468
00469
00470
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
00492
00493
00494 int
00495 gcd(int i, int j)
00496 {
00497
00498 return j ? gcd(j, i % j) : i;
00499 }
00500
00501
00502
00503
00504
00505
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
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;
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;
00563 filter_l += intratio;
00564
00565
00566 BLACKSIZE = filter_l + 1;
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
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
00592
00593 for (k = 0; k < desired_len; k++) {
00594 FLOAT time0;
00595 int joff;
00596
00597 time0 = k * gfc->resample_ratio;
00598 j = floor(time0 - gfc->itime[ch]);
00599
00600
00601 if ((filter_l + j - filter_l / 2) >= len)
00602 break;
00603
00604
00605
00606 offset = (time0 - gfc->itime[ch] - (j + .5 * (filter_l % 2)));
00607 assert(fabs(offset) <= .501);
00608
00609
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);
00623 #endif
00624 }
00625 outbuf[k] = xvalue;
00626 }
00627
00628
00629
00630
00631
00632
00633 *num_used = Min(len, filter_l + j - filter_l / 2);
00634
00635
00636
00637
00638 gfc->itime[ch] += *num_used - k * gfc->resample_ratio;
00639
00640
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
00647 int const n_shift = BLACKSIZE - *num_used;
00648
00649
00650
00651 for (i = 0; i < n_shift; ++i)
00652 inbuf_old[i] = inbuf_old[i + *num_used];
00653
00654
00655 for (j = 0; i < BLACKSIZE; ++i, ++j)
00656 inbuf_old[i] = inbuf[j];
00657
00658 assert(j == *num_used);
00659 }
00660 return k;
00661 }
00662
00663
00664
00665
00666
00667
00668
00669
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);
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);
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);
00723 }
00724
00725 va_end(args);
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735
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;
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;
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;
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;
00788 #endif
00789 #endif
00790 }
00791
00792 void
00793 disable_FPE(void)
00794 {
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807 #if defined(__FreeBSD__) && !defined(__alpha__)
00808 {
00809
00810 fp_except_t mask;
00811 mask = fpgetmask();
00812
00813 fpsetmask(mask & ~(FP_X_INV | FP_X_DZ));
00814
00815 }
00816 #endif
00817
00818 #if defined(__riscos__) && !defined(ABORTFP)
00819
00820
00821
00822
00823
00824
00825
00826 DisableFPETraps(_FPE_IVO | _FPE_DVZ | _FPE_OFL);
00827 #endif
00828
00829
00830
00831
00832
00833
00834
00835 #if defined(ABORTFP)
00836 #if defined(_MSC_VER)
00837 {
00838 #if 0
00839
00840
00841
00842
00843
00844
00845
00846
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
00862 # define _EM_UNDERFLOW 0x00000010
00863 # define _EM_OVERFLOW 0x00000008
00864 # define _EM_ZERODIVIDE 0x00000004
00865 # define _EM_INVALID 0x00000001
00866 {
00867 unsigned int mask;
00868 _FPU_GETCW(mask);
00869
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
00886
00887
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
00897 }
00898
00899
00900
00901
00902
00903 #ifdef USE_FAST_LOG
00904
00905
00906
00907
00908
00909
00910
00911
00912
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
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
00961 log2val += log_table[mantisse] * (1.0f - partial) + log_table[mantisse + 1] * partial;
00962
00963 return log2val;
00964 }
00965
00966 #else
00967
00968
00969 void
00970 init_log_table(void)
00971 {
00972 }
00973
00974
00975 #endif
00976
00977