xref: /plan9/sys/src/games/mp3enc/util.c (revision 8f5875f3e9b20916b4c52ad4336922bc8653eb7b)
1*8f5875f3SDavid du Colombier /*
2*8f5875f3SDavid du Colombier  *	lame utility library source file
3*8f5875f3SDavid du Colombier  *
4*8f5875f3SDavid du Colombier  *	Copyright (c) 1999 Albert L Faber
5*8f5875f3SDavid du Colombier  *
6*8f5875f3SDavid du Colombier  * This library is free software; you can redistribute it and/or
7*8f5875f3SDavid du Colombier  * modify it under the terms of the GNU Library General Public
8*8f5875f3SDavid du Colombier  * License as published by the Free Software Foundation; either
9*8f5875f3SDavid du Colombier  * version 2 of the License, or (at your option) any later version.
10*8f5875f3SDavid du Colombier  *
11*8f5875f3SDavid du Colombier  * This library is distributed in the hope that it will be useful,
12*8f5875f3SDavid du Colombier  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*8f5875f3SDavid du Colombier  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
14*8f5875f3SDavid du Colombier  * Library General Public License for more details.
15*8f5875f3SDavid du Colombier  *
16*8f5875f3SDavid du Colombier  * You should have received a copy of the GNU Library General Public
17*8f5875f3SDavid du Colombier  * License along with this library; if not, write to the
18*8f5875f3SDavid du Colombier  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19*8f5875f3SDavid du Colombier  * Boston, MA 02111-1307, USA.
20*8f5875f3SDavid du Colombier  */
21*8f5875f3SDavid du Colombier 
22*8f5875f3SDavid du Colombier /* $Id: util.c,v 1.67 2001/03/20 00:42:56 markt Exp $ */
23*8f5875f3SDavid du Colombier 
24*8f5875f3SDavid du Colombier #ifdef HAVE_CONFIG_H
25*8f5875f3SDavid du Colombier # include <config.h>
26*8f5875f3SDavid du Colombier #endif
27*8f5875f3SDavid du Colombier 
28*8f5875f3SDavid du Colombier #define PRECOMPUTE
29*8f5875f3SDavid du Colombier 
30*8f5875f3SDavid du Colombier #include "util.h"
31*8f5875f3SDavid du Colombier #include <ctype.h>
32*8f5875f3SDavid du Colombier #include <assert.h>
33*8f5875f3SDavid du Colombier #include <stdarg.h>
34*8f5875f3SDavid du Colombier 
35*8f5875f3SDavid du Colombier #if defined(__FreeBSD__) && !defined(__alpha__)
36*8f5875f3SDavid du Colombier # include <machine/floatingpoint.h>
37*8f5875f3SDavid du Colombier #endif
38*8f5875f3SDavid du Colombier 
39*8f5875f3SDavid du Colombier #ifdef WITH_DMALLOC
40*8f5875f3SDavid du Colombier #include <dmalloc.h>
41*8f5875f3SDavid du Colombier #endif
42*8f5875f3SDavid du Colombier 
43*8f5875f3SDavid du Colombier /***********************************************************************
44*8f5875f3SDavid du Colombier *
45*8f5875f3SDavid du Colombier *  Global Function Definitions
46*8f5875f3SDavid du Colombier *
47*8f5875f3SDavid du Colombier ***********************************************************************/
48*8f5875f3SDavid du Colombier /*empty and close mallocs in gfc */
49*8f5875f3SDavid du Colombier 
freegfc(lame_internal_flags * const gfc)50*8f5875f3SDavid du Colombier void  freegfc ( lame_internal_flags* const gfc )   /* bit stream structure */
51*8f5875f3SDavid du Colombier {
52*8f5875f3SDavid du Colombier     int  i;
53*8f5875f3SDavid du Colombier 
54*8f5875f3SDavid du Colombier #ifdef KLEMM_44
55*8f5875f3SDavid du Colombier     if (gfc->resample_in != NULL) {
56*8f5875f3SDavid du Colombier         resample_close(gfc->resample_in);
57*8f5875f3SDavid du Colombier         gfc->resample_in = NULL;
58*8f5875f3SDavid du Colombier     }
59*8f5875f3SDavid du Colombier     free(gfc->mfbuf[0]);
60*8f5875f3SDavid du Colombier     free(gfc->mfbuf[1]);
61*8f5875f3SDavid du Colombier #endif
62*8f5875f3SDavid du Colombier 
63*8f5875f3SDavid du Colombier     for ( i = 0 ; i <= 2*BPC; i++ )
64*8f5875f3SDavid du Colombier         if ( gfc->blackfilt[i] != NULL ) {
65*8f5875f3SDavid du Colombier             free ( gfc->blackfilt[i] );
66*8f5875f3SDavid du Colombier 	    gfc->blackfilt[i] = NULL;
67*8f5875f3SDavid du Colombier 	}
68*8f5875f3SDavid du Colombier     if ( gfc->inbuf_old[0] ) {
69*8f5875f3SDavid du Colombier         free ( gfc->inbuf_old[0] );
70*8f5875f3SDavid du Colombier 	gfc->inbuf_old[0] = NULL;
71*8f5875f3SDavid du Colombier     }
72*8f5875f3SDavid du Colombier     if ( gfc->inbuf_old[1] ) {
73*8f5875f3SDavid du Colombier         free ( gfc->inbuf_old[1] );
74*8f5875f3SDavid du Colombier 	gfc->inbuf_old[1] = NULL;
75*8f5875f3SDavid du Colombier     }
76*8f5875f3SDavid du Colombier 
77*8f5875f3SDavid du Colombier     if ( gfc->bs.buf != NULL ) {
78*8f5875f3SDavid du Colombier         free ( gfc->bs.buf );
79*8f5875f3SDavid du Colombier         gfc->bs.buf = NULL;
80*8f5875f3SDavid du Colombier     }
81*8f5875f3SDavid du Colombier 
82*8f5875f3SDavid du Colombier     if ( gfc->VBR_seek_table.bag ) {
83*8f5875f3SDavid du Colombier         free ( gfc->VBR_seek_table.bag );
84*8f5875f3SDavid du Colombier     }
85*8f5875f3SDavid du Colombier     if ( gfc->ATH ) {
86*8f5875f3SDavid du Colombier         free ( gfc->ATH );
87*8f5875f3SDavid du Colombier     }
88*8f5875f3SDavid du Colombier     free ( gfc );
89*8f5875f3SDavid du Colombier }
90*8f5875f3SDavid du Colombier 
ATHformula_old(FLOAT8 f)91*8f5875f3SDavid du Colombier FLOAT8 ATHformula_old(FLOAT8 f)
92*8f5875f3SDavid du Colombier {
93*8f5875f3SDavid du Colombier   FLOAT8 ath;
94*8f5875f3SDavid du Colombier   f /= 1000;  // convert to khz
95*8f5875f3SDavid du Colombier   f  = Max(0.01, f);
96*8f5875f3SDavid du Colombier   f  = Min(18.0, f);
97*8f5875f3SDavid du Colombier 
98*8f5875f3SDavid du Colombier   /* from Painter & Spanias, 1997 */
99*8f5875f3SDavid du Colombier   /* minimum: (i=77) 3.3kHz = -5db */
100*8f5875f3SDavid du Colombier   ath =    3.640 * pow(f,-0.8)
101*8f5875f3SDavid du Colombier          - 6.500 * exp(-0.6*pow(f-3.3,2.0))
102*8f5875f3SDavid du Colombier          + 0.001 * pow(f,4.0);
103*8f5875f3SDavid du Colombier   return ath;
104*8f5875f3SDavid du Colombier }
105*8f5875f3SDavid du Colombier 
ATHformula_GB(FLOAT8 f)106*8f5875f3SDavid du Colombier FLOAT8 ATHformula_GB(FLOAT8 f)
107*8f5875f3SDavid du Colombier {
108*8f5875f3SDavid du Colombier   FLOAT8 ath;
109*8f5875f3SDavid du Colombier   f /= 1000;  // convert to khz
110*8f5875f3SDavid du Colombier   f  = Max(0.01, f);
111*8f5875f3SDavid du Colombier   f  = Min(18.0, f);
112*8f5875f3SDavid du Colombier 
113*8f5875f3SDavid du Colombier   /* from Painter & Spanias, 1997 */
114*8f5875f3SDavid du Colombier   /* modified by Gabriel Bouvigne to better fit to the reality */
115*8f5875f3SDavid du Colombier   ath =    3.640 * pow(f,-0.8)
116*8f5875f3SDavid du Colombier          - 6.800 * exp(-0.6*pow(f-3.4,2.0))
117*8f5875f3SDavid du Colombier          + 6.000 * exp(-0.15*pow(f-8.7,2.0))
118*8f5875f3SDavid du Colombier          + 0.6* 0.001 * pow(f,4.0);
119*8f5875f3SDavid du Colombier   return ath;
120*8f5875f3SDavid du Colombier }
121*8f5875f3SDavid du Colombier 
ATHformula_GBtweak(FLOAT8 f)122*8f5875f3SDavid du Colombier FLOAT8 ATHformula_GBtweak(FLOAT8 f)
123*8f5875f3SDavid du Colombier {
124*8f5875f3SDavid du Colombier   FLOAT8 ath;
125*8f5875f3SDavid du Colombier   f /= 1000;  // convert to khz
126*8f5875f3SDavid du Colombier   f  = Max(0.01, f);
127*8f5875f3SDavid du Colombier   f  = Min(18.0, f);
128*8f5875f3SDavid du Colombier 
129*8f5875f3SDavid du Colombier   /* from Painter & Spanias, 1997 */
130*8f5875f3SDavid du Colombier   /* modified by Gabriel Bouvigne to better fit to the reality */
131*8f5875f3SDavid du Colombier   ath =    3.640 * pow(f,-0.8)
132*8f5875f3SDavid du Colombier          - 6.800 * exp(-0.6*pow(f-3.4,2.0))
133*8f5875f3SDavid du Colombier          + 6.000 * exp(-0.15*pow(f-8.7,2.0))
134*8f5875f3SDavid du Colombier          + 0.57* 0.001 * pow(f,4.0) //0.57 to maximize HF importance
135*8f5875f3SDavid du Colombier          + 6; //std --athlower -6 for
136*8f5875f3SDavid du Colombier   return ath;
137*8f5875f3SDavid du Colombier }
138*8f5875f3SDavid du Colombier 
139*8f5875f3SDavid du Colombier 
140*8f5875f3SDavid du Colombier /*
141*8f5875f3SDavid du Colombier  *  Klemm 1994 and 1997. Experimental data. Sorry, data looks a little bit
142*8f5875f3SDavid du Colombier  *  dodderly. Data below 30 Hz is extrapolated from other material, above 18
143*8f5875f3SDavid du Colombier  *  kHz the ATH is limited due to the original purpose (too much noise at
144*8f5875f3SDavid du Colombier  *  ATH is not good even if it's theoretically inaudible).
145*8f5875f3SDavid du Colombier  */
146*8f5875f3SDavid du Colombier 
ATHformula_Frank(FLOAT8 freq)147*8f5875f3SDavid du Colombier FLOAT8  ATHformula_Frank( FLOAT8 freq )
148*8f5875f3SDavid du Colombier {
149*8f5875f3SDavid du Colombier     /*
150*8f5875f3SDavid du Colombier      * one value per 100 cent = 1
151*8f5875f3SDavid du Colombier      * semitone = 1/4
152*8f5875f3SDavid du Colombier      * third = 1/12
153*8f5875f3SDavid du Colombier      * octave = 1/40 decade
154*8f5875f3SDavid du Colombier      * rest is linear interpolated, values are currently in decibel rel. 20 �Pa
155*8f5875f3SDavid du Colombier      */
156*8f5875f3SDavid du Colombier     static FLOAT tab [] = {
157*8f5875f3SDavid du Colombier         /*    10.0 */  96.69, 96.69, 96.26, 95.12,
158*8f5875f3SDavid du Colombier         /*    12.6 */  93.53, 91.13, 88.82, 86.76,
159*8f5875f3SDavid du Colombier         /*    15.8 */  84.69, 82.43, 79.97, 77.48,
160*8f5875f3SDavid du Colombier         /*    20.0 */  74.92, 72.39, 70.00, 67.62,
161*8f5875f3SDavid du Colombier         /*    25.1 */  65.29, 63.02, 60.84, 59.00,
162*8f5875f3SDavid du Colombier         /*    31.6 */  57.17, 55.34, 53.51, 51.67,
163*8f5875f3SDavid du Colombier         /*    39.8 */  50.04, 48.12, 46.38, 44.66,
164*8f5875f3SDavid du Colombier         /*    50.1 */  43.10, 41.73, 40.50, 39.22,
165*8f5875f3SDavid du Colombier         /*    63.1 */  37.23, 35.77, 34.51, 32.81,
166*8f5875f3SDavid du Colombier         /*    79.4 */  31.32, 30.36, 29.02, 27.60,
167*8f5875f3SDavid du Colombier         /*   100.0 */  26.58, 25.91, 24.41, 23.01,
168*8f5875f3SDavid du Colombier         /*   125.9 */  22.12, 21.25, 20.18, 19.00,
169*8f5875f3SDavid du Colombier         /*   158.5 */  17.70, 16.82, 15.94, 15.12,
170*8f5875f3SDavid du Colombier         /*   199.5 */  14.30, 13.41, 12.60, 11.98,
171*8f5875f3SDavid du Colombier         /*   251.2 */  11.36, 10.57,  9.98,  9.43,
172*8f5875f3SDavid du Colombier         /*   316.2 */   8.87,  8.46,  7.44,  7.12,
173*8f5875f3SDavid du Colombier         /*   398.1 */   6.93,  6.68,  6.37,  6.06,
174*8f5875f3SDavid du Colombier         /*   501.2 */   5.80,  5.55,  5.29,  5.02,
175*8f5875f3SDavid du Colombier         /*   631.0 */   4.75,  4.48,  4.22,  3.98,
176*8f5875f3SDavid du Colombier         /*   794.3 */   3.75,  3.51,  3.27,  3.22,
177*8f5875f3SDavid du Colombier         /*  1000.0 */   3.12,  3.01,  2.91,  2.68,
178*8f5875f3SDavid du Colombier         /*  1258.9 */   2.46,  2.15,  1.82,  1.46,
179*8f5875f3SDavid du Colombier         /*  1584.9 */   1.07,  0.61,  0.13, -0.35,
180*8f5875f3SDavid du Colombier         /*  1995.3 */  -0.96, -1.56, -1.79, -2.35,
181*8f5875f3SDavid du Colombier         /*  2511.9 */  -2.95, -3.50, -4.01, -4.21,
182*8f5875f3SDavid du Colombier         /*  3162.3 */  -4.46, -4.99, -5.32, -5.35,
183*8f5875f3SDavid du Colombier         /*  3981.1 */  -5.13, -4.76, -4.31, -3.13,
184*8f5875f3SDavid du Colombier         /*  5011.9 */  -1.79,  0.08,  2.03,  4.03,
185*8f5875f3SDavid du Colombier         /*  6309.6 */   5.80,  7.36,  8.81, 10.22,
186*8f5875f3SDavid du Colombier         /*  7943.3 */  11.54, 12.51, 13.48, 14.21,
187*8f5875f3SDavid du Colombier         /* 10000.0 */  14.79, 13.99, 12.85, 11.93,
188*8f5875f3SDavid du Colombier         /* 12589.3 */  12.87, 15.19, 19.14, 23.69,
189*8f5875f3SDavid du Colombier         /* 15848.9 */  33.52, 48.65, 59.42, 61.77,
190*8f5875f3SDavid du Colombier         /* 19952.6 */  63.85, 66.04, 68.33, 70.09,
191*8f5875f3SDavid du Colombier         /* 25118.9 */  70.66, 71.27, 71.91, 72.60,
192*8f5875f3SDavid du Colombier     };
193*8f5875f3SDavid du Colombier     FLOAT8    freq_log;
194*8f5875f3SDavid du Colombier     unsigned  index;
195*8f5875f3SDavid du Colombier 
196*8f5875f3SDavid du Colombier     if ( freq <    10. ) freq =    10.;
197*8f5875f3SDavid du Colombier     if ( freq > 29853. ) freq = 29853.;
198*8f5875f3SDavid du Colombier 
199*8f5875f3SDavid du Colombier     freq_log = 40. * log10 (0.1 * freq);   /* 4 steps per third, starting at 10 Hz */
200*8f5875f3SDavid du Colombier     index    = (unsigned) freq_log;
201*8f5875f3SDavid du Colombier     assert ( index < sizeof(tab)/sizeof(*tab) );
202*8f5875f3SDavid du Colombier     return tab [index] * (1 + index - freq_log) + tab [index+1] * (freq_log - index);
203*8f5875f3SDavid du Colombier }
204*8f5875f3SDavid du Colombier 
ATHformula(FLOAT8 f,lame_global_flags * gfp)205*8f5875f3SDavid du Colombier FLOAT8 ATHformula(FLOAT8 f,lame_global_flags *gfp)
206*8f5875f3SDavid du Colombier {
207*8f5875f3SDavid du Colombier   switch(gfp->ATHtype)
208*8f5875f3SDavid du Colombier     {
209*8f5875f3SDavid du Colombier     case 0:
210*8f5875f3SDavid du Colombier       return ATHformula_old(f);
211*8f5875f3SDavid du Colombier     case 1:
212*8f5875f3SDavid du Colombier       return ATHformula_Frank(f);
213*8f5875f3SDavid du Colombier     case 2:
214*8f5875f3SDavid du Colombier       return ATHformula_GB(f);
215*8f5875f3SDavid du Colombier     case 3:
216*8f5875f3SDavid du Colombier       return ATHformula_GBtweak(f);
217*8f5875f3SDavid du Colombier     }
218*8f5875f3SDavid du Colombier 
219*8f5875f3SDavid du Colombier   return ATHformula_Frank(f);
220*8f5875f3SDavid du Colombier }
221*8f5875f3SDavid du Colombier 
222*8f5875f3SDavid du Colombier /* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */
freq2bark(FLOAT8 freq)223*8f5875f3SDavid du Colombier FLOAT8 freq2bark(FLOAT8 freq)
224*8f5875f3SDavid du Colombier {
225*8f5875f3SDavid du Colombier   /* input: freq in hz  output: barks */
226*8f5875f3SDavid du Colombier     if (freq<0) freq=0;
227*8f5875f3SDavid du Colombier     freq = freq * 0.001;
228*8f5875f3SDavid du Colombier     return 13.0*atan(.76*freq) + 3.5*atan(freq*freq/(7.5*7.5));
229*8f5875f3SDavid du Colombier }
230*8f5875f3SDavid du Colombier 
231*8f5875f3SDavid du Colombier /* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */
freq2cbw(FLOAT8 freq)232*8f5875f3SDavid du Colombier FLOAT8 freq2cbw(FLOAT8 freq)
233*8f5875f3SDavid du Colombier {
234*8f5875f3SDavid du Colombier   /* input: freq in hz  output: critical band width */
235*8f5875f3SDavid du Colombier     freq = freq * 0.001;
236*8f5875f3SDavid du Colombier     return 25+75*pow(1+1.4*(freq*freq),0.69);
237*8f5875f3SDavid du Colombier }
238*8f5875f3SDavid du Colombier 
239*8f5875f3SDavid du Colombier 
240*8f5875f3SDavid du Colombier 
241*8f5875f3SDavid du Colombier 
242*8f5875f3SDavid du Colombier 
243*8f5875f3SDavid du Colombier 
244*8f5875f3SDavid du Colombier /***********************************************************************
245*8f5875f3SDavid du Colombier  * compute bitsperframe and mean_bits for a layer III frame
246*8f5875f3SDavid du Colombier  **********************************************************************/
getframebits(lame_global_flags * gfp,int * bitsPerFrame,int * mean_bits)247*8f5875f3SDavid du Colombier void getframebits(lame_global_flags *gfp, int *bitsPerFrame, int *mean_bits)
248*8f5875f3SDavid du Colombier {
249*8f5875f3SDavid du Colombier   lame_internal_flags *gfc=gfp->internal_flags;
250*8f5875f3SDavid du Colombier   int  whole_SpF;  /* integral number of Slots per Frame without padding */
251*8f5875f3SDavid du Colombier   int  bit_rate;
252*8f5875f3SDavid du Colombier 
253*8f5875f3SDavid du Colombier   /* get bitrate in kbps [?] */
254*8f5875f3SDavid du Colombier   if (gfc->bitrate_index)
255*8f5875f3SDavid du Colombier     bit_rate = bitrate_table[gfp->version][gfc->bitrate_index];
256*8f5875f3SDavid du Colombier   else
257*8f5875f3SDavid du Colombier     bit_rate = gfp->brate;
258*8f5875f3SDavid du Colombier   assert ( bit_rate <= 550 );
259*8f5875f3SDavid du Colombier 
260*8f5875f3SDavid du Colombier   // bytes_per_frame = bitrate * 1000 / ( gfp->out_samplerate / (gfp->version == 1  ?  1152  :  576 )) / 8;
261*8f5875f3SDavid du Colombier   // bytes_per_frame = bitrate * 1000 / gfp->out_samplerate * (gfp->version == 1  ?  1152  :  576 ) / 8;
262*8f5875f3SDavid du Colombier   // bytes_per_frame = bitrate * ( gfp->version == 1  ?  1152/8*1000  :  576/8*1000 ) / gfp->out_samplerate;
263*8f5875f3SDavid du Colombier 
264*8f5875f3SDavid du Colombier   whole_SpF = (gfp->version+1)*72000*bit_rate / gfp->out_samplerate;
265*8f5875f3SDavid du Colombier 
266*8f5875f3SDavid du Colombier   // There must be somewhere code toggling gfc->padding on and off
267*8f5875f3SDavid du Colombier 
268*8f5875f3SDavid du Colombier   /* main encoding routine toggles padding on and off */
269*8f5875f3SDavid du Colombier   /* one Layer3 Slot consists of 8 bits */
270*8f5875f3SDavid du Colombier   *bitsPerFrame = 8 * (whole_SpF + gfc->padding);
271*8f5875f3SDavid du Colombier 
272*8f5875f3SDavid du Colombier   // sideinfo_len
273*8f5875f3SDavid du Colombier   *mean_bits = (*bitsPerFrame - 8*gfc->sideinfo_len) / gfc->mode_gr;
274*8f5875f3SDavid du Colombier }
275*8f5875f3SDavid du Colombier 
276*8f5875f3SDavid du Colombier 
277*8f5875f3SDavid du Colombier 
278*8f5875f3SDavid du Colombier 
279*8f5875f3SDavid du Colombier #define ABS(A) (((A)>0) ? (A) : -(A))
280*8f5875f3SDavid du Colombier 
FindNearestBitrate(int bRate,int version,int samplerate)281*8f5875f3SDavid du Colombier int FindNearestBitrate(
282*8f5875f3SDavid du Colombier int bRate,        /* legal rates from 32 to 448 */
283*8f5875f3SDavid du Colombier int version,      /* MPEG-1 or MPEG-2 LSF */
284*8f5875f3SDavid du Colombier int samplerate)   /* convert bitrate in kbps to index */
285*8f5875f3SDavid du Colombier {
286*8f5875f3SDavid du Colombier     int  bitrate = 0;
287*8f5875f3SDavid du Colombier     int  i;
288*8f5875f3SDavid du Colombier 
289*8f5875f3SDavid du Colombier     for ( i = 1; i <= 14; i++ )
290*8f5875f3SDavid du Colombier         if ( ABS (bitrate_table[version][i] - bRate) < ABS (bitrate - bRate) )
291*8f5875f3SDavid du Colombier             bitrate = bitrate_table [version] [i];
292*8f5875f3SDavid du Colombier 
293*8f5875f3SDavid du Colombier     return bitrate;
294*8f5875f3SDavid du Colombier }
295*8f5875f3SDavid du Colombier 
296*8f5875f3SDavid du Colombier 
297*8f5875f3SDavid du Colombier /* map frequency to a valid MP3 sample frequency
298*8f5875f3SDavid du Colombier  *
299*8f5875f3SDavid du Colombier  * Robert.Hegemann@gmx.de 2000-07-01
300*8f5875f3SDavid du Colombier  */
map2MP3Frequency(int freq)301*8f5875f3SDavid du Colombier int map2MP3Frequency(int freq)
302*8f5875f3SDavid du Colombier {
303*8f5875f3SDavid du Colombier     if (freq <=  8000) return  8000;
304*8f5875f3SDavid du Colombier     if (freq <= 11025) return 11025;
305*8f5875f3SDavid du Colombier     if (freq <= 12000) return 12000;
306*8f5875f3SDavid du Colombier     if (freq <= 16000) return 16000;
307*8f5875f3SDavid du Colombier     if (freq <= 22050) return 22050;
308*8f5875f3SDavid du Colombier     if (freq <= 24000) return 24000;
309*8f5875f3SDavid du Colombier     if (freq <= 32000) return 32000;
310*8f5875f3SDavid du Colombier     if (freq <= 44100) return 44100;
311*8f5875f3SDavid du Colombier 
312*8f5875f3SDavid du Colombier     return 48000;
313*8f5875f3SDavid du Colombier }
314*8f5875f3SDavid du Colombier 
BitrateIndex(int bRate,int version,int samplerate)315*8f5875f3SDavid du Colombier int BitrateIndex(
316*8f5875f3SDavid du Colombier int bRate,        /* legal rates from 32 to 448 kbps */
317*8f5875f3SDavid du Colombier int version,      /* MPEG-1 or MPEG-2/2.5 LSF */
318*8f5875f3SDavid du Colombier int samplerate)   /* convert bitrate in kbps to index */
319*8f5875f3SDavid du Colombier {
320*8f5875f3SDavid du Colombier     int  i;
321*8f5875f3SDavid du Colombier 
322*8f5875f3SDavid du Colombier     for ( i = 0; i <= 14; i++)
323*8f5875f3SDavid du Colombier         if ( bitrate_table [version] [i] == bRate )
324*8f5875f3SDavid du Colombier             return i;
325*8f5875f3SDavid du Colombier 
326*8f5875f3SDavid du Colombier     return -1;
327*8f5875f3SDavid du Colombier }
328*8f5875f3SDavid du Colombier 
329*8f5875f3SDavid du Colombier /* convert samp freq in Hz to index */
330*8f5875f3SDavid du Colombier 
SmpFrqIndex(int sample_freq,int * const version)331*8f5875f3SDavid du Colombier int SmpFrqIndex ( int sample_freq, int* const version )
332*8f5875f3SDavid du Colombier {
333*8f5875f3SDavid du Colombier     switch ( sample_freq ) {
334*8f5875f3SDavid du Colombier     case 44100: *version = 1; return  0;
335*8f5875f3SDavid du Colombier     case 48000: *version = 1; return  1;
336*8f5875f3SDavid du Colombier     case 32000: *version = 1; return  2;
337*8f5875f3SDavid du Colombier     case 22050: *version = 0; return  0;
338*8f5875f3SDavid du Colombier     case 24000: *version = 0; return  1;
339*8f5875f3SDavid du Colombier     case 16000: *version = 0; return  2;
340*8f5875f3SDavid du Colombier     case 11025: *version = 0; return  0;
341*8f5875f3SDavid du Colombier     case 12000: *version = 0; return  1;
342*8f5875f3SDavid du Colombier     case  8000: *version = 0; return  2;
343*8f5875f3SDavid du Colombier     default:    *version = 0; return -1;
344*8f5875f3SDavid du Colombier     }
345*8f5875f3SDavid du Colombier }
346*8f5875f3SDavid du Colombier 
347*8f5875f3SDavid du Colombier 
348*8f5875f3SDavid du Colombier /*****************************************************************************
349*8f5875f3SDavid du Colombier *
350*8f5875f3SDavid du Colombier *  End of bit_stream.c package
351*8f5875f3SDavid du Colombier *
352*8f5875f3SDavid du Colombier *****************************************************************************/
353*8f5875f3SDavid du Colombier 
354*8f5875f3SDavid du Colombier /* reorder the three short blocks By Takehiro TOMINAGA */
355*8f5875f3SDavid du Colombier /*
356*8f5875f3SDavid du Colombier   Within each scalefactor band, data is given for successive
357*8f5875f3SDavid du Colombier   time windows, beginning with window 0 and ending with window 2.
358*8f5875f3SDavid du Colombier   Within each window, the quantized values are then arranged in
359*8f5875f3SDavid du Colombier   order of increasing frequency...
360*8f5875f3SDavid du Colombier */
freorder(int scalefac_band[],FLOAT8 ix_orig[576])361*8f5875f3SDavid du Colombier void freorder(int scalefac_band[],FLOAT8 ix_orig[576]) {
362*8f5875f3SDavid du Colombier   int i,sfb, window, j=0;
363*8f5875f3SDavid du Colombier   FLOAT8 ix[576];
364*8f5875f3SDavid du Colombier   for (sfb = 0; sfb < SBMAX_s; sfb++) {
365*8f5875f3SDavid du Colombier     int start = scalefac_band[sfb];
366*8f5875f3SDavid du Colombier     int end   = scalefac_band[sfb + 1];
367*8f5875f3SDavid du Colombier     for (window = 0; window < 3; window++) {
368*8f5875f3SDavid du Colombier       for (i = start; i < end; ++i) {
369*8f5875f3SDavid du Colombier 	ix[j++] = ix_orig[3*i+window];
370*8f5875f3SDavid du Colombier       }
371*8f5875f3SDavid du Colombier     }
372*8f5875f3SDavid du Colombier   }
373*8f5875f3SDavid du Colombier   memcpy(ix_orig,ix,576*sizeof(FLOAT8));
374*8f5875f3SDavid du Colombier }
375*8f5875f3SDavid du Colombier 
376*8f5875f3SDavid du Colombier 
377*8f5875f3SDavid du Colombier 
378*8f5875f3SDavid du Colombier 
379*8f5875f3SDavid du Colombier 
380*8f5875f3SDavid du Colombier 
381*8f5875f3SDavid du Colombier 
382*8f5875f3SDavid du Colombier #ifndef KLEMM_44
383*8f5875f3SDavid du Colombier 
384*8f5875f3SDavid du Colombier 
385*8f5875f3SDavid du Colombier /* resampling via FIR filter, blackman window */
blackman(FLOAT8 x,FLOAT8 fcn,int l)386*8f5875f3SDavid du Colombier inline static FLOAT8 blackman(FLOAT8 x,FLOAT8 fcn,int l)
387*8f5875f3SDavid du Colombier {
388*8f5875f3SDavid du Colombier   /* This algorithm from:
389*8f5875f3SDavid du Colombier SIGNAL PROCESSING ALGORITHMS IN FORTRAN AND C
390*8f5875f3SDavid du Colombier S.D. Stearns and R.A. David, Prentice-Hall, 1992
391*8f5875f3SDavid du Colombier   */
392*8f5875f3SDavid du Colombier   FLOAT8 bkwn,x2;
393*8f5875f3SDavid du Colombier   FLOAT8 wcn = (PI * fcn);
394*8f5875f3SDavid du Colombier 
395*8f5875f3SDavid du Colombier   x /= l;
396*8f5875f3SDavid du Colombier   if (x<0) x=0;
397*8f5875f3SDavid du Colombier   if (x>1) x=1;
398*8f5875f3SDavid du Colombier   x2 = x - .5;
399*8f5875f3SDavid du Colombier 
400*8f5875f3SDavid du Colombier   bkwn = 0.42 - 0.5*cos(2*x*PI)  + 0.08*cos(4*x*PI);
401*8f5875f3SDavid du Colombier   if (fabs(x2)<1e-9) return wcn/PI;
402*8f5875f3SDavid du Colombier   else
403*8f5875f3SDavid du Colombier     return  (  bkwn*sin(l*wcn*x2)  / (PI*l*x2)  );
404*8f5875f3SDavid du Colombier 
405*8f5875f3SDavid du Colombier 
406*8f5875f3SDavid du Colombier }
407*8f5875f3SDavid du Colombier 
408*8f5875f3SDavid du Colombier /* gcd - greatest common divisor */
409*8f5875f3SDavid du Colombier /* Joint work of Euclid and M. Hendry */
410*8f5875f3SDavid du Colombier 
gcd(int i,int j)411*8f5875f3SDavid du Colombier int gcd ( int i, int j )
412*8f5875f3SDavid du Colombier {
413*8f5875f3SDavid du Colombier //    assert ( i > 0  &&  j > 0 );
414*8f5875f3SDavid du Colombier     return j ? gcd(j, i % j) : i;
415*8f5875f3SDavid du Colombier }
416*8f5875f3SDavid du Colombier 
417*8f5875f3SDavid du Colombier 
418*8f5875f3SDavid du Colombier 
419*8f5875f3SDavid du Colombier /* copy in new samples from in_buffer into mfbuf, with resampling & scaling
420*8f5875f3SDavid du Colombier    if necessary.  n_in = number of samples from the input buffer that
421*8f5875f3SDavid du Colombier    were used.  n_out = number of samples copied into mfbuf  */
422*8f5875f3SDavid du Colombier 
fill_buffer(lame_global_flags * gfp,sample_t * mfbuf[2],sample_t * in_buffer[2],int nsamples,int * n_in,int * n_out)423*8f5875f3SDavid du Colombier void fill_buffer(lame_global_flags *gfp,
424*8f5875f3SDavid du Colombier 		 sample_t *mfbuf[2],
425*8f5875f3SDavid du Colombier 		 sample_t *in_buffer[2],
426*8f5875f3SDavid du Colombier 		 int nsamples, int *n_in, int *n_out)
427*8f5875f3SDavid du Colombier {
428*8f5875f3SDavid du Colombier     lame_internal_flags *gfc = gfp->internal_flags;
429*8f5875f3SDavid du Colombier     int ch,i;
430*8f5875f3SDavid du Colombier 
431*8f5875f3SDavid du Colombier     /* copy in new samples into mfbuf, with resampling if necessary */
432*8f5875f3SDavid du Colombier     if (gfc->resample_ratio != 1.0) {
433*8f5875f3SDavid du Colombier 	for (ch = 0; ch < gfc->channels_out; ch++) {
434*8f5875f3SDavid du Colombier 	    *n_out =
435*8f5875f3SDavid du Colombier 		fill_buffer_resample(gfp, &mfbuf[ch][gfc->mf_size],
436*8f5875f3SDavid du Colombier 				     gfp->framesize, in_buffer[ch],
437*8f5875f3SDavid du Colombier 				     nsamples, n_in, ch);
438*8f5875f3SDavid du Colombier 	}
439*8f5875f3SDavid du Colombier     }
440*8f5875f3SDavid du Colombier     else {
441*8f5875f3SDavid du Colombier 	*n_out = Min(gfp->framesize, nsamples);
442*8f5875f3SDavid du Colombier 	*n_in = *n_out;
443*8f5875f3SDavid du Colombier 	for (i = 0; i < *n_out; ++i) {
444*8f5875f3SDavid du Colombier 	    mfbuf[0][gfc->mf_size + i] = in_buffer[0][i];
445*8f5875f3SDavid du Colombier 	    if (gfc->channels_out == 2)
446*8f5875f3SDavid du Colombier 		mfbuf[1][gfc->mf_size + i] = in_buffer[1][i];
447*8f5875f3SDavid du Colombier 	}
448*8f5875f3SDavid du Colombier     }
449*8f5875f3SDavid du Colombier 
450*8f5875f3SDavid du Colombier     /* user selected scaling of the samples */
451*8f5875f3SDavid du Colombier     if (gfp->scale != 0) {
452*8f5875f3SDavid du Colombier 	for (i=0 ; i<*n_out; ++i) {
453*8f5875f3SDavid du Colombier 	    mfbuf[0][gfc->mf_size+i] *= gfp->scale;
454*8f5875f3SDavid du Colombier 	    if (gfc->channels_out == 2)
455*8f5875f3SDavid du Colombier 		mfbuf[1][gfc->mf_size + i] *= gfp->scale;
456*8f5875f3SDavid du Colombier 	}
457*8f5875f3SDavid du Colombier     }
458*8f5875f3SDavid du Colombier 
459*8f5875f3SDavid du Colombier }
460*8f5875f3SDavid du Colombier 
461*8f5875f3SDavid du Colombier 
462*8f5875f3SDavid du Colombier 
463*8f5875f3SDavid du Colombier 
fill_buffer_resample(lame_global_flags * gfp,sample_t * outbuf,int desired_len,sample_t * inbuf,int len,int * num_used,int ch)464*8f5875f3SDavid du Colombier int fill_buffer_resample(
465*8f5875f3SDavid du Colombier        lame_global_flags *gfp,
466*8f5875f3SDavid du Colombier        sample_t *outbuf,
467*8f5875f3SDavid du Colombier        int desired_len,
468*8f5875f3SDavid du Colombier        sample_t *inbuf,
469*8f5875f3SDavid du Colombier        int len,
470*8f5875f3SDavid du Colombier        int *num_used,
471*8f5875f3SDavid du Colombier        int ch)
472*8f5875f3SDavid du Colombier {
473*8f5875f3SDavid du Colombier 
474*8f5875f3SDavid du Colombier 
475*8f5875f3SDavid du Colombier   lame_internal_flags *gfc=gfp->internal_flags;
476*8f5875f3SDavid du Colombier   int BLACKSIZE;
477*8f5875f3SDavid du Colombier   FLOAT8 offset,xvalue;
478*8f5875f3SDavid du Colombier   int i,j=0,k;
479*8f5875f3SDavid du Colombier   int filter_l;
480*8f5875f3SDavid du Colombier   FLOAT8 fcn,intratio;
481*8f5875f3SDavid du Colombier   FLOAT *inbuf_old;
482*8f5875f3SDavid du Colombier   int bpc;   /* number of convolution functions to pre-compute */
483*8f5875f3SDavid du Colombier   bpc = gfp->out_samplerate/gcd(gfp->out_samplerate,gfp->in_samplerate);
484*8f5875f3SDavid du Colombier   if (bpc>BPC) bpc = BPC;
485*8f5875f3SDavid du Colombier 
486*8f5875f3SDavid du Colombier   intratio=( fabs(gfc->resample_ratio - floor(.5+gfc->resample_ratio)) < .0001 );
487*8f5875f3SDavid du Colombier   fcn = 1.00/gfc->resample_ratio;
488*8f5875f3SDavid du Colombier   if (fcn>1.00) fcn=1.00;
489*8f5875f3SDavid du Colombier   filter_l = gfp->quality < 7 ? 31 : 7;
490*8f5875f3SDavid du Colombier   filter_l = 31;
491*8f5875f3SDavid du Colombier   if (0==filter_l % 2 ) --filter_l;/* must be odd */
492*8f5875f3SDavid du Colombier   filter_l += intratio;            /* unless resample_ratio=int, it must be even */
493*8f5875f3SDavid du Colombier 
494*8f5875f3SDavid du Colombier 
495*8f5875f3SDavid du Colombier   BLACKSIZE = filter_l+1;  /* size of data needed for FIR */
496*8f5875f3SDavid du Colombier 
497*8f5875f3SDavid du Colombier   if ( gfc->fill_buffer_resample_init == 0 ) {
498*8f5875f3SDavid du Colombier     gfc->inbuf_old[0]=calloc(BLACKSIZE,sizeof(gfc->inbuf_old[0][0]));
499*8f5875f3SDavid du Colombier     gfc->inbuf_old[1]=calloc(BLACKSIZE,sizeof(gfc->inbuf_old[0][0]));
500*8f5875f3SDavid du Colombier     for (i=0; i<=2*bpc; ++i)
501*8f5875f3SDavid du Colombier       gfc->blackfilt[i]=calloc(BLACKSIZE,sizeof(gfc->blackfilt[0][0]));
502*8f5875f3SDavid du Colombier 
503*8f5875f3SDavid du Colombier     gfc->itime[0]=0;
504*8f5875f3SDavid du Colombier     gfc->itime[1]=0;
505*8f5875f3SDavid du Colombier 
506*8f5875f3SDavid du Colombier     /* precompute blackman filter coefficients */
507*8f5875f3SDavid du Colombier     for ( j = 0; j <= 2*bpc; j++ ) {
508*8f5875f3SDavid du Colombier         FLOAT8 sum = 0.;
509*8f5875f3SDavid du Colombier         offset = (j-bpc) / (2.*bpc);
510*8f5875f3SDavid du Colombier         for ( i = 0; i <= filter_l; i++ )
511*8f5875f3SDavid du Colombier             sum +=
512*8f5875f3SDavid du Colombier 	    gfc->blackfilt[j][i]  = blackman(i-offset,fcn,filter_l);
513*8f5875f3SDavid du Colombier 	for ( i = 0; i <= filter_l; i++ )
514*8f5875f3SDavid du Colombier 	  gfc->blackfilt[j][i] /= sum;
515*8f5875f3SDavid du Colombier     }
516*8f5875f3SDavid du Colombier     gfc->fill_buffer_resample_init = 1;
517*8f5875f3SDavid du Colombier   }
518*8f5875f3SDavid du Colombier 
519*8f5875f3SDavid du Colombier   inbuf_old=gfc->inbuf_old[ch];
520*8f5875f3SDavid du Colombier 
521*8f5875f3SDavid du Colombier   /* time of j'th element in inbuf = itime + j/ifreq; */
522*8f5875f3SDavid du Colombier   /* time of k'th element in outbuf   =  j/ofreq */
523*8f5875f3SDavid du Colombier   for (k=0;k<desired_len;k++) {
524*8f5875f3SDavid du Colombier     FLOAT time0;
525*8f5875f3SDavid du Colombier     int joff;
526*8f5875f3SDavid du Colombier 
527*8f5875f3SDavid du Colombier     time0 = k*gfc->resample_ratio;       /* time of k'th output sample */
528*8f5875f3SDavid du Colombier     j = floor( time0 -gfc->itime[ch]  );
529*8f5875f3SDavid du Colombier 
530*8f5875f3SDavid du Colombier     /* check if we need more input data */
531*8f5875f3SDavid du Colombier     if ((filter_l + j - filter_l/2) >= len) break;
532*8f5875f3SDavid du Colombier 
533*8f5875f3SDavid du Colombier     /* blackman filter.  by default, window centered at j+.5(filter_l%2) */
534*8f5875f3SDavid du Colombier     /* but we want a window centered at time0.   */
535*8f5875f3SDavid du Colombier     offset = ( time0 -gfc->itime[ch] - (j + .5*(filter_l%2)));
536*8f5875f3SDavid du Colombier     assert(fabs(offset)<=.500001);
537*8f5875f3SDavid du Colombier 
538*8f5875f3SDavid du Colombier     /* find the closest precomputed window for this offset: */
539*8f5875f3SDavid du Colombier     joff = floor((offset*2*bpc) + bpc +.5);
540*8f5875f3SDavid du Colombier 
541*8f5875f3SDavid du Colombier     xvalue = 0.;
542*8f5875f3SDavid du Colombier     for (i=0 ; i<=filter_l ; ++i) {
543*8f5875f3SDavid du Colombier       int j2 = i+j-filter_l/2;
544*8f5875f3SDavid du Colombier       int y;
545*8f5875f3SDavid du Colombier       assert(j2<len);
546*8f5875f3SDavid du Colombier       assert(j2+BLACKSIZE >= 0);
547*8f5875f3SDavid du Colombier       y = (j2<0) ? inbuf_old[BLACKSIZE+j2] : inbuf[j2];
548*8f5875f3SDavid du Colombier #define PRECOMPUTE
549*8f5875f3SDavid du Colombier #ifdef PRECOMPUTE
550*8f5875f3SDavid du Colombier       xvalue += y*gfc->blackfilt[joff][i];
551*8f5875f3SDavid du Colombier #else
552*8f5875f3SDavid du Colombier       xvalue += y*blackman(i-offset,fcn,filter_l);  /* very slow! */
553*8f5875f3SDavid du Colombier #endif
554*8f5875f3SDavid du Colombier     }
555*8f5875f3SDavid du Colombier     outbuf[k]=xvalue;
556*8f5875f3SDavid du Colombier   }
557*8f5875f3SDavid du Colombier 
558*8f5875f3SDavid du Colombier 
559*8f5875f3SDavid du Colombier   /* k = number of samples added to outbuf */
560*8f5875f3SDavid du Colombier   /* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2]  */
561*8f5875f3SDavid du Colombier 
562*8f5875f3SDavid du Colombier   /* how many samples of input data were used:  */
563*8f5875f3SDavid du Colombier   *num_used = Min(len,filter_l+j-filter_l/2);
564*8f5875f3SDavid du Colombier 
565*8f5875f3SDavid du Colombier   /* adjust our input time counter.  Incriment by the number of samples used,
566*8f5875f3SDavid du Colombier    * then normalize so that next output sample is at time 0, next
567*8f5875f3SDavid du Colombier    * input buffer is at time itime[ch] */
568*8f5875f3SDavid du Colombier   gfc->itime[ch] += *num_used - k*gfc->resample_ratio;
569*8f5875f3SDavid du Colombier 
570*8f5875f3SDavid du Colombier   /* save the last BLACKSIZE samples into the inbuf_old buffer */
571*8f5875f3SDavid du Colombier   if (*num_used >= BLACKSIZE) {
572*8f5875f3SDavid du Colombier       for (i=0;i<BLACKSIZE;i++)
573*8f5875f3SDavid du Colombier 	  inbuf_old[i]=inbuf[*num_used + i -BLACKSIZE];
574*8f5875f3SDavid du Colombier   }else{
575*8f5875f3SDavid du Colombier       /* shift in *num_used samples into inbuf_old  */
576*8f5875f3SDavid du Colombier        int n_shift = BLACKSIZE-*num_used;  /* number of samples to shift */
577*8f5875f3SDavid du Colombier 
578*8f5875f3SDavid du Colombier        /* shift n_shift samples by *num_used, to make room for the
579*8f5875f3SDavid du Colombier 	* num_used new samples */
580*8f5875f3SDavid du Colombier        for (i=0; i<n_shift; ++i )
581*8f5875f3SDavid du Colombier 	   inbuf_old[i] = inbuf_old[i+ *num_used];
582*8f5875f3SDavid du Colombier 
583*8f5875f3SDavid du Colombier        /* shift in the *num_used samples */
584*8f5875f3SDavid du Colombier        for (j=0; i<BLACKSIZE; ++i, ++j )
585*8f5875f3SDavid du Colombier 	   inbuf_old[i] = inbuf[j];
586*8f5875f3SDavid du Colombier 
587*8f5875f3SDavid du Colombier        assert(j==*num_used);
588*8f5875f3SDavid du Colombier   }
589*8f5875f3SDavid du Colombier   return k;  /* return the number samples created at the new samplerate */
590*8f5875f3SDavid du Colombier }
591*8f5875f3SDavid du Colombier 
592*8f5875f3SDavid du Colombier 
593*8f5875f3SDavid du Colombier #endif /* ndef KLEMM_44 */
594*8f5875f3SDavid du Colombier 
595*8f5875f3SDavid du Colombier 
596*8f5875f3SDavid du Colombier 
597*8f5875f3SDavid du Colombier /***********************************************************************
598*8f5875f3SDavid du Colombier *
599*8f5875f3SDavid du Colombier *  Message Output
600*8f5875f3SDavid du Colombier *
601*8f5875f3SDavid du Colombier ***********************************************************************/
lame_debugf(const lame_internal_flags * gfc,const char * format,...)602*8f5875f3SDavid du Colombier void  lame_debugf (const lame_internal_flags *gfc, const char* format, ... )
603*8f5875f3SDavid du Colombier {
604*8f5875f3SDavid du Colombier     va_list  args;
605*8f5875f3SDavid du Colombier 
606*8f5875f3SDavid du Colombier     va_start ( args, format );
607*8f5875f3SDavid du Colombier 
608*8f5875f3SDavid du Colombier     if ( gfc->report.debugf != NULL ) {
609*8f5875f3SDavid du Colombier         gfc->report.debugf( format, args );
610*8f5875f3SDavid du Colombier     } else {
611*8f5875f3SDavid du Colombier         (void) vfprintf ( stderr, format, args );
612*8f5875f3SDavid du Colombier         fflush ( stderr );      /* an debug function should flush immediately */
613*8f5875f3SDavid du Colombier     }
614*8f5875f3SDavid du Colombier 
615*8f5875f3SDavid du Colombier     va_end   ( args );
616*8f5875f3SDavid du Colombier }
617*8f5875f3SDavid du Colombier 
618*8f5875f3SDavid du Colombier 
lame_msgf(const lame_internal_flags * gfc,const char * format,...)619*8f5875f3SDavid du Colombier void  lame_msgf (const lame_internal_flags *gfc, const char* format, ... )
620*8f5875f3SDavid du Colombier {
621*8f5875f3SDavid du Colombier     va_list  args;
622*8f5875f3SDavid du Colombier 
623*8f5875f3SDavid du Colombier     va_start ( args, format );
624*8f5875f3SDavid du Colombier 
625*8f5875f3SDavid du Colombier     if ( gfc->report.msgf != NULL ) {
626*8f5875f3SDavid du Colombier         gfc->report.msgf( format, args );
627*8f5875f3SDavid du Colombier     } else {
628*8f5875f3SDavid du Colombier         (void) vfprintf ( stderr, format, args );
629*8f5875f3SDavid du Colombier         fflush ( stderr );     /* we print to stderr, so me may want to flush */
630*8f5875f3SDavid du Colombier     }
631*8f5875f3SDavid du Colombier 
632*8f5875f3SDavid du Colombier     va_end   ( args );
633*8f5875f3SDavid du Colombier }
634*8f5875f3SDavid du Colombier 
635*8f5875f3SDavid du Colombier 
lame_errorf(const lame_internal_flags * gfc,const char * format,...)636*8f5875f3SDavid du Colombier void  lame_errorf (const lame_internal_flags *gfc, const char* format, ... )
637*8f5875f3SDavid du Colombier {
638*8f5875f3SDavid du Colombier     va_list  args;
639*8f5875f3SDavid du Colombier 
640*8f5875f3SDavid du Colombier     va_start ( args, format );
641*8f5875f3SDavid du Colombier 
642*8f5875f3SDavid du Colombier     if ( gfc->report.errorf != NULL ) {
643*8f5875f3SDavid du Colombier         gfc->report.errorf( format, args );
644*8f5875f3SDavid du Colombier     } else {
645*8f5875f3SDavid du Colombier         (void) vfprintf ( stderr, format, args );
646*8f5875f3SDavid du Colombier         fflush   ( stderr );    /* an error function should flush immediately */
647*8f5875f3SDavid du Colombier     }
648*8f5875f3SDavid du Colombier 
649*8f5875f3SDavid du Colombier     va_end   ( args );
650*8f5875f3SDavid du Colombier }
651*8f5875f3SDavid du Colombier 
652*8f5875f3SDavid du Colombier 
653*8f5875f3SDavid du Colombier 
654*8f5875f3SDavid du Colombier /***********************************************************************
655*8f5875f3SDavid du Colombier  *
656*8f5875f3SDavid du Colombier  *      routines to detect CPU specific features like 3DNow, MMX, SIMD
657*8f5875f3SDavid du Colombier  *
658*8f5875f3SDavid du Colombier  *  donated by Frank Klemm
659*8f5875f3SDavid du Colombier  *  added Robert Hegemann 2000-10-10
660*8f5875f3SDavid du Colombier  *
661*8f5875f3SDavid du Colombier  ***********************************************************************/
662*8f5875f3SDavid du Colombier 
has_i387(void)663*8f5875f3SDavid du Colombier int  has_i387 ( void )
664*8f5875f3SDavid du Colombier {
665*8f5875f3SDavid du Colombier #ifdef HAVE_NASM
666*8f5875f3SDavid du Colombier     return 1;
667*8f5875f3SDavid du Colombier #else
668*8f5875f3SDavid du Colombier     return 0;   /* don't know, assume not */
669*8f5875f3SDavid du Colombier #endif
670*8f5875f3SDavid du Colombier }
671*8f5875f3SDavid du Colombier 
has_MMX(void)672*8f5875f3SDavid du Colombier int  has_MMX ( void )
673*8f5875f3SDavid du Colombier {
674*8f5875f3SDavid du Colombier #ifdef HAVE_NASM
675*8f5875f3SDavid du Colombier     extern int has_MMX_nasm ( void );
676*8f5875f3SDavid du Colombier     return has_MMX_nasm ();
677*8f5875f3SDavid du Colombier #else
678*8f5875f3SDavid du Colombier     return 0;   /* don't know, assume not */
679*8f5875f3SDavid du Colombier #endif
680*8f5875f3SDavid du Colombier }
681*8f5875f3SDavid du Colombier 
has_3DNow(void)682*8f5875f3SDavid du Colombier int  has_3DNow ( void )
683*8f5875f3SDavid du Colombier {
684*8f5875f3SDavid du Colombier #ifdef HAVE_NASM
685*8f5875f3SDavid du Colombier     extern int has_3DNow_nasm ( void );
686*8f5875f3SDavid du Colombier     return has_3DNow_nasm ();
687*8f5875f3SDavid du Colombier #else
688*8f5875f3SDavid du Colombier     return 0;   /* don't know, assume not */
689*8f5875f3SDavid du Colombier #endif
690*8f5875f3SDavid du Colombier }
691*8f5875f3SDavid du Colombier 
has_SIMD(void)692*8f5875f3SDavid du Colombier int  has_SIMD ( void )
693*8f5875f3SDavid du Colombier {
694*8f5875f3SDavid du Colombier #ifdef HAVE_NASM
695*8f5875f3SDavid du Colombier     extern int has_SIMD_nasm ( void );
696*8f5875f3SDavid du Colombier     return has_SIMD_nasm ();
697*8f5875f3SDavid du Colombier #else
698*8f5875f3SDavid du Colombier     return 0;   /* don't know, assume not */
699*8f5875f3SDavid du Colombier #endif
700*8f5875f3SDavid du Colombier }
701*8f5875f3SDavid du Colombier 
has_SIMD2(void)702*8f5875f3SDavid du Colombier int  has_SIMD2 ( void )
703*8f5875f3SDavid du Colombier {
704*8f5875f3SDavid du Colombier #ifdef HAVE_NASM
705*8f5875f3SDavid du Colombier     extern int has_SIMD2_nasm ( void );
706*8f5875f3SDavid du Colombier     return has_SIMD2_nasm ();
707*8f5875f3SDavid du Colombier #else
708*8f5875f3SDavid du Colombier     return 0;   /* don't know, assume not */
709*8f5875f3SDavid du Colombier #endif
710*8f5875f3SDavid du Colombier }
711*8f5875f3SDavid du Colombier 
712*8f5875f3SDavid du Colombier /***********************************************************************
713*8f5875f3SDavid du Colombier  *
714*8f5875f3SDavid du Colombier  *  some simple statistics
715*8f5875f3SDavid du Colombier  *
716*8f5875f3SDavid du Colombier  *  bitrate index 0: free bitrate -> not allowed in VBR mode
717*8f5875f3SDavid du Colombier  *  : bitrates, kbps depending on MPEG version
718*8f5875f3SDavid du Colombier  *  bitrate index 15: forbidden
719*8f5875f3SDavid du Colombier  *
720*8f5875f3SDavid du Colombier  *  mode_ext:
721*8f5875f3SDavid du Colombier  *  0:  LR
722*8f5875f3SDavid du Colombier  *  1:  LR-i
723*8f5875f3SDavid du Colombier  *  2:  MS
724*8f5875f3SDavid du Colombier  *  3:  MS-i
725*8f5875f3SDavid du Colombier  *
726*8f5875f3SDavid du Colombier  ***********************************************************************/
727*8f5875f3SDavid du Colombier 
updateStats(lame_internal_flags * const gfc)728*8f5875f3SDavid du Colombier void updateStats( lame_internal_flags * const gfc )
729*8f5875f3SDavid du Colombier {
730*8f5875f3SDavid du Colombier     assert ( gfc->bitrate_index < 16u );
731*8f5875f3SDavid du Colombier     assert ( gfc->mode_ext      <  4u );
732*8f5875f3SDavid du Colombier 
733*8f5875f3SDavid du Colombier     /* count bitrate indices */
734*8f5875f3SDavid du Colombier     gfc->bitrate_stereoMode_Hist [gfc->bitrate_index] [4] ++;
735*8f5875f3SDavid du Colombier 
736*8f5875f3SDavid du Colombier     /* count 'em for every mode extension in case of 2 channel encoding */
737*8f5875f3SDavid du Colombier     if (gfc->channels_out == 2)
738*8f5875f3SDavid du Colombier         gfc->bitrate_stereoMode_Hist [gfc->bitrate_index] [gfc->mode_ext]++;
739*8f5875f3SDavid du Colombier }
740*8f5875f3SDavid du Colombier 
741*8f5875f3SDavid du Colombier 
742*8f5875f3SDavid du Colombier 
743*8f5875f3SDavid du Colombier /*  caution: a[] will be resorted!!
744*8f5875f3SDavid du Colombier  */
select_kth_int(int a[],int N,int k)745*8f5875f3SDavid du Colombier int select_kth_int(int a[], int N, int k)
746*8f5875f3SDavid du Colombier {
747*8f5875f3SDavid du Colombier     int i, j, l, r, v, w;
748*8f5875f3SDavid du Colombier 
749*8f5875f3SDavid du Colombier     l = 0;
750*8f5875f3SDavid du Colombier     r = N-1;
751*8f5875f3SDavid du Colombier     while (r > l) {
752*8f5875f3SDavid du Colombier         v = a[r];
753*8f5875f3SDavid du Colombier         i = l-1;
754*8f5875f3SDavid du Colombier         j = r;
755*8f5875f3SDavid du Colombier         for (;;) {
756*8f5875f3SDavid du Colombier             while (a[++i] < v) /*empty*/;
757*8f5875f3SDavid du Colombier             while (a[--j] > v) /*empty*/;
758*8f5875f3SDavid du Colombier             if (i >= j)
759*8f5875f3SDavid du Colombier                 break;
760*8f5875f3SDavid du Colombier             /* swap i and j */
761*8f5875f3SDavid du Colombier             w = a[i];
762*8f5875f3SDavid du Colombier             a[i] = a[j];
763*8f5875f3SDavid du Colombier             a[j] = w;
764*8f5875f3SDavid du Colombier         }
765*8f5875f3SDavid du Colombier         /* swap i and r */
766*8f5875f3SDavid du Colombier         w = a[i];
767*8f5875f3SDavid du Colombier         a[i] = a[r];
768*8f5875f3SDavid du Colombier         a[r] = w;
769*8f5875f3SDavid du Colombier         if (i >= k)
770*8f5875f3SDavid du Colombier             r = i-1;
771*8f5875f3SDavid du Colombier         if (i <= k)
772*8f5875f3SDavid du Colombier             l = i+1;
773*8f5875f3SDavid du Colombier     }
774*8f5875f3SDavid du Colombier     return a[k];
775*8f5875f3SDavid du Colombier }
776*8f5875f3SDavid du Colombier 
777*8f5875f3SDavid du Colombier 
778*8f5875f3SDavid du Colombier 
disable_FPE(void)779*8f5875f3SDavid du Colombier void disable_FPE(void) {
780*8f5875f3SDavid du Colombier /* extremly system dependent stuff, move to a lib to make the code readable */
781*8f5875f3SDavid du Colombier /*==========================================================================*/
782*8f5875f3SDavid du Colombier 
783*8f5875f3SDavid du Colombier     /*
784*8f5875f3SDavid du Colombier      *  Disable floating point exceptions
785*8f5875f3SDavid du Colombier      */
786*8f5875f3SDavid du Colombier #if defined(__FreeBSD__) && !defined(__alpha__)
787*8f5875f3SDavid du Colombier     {
788*8f5875f3SDavid du Colombier         /* seet floating point mask to the Linux default */
789*8f5875f3SDavid du Colombier         fp_except_t mask;
790*8f5875f3SDavid du Colombier         mask = fpgetmask();
791*8f5875f3SDavid du Colombier         /* if bit is set, we get SIGFPE on that error! */
792*8f5875f3SDavid du Colombier         fpsetmask(mask & ~(FP_X_INV | FP_X_DZ));
793*8f5875f3SDavid du Colombier         /*  DEBUGF("FreeBSD mask is 0x%x\n",mask); */
794*8f5875f3SDavid du Colombier     }
795*8f5875f3SDavid du Colombier #endif
796*8f5875f3SDavid du Colombier 
797*8f5875f3SDavid du Colombier #if defined(__riscos__) && !defined(ABORTFP)
798*8f5875f3SDavid du Colombier     /* Disable FPE's under RISC OS */
799*8f5875f3SDavid du Colombier     /* if bit is set, we disable trapping that error! */
800*8f5875f3SDavid du Colombier     /*   _FPE_IVO : invalid operation */
801*8f5875f3SDavid du Colombier     /*   _FPE_DVZ : divide by zero */
802*8f5875f3SDavid du Colombier     /*   _FPE_OFL : overflow */
803*8f5875f3SDavid du Colombier     /*   _FPE_UFL : underflow */
804*8f5875f3SDavid du Colombier     /*   _FPE_INX : inexact */
805*8f5875f3SDavid du Colombier     DisableFPETraps(_FPE_IVO | _FPE_DVZ | _FPE_OFL);
806*8f5875f3SDavid du Colombier #endif
807*8f5875f3SDavid du Colombier 
808*8f5875f3SDavid du Colombier     /*
809*8f5875f3SDavid du Colombier      *  Debugging stuff
810*8f5875f3SDavid du Colombier      *  The default is to ignore FPE's, unless compiled with -DABORTFP
811*8f5875f3SDavid du Colombier      *  so add code below to ENABLE FPE's.
812*8f5875f3SDavid du Colombier      */
813*8f5875f3SDavid du Colombier 
814*8f5875f3SDavid du Colombier #if defined(ABORTFP)
815*8f5875f3SDavid du Colombier #if defined(_MSC_VER)
816*8f5875f3SDavid du Colombier     {
817*8f5875f3SDavid du Colombier #include <float.h>
818*8f5875f3SDavid du Colombier         unsigned int mask;
819*8f5875f3SDavid du Colombier         mask = _controlfp(0, 0);
820*8f5875f3SDavid du Colombier         mask &= ~(_EM_OVERFLOW | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_INVALID);
821*8f5875f3SDavid du Colombier         mask = _controlfp(mask, _MCW_EM);
822*8f5875f3SDavid du Colombier     }
823*8f5875f3SDavid du Colombier #elif defined(__CYGWIN__)
824*8f5875f3SDavid du Colombier #  define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
825*8f5875f3SDavid du Colombier #  define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
826*8f5875f3SDavid du Colombier 
827*8f5875f3SDavid du Colombier #  define _EM_INEXACT     0x00000020 /* inexact (precision) */
828*8f5875f3SDavid du Colombier #  define _EM_UNDERFLOW   0x00000010 /* underflow */
829*8f5875f3SDavid du Colombier #  define _EM_OVERFLOW    0x00000008 /* overflow */
830*8f5875f3SDavid du Colombier #  define _EM_ZERODIVIDE  0x00000004 /* zero divide */
831*8f5875f3SDavid du Colombier #  define _EM_INVALID     0x00000001 /* invalid */
832*8f5875f3SDavid du Colombier     {
833*8f5875f3SDavid du Colombier         unsigned int mask;
834*8f5875f3SDavid du Colombier         _FPU_GETCW(mask);
835*8f5875f3SDavid du Colombier         /* Set the FPU control word to abort on most FPEs */
836*8f5875f3SDavid du Colombier         mask &= ~(_EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID);
837*8f5875f3SDavid du Colombier         _FPU_SETCW(mask);
838*8f5875f3SDavid du Colombier     }
839*8f5875f3SDavid du Colombier # elif defined(__linux__)
840*8f5875f3SDavid du Colombier     {
841*8f5875f3SDavid du Colombier 
842*8f5875f3SDavid du Colombier #  include <fpu_control.h>
843*8f5875f3SDavid du Colombier #  ifndef _FPU_GETCW
844*8f5875f3SDavid du Colombier #  define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
845*8f5875f3SDavid du Colombier #  endif
846*8f5875f3SDavid du Colombier #  ifndef _FPU_SETCW
847*8f5875f3SDavid du Colombier #  define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
848*8f5875f3SDavid du Colombier #  endif
849*8f5875f3SDavid du Colombier 
850*8f5875f3SDavid du Colombier         /*
851*8f5875f3SDavid du Colombier          * Set the Linux mask to abort on most FPE's
852*8f5875f3SDavid du Colombier          * if bit is set, we _mask_ SIGFPE on that error!
853*8f5875f3SDavid du Colombier          *  mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM );
854*8f5875f3SDavid du Colombier          */
855*8f5875f3SDavid du Colombier 
856*8f5875f3SDavid du Colombier         unsigned int mask;
857*8f5875f3SDavid du Colombier         _FPU_GETCW(mask);
858*8f5875f3SDavid du Colombier         mask &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
859*8f5875f3SDavid du Colombier         _FPU_SETCW(mask);
860*8f5875f3SDavid du Colombier     }
861*8f5875f3SDavid du Colombier #endif
862*8f5875f3SDavid du Colombier #endif /* ABORTFP */
863*8f5875f3SDavid du Colombier }
864*8f5875f3SDavid du Colombier 
865*8f5875f3SDavid du Colombier 
866*8f5875f3SDavid du Colombier /* end of util.c */
867