initial revision
authorkramm <kramm>
Sun, 28 Apr 2002 17:30:17 +0000 (17:30 +0000)
committerkramm <kramm>
Sun, 28 Apr 2002 17:30:17 +0000 (17:30 +0000)
39 files changed:
lib/lame/VbrTag.c [new file with mode: 0644]
lib/lame/VbrTag.h [new file with mode: 0644]
lib/lame/bitstream.c [new file with mode: 0644]
lib/lame/bitstream.h [new file with mode: 0644]
lib/lame/config_static.h [new file with mode: 0644]
lib/lame/encoder.c [new file with mode: 0644]
lib/lame/encoder.h [new file with mode: 0644]
lib/lame/fft.c [new file with mode: 0644]
lib/lame/fft.h [new file with mode: 0644]
lib/lame/id3tag.c [new file with mode: 0644]
lib/lame/id3tag.h [new file with mode: 0644]
lib/lame/l3side.h [new file with mode: 0644]
lib/lame/lame-analysis.h [new file with mode: 0644]
lib/lame/lame.c [new file with mode: 0644]
lib/lame/lame.h [new file with mode: 0644]
lib/lame/lame_global_flags.h [new file with mode: 0644]
lib/lame/lameerror.h [new file with mode: 0644]
lib/lame/machine.h [new file with mode: 0644]
lib/lame/newmdct.c [new file with mode: 0644]
lib/lame/newmdct.h [new file with mode: 0644]
lib/lame/psymodel.c [new file with mode: 0644]
lib/lame/psymodel.h [new file with mode: 0644]
lib/lame/quantize.c [new file with mode: 0644]
lib/lame/quantize.h [new file with mode: 0644]
lib/lame/quantize_pvt.c [new file with mode: 0644]
lib/lame/quantize_pvt.h [new file with mode: 0644]
lib/lame/reservoir.c [new file with mode: 0644]
lib/lame/reservoir.h [new file with mode: 0644]
lib/lame/set_get.c [new file with mode: 0644]
lib/lame/tables.c [new file with mode: 0644]
lib/lame/tables.h [new file with mode: 0644]
lib/lame/takehiro.c [new file with mode: 0644]
lib/lame/tools.h [new file with mode: 0644]
lib/lame/util.c [new file with mode: 0644]
lib/lame/util.h [new file with mode: 0644]
lib/lame/vbrquantize.c [new file with mode: 0644]
lib/lame/vbrquantize.h [new file with mode: 0644]
lib/lame/version.c [new file with mode: 0644]
lib/lame/version.h [new file with mode: 0644]

diff --git a/lib/lame/VbrTag.c b/lib/lame/VbrTag.c
new file mode 100644 (file)
index 0000000..c5ca217
--- /dev/null
@@ -0,0 +1,944 @@
+/*
+ *     Xing VBR tagging for LAME.
+ *
+ *     Copyright (c) 1999 A.L. Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: VbrTag.c,v 1.1 2002/04/28 17:30:17 kramm Exp $ */
+
+#include "config_static.h"
+
+#include "machine.h"
+#if defined(__riscos__) && defined(FPA10)
+#include       "ymath.h"
+#else 
+#include       <math.h>
+#endif
+
+
+#include "bitstream.h"
+#include "lame.h"
+#include "VbrTag.h"
+#include "version.h"
+
+#include       <assert.h>
+#include       <stdlib.h>
+#include       <string.h>
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#ifdef _DEBUG
+/*  #define DEBUG_VBRTAG */
+#endif
+
+/*
+//    4 bytes for Header Tag
+//    4 bytes for Header Flags
+//  100 bytes for entry (NUMTOCENTRIES)
+//    4 bytes for FRAME SIZE
+//    4 bytes for STREAM_SIZE
+//    4 bytes for VBR SCALE. a VBR quality indicator: 0=best 100=worst
+//   20 bytes for LAME tag.  for example, "LAME3.12 (beta 6)"
+// ___________
+//  140 bytes
+*/
+#define VBRHEADERSIZE (NUMTOCENTRIES+4+4+4+4+4)
+
+#define LAMEHEADERSIZE (VBRHEADERSIZE + 9 + 1 + 1 + 8 + 1 + 1 + 3 + 1 + 1 + 2 + 4 + 2 + 2)
+
+/* the size of the Xing header (MPEG1 and MPEG2) in kbps */
+#define XING_BITRATE1 128
+#define XING_BITRATE2  64
+#define XING_BITRATE25 32
+
+
+
+const static char      VBRTag[]={"Xing"};
+const static char      VBRTag2[]={"Info"};
+
+
+
+
+/* Lookup table for fast CRC computation
+ * See 'CRC_update_lookup'
+ * Uses the polynomial x^16+x^15+x^2+1 */
+
+unsigned int crc16_lookup[256] =
+{
+       0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+       0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+       0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 
+       0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+       0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 
+       0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 
+       0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+       0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+       0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+       0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 
+       0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 
+       0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+       0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 
+       0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+       0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 
+       0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+       0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 
+       0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 
+       0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+       0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 
+       0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+       0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+       0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 
+       0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 
+       0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 
+       0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+       0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 
+       0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+       0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+       0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+       0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+       0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+
+
+
+
+
+/***********************************************************************
+ *  Robert Hegemann 2001-01-17
+ ***********************************************************************/
+
+static void addVbr(VBR_seek_info_t * v, int bitrate)
+{
+    int i;
+
+    v->sum += bitrate;
+    v->seen ++;
+    
+    if (v->seen < v->want) {
+        return;
+    }
+
+    if (v->pos < v->size) {
+        v->bag[v->pos] = v->sum;
+        v->pos ++;
+        v->seen = 0;
+    }
+    if (v->pos == v->size) {
+        for (i = 1; i < v->size; i += 2) {
+            v->bag[i/2] = v->bag[i]; 
+        }
+        v->want *= 2;
+        v->pos  /= 2;
+    }
+}
+
+static void Xing_seek_table(VBR_seek_info_t * v, unsigned char *t)
+{
+    int i, index;
+    int seek_point;
+    
+    if (v->pos <= 0)
+        return;
+        
+    for (i = 1; i < NUMTOCENTRIES; ++i) {
+        float j = i/(float)NUMTOCENTRIES, act, sum;
+        index = (int)(floor(j * v->pos));
+        if (index > v->pos-1)
+            index = v->pos-1;
+        act = v->bag[index];
+        sum = v->sum;
+        seek_point = (int)(256. * act / sum);
+        if (seek_point > 255)
+            seek_point = 255;
+        t[i] = seek_point;
+    }
+}
+
+#if 0
+void print_seeking(unsigned char *t)
+{
+    int i;
+    
+    printf("seeking table ");
+    for (i = 0; i < NUMTOCENTRIES; ++i) {
+        printf(" %d ", t[i]);
+    }
+    printf("\n");
+}
+#endif
+
+
+
+/****************************************************************************
+ * AddVbrFrame: Add VBR entry, used to fill the VBR the TOC entries
+ * Paramters:
+ *     nStreamPos: how many bytes did we write to the bitstream so far
+ *                             (in Bytes NOT Bits)
+ ****************************************************************************
+*/
+void AddVbrFrame(lame_global_flags *gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+
+    int kbps = bitrate_table[gfp->version][gfc->bitrate_index];
+    
+    if (gfc->VBR_seek_table.bag == NULL) {
+        gfc->VBR_seek_table.sum  = 0;
+        gfc->VBR_seek_table.seen = 0;
+        gfc->VBR_seek_table.want = 1;
+        gfc->VBR_seek_table.pos  = 0;
+        gfc->VBR_seek_table.bag  = malloc (400*sizeof(int));
+        if (gfc->VBR_seek_table.bag != NULL) {
+            gfc->VBR_seek_table.size = 400;
+        }
+        else {
+            gfc->VBR_seek_table.size = 0;
+            ERRORF (gfc,"Error: can't allocate VbrFrames buffer\n");
+            return;
+        }   
+    }
+    addVbr(&gfc->VBR_seek_table, kbps);
+    gfp->nVbrNumFrames++;
+}
+
+
+/*-------------------------------------------------------------*/
+static int ExtractI4(unsigned char *buf)
+{
+       int x;
+       /* big endian extract */
+       x = buf[0];
+       x <<= 8;
+       x |= buf[1];
+       x <<= 8;
+       x |= buf[2];
+       x <<= 8;
+       x |= buf[3];
+       return x;
+}
+
+static void CreateI4(unsigned char *buf, int nValue)
+{
+        /* big endian create */
+       buf[0]=(nValue>>24)&0xff;
+       buf[1]=(nValue>>16)&0xff;
+       buf[2]=(nValue>> 8)&0xff;
+       buf[3]=(nValue    )&0xff;
+}
+
+
+
+static void CreateI2(unsigned char *buf, int nValue)
+{
+        /* big endian create */
+       buf[0]=(nValue>> 8)&0xff;
+       buf[1]=(nValue    )&0xff;
+}
+
+
+/*-------------------------------------------------------------*/
+/* Same as GetVbrTag below, but only checks for the Xing tag.
+   requires buf to contain only 40 bytes */
+/*-------------------------------------------------------------*/
+int CheckVbrTag(unsigned char *buf)
+{
+       int                     h_id, h_mode, h_sr_index;
+
+       /* get selected MPEG header data */
+       h_id       = (buf[1] >> 3) & 1;
+       h_sr_index = (buf[2] >> 2) & 3;
+       h_mode     = (buf[3] >> 6) & 3;
+
+       /*  determine offset of header */
+       if( h_id )
+       {
+                /* mpeg1 */
+               if( h_mode != 3 )       buf+=(32+4);
+               else                            buf+=(17+4);
+       }
+       else
+       {
+                /* mpeg2 */
+               if( h_mode != 3 ) buf+=(17+4);
+               else              buf+=(9+4);
+       }
+
+       if( buf[0] != VBRTag[0] && buf[0] != VBRTag2[0] ) return 0;    /* fail */
+       if( buf[1] != VBRTag[1] && buf[1] != VBRTag2[1]) return 0;    /* header not found*/
+       if( buf[2] != VBRTag[2] && buf[2] != VBRTag2[2]) return 0;
+       if( buf[3] != VBRTag[3] && buf[3] != VBRTag2[3]) return 0;
+       return 1;
+}
+
+int GetVbrTag(VBRTAGDATA *pTagData,  unsigned char *buf)
+{
+       int                     i, head_flags;
+       int                     h_bitrate,h_id, h_mode, h_sr_index;
+        int enc_delay,enc_padding; 
+
+       /* get Vbr header data */
+       pTagData->flags = 0;
+
+       /* get selected MPEG header data */
+       h_id       = (buf[1] >> 3) & 1;
+       h_sr_index = (buf[2] >> 2) & 3;
+       h_mode     = (buf[3] >> 6) & 3;
+        h_bitrate  = ((buf[2]>>4)&0xf);
+       h_bitrate = bitrate_table[h_id][h_bitrate];
+
+        /* check for FFE syncword */
+        if ((buf[1]>>4)==0xE) 
+            pTagData->samprate = samplerate_table[2][h_sr_index];
+        else
+            pTagData->samprate = samplerate_table[h_id][h_sr_index];
+        //     if( h_id == 0 )
+        //             pTagData->samprate >>= 1;
+
+
+
+       /*  determine offset of header */
+       if( h_id )
+       {
+                /* mpeg1 */
+               if( h_mode != 3 )       buf+=(32+4);
+               else                            buf+=(17+4);
+       }
+       else
+       {
+                /* mpeg2 */
+               if( h_mode != 3 ) buf+=(17+4);
+               else              buf+=(9+4);
+       }
+
+       if( buf[0] != VBRTag[0] && buf[0] != VBRTag2[0] ) return 0;    /* fail */
+       if( buf[1] != VBRTag[1] && buf[1] != VBRTag2[1]) return 0;    /* header not found*/
+       if( buf[2] != VBRTag[2] && buf[2] != VBRTag2[2]) return 0;
+       if( buf[3] != VBRTag[3] && buf[3] != VBRTag2[3]) return 0;
+
+       buf+=4;
+
+       pTagData->h_id = h_id;
+
+       head_flags = pTagData->flags = ExtractI4(buf); buf+=4;      /* get flags */
+
+       if( head_flags & FRAMES_FLAG )
+       {
+               pTagData->frames   = ExtractI4(buf); buf+=4;
+       }
+
+       if( head_flags & BYTES_FLAG )
+       {
+               pTagData->bytes = ExtractI4(buf); buf+=4;
+       }
+
+       if( head_flags & TOC_FLAG )
+       {
+               if( pTagData->toc != NULL )
+               {
+                       for(i=0;i<NUMTOCENTRIES;i++)
+                               pTagData->toc[i] = buf[i];
+               }
+               buf+=NUMTOCENTRIES;
+       }
+
+       pTagData->vbr_scale = -1;
+
+       if( head_flags & VBR_SCALE_FLAG )
+       {
+               pTagData->vbr_scale = ExtractI4(buf); buf+=4;
+       }
+
+       pTagData->headersize = 
+         ((h_id+1)*72000*h_bitrate) / pTagData->samprate;
+
+        buf+=21;
+        enc_delay = buf[0] << 4;
+        enc_delay += buf[1] >> 4;
+        enc_padding= (buf[1] & 0x0F)<<8;
+        enc_padding += buf[2];
+        // check for reasonable values (this may be an old Xing header,
+        // not a INFO tag)
+        if (enc_delay<0 || enc_delay > 3000) enc_delay=-1;
+        if (enc_padding<0 || enc_padding > 3000) enc_padding=-1;
+
+        pTagData->enc_delay=enc_delay;
+        pTagData->enc_padding=enc_padding;
+
+#ifdef DEBUG_VBRTAG
+       fprintf(stderr,"\n\n********************* VBR TAG INFO *****************\n");
+       fprintf(stderr,"tag         :%s\n",VBRTag);
+       fprintf(stderr,"head_flags  :%d\n",head_flags);
+       fprintf(stderr,"bytes       :%d\n",pTagData->bytes);
+       fprintf(stderr,"frames      :%d\n",pTagData->frames);
+       fprintf(stderr,"VBR Scale   :%d\n",pTagData->vbr_scale);
+        fprintf(stderr,"enc_delay  = %i \n",enc_delay);
+        fprintf(stderr,"enc_padding= %i \n",enc_padding);
+       fprintf(stderr,"toc:\n");
+       if( pTagData->toc != NULL )
+       {
+               for(i=0;i<NUMTOCENTRIES;i++)
+               {
+                       if( (i%10) == 0 ) fprintf(stderr,"\n");
+                       fprintf(stderr," %3d", (int)(pTagData->toc[i]));
+               }
+       }
+       fprintf(stderr,"\n***************** END OF VBR TAG INFO ***************\n");
+#endif
+       return 1;       /* success */
+}
+
+
+/****************************************************************************
+ * InitVbrTag: Initializes the header, and write empty frame to stream
+ * Paramters:
+ *                             fpStream: pointer to output file stream
+ *                             nMode   : Channel Mode: 0=STEREO 1=JS 2=DS 3=MONO
+ ****************************************************************************
+*/
+int InitVbrTag(lame_global_flags *gfp)
+{
+       int nMode,SampIndex;
+       lame_internal_flags *gfc = gfp->internal_flags;
+#define MAXFRAMESIZE 2880 // or 0xB40, the max freeformat 640 32kHz framesize
+       //      uint8_t pbtStreamBuffer[MAXFRAMESIZE];
+       nMode = gfp->mode;
+       SampIndex = gfc->samplerate_index;
+
+
+       /* Clear Frame position array variables */
+       //gfp->pVbrFrames=NULL;
+       gfp->nVbrNumFrames=0;
+       gfp->nVbrFrameBufferSize=0;
+
+
+       /* Clear stream buffer */
+       //      memset(pbtStreamBuffer,0x00,sizeof(pbtStreamBuffer));
+
+
+
+       /*
+       // Xing VBR pretends to be a 48kbs layer III frame.  (at 44.1kHz).
+        // (at 48kHz they use 56kbs since 48kbs frame not big enough for
+        // table of contents)
+       // let's always embed Xing header inside a 64kbs layer III frame.
+       // this gives us enough room for a LAME version string too.
+       // size determined by sampling frequency (MPEG1)
+       // 32kHz:    216 bytes@48kbs    288bytes@ 64kbs
+       // 44.1kHz:  156 bytes          208bytes@64kbs     (+1 if padding = 1)
+       // 48kHz:    144 bytes          192
+       //
+       // MPEG 2 values are the same since the framesize and samplerate
+        // are each reduced by a factor of 2.
+       */
+       {
+       int i,bitrate,tot;
+       if (1==gfp->version) {
+         bitrate = XING_BITRATE1;
+       } else {
+         if (gfp->out_samplerate < 16000 )
+           bitrate = XING_BITRATE25;
+         else
+           bitrate = XING_BITRATE2;
+       }
+
+       if (gfp->VBR==vbr_off)
+                       bitrate = gfp->brate;
+       
+       gfp->TotalFrameSize= 
+         ((gfp->version+1)*72000*bitrate) / gfp->out_samplerate;
+
+       tot = (gfc->sideinfo_len+LAMEHEADERSIZE);
+
+       if (gfp->TotalFrameSize < tot || 
+            gfp->TotalFrameSize > MAXFRAMESIZE ) {
+            // disable tag, it wont fit
+            gfp->bWriteVbrTag = 0;
+            return 0;
+        }
+
+       for (i=0; i<gfp->TotalFrameSize; ++i)
+         add_dummy_byte(gfp,0);
+       }
+
+       /* Success */
+       return 0;
+}
+
+
+
+/* fast CRC-16 computation - uses table crc16_lookup 8*/
+int CRC_update_lookup(int value, int crc)
+{
+       int tmp;
+       tmp=crc^value;
+       crc=(crc>>8)^crc16_lookup[tmp & 0xff];
+       return crc;
+}
+
+void UpdateMusicCRC(uint16_t *crc,unsigned char *buffer, int size){
+    int i;
+    for (i=0; i<size; ++i) 
+        *crc = CRC_update_lookup(buffer[i],*crc);
+}
+
+
+
+
+void ReportLameTagProgress(lame_global_flags *gfp,int nStart)
+{
+       if (!gfp->bWriteVbrTag)
+               return;
+
+       if (nStart)
+               MSGF( gfp->internal_flags, "Writing LAME Tag...");
+       else
+               MSGF( gfp->internal_flags, "done\n");
+
+}
+
+
+/****************************************************************************
+ * Jonathan Dee 2001/08/31
+ *
+ * PutLameVBR: Write LAME info: mini version + info on various switches used
+ * Paramters:
+ *                             pbtStreamBuffer : pointer to output buffer  
+ *                             id3v2size               : size of id3v2 tag in bytes
+ *                             crc                             : computation of crc-16 of Lame Tag so far (starting at frame sync)
+ *                             
+ ****************************************************************************
+*/
+int PutLameVBR(lame_global_flags *gfp, FILE *fpStream, uint8_t *pbtStreamBuffer, uint32_t id3v2size,  uint16_t crc)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+//     FLOAT fVersion = LAME_MAJOR_VERSION + 0.01 * LAME_MINOR_VERSION;
+
+       int nBytesWritten = 0;
+       int nFilesize     = 0;          //size of fpStream. Will be equal to size after process finishes.
+       int i;
+
+    int enc_delay=lame_get_encoder_delay(gfp);       // encoder delay
+    int enc_padding=lame_get_encoder_padding(gfp);   // encoder padding 
+
+       //recall:       gfp->VBR_q is for example set by the switch -V 
+       //                      gfp->quality by -q, -h, -f, etc
+       
+       int nQuality            = (100 - 10 * gfp->VBR_q - gfp->quality);
+       
+
+       const char *szVersion   = get_lame_very_short_version();
+       uint8_t nVBR;
+       uint8_t nRevision = 0x00;
+       uint8_t nRevMethod;
+       uint8_t vbr_type_translator[] = {1,5,3,2,4,0,3};                //numbering different in vbr_mode vs. Lame tag
+
+       uint8_t nLowpass                = ( ((gfp->lowpassfreq / 100.0)+.5) > 255 ? 255 : (gfp->lowpassfreq / 100.0)+.5 );
+
+       ieee754_float32_t fPeakSignalAmplitude  = 0;                            //TODO...
+       uint16_t nRadioReplayGain               = 0;                            //TODO...
+       uint16_t nAudioPhileReplayGain  = 0;                            //TODO...
+
+
+
+
+       uint8_t nNoiseShaping                   = gfp->internal_flags->noise_shaping;
+       uint8_t nStereoMode                             = 0;
+       int             bNonOptimal                             = 0;
+       uint8_t nSourceFreq                             = 0;
+       uint8_t nMisc                                   = 0;
+       uint32_t nMusicLength                   = 0;
+       int             bId3v1Present                   = ((gfp->internal_flags->tag_spec.flags & CHANGED_FLAG)
+               && !(gfp->internal_flags->tag_spec.flags & V2_ONLY_FLAG));
+       uint16_t nMusicCRC                              = 0;
+
+       //psy model type: Gpsycho or NsPsytune
+       unsigned char    bExpNPsyTune   = gfp->exp_nspsytune & 1;
+       unsigned char    bSafeJoint             = (gfp->exp_nspsytune & 2)!=0;
+
+       unsigned char    bNoGapMore             = 0;
+       unsigned char    bNoGapPrevious = 0;
+
+       int              nNoGapCount    = gfp->internal_flags->nogap_total;
+       int              nNoGapCurr             = gfp->internal_flags->nogap_current;
+
+
+       uint8_t  nAthType               = gfp->ATHtype; //4 bits.
+       
+       uint8_t  nFlags                 = 0;
+
+       // if ABR, {store bitrate <=255} else { store "-b"}
+       int nABRBitrate = (gfp->VBR==vbr_abr)?gfp->VBR_mean_bitrate_kbps:gfp->brate;
+
+       //revision and vbr method
+       if (gfp->VBR>=0 && gfp->VBR < sizeof(vbr_type_translator))
+               nVBR = vbr_type_translator[gfp->VBR];
+       else
+               nVBR = 0x00;            //unknown.
+
+       nRevMethod = 0x10 * nRevision + nVBR; 
+       
+       //nogap
+       if (nNoGapCount != -1)
+       {
+               if (nNoGapCurr > 0)
+                       bNoGapPrevious = 1;
+
+               if (nNoGapCurr < nNoGapCount-1)
+                       bNoGapMore = 1;
+       }
+
+       //flags
+
+       nFlags  = nAthType      + (bExpNPsyTune         << 4)
+                                               + (bSafeJoint           << 5)
+                                               + (bNoGapMore           << 6)
+                                               + (bNoGapPrevious       << 7);
+
+
+       if (nQuality < 0)
+               nQuality = 0;
+
+       /*stereo mode field... a bit ugly.*/
+
+       switch(gfp->mode)
+       {
+       case MONO:
+               nStereoMode = 0;
+               break;
+       case STEREO:
+               nStereoMode = 1;
+               break;
+       case DUAL_CHANNEL:
+               nStereoMode = 2;
+               break;
+       case JOINT_STEREO:
+               if (gfp->force_ms)
+                       nStereoMode = 4;
+               else
+                       nStereoMode = 3;
+               break;
+       case NOT_SET:
+           /* FALLTHROUGH */
+       default:
+               nStereoMode = 7;
+               break;
+       }
+
+       if (gfp->mode_automs)
+               nStereoMode = 5;
+
+       /*Intensity stereo : nStereoMode = 6. IS is not implemented */
+
+       if (gfp->in_samplerate <= 32000)
+               nSourceFreq = 0x00;
+       else if (gfp->in_samplerate ==48000)
+               nSourceFreq = 0x02;
+       else if (gfp->in_samplerate > 48000)
+               nSourceFreq = 0x03;
+       else
+               nSourceFreq = 0x01;  //default is 44100Hz.
+
+
+       //Check if the user overrided the default LAME behaviour with some nasty options
+
+       if (gfp->short_blocks == short_block_forced                     ||
+               gfp->short_blocks == short_block_dispensed              ||
+               ((gfp->lowpassfreq == -1) && (gfp->highpassfreq == -1)) || // "-k"
+               (gfp->scale_left != gfp->scale_right)                   ||
+               gfp->disable_reservoir          ||
+               gfp->noATH                      ||
+               gfp->ATHonly                    ||
+               (nAthType == 0)    ||
+               gfp->in_samplerate <= 32000)
+                       bNonOptimal = 1;
+       
+       nMisc =         nNoiseShaping
+                       +       (nStereoMode << 2)
+                       +       (bNonOptimal << 5)
+                       +       (nSourceFreq << 6);
+
+
+       
+       //get filesize
+       fseek(fpStream, 0, SEEK_END);
+       nFilesize = ftell(fpStream);
+
+       
+       nMusicLength = nFilesize - id3v2size;           //omit current frame
+       if (bId3v1Present)
+               nMusicLength-=128;                     //id3v1 present.
+        nMusicCRC = gfc->nMusicCRC;
+
+
+       /*Write all this information into the stream*/
+       CreateI4(&pbtStreamBuffer[nBytesWritten], nQuality);
+       nBytesWritten+=4;
+
+       strncpy(&pbtStreamBuffer[nBytesWritten], szVersion, 9);
+       nBytesWritten+=9;
+
+       pbtStreamBuffer[nBytesWritten] = nRevMethod ;
+       nBytesWritten++;
+
+       pbtStreamBuffer[nBytesWritten] = nLowpass;
+       nBytesWritten++;
+
+       memmove(&pbtStreamBuffer[nBytesWritten], &fPeakSignalAmplitude, 4);
+       nBytesWritten+=4;
+
+       CreateI2(&pbtStreamBuffer[nBytesWritten],nRadioReplayGain);
+       nBytesWritten+=2;
+
+       CreateI2(&pbtStreamBuffer[nBytesWritten],nAudioPhileReplayGain);
+       nBytesWritten+=2;
+
+       pbtStreamBuffer[nBytesWritten] = nFlags;
+       nBytesWritten++;
+
+       if (nABRBitrate >= 255)
+               pbtStreamBuffer[nBytesWritten] = 0xFF;
+       else
+               pbtStreamBuffer[nBytesWritten] = nABRBitrate;
+       nBytesWritten++;
+
+        pbtStreamBuffer[nBytesWritten   ] = enc_delay >> 4; // works for win32, does it for unix?
+        pbtStreamBuffer[nBytesWritten +1] = (enc_delay << 4) + (enc_padding >> 8);
+        pbtStreamBuffer[nBytesWritten +2] = enc_padding;
+
+       nBytesWritten+=3;
+
+       pbtStreamBuffer[nBytesWritten] = nMisc;
+       nBytesWritten++;
+
+
+       memset(pbtStreamBuffer+nBytesWritten,0, 3);             //unused in rev0
+       nBytesWritten+=3;
+
+       CreateI4(&pbtStreamBuffer[nBytesWritten], nMusicLength);
+       nBytesWritten+=4;
+
+       CreateI2(&pbtStreamBuffer[nBytesWritten], nMusicCRC);
+       nBytesWritten+=2;
+
+       /*Calculate tag CRC.... must be done here, since it includes
+        *previous information*/
+       
+       for (i = 0;i<nBytesWritten;i++)
+               crc = CRC_update_lookup(pbtStreamBuffer[i], crc);
+       
+       CreateI2(&pbtStreamBuffer[nBytesWritten], crc);
+       nBytesWritten+=2;
+
+       return nBytesWritten;
+}
+
+/***********************************************************************
+ * 
+ * PutVbrTag: Write final VBR tag to the file
+ * Paramters:
+ *                             lpszFileName: filename of MP3 bit stream
+ *                             nVbrScale       : encoder quality indicator (0..100)
+ ****************************************************************************
+*/
+int PutVbrTag(lame_global_flags *gfp,FILE *fpStream,int nVbrScale)
+{
+    lame_internal_flags * gfc = gfp->internal_flags;
+
+       long lFileSize;
+       int nStreamIndex;
+       char abyte,bbyte;
+       uint8_t         btToc[NUMTOCENTRIES];
+       uint8_t pbtStreamBuffer[MAXFRAMESIZE];
+       
+       int i;
+       uint16_t crc = 0x00;
+       
+    unsigned char id3v2Header[10];
+    size_t id3v2TagSize;
+
+    if (gfc->VBR_seek_table.pos <= 0)
+       return -1;
+
+
+       /* Clear stream buffer */
+       memset(pbtStreamBuffer,0x00,sizeof(pbtStreamBuffer));
+
+       /* Seek to end of file*/
+       fseek(fpStream,0,SEEK_END);
+
+       /* Get file size */
+       lFileSize=ftell(fpStream);
+
+       /* Abort if file has zero length. Yes, it can happen :) */
+       if (lFileSize==0)
+               return -1;
+
+        /*
+         * The VBR tag may NOT be located at the beginning of the stream.
+         * If an ID3 version 2 tag was added, then it must be skipped to write
+         * the VBR tag data.
+         */
+
+        /* seek to the beginning of the stream */
+       fseek(fpStream,0,SEEK_SET);
+        /* read 10 bytes in case there's an ID3 version 2 header here */
+        fread(id3v2Header,1,sizeof id3v2Header,fpStream);
+        /* does the stream begin with the ID3 version 2 file identifier? */
+        if (!strncmp((char *)id3v2Header,"ID3",3)) {
+          /* the tag size (minus the 10-byte header) is encoded into four
+           * bytes where the most significant bit is clear in each byte */
+          id3v2TagSize=(((id3v2Header[6] & 0x7f)<<21)
+            | ((id3v2Header[7] & 0x7f)<<14)
+            | ((id3v2Header[8] & 0x7f)<<7)
+            | (id3v2Header[9] & 0x7f))
+            + sizeof id3v2Header;
+        } else {
+          /* no ID3 version 2 tag in this stream */
+          id3v2TagSize=0;
+        }
+
+       /* Seek to first real frame */
+       fseek(fpStream,id3v2TagSize+gfp->TotalFrameSize,SEEK_SET);
+
+       /* Read the header (first valid frame) */
+       fread(pbtStreamBuffer,4,1,fpStream);
+
+       /* the default VBR header. 48 kbps layer III, no padding, no crc */
+       /* but sampling freq, mode andy copyright/copy protection taken */
+       /* from first valid frame */
+       pbtStreamBuffer[0]=(uint8_t) 0xff;
+       abyte = (pbtStreamBuffer[1] & (char) 0xf1);
+       {       
+               int bitrate;
+               if (1==gfp->version) {
+                 bitrate = XING_BITRATE1;
+               } else {
+                 if (gfp->out_samplerate < 16000 )
+                       bitrate = XING_BITRATE25;
+                 else
+                       bitrate = XING_BITRATE2;
+               }
+               
+               if (gfp->VBR==vbr_off)
+                       bitrate = gfp->brate;
+
+               bbyte = 16*BitrateIndex(bitrate,gfp->version,gfp->out_samplerate);
+       }
+
+       /* Use as much of the info from the real frames in the
+        * Xing header:  samplerate, channels, crc, etc...
+        */ 
+       if (gfp->version==1) {
+         /* MPEG1 */
+         pbtStreamBuffer[1]=abyte | (char) 0x0a;     /* was 0x0b; */
+         abyte = pbtStreamBuffer[2] & (char) 0x0d;   /* AF keep also private bit */
+         pbtStreamBuffer[2]=(char) bbyte | abyte;     /* 64kbs MPEG1 frame */
+       }else{
+         /* MPEG2 */
+         pbtStreamBuffer[1]=abyte | (char) 0x02;     /* was 0x03; */
+         abyte = pbtStreamBuffer[2] & (char) 0x0d;   /* AF keep also private bit */
+         pbtStreamBuffer[2]=(char) bbyte | abyte;     /* 64kbs MPEG2 frame */
+       }
+
+       /* Clear all TOC entries */
+       memset(btToc,0,sizeof(btToc));
+
+        Xing_seek_table (&gfc->VBR_seek_table, btToc);
+        /* print_seeking (btToc); */
+
+       /* Start writing the tag after the zero frame */
+       nStreamIndex=gfc->sideinfo_len;
+       /* note! Xing header specifies that Xing data goes in the
+        * ancillary data with NO ERROR PROTECTION.  If error protecton
+        * in enabled, the Xing data still starts at the same offset,
+        * and now it is in sideinfo data block, and thus will not
+        * decode correctly by non-Xing tag aware players */
+       if (gfp->error_protection) nStreamIndex -= 2;
+
+       /* Put Vbr tag */
+       if (gfp->VBR == vbr_off)
+       {
+               pbtStreamBuffer[nStreamIndex++]=VBRTag2[0];
+               pbtStreamBuffer[nStreamIndex++]=VBRTag2[1];
+               pbtStreamBuffer[nStreamIndex++]=VBRTag2[2];
+               pbtStreamBuffer[nStreamIndex++]=VBRTag2[3];
+
+       }
+       else
+       {
+               pbtStreamBuffer[nStreamIndex++]=VBRTag[0];
+               pbtStreamBuffer[nStreamIndex++]=VBRTag[1];
+               pbtStreamBuffer[nStreamIndex++]=VBRTag[2];
+               pbtStreamBuffer[nStreamIndex++]=VBRTag[3];
+       }       
+
+       /* Put header flags */
+       CreateI4(&pbtStreamBuffer[nStreamIndex],FRAMES_FLAG+BYTES_FLAG+TOC_FLAG+VBR_SCALE_FLAG);
+       nStreamIndex+=4;
+
+       /* Put Total Number of frames */
+       CreateI4(&pbtStreamBuffer[nStreamIndex],gfp->nVbrNumFrames);
+       nStreamIndex+=4;
+
+       /* Put Total file size */
+       CreateI4(&pbtStreamBuffer[nStreamIndex],(int)lFileSize);
+       nStreamIndex+=4;
+
+       /* Put TOC */
+       memcpy(&pbtStreamBuffer[nStreamIndex],btToc,sizeof(btToc));
+       nStreamIndex+=sizeof(btToc);
+
+
+       if (gfp->error_protection) {
+         /* (jo) error_protection: add crc16 information to header */
+         CRC_writeheader(gfc, pbtStreamBuffer);
+       }
+
+
+
+       //work out CRC so far: initially crc = 0
+       for (i = 0;i< nStreamIndex ;i++)
+               crc = CRC_update_lookup(pbtStreamBuffer[i], crc);
+
+       /*Put LAME VBR info*/
+       nStreamIndex+=PutLameVBR(gfp, fpStream, pbtStreamBuffer + nStreamIndex, id3v2TagSize,crc);
+
+#ifdef DEBUG_VBRTAG
+       {
+         VBRTAGDATA TestHeader;
+         GetVbrTag(&TestHeader,pbtStreamBuffer);
+       }
+#endif
+
+       /*Seek to the beginning of the stream */
+       fseek(fpStream,id3v2TagSize,SEEK_SET);
+
+        /* Put it all to disk again */
+       if (fwrite(pbtStreamBuffer,(unsigned int)gfp->TotalFrameSize,1,fpStream)!=1)
+       {
+               return -1;
+       }
+       /* Save to delete the frame buffer */
+       //free(gfp->pVbrFrames);  see HACKING for instructions on how
+       //gfp->pVbrFrames=NULL;   memory in 'gfp' is allocated/free'd
+
+       return 0;       /* success */
+}
+
diff --git a/lib/lame/VbrTag.h b/lib/lame/VbrTag.h
new file mode 100644 (file)
index 0000000..f7d14d3
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ *     Xing VBR tagging for LAME.
+ *
+ *     Copyright (c) 1999 A.L. Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_VRBTAG_H
+#define LAME_VRBTAG_H
+#include "lame.h"
+/* -----------------------------------------------------------
+ * A Vbr header may be present in the ancillary
+ * data field of the first frame of an mp3 bitstream
+ * The Vbr header (optionally) contains
+ *      frames      total number of audio frames in the bitstream
+ *      bytes       total number of bytes in the bitstream
+ *      toc         table of contents
+
+ * toc (table of contents) gives seek points
+ * for random access
+ * the ith entry determines the seek point for
+ * i-percent duration
+ * seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes
+ * e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes
+ */
+
+
+#define FRAMES_FLAG     0x0001
+#define BYTES_FLAG      0x0002
+#define TOC_FLAG        0x0004
+#define VBR_SCALE_FLAG  0x0008
+
+#define NUMTOCENTRIES 100
+
+#define FRAMES_AND_BYTES (FRAMES_FLAG | BYTES_FLAG)
+
+
+/*structure to receive extracted header */
+/* toc may be NULL*/
+typedef struct
+{
+  int          h_id;                   /* from MPEG header, 0=MPEG2, 1=MPEG1 */
+  int          samprate;               /* determined from MPEG header */
+  int          flags;                  /* from Vbr header data */
+  int          frames;                 /* total bit stream frames from Vbr header data */
+  int          bytes;                  /* total bit stream bytes from Vbr header data*/
+  int          vbr_scale;              /* encoded vbr scale from Vbr header data*/
+  unsigned char        toc[NUMTOCENTRIES];     /* may be NULL if toc not desired*/
+  int           headersize;             /* size of VBR header, in bytes */
+  int           enc_delay;              /* encoder delay */
+  int           enc_padding;            /* encoder paddign added at end of stream */
+}   VBRTAGDATA;
+
+int CheckVbrTag(unsigned char *buf);
+int GetVbrTag(VBRTAGDATA *pTagData,  unsigned char *buf);
+
+int SeekPoint(unsigned char TOC[NUMTOCENTRIES], int file_bytes, float percent);
+int InitVbrTag(lame_global_flags *gfp);
+int PutVbrTag(lame_global_flags *gfp,FILE *fid,int nVbrScale);
+int PutLameVBR(lame_global_flags *gfp, FILE *fpStream, uint8_t *pbtStreamBuffer, uint32_t id3v2size,  uint16_t crc);
+void AddVbrFrame(lame_global_flags *gfp);
+void ReportLameTagProgress(lame_global_flags *gfp,int nStart);
+void UpdateMusicCRC(uint16_t *crc,unsigned char *buffer, int size);
+
+#endif
diff --git a/lib/lame/bitstream.c b/lib/lame/bitstream.c
new file mode 100644 (file)
index 0000000..fda431d
--- /dev/null
@@ -0,0 +1,977 @@
+/*
+ *     MP3 bitstream Output interface for LAME
+ *
+ *     Copyright (c) 1999 Takehiro TOMINAGA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * $Id: bitstream.c,v 1.1 2002/04/28 17:30:17 kramm Exp $
+ */
+
+
+#include "config_static.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include "tables.h"
+#include "bitstream.h"
+#include "quantize.h"
+#include "quantize_pvt.h"
+#include "version.h"
+#include "VbrTag.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+/* This is the scfsi_band table from 2.4.2.7 of the IS */
+const int scfsi_band[5] = { 0, 6, 11, 16, 21 };
+
+
+/* unsigned int is at least this large:  */
+/* we work with ints, so when doing bit manipulation, we limit
+ * ourselves to MAX_LENGTH-2 just to be on the safe side */
+#define MAX_LENGTH      32  
+
+
+
+#ifdef DEBUG
+static int hoge, hogege;
+#endif
+
+
+
+
+
+void putheader_bits(lame_internal_flags *gfc,int w_ptr)
+{
+    Bit_stream_struc *bs;
+    bs = &gfc->bs;
+#ifdef DEBUG
+    hoge += gfc->sideinfo_len * 8;
+    hogege += gfc->sideinfo_len * 8;
+#endif
+    memcpy(&bs->buf[bs->buf_byte_idx], gfc->header[gfc->w_ptr].buf,
+          gfc->sideinfo_len);
+    bs->buf_byte_idx += gfc->sideinfo_len;
+    bs->totbit += gfc->sideinfo_len * 8;
+    gfc->w_ptr = (gfc->w_ptr + 1) & (MAX_HEADER_BUF - 1);
+}
+
+
+
+
+/*write j bits into the bit stream */
+inline static void
+putbits2(lame_global_flags *gfp, int val, int j)
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    Bit_stream_struc *bs;
+    bs = &gfc->bs;
+
+    assert(j < MAX_LENGTH-2);
+
+    while (j > 0) {
+       int k;
+       if (bs->buf_bit_idx == 0) {
+           bs->buf_bit_idx = 8;
+           bs->buf_byte_idx++;
+           assert(bs->buf_byte_idx < BUFFER_SIZE);
+           assert(gfc->header[gfc->w_ptr].write_timing >= bs->totbit);
+           if (gfc->header[gfc->w_ptr].write_timing == bs->totbit) {
+             putheader_bits(gfc,gfc->w_ptr);
+           }
+           bs->buf[bs->buf_byte_idx] = 0;
+       }
+
+       k = Min(j, bs->buf_bit_idx);
+       j -= k;
+        
+       bs->buf_bit_idx -= k;
+        
+       assert (j < MAX_LENGTH); /* 32 too large on 32 bit machines */
+        assert (bs->buf_bit_idx < MAX_LENGTH); 
+       
+        bs->buf[bs->buf_byte_idx] |= ((val >> j) << bs->buf_bit_idx);
+       bs->totbit += k;
+    }
+}
+
+/*write j bits into the bit stream, ignoring frame headers */
+inline static void
+putbits_noheaders(lame_global_flags *gfp, int val, int j)
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    Bit_stream_struc *bs;
+    bs = &gfc->bs;
+
+    assert(j < MAX_LENGTH-2);
+
+    while (j > 0) {
+       int k;
+       if (bs->buf_bit_idx == 0) {
+           bs->buf_bit_idx = 8;
+           bs->buf_byte_idx++;
+           assert(bs->buf_byte_idx < BUFFER_SIZE);
+           bs->buf[bs->buf_byte_idx] = 0;
+       }
+
+       k = Min(j, bs->buf_bit_idx);
+       j -= k;
+        
+       bs->buf_bit_idx -= k;
+        
+       assert (j < MAX_LENGTH); /* 32 too large on 32 bit machines */
+        assert (bs->buf_bit_idx < MAX_LENGTH); 
+       
+        bs->buf[bs->buf_byte_idx] |= ((val >> j) << bs->buf_bit_idx);
+       bs->totbit += k;
+    }
+}
+
+
+/*
+  Some combinations of bitrate, Fs, and stereo make it impossible to stuff
+  out a frame using just main_data, due to the limited number of bits to
+  indicate main_data_length. In these situations, we put stuffing bits into
+  the ancillary data...
+*/
+
+inline static void
+drain_into_ancillary(lame_global_flags *gfp,int remainingBits)
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    int i;
+    assert(remainingBits >= 0);
+
+    if (remainingBits >= 8) {
+      putbits2(gfp,0x4c,8);
+      remainingBits -= 8;
+    }
+    if (remainingBits >= 8) {
+      putbits2(gfp,0x41,8);
+      remainingBits -= 8;
+    }
+    if (remainingBits >= 8) {
+      putbits2(gfp,0x4d,8);
+      remainingBits -= 8;
+    }
+    if (remainingBits >= 8) {
+      putbits2(gfp,0x45,8);
+      remainingBits -= 8;
+    }
+      
+    if (remainingBits >= 32) {
+      const char *version = get_lame_short_version ();
+      if (remainingBits >= 32) 
+       for (i=0; i<(int)strlen(version) && remainingBits >=8 ; ++i) {
+         remainingBits -= 8;
+         putbits2(gfp,version[i],8);
+       }
+    }
+
+    for (; remainingBits >= 1; remainingBits -= 1 ) {
+        putbits2 ( gfp, gfc->ancillary_flag, 1 );
+        gfc->ancillary_flag ^= 1;
+    }
+
+    assert (remainingBits == 0);
+
+}
+
+/*write N bits into the header */
+inline static void
+writeheader(lame_internal_flags *gfc,int val, int j)
+{
+    int ptr = gfc->header[gfc->h_ptr].ptr;
+
+    while (j > 0) {
+       int k = Min(j, 8 - (ptr & 7));
+       j -= k;
+        assert (j < MAX_LENGTH); /* >> 32  too large for 32 bit machines */
+       gfc->header[gfc->h_ptr].buf[ptr >> 3]
+           |= ((val >> j)) << (8 - (ptr & 7) - k);
+       ptr += k;
+    }
+    gfc->header[gfc->h_ptr].ptr = ptr;
+}
+
+
+static int
+CRC_update(int value, int crc)
+{
+    int i;
+    value <<= 8;
+    for (i = 0; i < 8; i++) {
+       value <<= 1;
+       crc <<= 1;
+
+       if (((crc ^ value) & 0x10000))
+           crc ^= CRC16_POLYNOMIAL;
+    }
+    return crc;
+}
+
+
+void
+CRC_writeheader(lame_internal_flags *gfc, char *header)
+{
+    int crc = 0xffff; /* (jo) init crc16 for error_protection */
+    int i;
+
+    crc = CRC_update(((unsigned char*)header)[2], crc);
+    crc = CRC_update(((unsigned char*)header)[3], crc);
+    for (i = 6; i < gfc->sideinfo_len; i++) {
+       crc = CRC_update(((unsigned char*)header)[i], crc);
+    }
+
+    header[4] = crc >> 8;
+    header[5] = crc & 255;
+}
+
+inline static void
+encodeSideInfo2(lame_global_flags *gfp,int bitsPerFrame)
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    III_side_info_t *l3_side;
+    int gr, ch;
+    
+    l3_side = &gfc->l3_side;
+    gfc->header[gfc->h_ptr].ptr = 0;
+    memset(gfc->header[gfc->h_ptr].buf, 0, gfc->sideinfo_len);
+    if (gfp->out_samplerate < 16000) 
+      writeheader(gfc,0xffe,                12);
+    else
+      writeheader(gfc,0xfff,                12);
+    writeheader(gfc,(gfp->version),            1);
+    writeheader(gfc,4 - 3,                 2);
+    writeheader(gfc,(!gfp->error_protection),  1);
+    writeheader(gfc,(gfc->bitrate_index),      4);
+    writeheader(gfc,(gfc->samplerate_index),   2);
+    writeheader(gfc,(gfc->padding),            1);
+    writeheader(gfc,(gfp->extension),          1);
+    writeheader(gfc,(gfp->mode),               2);
+    writeheader(gfc,(gfc->mode_ext),           2);
+    writeheader(gfc,(gfp->copyright),          1);
+    writeheader(gfc,(gfp->original),           1);
+    writeheader(gfc,(gfp->emphasis),           2);
+    if (gfp->error_protection) {
+       writeheader(gfc,0, 16); /* dummy */
+    }
+
+    if (gfp->version == 1) {
+       /* MPEG1 */
+       assert(l3_side->main_data_begin >= 0);
+       writeheader(gfc,(l3_side->main_data_begin), 9);
+
+       if (gfc->channels_out == 2)
+           writeheader(gfc,l3_side->private_bits, 3);
+       else
+           writeheader(gfc,l3_side->private_bits, 5);
+
+       for (ch = 0; ch < gfc->channels_out; ch++) {
+           int band;
+           for (band = 0; band < 4; band++) {
+               writeheader(gfc,l3_side->scfsi[ch][band], 1);
+           }
+       }
+
+       for (gr = 0; gr < 2; gr++) {
+           for (ch = 0; ch < gfc->channels_out; ch++) {
+               gr_info *gi = &l3_side->gr[gr].ch[ch].tt;
+               writeheader(gfc,gi->part2_3_length,       12);
+               writeheader(gfc,gi->big_values / 2,        9);
+               writeheader(gfc,gi->global_gain,           8);
+               writeheader(gfc,gi->scalefac_compress,     4);
+               writeheader(gfc,gi->window_switching_flag, 1);
+
+               if (gi->window_switching_flag) {
+                   writeheader(gfc,gi->block_type,       2);
+                   writeheader(gfc,gi->mixed_block_flag, 1);
+
+                   if (gi->table_select[0] == 14)
+                       gi->table_select[0] = 16;
+                   writeheader(gfc,gi->table_select[0],  5);
+                   if (gi->table_select[1] == 14)
+                       gi->table_select[1] = 16;
+                   writeheader(gfc,gi->table_select[1],  5);
+
+                   writeheader(gfc,gi->subblock_gain[0], 3);
+                   writeheader(gfc,gi->subblock_gain[1], 3);
+                   writeheader(gfc,gi->subblock_gain[2], 3);
+               } else {
+                   assert(gi->block_type == NORM_TYPE);
+                   if (gi->table_select[0] == 14)
+                       gi->table_select[0] = 16;
+                   writeheader(gfc,gi->table_select[0], 5);
+                   if (gi->table_select[1] == 14)
+                       gi->table_select[1] = 16;
+                   writeheader(gfc,gi->table_select[1], 5);
+                   if (gi->table_select[2] == 14)
+                       gi->table_select[2] = 16;
+                   writeheader(gfc,gi->table_select[2], 5);
+
+                   assert(gi->region0_count < 16U);
+                   assert(gi->region1_count < 8U);
+                   writeheader(gfc,gi->region0_count, 4);
+                   writeheader(gfc,gi->region1_count, 3);
+               }
+               writeheader(gfc,gi->preflag,            1);
+               writeheader(gfc,gi->scalefac_scale,     1);
+               writeheader(gfc,gi->count1table_select, 1);
+           }
+       }
+    } else {
+       /* MPEG2 */
+       assert(l3_side->main_data_begin >= 0);
+       writeheader(gfc,(l3_side->main_data_begin), 8);
+       writeheader(gfc,l3_side->private_bits, gfc->channels_out);
+
+       gr = 0;
+       for (ch = 0; ch < gfc->channels_out; ch++) {
+           gr_info *gi = &l3_side->gr[gr].ch[ch].tt;
+           writeheader(gfc,gi->part2_3_length,       12);
+           writeheader(gfc,gi->big_values / 2,        9);
+           writeheader(gfc,gi->global_gain,           8);
+           writeheader(gfc,gi->scalefac_compress,     9);
+           writeheader(gfc,gi->window_switching_flag, 1);
+
+           if (gi->window_switching_flag) {
+               writeheader(gfc,gi->block_type,       2);
+               writeheader(gfc,gi->mixed_block_flag, 1);
+
+               if (gi->table_select[0] == 14)
+                   gi->table_select[0] = 16;
+               writeheader(gfc,gi->table_select[0],  5);
+               if (gi->table_select[1] == 14)
+                   gi->table_select[1] = 16;
+               writeheader(gfc,gi->table_select[1],  5);
+
+               writeheader(gfc,gi->subblock_gain[0], 3);
+               writeheader(gfc,gi->subblock_gain[1], 3);
+               writeheader(gfc,gi->subblock_gain[2], 3);
+           } else {
+               if (gi->table_select[0] == 14)
+                   gi->table_select[0] = 16;
+               writeheader(gfc,gi->table_select[0], 5);
+               if (gi->table_select[1] == 14)
+                   gi->table_select[1] = 16;
+               writeheader(gfc,gi->table_select[1], 5);
+               if (gi->table_select[2] == 14)
+                   gi->table_select[2] = 16;
+               writeheader(gfc,gi->table_select[2], 5);
+
+               assert(gi->region0_count < 16U);
+               assert(gi->region1_count < 8U);
+               writeheader(gfc,gi->region0_count, 4);
+               writeheader(gfc,gi->region1_count, 3);
+           }
+
+           writeheader(gfc,gi->scalefac_scale,     1);
+           writeheader(gfc,gi->count1table_select, 1);
+       }
+    }
+
+    if (gfp->error_protection) {
+       /* (jo) error_protection: add crc16 information to header */
+       CRC_writeheader(gfc, gfc->header[gfc->h_ptr].buf);
+    }
+
+    {
+       int old = gfc->h_ptr;
+       assert(gfc->header[old].ptr == gfc->sideinfo_len * 8);
+
+       gfc->h_ptr = (old + 1) & (MAX_HEADER_BUF - 1);
+       gfc->header[gfc->h_ptr].write_timing =
+           gfc->header[old].write_timing + bitsPerFrame;
+
+       if (gfc->h_ptr == gfc->w_ptr) {
+         /* yikes! we are out of header buffer space */
+         ERRORF(gfc,"Error: MAX_HEADER_BUF too small in bitstream.c \n");
+       }
+
+    }
+}
+
+
+inline static int
+huffman_coder_count1(lame_global_flags *gfp,int *ix, gr_info *gi)
+{
+#ifdef DEBUG
+    lame_internal_flags *gfc = gfp->internal_flags;
+#endif
+    /* Write count1 area */
+    const struct huffcodetab *h = &ht[gi->count1table_select + 32];
+    int i,bits=0;
+#ifdef DEBUG
+    int gegebo = gfc->bs.totbit;
+#endif
+
+    ix += gi->big_values;
+    assert(gi->count1table_select < 2);
+
+
+    for (i = (gi->count1 - gi->big_values) / 4; i > 0; --i) {
+       int huffbits = 0;
+       int p = 0, v;
+
+       v = ix[0];
+       if (v) {
+           p += 8;
+           if (v < 0)
+               huffbits++;
+           assert(-1 <= v && v <= 1);
+       }
+
+       v = ix[1];
+       if (v) {
+           p += 4;
+           huffbits *= 2;
+           if (v < 0)
+               huffbits++;
+           assert(-1 <= v && v <= 1);
+       }
+
+       v = ix[2];
+       if (v) {
+           p += 2;
+           huffbits *= 2;
+           if (v < 0)
+               huffbits++;
+           assert(-1 <= v && v <= 1);
+       }
+
+       v = ix[3];
+       if (v) {
+           p++;
+           huffbits *= 2;
+           if (v < 0)
+               huffbits++;
+           assert(-1 <= v && v <= 1);
+       }
+
+       ix += 4;
+       putbits2(gfp,huffbits + h->table[p], h->hlen[p]);
+       bits += h->hlen[p];
+    }
+#ifdef DEBUG
+    DEBUGF(gfc,"%ld %d %d %d\n",gfc->bs.totbit -gegebo, gi->count1bits, gi->big_values, gi->count1);
+#endif
+    return bits;
+}
+
+
+
+/*
+  Implements the pseudocode of page 98 of the IS
+  */
+
+inline static int
+HuffmanCode ( lame_global_flags* const gfp, const int table_select, int x1, int x2 )
+{
+    const struct huffcodetab* h = ht + table_select;
+    int  code    = 0;
+    int  cbits   = 0;
+    int  xbits   = 0;
+    int  sgn_x1  = 0;
+    int  sgn_x2  = 0;
+    int  linbits = h->xlen;
+    int  xlen    = h->xlen;
+    int  ext; 
+
+    assert ( table_select > 0 );
+
+    if (x1 < 0) {
+       sgn_x1++;
+       x1 = -x1;
+    }
+
+    if (x2 < 0) {
+       sgn_x2++;
+       x2 = -x2;
+    }
+
+    ext     = sgn_x1;
+
+    if (table_select > 15) {
+       /* use ESC-words */
+       if (x1 > 14) {
+           int linbits_x1 = x1 - 15;
+           assert ( linbits_x1 <= h->linmax );
+           ext   |= linbits_x1 << 1;
+           xbits  = linbits;
+           x1     = 15;
+       }
+
+       if (x2 > 14) {
+           int linbits_x2 = x2 - 15;
+           assert ( linbits_x2 <= h->linmax );
+           ext  <<= linbits;
+           ext   |= linbits_x2;
+           xbits += linbits;
+           x2     = 15;
+       }
+       xlen = 16;
+    }
+
+    if (x1 != 0) {
+       cbits--;
+    }
+
+    if (x2 != 0) {
+       ext <<= 1;
+       ext  |= sgn_x2;
+       cbits--;
+    }
+
+    xbits -= cbits;
+
+    assert ( (x1|x2) < 16u );
+
+    x1 = x1 * xlen + x2;
+
+    code   = h->table [x1];
+    cbits += h->hlen  [x1];
+
+    assert ( cbits <= MAX_LENGTH );
+    assert ( xbits <= MAX_LENGTH );
+
+    putbits2 ( gfp, code, cbits );
+    putbits2 ( gfp, ext,  xbits );
+    
+    return cbits + xbits;
+}
+
+static int
+Huffmancodebits(lame_global_flags *gfp, int tableindex, int start, int end, int *ix)
+{
+    int i,bits;
+
+    assert(tableindex < 32);
+    if (!tableindex) return 0;
+
+    bits=0;
+    for (i = start; i < end; i += 2) {
+      bits +=HuffmanCode(gfp,tableindex, ix[i], ix[i + 1]);
+    }
+    return bits;
+}
+
+
+
+/*
+  Note the discussion of huffmancodebits() on pages 28
+  and 29 of the IS, as well as the definitions of the side
+  information on pages 26 and 27.
+  */
+static int
+ShortHuffmancodebits(lame_global_flags *gfp,int *ix, gr_info *gi)
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    int bits;
+    int region1Start;
+    
+    region1Start = 3*gfc->scalefac_band.s[3];
+    if (region1Start > gi->big_values)         
+        region1Start = gi->big_values;
+
+    /* short blocks do not have a region2 */
+    bits  = Huffmancodebits(gfp,gi->table_select[0], 0, region1Start, ix);
+    bits += Huffmancodebits(gfp,gi->table_select[1], region1Start, gi->big_values, ix);
+    return bits;
+}
+
+static int
+LongHuffmancodebits(lame_global_flags *gfp,int *ix, gr_info *gi)
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    int i, bigvalues,bits=0;
+    int region1Start, region2Start;
+
+    bigvalues = gi->big_values;
+    assert(0 <= bigvalues && bigvalues <= 576);
+
+    i = gi->region0_count + 1;
+    assert(i < 23);
+    region1Start = gfc->scalefac_band.l[i];
+    i += gi->region1_count + 1;
+    assert(i < 23);
+    region2Start = gfc->scalefac_band.l[i];
+
+    if (region1Start > bigvalues)
+       region1Start = bigvalues;
+
+    if (region2Start > bigvalues)
+       region2Start = bigvalues;
+
+    bits +=Huffmancodebits(gfp,gi->table_select[0], 0, region1Start, ix);
+    bits +=Huffmancodebits(gfp,gi->table_select[1], region1Start, region2Start, ix);
+    bits +=Huffmancodebits(gfp,gi->table_select[2], region2Start, bigvalues, ix);
+    return bits;
+}
+
+inline static int
+writeMainData ( lame_global_flags * const gfp,
+        int              l3_enc   [2] [2] [576],
+        III_scalefac_t   scalefac [2] [2] )
+{
+    int gr, ch, sfb,data_bits,scale_bits,tot_bits=0;
+    lame_internal_flags *gfc=gfp->internal_flags;
+    III_side_info_t *l3_side;
+
+    l3_side = &gfc->l3_side;
+    if (gfp->version == 1) {
+       /* MPEG 1 */
+       for (gr = 0; gr < 2; gr++) {
+           for (ch = 0; ch < gfc->channels_out; ch++) {
+               gr_info *gi = &l3_side->gr[gr].ch[ch].tt;
+               int slen1 = slen1_tab[gi->scalefac_compress];
+               int slen2 = slen2_tab[gi->scalefac_compress];
+               data_bits=0;
+               scale_bits=0;
+
+#ifdef DEBUG
+               hogege = gfc->bs.totbit;
+#endif
+               if (gi->block_type == SHORT_TYPE) {
+                   for (sfb = 0; sfb < SBPSY_s; sfb++) {
+                       int slen = sfb < 6 ? slen1 : slen2;
+
+                       assert(scalefac[gr][ch].s[sfb][0]>=0);
+                       assert(scalefac[gr][ch].s[sfb][1]>=0);
+                       assert(scalefac[gr][ch].s[sfb][2]>=0);
+
+                       putbits2(gfp,scalefac[gr][ch].s[sfb][0], slen);
+                       putbits2(gfp,scalefac[gr][ch].s[sfb][1], slen);
+                       putbits2(gfp,scalefac[gr][ch].s[sfb][2], slen);
+                       scale_bits += 3*slen;
+                   }
+                   data_bits += ShortHuffmancodebits(gfp,l3_enc[gr][ch], gi);
+               } else {
+                   int i;
+                   for (i = 0; i < sizeof(scfsi_band) / sizeof(int) - 1;
+                        i++) {
+                       if (gr != 0 && l3_side->scfsi[ch][i])
+                           continue;
+
+                       for (sfb = scfsi_band[i]; sfb < scfsi_band[i + 1];
+                            sfb++) {
+
+                           assert(scalefac[gr][ch].l[sfb]>=0);
+                           putbits2(gfp,scalefac[gr][ch].l[sfb],
+                                   sfb < 11 ? slen1 : slen2);
+                           scale_bits += sfb < 11 ? slen1 : slen2;
+                       }
+                   }
+                   data_bits +=LongHuffmancodebits(gfp,l3_enc[gr][ch], gi);
+               }
+               data_bits +=huffman_coder_count1(gfp,l3_enc[gr][ch], gi);
+#ifdef DEBUG
+               DEBUGF(gfc,"<%ld> ", gfc->bs.totbit-hogege);
+#endif
+               /* does bitcount in quantize.c agree with actual bit count?*/
+               assert(data_bits==gi->part2_3_length-gi->part2_length);
+               assert(scale_bits==gi->part2_length);
+               tot_bits += scale_bits + data_bits;
+
+           } /* for ch */
+       } /* for gr */
+    } else {
+       /* MPEG 2 */
+       gr = 0;
+       for (ch = 0; ch < gfc->channels_out; ch++) {
+           gr_info *gi = &l3_side->gr[gr].ch[ch].tt;
+           int i, sfb_partition;
+           assert(gi->sfb_partition_table);
+           data_bits = 0;
+           scale_bits=0;
+
+           sfb = 0;
+           sfb_partition = 0;
+           if (gi->block_type == SHORT_TYPE) {
+               for (; sfb_partition < 4; sfb_partition++) {
+                   int sfbs = gi->sfb_partition_table[sfb_partition] / 3;
+                   int slen = gi->slen[sfb_partition];
+                   for (i = 0; i < sfbs; i++, sfb++) {
+                       putbits2(gfp,Max(scalefac[gr][ch].s[sfb][0], 0U), slen);
+                       putbits2(gfp,Max(scalefac[gr][ch].s[sfb][1], 0U), slen);
+                       putbits2(gfp,Max(scalefac[gr][ch].s[sfb][2], 0U), slen);
+                       scale_bits += 3*slen;
+                   }
+               }
+               data_bits += ShortHuffmancodebits(gfp,l3_enc[gr][ch], gi);
+           } else {
+               for (; sfb_partition < 4; sfb_partition++) {
+                   int sfbs = gi->sfb_partition_table[sfb_partition];
+                   int slen = gi->slen[sfb_partition];
+                   for (i = 0; i < sfbs; i++, sfb++) {
+                       putbits2(gfp,Max(scalefac[gr][ch].l[sfb], 0U), slen);
+                       scale_bits += slen;
+                   }
+               }
+               data_bits +=LongHuffmancodebits(gfp,l3_enc[gr][ch], gi);
+           }
+           data_bits +=huffman_coder_count1(gfp,l3_enc[gr][ch], gi);
+
+           /* does bitcount in quantize.c agree with actual bit count?*/
+           assert(data_bits==gi->part2_3_length-gi->part2_length);
+           assert(scale_bits==gi->part2_length);
+           tot_bits += scale_bits + data_bits;
+       } /* for ch */
+    } /* for gf */
+    return tot_bits;
+} /* main_data */
+
+
+
+/* compute the number of bits required to flush all mp3 frames
+   currently in the buffer.  This should be the same as the
+   reservoir size.  Only call this routine between frames - i.e.
+   only after all headers and data have been added to the buffer
+   by format_bitstream().
+
+   Also compute total_bits_output = 
+       size of mp3 buffer (including frame headers which may not
+       have yet been send to the mp3 buffer) + 
+       number of bits needed to flush all mp3 frames.
+
+   total_bytes_output is the size of the mp3 output buffer if 
+   lame_encode_flush_nogap() was called right now. 
+
+ */
+int
+compute_flushbits( const lame_global_flags * gfp, int *total_bytes_output )
+{
+  lame_internal_flags *gfc=gfp->internal_flags;
+  int flushbits,remaining_headers;
+  int bitsPerFrame, mean_bits;
+  int last_ptr,first_ptr;
+  first_ptr=gfc->w_ptr;           /* first header to add to bitstream */
+  last_ptr = gfc->h_ptr - 1;   /* last header to add to bitstream */
+  if (last_ptr==-1) last_ptr=MAX_HEADER_BUF-1;   
+
+  /* add this many bits to bitstream so we can flush all headers */
+  flushbits = gfc->header[last_ptr].write_timing - gfc->bs.totbit;
+  *total_bytes_output=flushbits;
+
+  if (flushbits >= 0) {
+    /* if flushbits >= 0, some headers have not yet been written */
+    /* reduce flushbits by the size of the headers */
+    remaining_headers= 1+last_ptr - first_ptr;
+    if (last_ptr < first_ptr) 
+      remaining_headers= 1+last_ptr - first_ptr + MAX_HEADER_BUF;
+    flushbits -= remaining_headers*8*gfc->sideinfo_len;
+  }
+
+
+  /* finally, add some bits so that the last frame is complete
+   * these bits are not necessary to decode the last frame, but
+   * some decoders will ignore last frame if these bits are missing 
+   */
+  getframebits(gfp,&bitsPerFrame,&mean_bits);
+  flushbits += bitsPerFrame;
+  *total_bytes_output += bitsPerFrame;
+  // round up:  
+  if (*total_bytes_output % 8) 
+      *total_bytes_output = 1 + (*total_bytes_output/8);
+  else
+      *total_bytes_output = (*total_bytes_output/8);
+  *total_bytes_output +=  gfc->bs.buf_byte_idx + 1;
+
+
+  if (flushbits<0) {
+#if 0
+    /* if flushbits < 0, this would mean that the buffer looks like:
+     * (data...)  last_header  (data...)  (extra data that should not be here...)
+     */
+    DEBUGF(gfc,"last header write_timing = %i \n",gfc->header[last_ptr].write_timing);
+    DEBUGF(gfc,"first header write_timing = %i \n",gfc->header[first_ptr].write_timing);
+    DEBUGF(gfc,"bs.totbit:                 %i \n",gfc->bs.totbit);
+    DEBUGF(gfc,"first_ptr, last_ptr        %i %i \n",first_ptr,last_ptr);
+    DEBUGF(gfc,"remaining_headers =        %i \n",remaining_headers);
+    DEBUGF(gfc,"bitsperframe:              %i \n",bitsPerFrame);
+    DEBUGF(gfc,"sidelen:                   %i \n",gfc->sideinfo_len);
+#endif
+    ERRORF(gfc,"strange error flushing buffer ... \n");
+  }
+  return flushbits;
+}
+
+
+
+void
+flush_bitstream(lame_global_flags *gfp)
+{
+  lame_internal_flags *gfc=gfp->internal_flags;
+  III_side_info_t *l3_side;
+  int nbytes;
+  int flushbits;
+  int bitsPerFrame, mean_bits;
+  int last_ptr,first_ptr;
+  first_ptr=gfc->w_ptr;           /* first header to add to bitstream */
+  last_ptr = gfc->h_ptr - 1;   /* last header to add to bitstream */
+  if (last_ptr==-1) last_ptr=MAX_HEADER_BUF-1;   
+  l3_side = &gfc->l3_side;
+
+
+  if ((flushbits = compute_flushbits(gfp,&nbytes)) < 0) return;  
+  drain_into_ancillary(gfp,flushbits);
+
+  /* check that the 100% of the last frame has been written to bitstream */
+  getframebits(gfp,&bitsPerFrame,&mean_bits);
+  assert (gfc->header[last_ptr].write_timing + bitsPerFrame  == gfc->bs.totbit);
+
+  /* we have padded out all frames with ancillary data, which is the
+     same as filling the bitreservoir with ancillary data, so : */
+  gfc->ResvSize=0;
+  l3_side->main_data_begin = 0;
+
+}
+
+
+
+
+void  add_dummy_byte ( lame_global_flags* const gfp, unsigned char val )
+{
+  lame_internal_flags *gfc = gfp->internal_flags;
+  int i;
+
+  putbits_noheaders(gfp,val,8);   
+
+  for (i=0 ; i< MAX_HEADER_BUF ; ++i) 
+    gfc->header[i].write_timing += 8;
+}
+
+
+/*
+  format_bitstream()
+
+  This is called after a frame of audio has been quantized and coded.
+  It will write the encoded audio to the bitstream. Note that
+  from a layer3 encoder's perspective the bit stream is primarily
+  a series of main_data() blocks, with header and side information
+  inserted at the proper locations to maintain framing. (See Figure A.7
+  in the IS).
+  */
+int
+format_bitstream(lame_global_flags *gfp, int bitsPerFrame,
+      int              l3_enc[2][2][576],
+       III_scalefac_t   scalefac[2][2] )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    int bits,nbytes;
+    III_side_info_t *l3_side;
+    l3_side = &gfc->l3_side;
+
+    drain_into_ancillary(gfp,l3_side->resvDrain_pre);
+
+    encodeSideInfo2(gfp,bitsPerFrame);
+    bits = 8*gfc->sideinfo_len;
+    bits+=writeMainData(gfp,l3_enc,scalefac);
+    drain_into_ancillary(gfp,l3_side->resvDrain_post);
+    bits += l3_side->resvDrain_post;
+
+    l3_side->main_data_begin += (bitsPerFrame-bits)/8;
+
+    /* compare number of bits needed to clear all buffered mp3 frames
+     * with what we think the resvsize is: */
+    if (compute_flushbits(gfp,&nbytes) != gfc->ResvSize) {
+        ERRORF(gfc,"Internal buffer inconsistency. flushbits <> ResvSize");
+    }
+
+
+    /* compare main_data_begin for the next frame with what we
+     * think the resvsize is: */
+    if ((l3_side->main_data_begin * 8) != gfc->ResvSize ) {
+      ERRORF(gfc,"bit reservoir error: \n"
+             "l3_side->main_data_begin: %i \n"
+             "Resvoir size:             %i \n"
+             "resv drain (post)         %i \n"
+             "resv drain (pre)          %i \n"
+             "header and sideinfo:      %i \n"
+             "data bits:                %i \n"
+             "total bits:               %i (remainder: %i) \n"
+             "bitsperframe:             %i \n",
+
+             8*l3_side->main_data_begin,
+             gfc->ResvSize,
+             l3_side->resvDrain_post,
+             l3_side->resvDrain_pre,
+             8*gfc->sideinfo_len,
+             bits-l3_side->resvDrain_post-8*gfc->sideinfo_len,
+             bits, bits % 8,
+             bitsPerFrame
+      );
+
+      gfc->ResvSize = l3_side->main_data_begin*8;
+    };
+    assert(gfc->bs.totbit % 8 == 0);
+
+    if (gfc->bs.totbit > 1000000000  ) {
+      /* to avoid totbit overflow, (at 8h encoding at 128kbs) lets reset bit counter*/
+      int i;
+      for (i=0 ; i< MAX_HEADER_BUF ; ++i) 
+       gfc->header[i].write_timing -= gfc->bs.totbit;      
+      gfc->bs.totbit=0;
+    }
+
+
+    return 0;
+}
+
+
+
+
+
+/* copy data out of the internal MP3 bit buffer into a user supplied
+   unsigned char buffer.
+
+   mp3data=0      indicates data in buffer is an id3tags and VBR tags
+   mp3data=1      data is real mp3 frame data. 
+
+
+*/
+int copy_buffer(lame_internal_flags *gfc,unsigned char *buffer,int size,int mp3data) 
+{
+    Bit_stream_struc *bs=&gfc->bs;
+    int minimum = bs->buf_byte_idx + 1;
+    if (minimum <= 0) return 0;
+    if (size!=0 && minimum>size) return -1; /* buffer is too small */
+    memcpy(buffer,bs->buf,minimum);
+    bs->buf_byte_idx = -1;
+    bs->buf_bit_idx = 0;
+    
+    if (mp3data) {
+        UpdateMusicCRC(&gfc->nMusicCRC,buffer,minimum);
+    }
+    return minimum;
+}
+
+
+void init_bit_stream_w(lame_internal_flags *gfc)
+{
+   gfc->bs.buf = (unsigned char *)       malloc(BUFFER_SIZE);
+   gfc->bs.buf_size = BUFFER_SIZE;
+
+   gfc->h_ptr = gfc->w_ptr = 0;
+   gfc->header[gfc->h_ptr].write_timing = 0;
+   gfc->bs.buf_byte_idx = -1;
+   gfc->bs.buf_bit_idx = 0;
+   gfc->bs.totbit = 0;
+}
+
+/* end of bitstream.c */
diff --git a/lib/lame/bitstream.h b/lib/lame/bitstream.h
new file mode 100644 (file)
index 0000000..9ff1dbc
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *     MP3 bitstream Output interface for LAME
+ *
+ *     Copyright (c) 1999 Takehiro TOMINAGA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_BITSTREAM_H
+#define LAME_BITSTREAM_H
+#include "util.h"
+
+int format_bitstream(lame_global_flags *gfp, int i,
+                    int              l3_enc[2][2][576],
+                    III_scalefac_t   scalefac[2][2] );
+
+void flush_bitstream(lame_global_flags *gfp);
+void add_dummy_byte ( lame_global_flags* const gfp, unsigned char val );
+
+int  copy_buffer(lame_internal_flags *gfc,unsigned char *buffer,int buffer_size,int update_crc);
+void init_bit_stream_w(lame_internal_flags *gfc);
+void CRC_writeheader (lame_internal_flags *gfc, char *buffer);
+int compute_flushbits(const lame_global_flags *gfp, int *nbytes);
+
+
+#endif
diff --git a/lib/lame/config_static.h b/lib/lame/config_static.h
new file mode 100644 (file)
index 0000000..62c24ff
--- /dev/null
@@ -0,0 +1,124 @@
+/* Define if you have alloca, as a function or macro.  */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+#define HAVE_ALLOCA_H 1
+
+/* Define if the `long double' type works.  */
+#define HAVE_LONG_DOUBLE 1
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+/* #undef size_t */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+/* #undef WORDS_BIGENDIAN */
+
+/* #undef  int8_t */
+#define uint8_t unsigned char
+/* #undef  int18_t */
+#define uint16_t unsigned short
+/* #undef  int32_t */
+#define uint32_t unsigned int
+/* #undef  int64_t */
+#define uint64_t unsigned long long
+#define ieee854_float80_t long double
+#define ieee754_float64_t double
+#define ieee754_float32_t float
+
+/* The number of bytes in a double.  */
+#define SIZEOF_DOUBLE 8
+
+/* The number of bytes in a float.  */
+#define SIZEOF_FLOAT 4
+
+/* The number of bytes in a int.  */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long.  */
+#define SIZEOF_LONG 4
+
+/* The number of bytes in a long double.  */
+/* #undef SIZEOF_LONG_DOUBLE */
+
+/* The number of bytes in a long long.  */
+#define SIZEOF_LONG_LONG 8
+
+/* The number of bytes in a short.  */
+#define SIZEOF_SHORT 2
+
+/* The number of bytes in a unsigned int.  */
+#define SIZEOF_UNSIGNED_INT 4
+
+/* The number of bytes in a unsigned long.  */
+#define SIZEOF_UNSIGNED_LONG 4
+
+/* The number of bytes in a unsigned long long.  */
+#define SIZEOF_UNSIGNED_LONG_LONG 8
+
+/* The number of bytes in a unsigned short.  */
+#define SIZEOF_UNSIGNED_SHORT 2
+
+/* Define if you have the <errno.h> header file.  */
+#define HAVE_ERRNO_H 1
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <limits.h> header file.  */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <string.h> header file.  */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/time.h> header file.  */
+#define HAVE_SYS_TIME_H 1
+
+/* Define if you have the <termcap.h> header file.  */
+#define HAVE_TERMCAP_H 1
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 1
+
+/* Name of package */
+#define PACKAGE "lame"
+
+/* Version number of package */
+#define VERSION "3.91"
+
+/* Define if compiler has function prototypes */
+#define PROTOTYPES 1
+
+/* system has 80 bit floats */
+#define HAVE_IEEE854_FLOAT80 1
+
+/* requested by Frank, seems to be temporary needed for a smooth transition */
+#define LAME_LIBRARY_BUILD 1
+
+/* have working GTK */
+#define HAVE_GTK 1
+
+/* build with layer 1 decoding */
+#define USE_LAYER_1 1
+
+/* build with layer 2 decoding */
+#define USE_LAYER_2 1
+
+/* enable VBR bitrate histogram */
+#define BRHIST 1
+
+/* have termcap */
+#define HAVE_TERMCAP 1
+
+/* IEEE754 compatible machine */
+#define TAKEHIRO_IEEE754_HACK 1
+
+/* no debug build */
+#define NDEBUG 1
+
diff --git a/lib/lame/encoder.c b/lib/lame/encoder.c
new file mode 100644 (file)
index 0000000..6c41875
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+ *     LAME MP3 encoding engine
+ *
+ *     Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: encoder.c,v 1.1 2002/04/28 17:30:18 kramm Exp $ */
+
+#include "config_static.h"
+
+#include <assert.h>
+
+#include "lame.h"
+#include "util.h"
+#include "newmdct.h"
+#include "psymodel.h"
+#include "quantize.h"
+#include "quantize_pvt.h"
+#include "bitstream.h"
+#include "VbrTag.h"
+#include "vbrquantize.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+
+/*
+ * auto-adjust of ATH, useful for low volume
+ * Gabriel Bouvigne 3 feb 2001
+ *
+ * modifies some values in
+ *   gfp->internal_flags->ATH
+ *   (gfc->ATH)
+ */
+void
+adjust_ATH( lame_global_flags* const  gfp,
+            FLOAT8              tot_ener[2][4] )
+{
+    lame_internal_flags* const  gfc = gfp->internal_flags;
+    int gr, channel;
+    FLOAT max_pow, max_pow_alt;
+    FLOAT8 max_val;
+
+    if (gfc->ATH->use_adjust == 0) {
+        gfc->ATH->adjust = 1.0;        /* no adjustment */
+        return;
+    }
+    
+    switch( gfp->athaa_loudapprox ) {
+    case 1:
+                                /* flat approximation for loudness (squared) */
+        max_pow = 0;
+        for ( gr = 0; gr < gfc->mode_gr; ++gr ) 
+            for ( channel = 0; channel < gfc->channels_out; ++channel ) 
+                max_pow = Max( max_pow, tot_ener[gr][channel] );
+        max_pow *= 0.25/ 5.6e13; /* scale to 0..1 (5.6e13), and tune (0.25) */
+        break;
+    
+    case 2:                     /* jd - 2001 mar 12, 27, jun 30 */
+    {                          /* loudness based on equal loudness curve; */
+                                /* use granule with maximum combined loudness*/
+       FLOAT gr2_max;
+        max_pow = gfc->loudness_sq[0][0];
+        if( gfc->channels_out == 2 ) {
+            max_pow += gfc->loudness_sq[0][1];
+           gr2_max = gfc->loudness_sq[1][0] + gfc->loudness_sq[1][1];
+       } else {
+           gr2_max = gfc->loudness_sq[1][0];
+           max_pow += max_pow;
+           gr2_max += gr2_max;
+       }
+       if( gfc->mode_gr == 2 ) {
+           max_pow = Max( max_pow, gr2_max );
+       }
+       max_pow *= 0.5;         /* max_pow approaches 1.0 for full band noise*/
+        break;
+    }
+
+    default:                    /* jd - 2001 mar 27, 31, jun 30 */
+                                /* no adaptive threshold */
+        max_pow = 1.0 / gfc->athaa_sensitivity_p;
+        break;
+    }
+
+                                /* jd - 2001 mar 31, jun 30 */
+                                /* user tuning of ATH adjustment region */
+    max_pow_alt = max_pow;
+    max_pow *= gfc->athaa_sensitivity_p;
+    if (gfc->presetTune.use)
+        max_pow_alt *= pow( 10.0, gfc->presetTune.athadjust_safe_athaasensitivity / -10.0 );
+
+    /*  adjust ATH depending on range of maximum value
+     */
+    switch ( gfc->ATH->use_adjust ) {
+
+    case  1:
+        max_val = sqrt( max_pow ); /* GB's original code requires a maximum */
+        max_val *= 32768;          /*  sample or loudness value up to 32768 */
+
+                                /* by Gabriel Bouvigne */
+        if      (0.5 < max_val / 32768) {       /* value above 50 % */
+                gfc->ATH->adjust = 1.0;         /* do not reduce ATH */
+        }
+        else if (0.3 < max_val / 32768) {       /* value above 30 % */
+                gfc->ATH->adjust *= 0.955;      /* reduce by ~0.2 dB */
+                if (gfc->ATH->adjust < 0.3)     /* but ~5 dB in maximum */
+                    gfc->ATH->adjust = 0.3;            
+        }
+        else {                                  /* value below 30 % */
+                gfc->ATH->adjust *= 0.93;       /* reduce by ~0.3 dB */
+                if (gfc->ATH->adjust < 0.01)    /* but 20 dB in maximum */
+                    gfc->ATH->adjust = 0.01;
+        }
+        break;
+
+    case  2:   
+        max_val = Min( max_pow, 1.0 ) * 32768; /* adapt for RH's adjust */
+
+      {                         /* by Robert Hegemann */
+        /*  this code reduces slowly the ATH (speed of 12 dB per second)
+         */
+        FLOAT8 
+        //x = Max (640, 320*(int)(max_val/320));
+        x = Max (32, 32*(int)(max_val/32));
+        x = x/32768;
+        gfc->ATH->adjust *= gfc->ATH->decay;
+        if (gfc->ATH->adjust < x)       /* but not more than f(x) dB */
+            gfc->ATH->adjust = x;
+      }
+        break;
+
+    case  3:
+      {                         /* jd - 2001 feb27, mar12,20, jun30, jul22 */
+                                /* continuous curves based on approximation */
+                                /* to GB's original values. */
+        FLOAT8 adj_lim_new;
+                                /* For an increase in approximate loudness, */
+                                /* set ATH adjust to adjust_limit immediately*/
+                                /* after a delay of one frame. */
+                                /* For a loudness decrease, reduce ATH adjust*/
+                                /* towards adjust_limit gradually. */
+                                /* max_pow is a loudness squared or a power. */
+        if( max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */
+            if( gfc->ATH->adjust >= 1.0) {
+                gfc->ATH->adjust = 1.0;
+                if (gfc->presetTune.use) {
+                       if (max_pow_alt > gfc->presetTune.athadjust_safe_noiseshaping_thre)
+                             gfc->presetTune.athadjust_safe_noiseshaping = 1;
+                       else
+                             gfc->presetTune.athadjust_safe_noiseshaping = 0;
+                }
+            } else {
+                                /* preceding frame has lower ATH adjust; */
+                                /* ascend only to the preceding adjust_limit */
+                                /* in case there is leading low volume */
+                if( gfc->ATH->adjust < gfc->ATH->adjust_limit) {
+                    gfc->ATH->adjust = gfc->ATH->adjust_limit;
+                    if (gfc->presetTune.use) {
+                        if (max_pow_alt > gfc->presetTune.athadjust_safe_noiseshaping_thre)
+                            gfc->presetTune.athadjust_safe_noiseshaping = 1;
+                        else
+                            gfc->presetTune.athadjust_safe_noiseshaping = 0;
+                    }
+                }
+            }
+            gfc->ATH->adjust_limit = 1.0;
+        } else {                /* adjustment curve */
+                                /* about 32 dB maximum adjust (0.000625) */
+            adj_lim_new = 31.98 * max_pow + 0.000625;
+            if( gfc->ATH->adjust >= adj_lim_new) { /* descend gradually */
+                gfc->ATH->adjust *= adj_lim_new * 0.075 + 0.925;
+                if( gfc->ATH->adjust < adj_lim_new) { /* stop descent */
+                    gfc->ATH->adjust = adj_lim_new;
+                }
+            } else {            /* ascend */
+                if( gfc->ATH->adjust_limit >= adj_lim_new) {
+                    gfc->ATH->adjust = adj_lim_new;
+                } else {        /* preceding frame has lower ATH adjust; */
+                                /* ascend only to the preceding adjust_limit */
+                    if( gfc->ATH->adjust < gfc->ATH->adjust_limit) {
+                        gfc->ATH->adjust = gfc->ATH->adjust_limit;
+                    }
+                }
+            }
+            gfc->ATH->adjust_limit = adj_lim_new;
+        }
+      }
+        break;
+        
+    default:
+        gfc->ATH->adjust = 1.0;        /* no adjustment */
+        break;
+    }   /* switch */
+}
+
+/************************************************************************
+*
+* encodeframe()           Layer 3
+*
+* encode a single frame
+*
+************************************************************************
+lame_encode_frame()
+
+
+                       gr 0            gr 1
+inbuf:           |--------------|---------------|-------------|
+MDCT output:  |--------------|---------------|-------------|
+
+FFT's                    <---------1024---------->
+                                         <---------1024-------->
+
+
+
+    inbuf = buffer of PCM data size=MP3 framesize
+    encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY
+    so the MDCT coefficints are from inbuf[ch][-MDCTDELAY]
+
+    psy-model FFT has a 1 granule delay, so we feed it data for the 
+    next granule.
+    FFT is centered over granule:  224+576+224
+    So FFT starts at:   576-224-MDCTDELAY
+
+    MPEG2:  FFT ends at:  BLKSIZE+576-224-MDCTDELAY
+    MPEG1:  FFT ends at:  BLKSIZE+2*576-224-MDCTDELAY    (1904)
+
+    FFT starts at 576-224-MDCTDELAY (304)  = 576-FFTOFFSET
+
+*/
+
+typedef FLOAT8 chgrdata[2][2];
+
+int  lame_encode_mp3_frame (                           // Output
+       lame_global_flags* const  gfp,                  // Context
+       sample_t*                 inbuf_l,              // Input
+       sample_t*                 inbuf_r,              // Input
+       unsigned char*            mp3buf,               // Output
+       int                    mp3buf_size )            // Output
+{
+#ifdef macintosh /* PLL 14/04/2000 */
+  static FLOAT8 xr[2][2][576];
+  static int l3_enc[2][2][576];
+#else
+  FLOAT8 xr[2][2][576];
+  int l3_enc[2][2][576];
+#endif
+  int mp3count;
+  III_psy_ratio masking_LR[2][2];    /*LR masking & energy */
+  III_psy_ratio masking_MS[2][2]; /*MS masking & energy */
+  III_psy_ratio (*masking)[2][2];  /*pointer to selected maskings*/
+  III_scalefac_t scalefac[2][2];
+  const sample_t *inbuf[2];
+  lame_internal_flags *gfc=gfp->internal_flags;
+
+  FLOAT8 tot_ener[2][4];   
+  FLOAT8 ms_ener_ratio[2]={.5,.5};
+  chgrdata pe,pe_MS;
+  chgrdata *pe_use;
+
+  int ch,gr,mean_bits;
+  int bitsPerFrame;
+
+  int check_ms_stereo;
+  FLOAT8 ms_ratio_next = 0.;
+  FLOAT8 ms_ratio_prev = 0.;
+
+
+  memset((char *) masking_LR, 0, sizeof(masking_LR));
+  memset((char *) masking_MS, 0, sizeof(masking_MS));
+  memset((char *) scalefac, 0, sizeof(scalefac));
+  inbuf[0]=inbuf_l;
+  inbuf[1]=inbuf_r;
+
+  check_ms_stereo =  (gfp->mode == JOINT_STEREO);
+  gfc->mode_ext = MPG_MD_LR_LR;
+
+  if (gfc->lame_encode_frame_init==0 )  {
+    gfc->lame_encode_frame_init=1;
+    
+    /* padding method as described in 
+     * "MPEG-Layer3 / Bitstream Syntax and Decoding"
+     * by Martin Sieler, Ralph Sperschneider
+     *
+     * note: there is no padding for the very first frame
+     *
+     * Robert.Hegemann@gmx.de 2000-06-22
+     */
+        
+    gfc->frac_SpF = ((gfp->version+1)*72000L*gfp->brate) % gfp->out_samplerate;
+    gfc->slot_lag  = gfc->frac_SpF;
+    
+    /* check FFT will not use a negative starting offset */
+#if 576 < FFTOFFSET
+# error FFTOFFSET greater than 576: FFT uses a negative offset
+#endif
+    /* check if we have enough data for FFT */
+    assert(gfc->mf_size>=(BLKSIZE+gfp->framesize-FFTOFFSET));
+    /* check if we have enough data for polyphase filterbank */
+    /* it needs 1152 samples + 286 samples ignored for one granule */
+    /*          1152+576+286 samples for two granules */
+    assert(gfc->mf_size>=(286+576*(1+gfc->mode_gr)));
+
+    /* prime the MDCT/polyphase filterbank with a short block */
+    { 
+      int i,j;
+      sample_t primebuff0[286+1152+576];
+      sample_t primebuff1[286+1152+576];
+      for (i=0, j=0; i<286+576*(1+gfc->mode_gr); ++i) {
+       if (i<576*gfc->mode_gr) {
+         primebuff0[i]=0;
+         if (gfc->channels_out==2) 
+           primebuff1[i]=0;
+       }else{
+         primebuff0[i]=inbuf[0][j];
+         if (gfc->channels_out==2) 
+           primebuff1[i]=inbuf[1][j];
+         ++j;
+       }
+      }
+      /* polyphase filtering / mdct */
+      for ( gr = 0; gr < gfc->mode_gr; gr++ ) {
+       for ( ch = 0; ch < gfc->channels_out; ch++ ) {
+         gfc->l3_side.gr[gr].ch[ch].tt.block_type=SHORT_TYPE;
+       }
+      }
+      mdct_sub48(gfc, primebuff0, primebuff1, xr);
+    }
+    
+    iteration_init(gfp);
+    
+    /*  prepare for ATH auto adjustment:
+     *  we want to decrease the ATH by 12 dB per second
+     */ {
+        FLOAT8 frame_duration = 576. * gfc->mode_gr / gfp->out_samplerate;
+        gfc->ATH->decay = pow(10., -12./10. * frame_duration);
+        gfc->ATH->adjust = 0.01; /* minimum, for leading low loudness */
+        gfc->ATH->adjust_limit = 1.0; /* on lead, allow adjust up to maximum */
+    }
+  }
+
+
+  /********************** padding *****************************/
+  switch (gfp->padding_type) {
+  case PAD_NO:
+    gfc->padding = FALSE;
+    break;
+  case PAD_ALL:
+    gfc->padding = TRUE;
+    break;
+  case PAD_ADJUST:
+  default:
+    if (gfp->VBR!=vbr_off) {
+      gfc->padding = FALSE;
+    } else {
+      if (gfp->disable_reservoir) {
+       gfc->padding = FALSE;
+       /* if the user specified --nores, dont very gfc->padding either */
+       /* tiny changes in frac_SpF rounding will cause file differences */
+      }else{
+        /* padding method as described in 
+         * "MPEG-Layer3 / Bitstream Syntax and Decoding"
+         * by Martin Sieler, Ralph Sperschneider
+         *
+         * note: there is no padding for the very first frame
+         *
+         * Robert.Hegemann@gmx.de 2000-06-22
+         */
+
+        gfc->slot_lag -= gfc->frac_SpF;
+        if (gfc->slot_lag < 0) {
+          gfc->slot_lag += gfp->out_samplerate;
+          gfc->padding = TRUE;
+        } else {
+          gfc->padding = FALSE;
+        }
+      } /* reservoir enabled */
+    }
+  }
+
+
+  if (gfc->psymodel) {
+    /* psychoacoustic model
+     * psy model has a 1 granule (576) delay that we must compensate for
+     * (mt 6/99).
+     */
+    int ret;
+    const sample_t *bufp[2];  /* address of beginning of left & right granule */
+    int blocktype[2];
+
+    ms_ratio_prev=gfc->ms_ratio[gfc->mode_gr-1];
+    for (gr=0; gr < gfc->mode_gr ; gr++) {
+
+      for ( ch = 0; ch < gfc->channels_out; ch++ )
+       bufp[ch] = &inbuf[ch][576 + gr*576-FFTOFFSET];
+
+      if (gfc->nsPsy.use) {
+       ret=L3psycho_anal_ns( gfp, bufp, gr, 
+                             &gfc->ms_ratio[gr],&ms_ratio_next,
+                             masking_LR, masking_MS,
+                             pe[gr],pe_MS[gr],tot_ener[gr],blocktype);
+      } else {
+       ret=L3psycho_anal( gfp, bufp, gr, 
+                          &gfc->ms_ratio[gr],&ms_ratio_next,
+                          masking_LR, masking_MS,
+                          pe[gr],pe_MS[gr],tot_ener[gr],blocktype);
+      }
+      if (ret!=0) return -4;
+
+      for ( ch = 0; ch < gfc->channels_out; ch++ )
+       gfc->l3_side.gr[gr].ch[ch].tt.block_type=blocktype[ch];
+
+      if (check_ms_stereo) {
+         ms_ener_ratio[gr] = tot_ener[gr][2]+tot_ener[gr][3];
+         if (ms_ener_ratio[gr]>0)
+             ms_ener_ratio[gr] = tot_ener[gr][3]/ms_ener_ratio[gr];
+      }
+
+    }
+  }else{
+    for (gr=0; gr < gfc->mode_gr ; gr++)
+      for ( ch = 0; ch < gfc->channels_out; ch++ ) {
+       gfc->l3_side.gr[gr].ch[ch].tt.block_type=NORM_TYPE;
+       pe_MS[gr][ch]=pe[gr][ch]=700;
+      }
+  }
+
+
+
+  /* auto-adjust of ATH, useful for low volume */
+  adjust_ATH( gfp, tot_ener );
+
+
+
+  /* block type flags */
+  for( gr = 0; gr < gfc->mode_gr; gr++ ) {
+    for ( ch = 0; ch < gfc->channels_out; ch++ ) {
+      gr_info *cod_info = &gfc->l3_side.gr[gr].ch[ch].tt;
+      cod_info->mixed_block_flag = 0;     /* never used by this model */
+      if (cod_info->block_type == NORM_TYPE )
+       cod_info->window_switching_flag = 0;
+      else
+       cod_info->window_switching_flag = 1;
+    }
+  }
+
+
+  /* polyphase filtering / mdct */
+  mdct_sub48(gfc, inbuf[0], inbuf[1], xr);
+  /* re-order the short blocks, for more efficient encoding below */
+  for (gr = 0; gr < gfc->mode_gr; gr++) {
+    for (ch = 0; ch < gfc->channels_out; ch++) {
+      gr_info *cod_info = &gfc->l3_side.gr[gr].ch[ch].tt;
+      if (cod_info->block_type==SHORT_TYPE) {
+       freorder(gfc->scalefac_band.s,xr[gr][ch]);
+      }
+    }
+  }
+  
+
+  /* use m/s gfc->channels_out? */
+  if (check_ms_stereo) {
+    int gr0 = 0, gr1 = gfc->mode_gr-1;
+    /* make sure block type is the same in each channel */
+    check_ms_stereo =
+      (gfc->l3_side.gr[gr0].ch[0].tt.block_type==gfc->l3_side.gr[gr0].ch[1].tt.block_type) &&
+      (gfc->l3_side.gr[gr1].ch[0].tt.block_type==gfc->l3_side.gr[gr1].ch[1].tt.block_type);
+  }
+  
+  /* Here will be selected MS or LR coding of the 2 stereo channels */
+
+  assert (  gfc->mode_ext == MPG_MD_LR_LR );
+  gfc->mode_ext = MPG_MD_LR_LR;
+  
+  if (gfp->force_ms) {
+    gfc->mode_ext = MPG_MD_MS_LR;
+  } else if (check_ms_stereo) {
+      /* ms_ratio = is scaled, for historical reasons, to look like
+        a ratio of side_channel / total.  
+         0 = signal is 100% mono
+         .5 = L & R uncorrelated
+      */
+      
+      /* [0] and [1] are the results for the two granules in MPEG-1,
+       * in MPEG-2 it's only a faked averaging of the same value
+       * _prev is the value of the last granule of the previous frame
+       * _next is the value of the first granule of the next frame
+       */
+      FLOAT8  ms_ratio_ave1;
+      FLOAT8  ms_ratio_ave2;
+      FLOAT8  threshold1    = 0.35;
+      FLOAT8  threshold2    = 0.45;
+
+      /* take an average */
+      if (gfc->mode_gr==1) {
+         /* MPEG2 - no second granule */
+         ms_ratio_ave1 = 0.33 * ( gfc->ms_ratio[0] + ms_ratio_prev + ms_ratio_next );
+         ms_ratio_ave2 = gfc->ms_ratio[0];
+      }else{
+         ms_ratio_ave1 = 0.25 * ( gfc->ms_ratio[0] + gfc->ms_ratio[1] + ms_ratio_prev + ms_ratio_next );
+         ms_ratio_ave2 = 0.50 * ( gfc->ms_ratio[0] + gfc->ms_ratio[1] );
+      }
+      
+      if (gfp->mode_automs) {
+         if ( gfp->compression_ratio < 11.025 ) {
+             /* 11.025 => 1, 6.3 => 0 */
+             double thr = (gfp->compression_ratio - 6.3) / (11.025 - 6.3);
+             if (thr<0) thr=0;
+             threshold1   *= thr;
+             threshold2   *= thr;
+         }
+      }
+      
+      if ((ms_ratio_ave1 < threshold1  &&  ms_ratio_ave2 < threshold2) || gfc->nsPsy.use) {
+         int  sum_pe_MS = 0;
+         int  sum_pe_LR = 0;
+         for ( gr = 0; gr < gfc->mode_gr; gr++ ) {
+             for ( ch = 0; ch < gfc->channels_out; ch++ ) {
+                 sum_pe_MS += pe_MS[gr][ch];
+                 sum_pe_LR += pe[gr][ch];
+             }
+         }
+         
+         /* based on PE: M/S coding would not use much more bits than L/R coding */
+         
+         if (sum_pe_MS <= 1.07 * sum_pe_LR && !gfc->nsPsy.use) gfc->mode_ext = MPG_MD_MS_LR;
+         if (sum_pe_MS <= 1.00 * sum_pe_LR &&  gfc->nsPsy.use) gfc->mode_ext = MPG_MD_MS_LR;
+      }
+  }
+
+
+#if defined(HAVE_GTK)
+  /* copy data for MP3 frame analyzer */
+  if (gfp->analysis && gfc->pinfo != NULL) {
+    for ( gr = 0; gr < gfc->mode_gr; gr++ ) {
+      for ( ch = 0; ch < gfc->channels_out; ch++ ) {
+       gfc->pinfo->ms_ratio[gr]=gfc->ms_ratio[gr];
+       gfc->pinfo->ms_ener_ratio[gr]=ms_ener_ratio[gr];
+       gfc->pinfo->blocktype[gr][ch]=
+         gfc->l3_side.gr[gr].ch[ch].tt.block_type;
+       memcpy(gfc->pinfo->xr[gr][ch],xr[gr][ch],sizeof(xr[gr][ch]));
+       /* in psymodel, LR and MS data was stored in pinfo.  
+          switch to MS data: */
+       if (gfc->mode_ext==MPG_MD_MS_LR) {
+         gfc->pinfo->pe[gr][ch]=gfc->pinfo->pe[gr][ch+2];
+         gfc->pinfo->ers[gr][ch]=gfc->pinfo->ers[gr][ch+2];
+         memcpy(gfc->pinfo->energy[gr][ch],gfc->pinfo->energy[gr][ch+2],
+                sizeof(gfc->pinfo->energy[gr][ch]));
+       }
+      }
+    }
+  }
+#endif
+
+
+
+
+  /* bit and noise allocation */
+  if (MPG_MD_MS_LR == gfc->mode_ext) {
+    masking = &masking_MS;    /* use MS masking */
+    pe_use = &pe_MS;
+  } else {
+    masking = &masking_LR;    /* use LR masking */
+    pe_use = &pe;
+  }
+
+
+  if (gfc->nsPsy.use && (gfp->VBR == vbr_off || gfp->VBR == vbr_abr)) {
+    static FLOAT fircoef[19] = {
+      -0.0207887,-0.0378413,-0.0432472,-0.031183,
+      7.79609e-18,0.0467745,0.10091,0.151365,
+      0.187098,0.2,0.187098,0.151365,
+      0.10091,0.0467745,7.79609e-18,-0.031183,
+      -0.0432472,-0.0378413,-0.0207887,
+    };
+    int i;
+    FLOAT8 f;
+
+    for(i=0;i<18;i++) gfc->nsPsy.pefirbuf[i] = gfc->nsPsy.pefirbuf[i+1];
+
+    i=0;
+    gfc->nsPsy.pefirbuf[18] = 0;
+    for ( gr = 0; gr < gfc->mode_gr; gr++ ) {
+      for ( ch = 0; ch < gfc->channels_out; ch++ ) {
+       gfc->nsPsy.pefirbuf[18] += (*pe_use)[gr][ch];
+       i++;
+      }
+    }
+
+    gfc->nsPsy.pefirbuf[18] = gfc->nsPsy.pefirbuf[18] / i;
+    f = 0;
+    for(i=0;i<19;i++) f += gfc->nsPsy.pefirbuf[i] * fircoef[i];
+
+    for ( gr = 0; gr < gfc->mode_gr; gr++ ) {
+      for ( ch = 0; ch < gfc->channels_out; ch++ ) {
+       (*pe_use)[gr][ch] *= 670 / f;
+      }
+    }
+  }
+
+  switch (gfp->VBR){ 
+  default:
+  case vbr_off:
+    iteration_loop( gfp,*pe_use,ms_ener_ratio, xr, *masking, l3_enc, scalefac);
+    break;
+  case vbr_mt:
+    VBR_quantize( gfp,*pe_use,ms_ener_ratio, xr, *masking, l3_enc, scalefac);
+    break;
+  case vbr_rh:
+  case vbr_mtrh:
+    VBR_iteration_loop( gfp,*pe_use,ms_ener_ratio, xr, *masking, l3_enc, scalefac);
+    break;
+  case vbr_abr:
+    ABR_iteration_loop( gfp,*pe_use,ms_ener_ratio, xr, *masking, l3_enc, scalefac);
+    break;
+  }
+
+  /*  write the frame to the bitstream  */
+  getframebits(gfp, &bitsPerFrame, &mean_bits);
+
+  format_bitstream( gfp, bitsPerFrame, l3_enc, scalefac);
+
+  /* copy mp3 bit buffer into array */
+  mp3count = copy_buffer(gfc,mp3buf,mp3buf_size,1);
+
+
+
+
+  if (gfp->bWriteVbrTag) AddVbrFrame(gfp);
+
+
+#if defined(HAVE_GTK)
+  /* copy data for MP3 frame analyzer */
+  if (gfp->analysis && gfc->pinfo != NULL) {
+    int j;
+    for ( ch = 0; ch < gfc->channels_out; ch++ ) {
+      for ( j = 0; j < FFTOFFSET; j++ )
+       gfc->pinfo->pcmdata[ch][j] = gfc->pinfo->pcmdata[ch][j+gfp->framesize];
+      for ( j = FFTOFFSET; j < 1600; j++ ) {
+       gfc->pinfo->pcmdata[ch][j] = inbuf[ch][j-FFTOFFSET];
+      }
+    }
+    set_frame_pinfo (gfp, xr, *masking, l3_enc, scalefac);
+  }
+#endif
+  
+  updateStats( gfc );
+
+  return mp3count;
+}
diff --git a/lib/lame/encoder.h b/lib/lame/encoder.h
new file mode 100644 (file)
index 0000000..2fd2c19
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ *      encoder.h include file
+ *
+ *      Copyright (c) 2000 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef LAME_ENCODER_H
+#define LAME_ENCODER_H
+
+/***********************************************************************
+*
+*  encoder and decoder delays
+*
+***********************************************************************/
+
+/* 
+ * layer III enc->dec delay:  1056 (1057?)   (observed)
+ * layer  II enc->dec delay:   480  (481?)   (observed)
+ *
+ * polyphase 256-16             (dec or enc)        = 240
+ * mdct      256+32  (9*32)     (dec or enc)        = 288
+ * total:    512+16
+ *
+ * My guess is that delay of polyphase filterbank is actualy 240.5
+ * (there are technical reasons for this, see postings in mp3encoder).
+ * So total Encode+Decode delay = ENCDELAY + 528 + 1
+ */
+
+/* 
+ * ENCDELAY  The encoder delay.  
+ *
+ * Minimum allowed is MDCTDELAY (see below)
+ *  
+ * The first 96 samples will be attenuated, so using a value less than 96
+ * will result in corrupt data for the first 96-ENCDELAY samples.
+ *
+ * suggested: 576
+ * set to 1160 to sync with FhG.
+ */
+#define ENCDELAY      576
+
+
+
+/*
+ * make sure there is at least one complete frame after the
+ * last frame containing real data
+ *
+ * Using a value of 288 would be sufficient for a 
+ * a very sophisticated decoder that can decode granule-by-granule instead
+ * of frame by frame.  But lets not assume this, and assume the decoder  
+ * will not decode frame N unless it also has data for frame N+1
+ *
+ */
+/*#define POSTDELAY   288*/
+#define POSTDELAY   1152
+
+
+
+/* 
+ * delay of the MDCT used in mdct.c
+ * original ISO routines had a delay of 528!  
+ * Takehiro's routines: 
+ */
+
+#define MDCTDELAY     48  
+#define FFTOFFSET     (224+MDCTDELAY)
+
+/*
+ * Most decoders, including the one we use, have a delay of 528 samples.  
+ */
+#define DECDELAY      528
+
+
+/* number of subbands */
+#define SBLIMIT       32
+
+/* parition bands bands */
+#define CBANDS        64
+
+/* number of critical bands/scale factor bands where masking is computed*/
+#define SBPSY_l       21
+#define SBPSY_s       12
+
+/* total number of scalefactor bands encoded */
+#define SBMAX_l       22
+#define SBMAX_s       13
+
+
+
+/* FFT sizes */
+#define BLKSIZE       1024
+#define HBLKSIZE      (BLKSIZE/2 + 1)
+#define BLKSIZE_s     256
+#define HBLKSIZE_s    (BLKSIZE_s/2 + 1)
+
+
+/* #define switch_pe        1800 */
+#define NORM_TYPE     0
+#define START_TYPE    1
+#define SHORT_TYPE    2
+#define STOP_TYPE     3
+
+/* 
+ * Mode Extention:
+ * When we are in stereo mode, there are 4 possible methods to store these
+ * two channels. The stereo modes -m? are using a subset of them.
+ *
+ *  -ms: MPG_MD_LR_LR
+ *  -mj: MPG_MD_LR_LR and MPG_MD_MS_LR
+ *  -mf: MPG_MD_MS_LR
+ *  -mi: all
+ */
+#define MPG_MD_LR_LR  0
+#define MPG_MD_LR_I   1
+#define MPG_MD_MS_LR  2
+#define MPG_MD_MS_I   3
+
+
+#include "machine.h"
+#include "lame.h"
+
+int  lame_encode_mp3_frame (
+        lame_global_flags*  const gfp,
+        sample_t*           inbuf_l,
+        sample_t*           inbuf_r,
+        unsigned char*      mp3buf, 
+       int                 mp3buf_size );
+
+#endif /* LAME_ENCODER_H */
diff --git a/lib/lame/fft.c b/lib/lame/fft.c
new file mode 100644 (file)
index 0000000..f0d7aca
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+** FFT and FHT routines
+**  Copyright 1988, 1993; Ron Mayer
+**  
+**  fht(fz,n);
+**      Does a hartley transform of "n" points in the array "fz".
+**      
+** NOTE: This routine uses at least 2 patented algorithms, and may be
+**       under the restrictions of a bunch of different organizations.
+**       Although I wrote it completely myself; it is kind of a derivative
+**       of a routine I once authored and released under the GPL, so it
+**       may fall under the free software foundation's restrictions;
+**       it was worked on as a Stanford Univ project, so they claim
+**       some rights to it; it was further optimized at work here, so
+**       I think this company claims parts of it.  The patents are
+**       held by R. Bracewell (the FHT algorithm) and O. Buneman (the
+**       trig generator), both at Stanford Univ.
+**       If it were up to me, I'd say go do whatever you want with it;
+**       but it would be polite to give credit to the following people
+**       if you use this anywhere:
+**           Euler     - probable inventor of the fourier transform.
+**           Gauss     - probable inventor of the FFT.
+**           Hartley   - probable inventor of the hartley transform.
+**           Buneman   - for a really cool trig generator
+**           Mayer(me) - for authoring this particular version and
+**                       including all the optimizations in one package.
+**       Thanks,
+**       Ron Mayer; mayer@acuson.com
+** and added some optimization by
+**           Mather    - idea of using lookup table
+**           Takehiro  - some dirty hack for speed up
+*/
+
+/* $Id: fft.c,v 1.1 2002/04/28 17:30:18 kramm Exp $ */
+
+#include "config_static.h"
+
+#include <math.h>
+#include "util.h"
+#include "fft.h"
+
+
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#define TRI_SIZE (5-1) /* 1024 =  4**5 */
+
+static const FLOAT costab[TRI_SIZE*2] = {
+  9.238795325112867e-01, 3.826834323650898e-01,
+  9.951847266721969e-01, 9.801714032956060e-02,
+  9.996988186962042e-01, 2.454122852291229e-02,
+  9.999811752826011e-01, 6.135884649154475e-03
+};
+
+static void fht(FLOAT *fz, int n)
+{
+    const FLOAT *tri = costab;
+    int           k4;
+    FLOAT *fi, *fn, *gi;
+
+    n <<= 1;        /* to get BLKSIZE, because of 3DNow! ASM routine */
+    fn = fz + n;
+    k4 = 4;
+    do {
+       FLOAT s1, c1;
+       int   i, k1, k2, k3, kx;
+       kx  = k4 >> 1;
+       k1  = k4;
+       k2  = k4 << 1;
+       k3  = k2 + k1;
+       k4  = k2 << 1;
+       fi  = fz;
+       gi  = fi + kx;
+       do {
+           FLOAT f0,f1,f2,f3;
+           f1      = fi[0]  - fi[k1];
+           f0      = fi[0]  + fi[k1];
+           f3      = fi[k2] - fi[k3];
+           f2      = fi[k2] + fi[k3];
+           fi[k2]  = f0     - f2;
+           fi[0 ]  = f0     + f2;
+           fi[k3]  = f1     - f3;
+           fi[k1]  = f1     + f3;
+           f1      = gi[0]  - gi[k1];
+           f0      = gi[0]  + gi[k1];
+           f3      = SQRT2  * gi[k3];
+           f2      = SQRT2  * gi[k2];
+           gi[k2]  = f0     - f2;
+           gi[0 ]  = f0     + f2;
+           gi[k3]  = f1     - f3;
+           gi[k1]  = f1     + f3;
+           gi     += k4;
+           fi     += k4;
+       } while (fi<fn);
+       c1 = tri[0];
+       s1 = tri[1];
+       for (i = 1; i < kx; i++) {
+           FLOAT c2,s2;
+           c2 = 1 - (2*s1)*s1;
+           s2 = (2*s1)*c1;
+           fi = fz + i;
+           gi = fz + k1 - i;
+           do {
+               FLOAT a,b,g0,f0,f1,g1,f2,g2,f3,g3;
+               b       = s2*fi[k1] - c2*gi[k1];
+               a       = c2*fi[k1] + s2*gi[k1];
+               f1      = fi[0 ]    - a;
+               f0      = fi[0 ]    + a;
+               g1      = gi[0 ]    - b;
+               g0      = gi[0 ]    + b;
+               b       = s2*fi[k3] - c2*gi[k3];
+               a       = c2*fi[k3] + s2*gi[k3];
+               f3      = fi[k2]    - a;
+               f2      = fi[k2]    + a;
+               g3      = gi[k2]    - b;
+               g2      = gi[k2]    + b;
+               b       = s1*f2     - c1*g3;
+               a       = c1*f2     + s1*g3;
+               fi[k2]  = f0        - a;
+               fi[0 ]  = f0        + a;
+               gi[k3]  = g1        - b;
+               gi[k1]  = g1        + b;
+               b       = c1*g2     - s1*f3;
+               a       = s1*g2     + c1*f3;
+               gi[k2]  = g0        - a;
+               gi[0 ]  = g0        + a;
+               fi[k3]  = f1        - b;
+               fi[k1]  = f1        + b;
+               gi     += k4;
+               fi     += k4;
+           } while (fi<fn);
+           c2 = c1;
+           c1 = c2 * tri[0] - s1 * tri[1];
+           s1 = c2 * tri[1] + s1 * tri[0];
+        }
+       tri += 2;
+    } while (k4<n);
+}
+
+static const unsigned char rv_tbl[] = {
+    0x00,    0x80,    0x40,    0xc0,    0x20,    0xa0,    0x60,    0xe0,
+    0x10,    0x90,    0x50,    0xd0,    0x30,    0xb0,    0x70,    0xf0,
+    0x08,    0x88,    0x48,    0xc8,    0x28,    0xa8,    0x68,    0xe8,
+    0x18,    0x98,    0x58,    0xd8,    0x38,    0xb8,    0x78,    0xf8,
+    0x04,    0x84,    0x44,    0xc4,    0x24,    0xa4,    0x64,    0xe4,
+    0x14,    0x94,    0x54,    0xd4,    0x34,    0xb4,    0x74,    0xf4,
+    0x0c,    0x8c,    0x4c,    0xcc,    0x2c,    0xac,    0x6c,    0xec,
+    0x1c,    0x9c,    0x5c,    0xdc,    0x3c,    0xbc,    0x7c,    0xfc,
+    0x02,    0x82,    0x42,    0xc2,    0x22,    0xa2,    0x62,    0xe2,
+    0x12,    0x92,    0x52,    0xd2,    0x32,    0xb2,    0x72,    0xf2,
+    0x0a,    0x8a,    0x4a,    0xca,    0x2a,    0xaa,    0x6a,    0xea,
+    0x1a,    0x9a,    0x5a,    0xda,    0x3a,    0xba,    0x7a,    0xfa,
+    0x06,    0x86,    0x46,    0xc6,    0x26,    0xa6,    0x66,    0xe6,
+    0x16,    0x96,    0x56,    0xd6,    0x36,    0xb6,    0x76,    0xf6,
+    0x0e,    0x8e,    0x4e,    0xce,    0x2e,    0xae,    0x6e,    0xee,
+    0x1e,    0x9e,    0x5e,    0xde,    0x3e,    0xbe,    0x7e,    0xfe
+};
+
+#define ch01(index)  (buffer[chn][index])
+
+#define ml00(f)        (window[i        ] * f(i))
+#define ml10(f)        (window[i + 0x200] * f(i + 0x200))
+#define ml20(f)        (window[i + 0x100] * f(i + 0x100))
+#define ml30(f)        (window[i + 0x300] * f(i + 0x300))
+
+#define ml01(f)        (window[i + 0x001] * f(i + 0x001))
+#define ml11(f)        (window[i + 0x201] * f(i + 0x201))
+#define ml21(f)        (window[i + 0x101] * f(i + 0x101))
+#define ml31(f)        (window[i + 0x301] * f(i + 0x301))
+
+#define ms00(f)        (window_s[i       ] * f(i + k))
+#define ms10(f)        (window_s[0x7f - i] * f(i + k + 0x80))
+#define ms20(f)        (window_s[i + 0x40] * f(i + k + 0x40))
+#define ms30(f)        (window_s[0x3f - i] * f(i + k + 0xc0))
+
+#define ms01(f)        (window_s[i + 0x01] * f(i + k + 0x01))
+#define ms11(f)        (window_s[0x7e - i] * f(i + k + 0x81))
+#define ms21(f)        (window_s[i + 0x41] * f(i + k + 0x41))
+#define ms31(f)        (window_s[0x3e - i] * f(i + k + 0xc1))
+
+
+void fft_short(lame_internal_flags * const gfc, 
+                FLOAT x_real[3][BLKSIZE_s], int chn, const sample_t *buffer[2])
+{
+    const FLOAT*  window_s = (const FLOAT *)&gfc->window_s[0];
+    int           i;
+    int           j;
+    int           b;
+
+    for (b = 0; b < 3; b++) {
+       FLOAT *x = &x_real[b][BLKSIZE_s / 2];
+       short k = (576 / 3) * (b + 1);
+       j = BLKSIZE_s / 8 - 1;
+       do {
+         FLOAT f0,f1,f2,f3, w;
+
+         i = rv_tbl[j << 2];
+
+         f0 = ms00(ch01); w = ms10(ch01); f1 = f0 - w; f0 = f0 + w;
+         f2 = ms20(ch01); w = ms30(ch01); f3 = f2 - w; f2 = f2 + w;
+
+         x -= 4;
+         x[0] = f0 + f2;
+         x[2] = f0 - f2;
+         x[1] = f1 + f3;
+         x[3] = f1 - f3;
+
+         f0 = ms01(ch01); w = ms11(ch01); f1 = f0 - w; f0 = f0 + w;
+         f2 = ms21(ch01); w = ms31(ch01); f3 = f2 - w; f2 = f2 + w;
+
+         x[BLKSIZE_s / 2 + 0] = f0 + f2;
+         x[BLKSIZE_s / 2 + 2] = f0 - f2;
+         x[BLKSIZE_s / 2 + 1] = f1 + f3;
+         x[BLKSIZE_s / 2 + 3] = f1 - f3;
+       } while (--j >= 0);
+
+       gfc->fft_fht(x, BLKSIZE_s/2);   
+        /* BLKSIZE_s/2 because of 3DNow! ASM routine */
+    }
+}
+
+void fft_long(lame_internal_flags * const gfc,
+               FLOAT x[BLKSIZE], int chn, const sample_t *buffer[2] )
+{
+    const FLOAT*  window = (const FLOAT *)&gfc->window[0];
+    int           i;
+    int           jj = BLKSIZE / 8 - 1;
+    x += BLKSIZE / 2;
+
+    do {
+      FLOAT f0,f1,f2,f3, w;
+
+      i = rv_tbl[jj];
+      f0 = ml00(ch01); w = ml10(ch01); f1 = f0 - w; f0 = f0 + w;
+      f2 = ml20(ch01); w = ml30(ch01); f3 = f2 - w; f2 = f2 + w;
+
+      x -= 4;
+      x[0] = f0 + f2;
+      x[2] = f0 - f2;
+      x[1] = f1 + f3;
+      x[3] = f1 - f3;
+
+      f0 = ml01(ch01); w = ml11(ch01); f1 = f0 - w; f0 = f0 + w;
+      f2 = ml21(ch01); w = ml31(ch01); f3 = f2 - w; f2 = f2 + w;
+
+      x[BLKSIZE / 2 + 0] = f0 + f2;
+      x[BLKSIZE / 2 + 2] = f0 - f2;
+      x[BLKSIZE / 2 + 1] = f1 + f3;
+      x[BLKSIZE / 2 + 3] = f1 - f3;
+    } while (--jj >= 0);
+
+    gfc->fft_fht(x, BLKSIZE/2);
+    /* BLKSIZE/2 because of 3DNow! ASM routine */
+}
+
+
+void init_fft(lame_internal_flags * const gfc)
+{
+    FLOAT *window   = &gfc->window[0];
+    FLOAT *window_s = &gfc->window_s[0];
+    int i;
+
+#if 0
+    if (gfc->nsPsy.use) {
+      for (i = 0; i < BLKSIZE ; i++)
+       /* blackman window */
+       window[i] = 0.42-0.5*cos(2*PI*i/(BLKSIZE-1))+0.08*cos(4*PI*i/(BLKSIZE-1));
+    } else {
+      /*
+       * calculate HANN window coefficients 
+       */
+      for (i = 0; i < BLKSIZE ; i++)
+       window[i] = 0.5 * (1.0 - cos(2.0 * PI * (i + 0.5) / BLKSIZE));
+    }
+#endif
+
+    // The type of window used here will make no real difference, but
+    // in the interest of merging nspsytune stuff - switch to blackman window
+    for (i = 0; i < BLKSIZE ; i++)
+      /* blackman window */
+      window[i] = 0.42-0.5*cos(2*PI*(i+.5)/BLKSIZE)+
+       0.08*cos(4*PI*(i+.5)/BLKSIZE);
+
+    for (i = 0; i < BLKSIZE_s/2 ; i++)
+       window_s[i] = 0.5 * (1.0 - cos(2.0 * PI * (i + 0.5) / BLKSIZE_s));
+
+#ifdef HAVE_NASM
+    if (gfc->CPU_features.AMD_3DNow) {
+        extern void fht_3DN(FLOAT *fz, int n);
+        gfc->fft_fht = fht_3DN;
+    } else 
+#endif
+#ifdef USE_FFTSSE
+    if (gfc->CPU_features.SIMD) {
+        extern void fht_SSE(FLOAT *fz, int n);
+        gfc->fft_fht = fht_SSE;
+    } else 
+#endif
+#ifdef USE_FFTFPU
+    if (gfc->CPU_features.i387) {
+        extern void fht_FPU(FLOAT *fz, int n);
+        gfc->fft_fht = fht_FPU;
+    } else
+#endif
+        gfc->fft_fht = fht;
+}
diff --git a/lib/lame/fft.h b/lib/lame/fft.h
new file mode 100644 (file)
index 0000000..b96c527
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *     Fast Fourier Transform include file
+ *
+ *     Copyright (c) 2000 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_FFT_H
+#define LAME_FFT_H
+
+#include "encoder.h"
+
+void fft_long(lame_internal_flags* const gfc, FLOAT x_real[BLKSIZE], 
+               int chn, const sample_t *data[2] );
+
+void fft_short(lame_internal_flags* const gfc, FLOAT x_real[3][BLKSIZE_s], 
+               int chn, const sample_t *data[2] );
+
+void init_fft(lame_internal_flags* const gfc );
+
+#endif
+
+/* End of fft.h */
diff --git a/lib/lame/id3tag.c b/lib/lame/id3tag.c
new file mode 100644 (file)
index 0000000..f3fecd9
--- /dev/null
@@ -0,0 +1,532 @@
+/*
+ * id3tag.c -- Write ID3 version 1 and 2 tags.
+ *
+ * Copyright (C) 2000 Don Melton.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * HISTORY: This source file is part of LAME (see http://www.mp3dev.org/mp3/)
+ * and was originally adapted by Conrad Sanderson <c.sanderson@me.gu.edu.au>
+ * from mp3info by Ricardo Cerqueira <rmc@rccn.net> to write only ID3 version 1
+ * tags.  Don Melton <don@blivet.com> COMPLETELY rewrote it to support version
+ * 2 tags and be more conformant to other standards while remaining flexible.
+ *
+ * NOTE: See http://id3.org/ for more information about ID3 tag formats.
+ */
+
+/* $Id: id3tag.c,v 1.1 2002/04/28 17:30:19 kramm Exp $ */
+
+#include "config_static.h"
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+# include <stdlib.h>
+# include <string.h>
+#else
+# ifndef HAVE_STRCHR
+#  define strchr index
+#  define strrchr rindex
+# endif
+char *strchr (), *strrchr ();
+# ifndef HAVE_MEMCPY
+#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+#  define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#include "lame.h"
+#include "id3tag.h"
+#include "util.h"
+#include "bitstream.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+static const char *const genre_names[] =
+{
+    /*
+     * NOTE: The spelling of these genre names is identical to those found in
+     * Winamp and mp3info.
+     */
+    "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge",
+    "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B",
+    "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska",
+    "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop",
+    "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental",
+    "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "Alt. Rock",
+    "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop",
+    "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial",
+    "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy",
+    "Cult", "Gangsta Rap", "Top 40", "Christian Rap", "Pop/Funk", "Jungle",
+    "Native American", "Cabaret", "New Wave", "Psychedelic", "Rave",
+    "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz",
+    "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk",
+    "Folk/Rock", "National Folk", "Swing", "Fast-Fusion", "Bebob", "Latin",
+    "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock",
+    "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock",
+    "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech",
+    "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass",
+    "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba",
+    "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet",
+    "Punk Rock", "Drum Solo", "A Cappella", "Euro-House", "Dance Hall",
+    "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror", "Indie",
+    "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta Rap",
+    "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian",
+    "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop",
+    "Synthpop"
+};
+
+#define GENRE_NAME_COUNT \
+    ((int)(sizeof genre_names / sizeof (const char *const)))
+
+static const int genre_alpha_map [] = {
+    123, 34, 74, 73, 99, 20, 40, 26, 145, 90, 116, 41, 135, 85, 96, 138, 89, 0,
+    107, 132, 65, 88, 104, 102, 97, 136, 61, 141, 32, 1, 112, 128, 57, 140, 2,
+    139, 58, 3, 125, 50, 22, 4, 55, 127, 122, 120, 98, 52, 48, 54, 124, 25, 84,
+    80, 115, 81, 119, 5, 30, 36, 59, 126, 38, 49, 91, 6, 129, 79, 137, 7, 35,
+    100, 131, 19, 33, 46, 47, 8, 29, 146, 63, 86, 71, 45, 142, 9, 77, 82, 64,
+    133, 10, 66, 39, 11, 103, 12, 75, 134, 13, 53, 62, 109, 117, 23, 108, 92,
+    67, 93, 43, 121, 15, 68, 14, 16, 76, 87, 118, 17, 78, 143, 114, 110, 69, 21,
+    111, 95, 105, 42, 37, 24, 56, 44, 101, 83, 94, 106, 147, 113, 18, 51, 130,
+    144, 60, 70, 31, 72, 27, 28
+};
+
+#define GENRE_ALPHA_COUNT ((int)(sizeof genre_alpha_map / sizeof (int)))
+
+void
+id3tag_genre_list(void (*handler)(int, const char *, void *), void *cookie)
+{
+    if (handler) {
+        int i;
+        for (i = 0; i < GENRE_NAME_COUNT; ++i) {
+            if (i < GENRE_ALPHA_COUNT) {
+                int j = genre_alpha_map[i];
+                handler(j, genre_names[j], cookie);
+            }
+        }
+    }
+}
+
+#define GENRE_NUM_UNKNOWN 255
+
+void
+id3tag_init(lame_global_flags *gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    memset(&gfc->tag_spec, 0, sizeof gfc->tag_spec);
+    gfc->tag_spec.genre = GENRE_NUM_UNKNOWN;
+}
+
+
+
+void
+id3tag_add_v2(lame_global_flags *gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    gfc->tag_spec.flags &= ~V1_ONLY_FLAG;
+    gfc->tag_spec.flags |= ADD_V2_FLAG;
+}
+
+void
+id3tag_v1_only(lame_global_flags *gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    gfc->tag_spec.flags &= ~(ADD_V2_FLAG | V2_ONLY_FLAG);
+    gfc->tag_spec.flags |= V1_ONLY_FLAG;
+}
+
+void
+id3tag_v2_only(lame_global_flags *gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    gfc->tag_spec.flags &= ~V1_ONLY_FLAG;
+    gfc->tag_spec.flags |= V2_ONLY_FLAG;
+}
+
+void
+id3tag_space_v1(lame_global_flags *gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    gfc->tag_spec.flags &= ~V2_ONLY_FLAG;
+    gfc->tag_spec.flags |= SPACE_V1_FLAG;
+}
+
+void
+id3tag_pad_v2(lame_global_flags *gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    gfc->tag_spec.flags &= ~V1_ONLY_FLAG;
+    gfc->tag_spec.flags |= PAD_V2_FLAG;
+}
+
+void
+id3tag_set_title(lame_global_flags *gfp, const char *title)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    if (title && *title) {
+        gfc->tag_spec.title = title;
+        gfc->tag_spec.flags |= CHANGED_FLAG;
+    }
+}
+
+void
+id3tag_set_artist(lame_global_flags *gfp, const char *artist)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    if (artist && *artist) {
+        gfc->tag_spec.artist = artist;
+        gfc->tag_spec.flags |= CHANGED_FLAG;
+    }
+}
+
+void
+id3tag_set_album(lame_global_flags *gfp, const char *album)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    if (album && *album) {
+        gfc->tag_spec.album = album;
+        gfc->tag_spec.flags |= CHANGED_FLAG;
+    }
+}
+
+void
+id3tag_set_year(lame_global_flags *gfp, const char *year)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    if (year && *year) {
+        int num = atoi(year);
+        if (num < 0) {
+            num = 0;
+        }
+        /* limit a year to 4 digits so it fits in a version 1 tag */
+        if (num > 9999) {
+            num = 9999;
+        }
+        if (num) {
+            gfc->tag_spec.year = num;
+            gfc->tag_spec.flags |= CHANGED_FLAG;
+        }
+    }
+}
+
+void
+id3tag_set_comment(lame_global_flags *gfp, const char *comment)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    if (comment && *comment) {
+        gfc->tag_spec.comment = comment;
+        gfc->tag_spec.flags |= CHANGED_FLAG;
+    }
+}
+
+void
+id3tag_set_track(lame_global_flags *gfp, const char *track)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    if (track && *track) {
+        int num = atoi(track);
+        if (num < 0) {
+            num = 0;
+        }
+        /* limit a track to 255 so it fits in a version 1 tag even though CD
+         * audio doesn't allow more than 99 tracks */
+        if (num > 255) {
+            num = 255;
+        }
+        if (num) {
+            gfc->tag_spec.track = num;
+            gfc->tag_spec.flags |= CHANGED_FLAG;
+        }
+    }
+}
+
+/* would use real "strcasecmp" but it isn't portable */
+static int
+local_strcasecmp(const char *s1, const char *s2)
+{
+    unsigned char c1;
+    unsigned char c2;
+    do {
+        c1 = tolower(*s1);
+        c2 = tolower(*s2);
+        if (!c1) {
+            break;
+        }
+        ++s1;
+        ++s2;
+    } while (c1 == c2);
+    return c1 - c2;
+}
+
+int
+id3tag_set_genre(lame_global_flags *gfp, const char *genre)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    if (genre && *genre) {
+        char *str;
+        int num = strtol(genre, &str, 10);
+        /* is the input a string or a valid number? */
+        if (*str) {
+            int i;
+            for (i = 0; i < GENRE_NAME_COUNT; ++i) {
+                if (!local_strcasecmp(genre, genre_names[i])) {
+                    num = i;
+                    break;
+                }
+            }
+            if (i == GENRE_NAME_COUNT) {
+                return -1;
+            }
+        } else if ((num < 0) || (num >= GENRE_NAME_COUNT)) {
+            return -1;
+        }
+        gfc->tag_spec.genre = num;
+        gfc->tag_spec.flags |= CHANGED_FLAG;
+    }
+    return 0;
+}
+
+static unsigned char *
+set_4_byte_value(unsigned char *bytes, unsigned long value)
+{
+    int index;
+    for (index = 3; index >= 0; --index) {
+        bytes[index] = value & 0xfful;
+        value >>= 8;
+    }
+    return bytes + 4;
+}
+
+#define FRAME_ID(a, b, c, d) \
+    ( ((unsigned long)(a) << 24) \
+    | ((unsigned long)(b) << 16) \
+    | ((unsigned long)(c) <<  8) \
+    | ((unsigned long)(d) <<  0) )
+#define TITLE_FRAME_ID FRAME_ID('T', 'I', 'T', '2')
+#define ARTIST_FRAME_ID FRAME_ID('T', 'P', 'E', '1')
+#define ALBUM_FRAME_ID FRAME_ID('T', 'A', 'L', 'B')
+#define YEAR_FRAME_ID FRAME_ID('T', 'Y', 'E', 'R')
+#define COMMENT_FRAME_ID FRAME_ID('C', 'O', 'M', 'M')
+#define TRACK_FRAME_ID FRAME_ID('T', 'R', 'C', 'K')
+#define GENRE_FRAME_ID FRAME_ID('T', 'C', 'O', 'N')
+
+static unsigned char *
+set_frame(unsigned char *frame, unsigned long id, const char *text,
+    size_t length)
+{
+    if (length) {
+        frame = set_4_byte_value(frame, id);
+        /* Set frame size = total size - header size.  Frame header and field
+         * bytes include 2-byte header flags, 1 encoding descriptor byte, and
+         * for comment frames: 3-byte language descriptor and 1 content
+         * descriptor byte */
+        frame = set_4_byte_value(frame, ((id == COMMENT_FRAME_ID) ? 5 : 1)
+                + length);
+        /* clear 2-byte header flags */
+        *frame++ = 0;
+        *frame++ = 0;
+        /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */
+        *frame++ = 0;
+        if (id == COMMENT_FRAME_ID) {
+            /* use id3lib-compatible bogus language descriptor */
+            *frame++ = 'X';
+            *frame++ = 'X';
+            *frame++ = 'X';
+            /* clear 1 byte to make content descriptor empty string */
+            *frame++ = 0;
+        }
+        while (length--) {
+            *frame++ = *text++;
+        }
+    }
+    return frame;
+}
+
+int
+id3tag_write_v2(lame_global_flags *gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    if ((gfc->tag_spec.flags & CHANGED_FLAG)
+            && !(gfc->tag_spec.flags & V1_ONLY_FLAG)) {
+        /* calculate length of four fields which may not fit in verion 1 tag */
+        size_t title_length = gfc->tag_spec.title
+            ? strlen(gfc->tag_spec.title) : 0;
+        size_t artist_length = gfc->tag_spec.artist
+            ? strlen(gfc->tag_spec.artist) : 0;
+        size_t album_length = gfc->tag_spec.album
+            ? strlen(gfc->tag_spec.album) : 0;
+        size_t comment_length = gfc->tag_spec.comment
+            ? strlen(gfc->tag_spec.comment) : 0;
+        /* write tag if explicitly requested or if fields overflow */
+        if ((gfc->tag_spec.flags & (ADD_V2_FLAG | V2_ONLY_FLAG))
+                || (title_length > 30)
+                || (artist_length > 30) || (album_length > 30)
+                || (comment_length > 30)
+                || (gfc->tag_spec.track && (comment_length > 28))) {
+            size_t tag_size;
+            char year[5];
+            size_t year_length;
+            char track[3];
+            size_t track_length;
+            char genre[6];
+            size_t genre_length;
+            unsigned char *tag;
+            unsigned char *p;
+            size_t adjusted_tag_size;
+            unsigned int index;
+            /* calulate size of tag starting with 10-byte tag header */
+            tag_size = 10;
+            if (title_length) {
+                /* add 10-byte frame header, 1 encoding descriptor byte ... */
+                tag_size += 11 + title_length;
+            }
+            if (artist_length) {
+                tag_size += 11 + artist_length;
+            }
+            if (album_length) {
+                tag_size += 11 + album_length;
+            }
+            if (gfc->tag_spec.year) {
+                year_length = sprintf(year, "%d", gfc->tag_spec.year);
+                tag_size += 11 + year_length;
+            } else {
+                year_length = 0;
+            }
+            if (comment_length) {
+                /* add 10-byte frame header, 1 encoding descriptor byte,
+                 * 3-byte language descriptor, 1 content descriptor byte ... */
+                tag_size += 15 + comment_length;
+            }
+            if (gfc->tag_spec.track) {
+                track_length = sprintf(track, "%d", gfc->tag_spec.track);
+                tag_size += 11 + track_length;
+            } else {
+                track_length = 0;
+            }
+            if (gfc->tag_spec.genre != GENRE_NUM_UNKNOWN) {
+                genre_length = sprintf(genre, "(%d)", gfc->tag_spec.genre);
+                tag_size += 11 + genre_length;
+            } else {
+                genre_length = 0;
+            }
+            if (gfc->tag_spec.flags & PAD_V2_FLAG) {
+                /* add 128 bytes of padding */
+                tag_size += 128;
+            }
+            tag = (unsigned char *)malloc(tag_size);
+            if (!tag) {
+                return -1;
+            }
+            p = tag;
+            /* set tag header starting with file identifier */
+            *p++ = 'I'; *p++ = 'D'; *p++ = '3';
+            /* set version number word */
+            *p++ = 3; *p++ = 0;
+            /* clear flags byte */
+            *p++ = 0;
+            /* calculate and set tag size = total size - header size */
+            adjusted_tag_size = tag_size - 10;
+            /* encode adjusted size into four bytes where most significant 
+             * bit is clear in each byte, for 28-bit total */
+            *p++ = (adjusted_tag_size >> 21) & 0x7fu;
+            *p++ = (adjusted_tag_size >> 14) & 0x7fu;
+            *p++ = (adjusted_tag_size >> 7) & 0x7fu;
+            *p++ = adjusted_tag_size & 0x7fu;
+
+            /*
+             * NOTE: The remainder of the tag (frames and padding, if any)
+             * are not "unsynchronized" to prevent false MPEG audio headers
+             * from appearing in the bitstream.  Why?  Well, most players
+             * and utilities know how to skip the ID3 version 2 tag by now
+             * even if they don't read its contents, and it's actually
+             * very unlikely that such a false "sync" pattern would occur
+             * in just the simple text frames added here.
+             */
+
+            /* set each frame in tag */
+            p = set_frame(p, TITLE_FRAME_ID, gfc->tag_spec.title, title_length);
+            p = set_frame(p, ARTIST_FRAME_ID, gfc->tag_spec.artist,
+                    artist_length);
+            p = set_frame(p, ALBUM_FRAME_ID, gfc->tag_spec.album, album_length);
+            p = set_frame(p, YEAR_FRAME_ID, year, year_length);
+            p = set_frame(p, COMMENT_FRAME_ID, gfc->tag_spec.comment,
+                    comment_length);
+            p = set_frame(p, TRACK_FRAME_ID, track, track_length);
+            p = set_frame(p, GENRE_FRAME_ID, genre, genre_length);
+            /* clear any padding bytes */
+            memset(p, 0, tag_size - (p - tag));
+            /* write tag directly into bitstream at current position */
+            for (index = 0; index < tag_size; ++index) {
+                add_dummy_byte(gfp, tag[index]);
+            }
+            free(tag);
+            return tag_size;
+        }
+    }
+    return 0;
+}
+
+static unsigned char *
+set_text_field(unsigned char *field, const char *text, size_t size, int pad)
+{
+    while (size--) {
+        if (text && *text) {
+            *field++ = *text++;
+        } else {
+            *field++ = pad;
+        }
+    }
+    return field;
+}
+
+int
+id3tag_write_v1(lame_global_flags *gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    if ((gfc->tag_spec.flags & CHANGED_FLAG)
+            && !(gfc->tag_spec.flags & V2_ONLY_FLAG)) {
+        unsigned char tag[128];
+        unsigned char *p = tag;
+        int pad = (gfc->tag_spec.flags & SPACE_V1_FLAG) ? ' ' : 0;
+        char year[5];
+        unsigned int index;
+        /* set tag identifier */
+        *p++ = 'T'; *p++ = 'A'; *p++ = 'G';
+        /* set each field in tag */
+        p = set_text_field(p, gfc->tag_spec.title, 30, pad);
+        p = set_text_field(p, gfc->tag_spec.artist, 30, pad);
+        p = set_text_field(p, gfc->tag_spec.album, 30, pad);
+        sprintf(year, "%d", gfc->tag_spec.year);
+        p = set_text_field(p, gfc->tag_spec.year ? year : NULL, 4, pad);
+        /* limit comment field to 28 bytes if a track is specified */
+        p = set_text_field(p, gfc->tag_spec.comment, gfc->tag_spec.track
+                ? 28 : 30, pad);
+        if (gfc->tag_spec.track) {
+            /* clear the next byte to indicate a version 1.1 tag */
+            *p++ = 0;
+            *p++ = gfc->tag_spec.track;
+        }
+        *p++ = gfc->tag_spec.genre;
+        /* write tag directly into bitstream at current position */
+        for (index = 0; index < 128; ++index) {
+            add_dummy_byte(gfp, tag[index]);
+        }
+        return 128;
+    }
+    return 0;
+}
diff --git a/lib/lame/id3tag.h b/lib/lame/id3tag.h
new file mode 100644 (file)
index 0000000..7f63619
--- /dev/null
@@ -0,0 +1,38 @@
+
+#ifndef LAME_ID3_H
+#define LAME_ID3_H
+
+#include "lame.h"
+
+
+#define CHANGED_FLAG    (1U << 0)
+#define ADD_V2_FLAG     (1U << 1)
+#define V1_ONLY_FLAG    (1U << 2)
+#define V2_ONLY_FLAG    (1U << 3)
+#define SPACE_V1_FLAG   (1U << 4)
+#define PAD_V2_FLAG     (1U << 5)
+
+struct id3tag_spec
+{
+    /* private data members */
+    int flags;
+    const char *title;
+    const char *artist;
+    const char *album;
+    int year;
+    const char *comment;
+    int track;
+    int genre;
+};
+
+
+/* write tag into stream at current position */
+extern int id3tag_write_v2(lame_global_flags *gfp);
+extern int id3tag_write_v1(lame_global_flags *gfp);
+/*
+ * NOTE: A version 2 tag will NOT be added unless one of the text fields won't
+ * fit in a version 1 tag (e.g. the title string is longer than 30 characters),
+ * or the "id3tag_add_v2" or "id3tag_v2_only" functions are used.
+ */
+
+#endif
diff --git a/lib/lame/l3side.h b/lib/lame/l3side.h
new file mode 100644 (file)
index 0000000..d9461b5
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ *     Layer 3 side include file
+ *
+ *     Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_L3SIDE_H
+#define LAME_L3SIDE_H
+
+#include "encoder.h"
+#include "machine.h"
+
+/* Layer III side information. */
+
+typedef FLOAT8 D576[576];
+typedef int    I576[576];
+typedef FLOAT8 D192_3[192][3];
+typedef int    I192_3[192][3];
+
+
+typedef struct 
+{
+   int l[1+SBMAX_l];
+   int s[1+SBMAX_s];
+} scalefac_struct;
+
+
+typedef struct {
+       FLOAT8  l[SBMAX_l];
+       FLOAT8  s[SBMAX_s][3];
+} III_psy_xmin;
+
+typedef struct {
+    III_psy_xmin thm;
+    III_psy_xmin en;
+} III_psy_ratio;
+
+typedef struct {
+       int part2_3_length;
+       int big_values;
+       int count1;
+       int global_gain;
+       int scalefac_compress;
+       int window_switching_flag;
+       int block_type;
+       int mixed_block_flag;
+       int table_select[3];
+        int subblock_gain[3];
+        int region0_count;
+        int region1_count;
+        int preflag;
+        int scalefac_scale;
+        int count1table_select;
+
+        int part2_length;
+        int sfb_lmax;
+        int sfb_smin;
+        int count1bits;
+       /* added for LSF */
+        const int *sfb_partition_table;
+        int slen[4];
+} gr_info;
+
+typedef struct {
+       int main_data_begin; 
+       int private_bits;
+       int resvDrain_pre;
+       int resvDrain_post;
+       int scfsi[2][4];
+       struct {
+               struct gr_info_ss {
+                       gr_info tt;
+                       } ch[2];
+               } gr[2];
+       } III_side_info_t;
+
+/* Layer III scale factors. */
+/* note: there are only SBPSY_l=(SBMAX_l-1) and SBPSY_s=(SBMAX_s-1) scalefactors.
+ * Dont know why these would be dimensioned SBMAX_l and SBMAX-s */
+typedef struct {
+       int l[SBMAX_l];            /* [cb] */
+       int s[SBMAX_s][3];         /* [window][cb] */
+} III_scalefac_t;  /* [gr][ch] */
+
+#endif
diff --git a/lib/lame/lame-analysis.h b/lib/lame/lame-analysis.h
new file mode 100644 (file)
index 0000000..2a1423b
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *     GTK plotting routines source file
+ *
+ *     Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_GTKANAL_H
+#define LAME_GTKANAL_H
+
+#include "encoder.h"
+
+#define READ_AHEAD 10             /* number of frames to read ahead */
+#define MAXMPGLAG READ_AHEAD      /* if the mpg123 lag becomes bigger than this                                     we have to stop */
+#define NUMBACK 6                 /* number of frames we can back up */
+#define NUMPINFO (NUMBACK+READ_AHEAD+1)
+
+
+
+typedef struct {
+  int frameNum;           /* current frame number */
+  int frameNum123;
+  int num_samples;        /* number of pcm samples read for this frame */
+  double frametime;       /* starting time of frame, in seconds */
+  double pcmdata[2][1600];
+  double pcmdata2[2][1152+1152-DECDELAY];
+  double xr[2][2][576];
+  double mpg123xr[2][2][576];
+  double ms_ratio[2];
+  double ms_ener_ratio[2];
+
+  /* L,R, M and S values */
+  double energy[2][4][BLKSIZE];
+  double pe[2][4];
+  double thr[2][4][SBMAX_l];
+  double en[2][4][SBMAX_l];
+  double thr_s[2][4][3*SBMAX_s];
+  double en_s[2][4][3*SBMAX_s];
+  double ers[2][4];
+
+  double sfb[2][2][SBMAX_l];
+  double sfb_s[2][2][3*SBMAX_s];
+  double LAMEsfb[2][2][SBMAX_l];
+  double LAMEsfb_s[2][2][3*SBMAX_s];
+
+  int LAMEqss[2][2];
+  int qss[2][2];
+  int big_values[2][2];
+  int sub_gain[2][2][3];
+
+  double xfsf[2][2][SBMAX_l];
+  double xfsf_s[2][2][3*SBMAX_s];
+
+  int over[2][2];
+  double tot_noise[2][2];
+  double max_noise[2][2];
+  double over_noise[2][2];
+  int blocktype[2][2];
+  int scalefac_scale[2][2];
+  int preflag[2][2];
+  int mpg123blocktype[2][2];
+  int mixed[2][2];
+  int mainbits[2][2];
+  int sfbits[2][2];
+  int LAMEmainbits[2][2];
+  int LAMEsfbits[2][2];
+  int framesize,stereo,js,ms_stereo,i_stereo,emph,bitrate,sampfreq,maindata;
+  int crc,padding;
+  int scfsi[2],mean_bits,resvsize;
+  int totbits;
+} plotting_data;
+
+extern plotting_data *pinfo;
+
+#endif
diff --git a/lib/lame/lame.c b/lib/lame/lame.c
new file mode 100644 (file)
index 0000000..df4fdac
--- /dev/null
@@ -0,0 +1,2239 @@
+/* -*- mode: C; mode: fold -*- */
+/*
+ *     LAME MP3 encoding engine
+ *
+ *     Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: lame.c,v 1.1 2002/04/28 17:30:20 kramm Exp $ */
+
+#include "config_static.h"
+
+
+#include <assert.h>
+#include "lame-analysis.h"
+#include "lame.h"
+#include "util.h"
+#include "bitstream.h"
+#include "version.h"
+#include "tables.h"
+#include "quantize_pvt.h"
+#include "VbrTag.h"
+
+#if defined(__FreeBSD__) && !defined(__alpha__)
+#include <floatingpoint.h>
+#endif
+#ifdef __riscos__
+#include "asmstuff.h"
+#endif
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+
+static void
+lame_init_params_ppflt_lowpass(FLOAT8 amp_lowpass[32], FLOAT lowpass1,
+                               FLOAT lowpass2, int *lowpass_band,
+                               int *minband, int *maxband)
+{
+    int     band;
+    FLOAT8  freq;
+
+    for (band = 0; band <= 31; band++) {
+        freq = band / 31.0;
+        amp_lowpass[band] = 1;
+        /* this band and above will be zeroed: */
+        if (freq >= lowpass2) {
+            *lowpass_band = Min(*lowpass_band, band);
+            amp_lowpass[band] = 0;
+        }
+        if (lowpass1 < freq && freq < lowpass2) {
+            *minband = Min(*minband, band);
+            *maxband = Max(*maxband, band);
+            amp_lowpass[band] = cos((PI / 2) *
+                                    (lowpass1 - freq) / (lowpass2 - lowpass1));
+        }
+        /*
+         * DEBUGF("lowpass band=%i  amp=%f \n",
+         *      band, gfc->amp_lowpass[band]);
+         */
+    }
+}
+
+/* lame_init_params_ppflt */
+
+/*}}}*/
+/* static void   lame_init_params_ppflt         (lame_internal_flags *gfc)                                                                                        *//*{{{ */
+
+static void
+lame_init_params_ppflt(lame_global_flags * gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+  /***************************************************************/
+    /* compute info needed for polyphase filter (filter type==0, default) */
+  /***************************************************************/
+
+    int     band, maxband, minband;
+    FLOAT8  freq;
+
+    if (gfc->lowpass1 > 0) {
+        minband = 999;
+        maxband = -1;
+        lame_init_params_ppflt_lowpass(gfc->amp_lowpass,
+                                       gfc->lowpass1, gfc->lowpass2,
+                                       &gfc->lowpass_band, &minband, &maxband);
+        /* compute the *actual* transition band implemented by
+         * the polyphase filter */
+        if (minband == 999) {
+            gfc->lowpass1 = (gfc->lowpass_band - .75) / 31.0;
+        }
+        else {
+            gfc->lowpass1 = (minband - .75) / 31.0;
+        }
+        gfc->lowpass2 = gfc->lowpass_band / 31.0;
+
+        gfc->lowpass_start_band = minband;
+        gfc->lowpass_end_band = maxband;
+
+        /* as the lowpass may have changed above
+         * calculate the amplification here again
+         */
+        for (band = minband; band <= maxband; band++) {
+            freq = band / 31.0;
+            gfc->amp_lowpass[band] =
+                cos((PI / 2) * (gfc->lowpass1 - freq) /
+                    (gfc->lowpass2 - gfc->lowpass1));
+        }
+    }
+    else {
+        gfc->lowpass_start_band = 0;
+        gfc->lowpass_end_band = -1; /* do not to run into for-loops */
+    }
+
+    /* make sure highpass filter is within 90% of what the effective
+     * highpass frequency will be */
+    if (gfc->highpass2 > 0) {
+        if (gfc->highpass2 < .9 * (.75 / 31.0)) {
+            gfc->highpass1 = 0;
+            gfc->highpass2 = 0;
+            MSGF(gfc, "Warning: highpass filter disabled.  "
+                 "highpass frequency too small\n");
+        }
+    }
+
+    if (gfc->highpass2 > 0) {
+        minband = 999;
+        maxband = -1;
+        for (band = 0; band <= 31; band++) {
+            freq = band / 31.0;
+            gfc->amp_highpass[band] = 1;
+            /* this band and below will be zereod */
+            if (freq <= gfc->highpass1) {
+                gfc->highpass_band = Max(gfc->highpass_band, band);
+                gfc->amp_highpass[band] = 0;
+            }
+            if (gfc->highpass1 < freq && freq < gfc->highpass2) {
+                minband = Min(minband, band);
+                maxband = Max(maxband, band);
+                gfc->amp_highpass[band] =
+                    cos((PI / 2) *
+                        (gfc->highpass2 - freq) /
+                        (gfc->highpass2 - gfc->highpass1));
+            }
+            /*
+               DEBUGF("highpass band=%i  amp=%f \n",
+               band, gfc->amp_highpass[band]);
+             */
+        }
+        /* compute the *actual* transition band implemented by
+         * the polyphase filter */
+        gfc->highpass1 = gfc->highpass_band / 31.0;
+        if (maxband == -1) {
+            gfc->highpass2 = (gfc->highpass_band + .75) / 31.0;
+        }
+        else {
+            gfc->highpass2 = (maxband + .75) / 31.0;
+        }
+
+        gfc->highpass_start_band = minband;
+        gfc->highpass_end_band = maxband;
+
+        /* as the highpass may have changed above
+         * calculate the amplification here again
+         */
+        for (band = minband; band <= maxband; band++) {
+            freq = band / 31.0;
+            gfc->amp_highpass[band] =
+                cos((PI / 2) * (gfc->highpass2 - freq) /
+                    (gfc->highpass2 - gfc->highpass1));
+        }
+    }
+    else {
+        gfc->highpass_start_band = 0;
+        gfc->highpass_end_band = -1; /* do not to run into for-loops */
+    }
+    /*
+       DEBUGF("lowpass band with amp=0:  %i \n",gfc->lowpass_band);
+       DEBUGF("highpass band with amp=0:  %i \n",gfc->highpass_band);
+       DEBUGF("lowpass band start:  %i \n",gfc->lowpass_start_band);
+       DEBUGF("lowpass band end:    %i \n",gfc->lowpass_end_band);
+       DEBUGF("highpass band start:  %i \n",gfc->highpass_start_band);
+       DEBUGF("highpass band end:    %i \n",gfc->highpass_end_band);
+     */
+}
+
+/*}}}*/
+
+
+static void
+optimum_bandwidth(double *const lowerlimit,
+                  double *const upperlimit,
+                  const unsigned bitrate,
+                  const int samplefreq,
+                  const double channels)
+{
+/* 
+ *  Input:
+ *      bitrate     total bitrate in bps
+ *      samplefreq  output sampling frequency in Hz
+ *      channels    1 for mono, 2+epsilon for MS stereo, 3 for LR stereo
+ *                  epsilon is the percentage of LR frames for typical audio
+ *                  (I use 'Fade to Gray' by Metallica)
+ *
+ *   Output:
+ *      lowerlimit: best lowpass frequency limit for input filter in Hz
+ *      upperlimit: best highpass frequency limit for input filter in Hz
+ */
+    double  f_low;
+    double  f_high;
+    double  br;
+
+    assert(bitrate >= 8000 && bitrate <= 320000);
+    assert(samplefreq >= 8000 && samplefreq <= 48000);
+    assert(channels == 1 || (channels >= 2 && channels <= 3));
+
+    if (samplefreq >= 32000)
+        br =
+            bitrate - (channels ==
+                       1 ? (17 + 4) * 8 : (32 + 4) * 8) * samplefreq / 1152;
+    else
+        br =
+            bitrate - (channels ==
+                       1 ? (9 + 4) * 8 : (17 + 4) * 8) * samplefreq / 576;
+
+    if (channels >= 2.)
+        br /= 1.75 + 0.25 * (channels - 2.); // MS needs 1.75x mono, LR needs 2.00x mono (experimental data of a lot of albums)
+
+    br *= 0.5;          // the sine and cosine term must share the bitrate
+
+/* 
+ *  So, now we have the bitrate for every spectral line.
+ *  Let's look at the current settings:
+ *
+ *    Bitrate   limit    bits/line
+ *     8 kbps   0.34 kHz  4.76
+ *    16 kbps   1.9 kHz   2.06
+ *    24 kbps   2.8 kHz   2.21
+ *    32 kbps   3.85 kHz  2.14
+ *    40 kbps   5.1 kHz   2.06
+ *    48 kbps   5.6 kHz   2.21
+ *    56 kbps   7.0 kHz   2.10
+ *    64 kbps   7.7 kHz   2.14
+ *    80 kbps  10.1 kHz   2.08
+ *    96 kbps  11.2 kHz   2.24
+ *   112 kbps  14.0 kHz   2.12
+ *   128 kbps  15.4 kHz   2.17
+ *   160 kbps  18.2 kHz   2.05
+ *   192 kbps  21.1 kHz   2.14
+ *   224 kbps  22.0 kHz   2.41
+ *   256 kbps  22.0 kHz   2.78
+ *
+ *   What can we see?
+ *       Value for 8 kbps is nonsense (although 8 kbps and stereo is nonsense)
+ *       Values are between 2.05 and 2.24 for 16...192 kbps
+ *       Some bitrate lack the following bitrates have: 16, 40, 80, 160 kbps
+ *       A lot of bits per spectral line have: 24, 48, 96 kbps
+ *
+ *   What I propose?
+ *       A slightly with the bitrate increasing bits/line function. It is
+ *       better to decrease NMR for low bitrates to get a little bit more
+ *       bandwidth. So we have a better trade off between twickling and
+ *       muffled sound.
+ */
+
+    f_low = br / log10(br * 4.425e-3); // Tests with 8, 16, 32, 64, 112 and 160 kbps
+/*
+GB 04/04/01
+sfb21 is a huge bitrate consumer in vbr with the new ath.
+Need to reduce the lowpass to more reasonable values. This extra lowpass
+won't reduce quality over 3.87 as the previous ath was doing this lowpass
+*/
+/*GB 22/05/01
+I'm also extending this to CBR as tests showed that a
+limited bandwidth is increasing quality
+*/
+    if (f_low>18400)
+           f_low = 18400+(f_low-18400)/4;
+
+/*
+ *  What we get now?
+ *
+ *    Bitrate       limit  bits/line   difference
+ *     8 kbps (8)  1.89 kHz  0.86          +1.6 kHz
+ *    16 kbps (8)  3.16 kHz  1.24          +1.2 kHz
+ *    32 kbps(16)  5.08 kHz  1.54          +1.2 kHz
+ *    56 kbps(22)  7.88 kHz  1.80          +0.9 kHz
+ *    64 kbps(22)  8.83 kHz  1.86          +1.1 kHz
+ *   112 kbps(32) 14.02 kHz  2.12           0.0 kHz
+ *   112 kbps(44) 13.70 kHz  2.11          -0.3 kHz
+ *   128 kbps     15.40 kHz  2.17           0.0 kHz
+ *   160 kbps     16.80 kHz  2.22          -1.4 kHz 
+ *   192 kbps     19.66 kHz  2.30          -1.4 kHz
+ *   256 kbps     22.05 kHz  2.78           0.0 kHz
+ */
+
+
+/*
+ *  Now we try to choose a good high pass filtering frequency.
+ *  This value is currently not used.
+ *    For fu < 16 kHz:  sqrt(fu*fl) = 560 Hz
+ *    For fu = 18 kHz:  no high pass filtering
+ *  This gives:
+ *
+ *   2 kHz => 160 Hz
+ *   3 kHz => 107 Hz
+ *   4 kHz =>  80 Hz
+ *   8 kHz =>  40 Hz
+ *  16 kHz =>  20 Hz
+ *  17 kHz =>  10 Hz
+ *  18 kHz =>   0 Hz
+ *
+ *  These are ad hoc values and these can be optimized if a high pass is available.
+ */
+    if (f_low <= 16000)
+        f_high = 16000. * 20. / f_low;
+    else if (f_low <= 18000)
+        f_high = 180. - 0.01 * f_low;
+    else
+        f_high = 0.;
+
+    /*  
+     *  When we sometimes have a good highpass filter, we can add the highpass
+     *  frequency to the lowpass frequency
+     */
+
+    if (lowerlimit != NULL)
+        *lowerlimit = (f_low>0.5 * samplefreq ? 0.5 * samplefreq : f_low); // roel - fixes mono "-b320 -a"
+    if (upperlimit != NULL)
+        *upperlimit = f_high;
+/*
+ * Now the weak points:
+ *
+ *   - the formula f_low=br/log10(br*4.425e-3) is an ad hoc formula
+ *     (but has a physical background and is easy to tune)
+ *   - the switch to the ATH based bandwidth selecting is the ad hoc
+ *     value of 128 kbps
+ */
+}
+
+static int
+optimum_samplefreq(int lowpassfreq, int input_samplefreq)
+{
+/*
+ * Rules:
+ *
+ *  - output sample frequency should NOT be decreased by more than 3% if lowpass allows this
+ *  - if possible, sfb21 should NOT be used
+ *
+ *  Problem: Switches to 32 kHz at 112 kbps
+ */
+    if (input_samplefreq <= 8000 * 1.03 || lowpassfreq <= 3622)
+        return 8000;
+    if (input_samplefreq <= 11025 * 1.03 || lowpassfreq <= 4991)
+        return 11025;
+    if (input_samplefreq <= 12000 * 1.03 || lowpassfreq <= 5620)
+        return 12000;
+    if (input_samplefreq <= 16000 * 1.03 || lowpassfreq <= 7244)
+        return 16000;
+    if (input_samplefreq <= 22050 * 1.03 || lowpassfreq <= 9982)
+        return 22050;
+    if (input_samplefreq <= 24000 * 1.03 || lowpassfreq <= 11240)
+        return 24000;
+    if (input_samplefreq <= 32000 * 1.03 || lowpassfreq <= 15264)
+        return 32000;
+    if (input_samplefreq <= 44100 * 1.03)
+        return 44100;
+    return 48000;
+}
+
+
+/* set internal feature flags.  USER should not access these since
+ * some combinations will produce strange results */
+void
+lame_init_qval(lame_global_flags * gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+
+    switch (gfp->quality) {
+    case 9:            /* no psymodel, no noise shaping */
+        gfc->filter_type = 0;
+        gfc->psymodel = 0;
+        gfc->quantization = 0;
+        gfc->noise_shaping = 0;
+        gfc->noise_shaping_amp = 0;
+        gfc->noise_shaping_stop = 0;
+        gfc->use_best_huffman = 0;
+        break;
+
+    case 8:
+        gfp->quality = 7;
+    case 7:            /* use psymodel (for short block and m/s switching), but no noise shapping */
+        gfc->filter_type = 0;
+        gfc->psymodel = 1;
+        gfc->quantization = 0;
+        gfc->noise_shaping = 0;
+        gfc->noise_shaping_amp = 0;
+        gfc->noise_shaping_stop = 0;
+        gfc->use_best_huffman = 0;
+        break;
+
+    case 6:
+        gfp->quality = 5;
+    case 5:            /* the default */
+        gfc->filter_type = 0;
+        gfc->psymodel = 1;
+        gfc->quantization = 0;
+        gfc->noise_shaping = 1;
+         /**/ gfc->noise_shaping_amp = 0;
+        gfc->noise_shaping_stop = 0;
+        gfc->use_best_huffman = 0;
+        break;
+
+    case 4:
+        gfp->quality = 3;
+    case 3:
+        gfc->filter_type = 0;
+        gfc->psymodel = 1;
+        gfc->quantization = 1;
+        gfc->noise_shaping = 1;
+        gfc->noise_shaping_amp = 0;
+        gfc->noise_shaping_stop = 0;
+        gfc->use_best_huffman = 1;
+        break;
+
+    case 2:
+        gfc->filter_type = 0;
+        gfc->psymodel = 1;
+        gfc->quantization = 1;
+        gfc->noise_shaping = 1;
+        gfc->noise_shaping_amp = 1;
+        gfc->noise_shaping_stop = 1;
+        gfc->use_best_huffman = 1;
+        break;
+
+    case 1:
+        gfc->filter_type = 0;
+        gfc->psymodel = 1;
+        gfc->quantization = 1;
+        gfc->noise_shaping = 1;
+        gfc->noise_shaping_amp = 2;
+        gfc->noise_shaping_stop = 1;
+        gfc->use_best_huffman = 1;
+        break;
+
+    case 0:            /* 0..1 quality */
+        gfc->filter_type = 0; /* 1 not yet coded */
+        gfc->psymodel = 1;
+        gfc->quantization = 1;
+        gfc->noise_shaping = 1; /* 2=usually lowers quality */
+        gfc->noise_shaping_amp = 3;
+        gfc->noise_shaping_stop = 1;
+        gfc->use_best_huffman = 1; /* 2 not yet coded */
+    }
+
+    /* modifications to the above rules: */
+
+    /* -Z option toggles scalefactor_scale: */
+    if ( (gfp->experimentalZ & 1) > 0) {
+        gfc->noise_shaping = 2;
+    }
+}
+
+
+
+
+
+
+
+/* int           lame_init_params               (lame_global_flags *gfp)                                                                                          *//*{{{ */
+
+/********************************************************************
+ *   initialize internal params based on data in gf
+ *   (globalflags struct filled in by calling program)
+ *
+ *  OUTLINE:
+ *
+ * We first have some complex code to determine bitrate, 
+ * output samplerate and mode.  It is complicated by the fact
+ * that we allow the user to set some or all of these parameters,
+ * and need to determine best possible values for the rest of them:
+ *
+ *  1. set some CPU related flags
+ *  2. check if we are mono->mono, stereo->mono or stereo->stereo
+ *  3.  compute bitrate and output samplerate:
+ *          user may have set compression ratio
+ *          user may have set a bitrate  
+ *          user may have set a output samplerate
+ *  4. set some options which depend on output samplerate
+ *  5. compute the actual compression ratio
+ *  6. set mode based on compression ratio
+ *
+ *  The remaining code is much simpler - it just sets options
+ *  based on the mode & compression ratio: 
+ *   
+ *   set allow_diff_short based on mode
+ *   select lowpass filter based on compression ratio & mode
+ *   set the bitrate index, and min/max bitrates for VBR modes
+ *   disable VBR tag if it is not appropriate
+ *   initialize the bitstream
+ *   initialize scalefac_band data
+ *   set sideinfo_len (based on channels, CRC, out_samplerate)
+ *   write an id3v2 tag into the bitstream
+ *   write VBR tag into the bitstream
+ *   set mpeg1/2 flag
+ *   estimate the number of frames (based on a lot of data)
+ *         
+ *   now we set more flags:
+ *   nspsytune:
+ *      see code
+ *   VBR modes
+ *      see code      
+ *   CBR/ABR
+ *      see code   
+ *
+ *  Finally, we set the algorithm flags based on the gfp->quality value
+ *  lame_init_qval(gfp);
+ *
+ ********************************************************************/
+int
+lame_init_params(lame_global_flags * const gfp)
+{
+
+    int     i;
+    int     j;
+    lame_internal_flags *gfc = gfp->internal_flags;
+
+    gfc->gfp = gfp;
+
+    gfc->Class_ID = 0;
+
+    /* report functions */
+    gfc->report.msgf   = gfp->report.msgf;
+    gfc->report.debugf = gfp->report.debugf;
+    gfc->report.errorf = gfp->report.errorf;
+
+    gfc->CPU_features.i387 = has_i387();
+    gfc->CPU_features.AMD_3DNow = has_3DNow();
+    gfc->CPU_features.MMX = has_MMX();
+    gfc->CPU_features.SIMD = has_SIMD();
+    gfc->CPU_features.SIMD2 = has_SIMD2();
+
+
+    if (NULL == gfc->ATH)
+        gfc->ATH = calloc(1, sizeof(ATH_t));
+
+    if (NULL == gfc->ATH)
+        return -2;  // maybe error codes should be enumerated in lame.h ??
+
+    if (NULL == gfc->VBR)
+        gfc->VBR = calloc(1, sizeof(VBR_t));
+    if (NULL == gfc->VBR)
+        return -2;
+        
+    if (NULL == gfc->PSY)
+        gfc->PSY = calloc(1, sizeof(PSY_t));
+    if (NULL == gfc->PSY)
+        return -2;
+        
+#ifdef KLEMM_44
+    /* Select the fastest functions for this CPU */
+    init_scalar_functions(gfc);
+#endif
+
+    gfc->channels_in = gfp->num_channels;
+    if (gfc->channels_in == 1)
+        gfp->mode = MONO;
+    gfc->channels_out = (gfp->mode == MONO) ? 1 : 2;
+    gfc->mode_ext = MPG_MD_LR_LR;
+    if (gfp->mode == MONO)
+        gfp->force_ms = 0; // don't allow forced mid/side stereo for mono output
+
+
+    if (gfp->VBR != vbr_off) {
+        gfp->free_format = 0; /* VBR can't be mixed with free format */
+    }
+
+    if (gfp->VBR == vbr_off && gfp->brate == 0) {
+        /* no bitrate or compression ratio specified, use a compression ratio of 11.025 */
+        if (gfp->compression_ratio == 0)
+            gfp->compression_ratio = 11.025; /* rate to compress a CD down to exactly 128000 bps */
+    }
+
+
+    if (gfp->VBR == vbr_off && gfp->brate == 0) {
+        /* no bitrate or compression ratio specified, use 11.025 */
+        if (gfp->compression_ratio == 0)
+            gfp->compression_ratio = 11.025; /* rate to compress a CD down to exactly 128000 bps */
+    }
+
+    /* find bitrate if user specify a compression ratio */
+    if (gfp->VBR == vbr_off && gfp->compression_ratio > 0) {
+
+        if (gfp->out_samplerate == 0)
+            gfp->out_samplerate = map2MP3Frequency( (int)( 0.97 * gfp->in_samplerate ) ); /* round up with a margin of 3% */
+
+        /* choose a bitrate for the output samplerate which achieves
+         * specified compression ratio 
+         */
+        gfp->brate =
+            gfp->out_samplerate * 16 * gfc->channels_out / (1.e3 *
+                                                            gfp->
+                                                            compression_ratio);
+
+        /* we need the version for the bitrate table look up */
+        gfc->samplerate_index = SmpFrqIndex(gfp->out_samplerate, &gfp->version);
+
+        if (!gfp->free_format) /* for non Free Format find the nearest allowed bitrate */
+            gfp->brate =
+                FindNearestBitrate(gfp->brate, gfp->version,
+                                   gfp->out_samplerate);
+    }
+
+    if (gfp->VBR != vbr_off && gfp->brate >= 320)
+        gfp->VBR = vbr_off; /* at 160 kbps (MPEG-2/2.5)/ 320 kbps (MPEG-1) only Free format or CBR are possible, no VBR */
+
+
+    if (gfp->out_samplerate == 0) { /* if output sample frequency is not given, find an useful value */
+        gfp->out_samplerate = map2MP3Frequency( (int)( 0.97 * gfp->in_samplerate ) );
+
+
+        /* check if user specified bitrate requires downsampling, if compression    */
+        /* ratio is > 13, choose a new samplerate to get the ratio down to about 10 */
+
+        if (gfp->VBR == vbr_off && gfp->brate > 0) {
+            gfp->compression_ratio =
+                gfp->out_samplerate * 16 * gfc->channels_out / (1.e3 *
+                                                                gfp->brate);
+            if (gfp->compression_ratio > 13.)
+                gfp->out_samplerate =
+                    map2MP3Frequency( (int)( (10. * 1.e3 * gfp->brate) /
+                                     (16 * gfc->channels_out)));
+        }
+        if (gfp->VBR == vbr_abr) {
+            gfp->compression_ratio =
+                gfp->out_samplerate * 16 * gfc->channels_out / (1.e3 *
+                                                                gfp->
+                                                                VBR_mean_bitrate_kbps);
+            if (gfp->compression_ratio > 13.)
+                gfp->out_samplerate =
+                    map2MP3Frequency((int)((10. * 1.e3 * gfp->VBR_mean_bitrate_kbps) /
+                                     (16 * gfc->channels_out)));
+        }
+    }
+
+    if (gfp->ogg) {
+        gfp->framesize = 1024;
+        gfp->encoder_delay = ENCDELAY;
+        gfc->coding = coding_Ogg_Vorbis;
+    }
+    else {
+        gfc->mode_gr = gfp->out_samplerate <= 24000 ? 1 : 2; // Number of granules per frame
+        gfp->framesize = 576 * gfc->mode_gr;
+        gfp->encoder_delay = ENCDELAY;
+        gfc->coding = coding_MPEG_Layer_3;
+    }
+
+    gfc->frame_size = gfp->framesize;
+
+    gfc->resample_ratio = (double) gfp->in_samplerate / gfp->out_samplerate;
+
+    /* 
+     *  sample freq       bitrate     compression ratio
+     *     [kHz]      [kbps/channel]   for 16 bit input
+     *     44.1            56               12.6
+     *     44.1            64               11.025
+     *     44.1            80                8.82
+     *     22.05           24               14.7
+     *     22.05           32               11.025
+     *     22.05           40                8.82
+     *     16              16               16.0
+     *     16              24               10.667
+     *
+     */
+    /* 
+     *  For VBR, take a guess at the compression_ratio. 
+     *  For example:
+     *
+     *    VBR_q    compression     like
+     *     -        4.4         320 kbps/44 kHz
+     *   0...1      5.5         256 kbps/44 kHz
+     *     2        7.3         192 kbps/44 kHz
+     *     4        8.8         160 kbps/44 kHz
+     *     6       11           128 kbps/44 kHz
+     *     9       14.7          96 kbps
+     *
+     *  for lower bitrates, downsample with --resample
+     */
+
+    switch (gfp->VBR) {
+    case vbr_mt:
+    case vbr_rh:
+    case vbr_mtrh:
+        {
+            FLOAT8  cmp[] = { 5.7, 6.5, 7.3, 8.2, 9.1, 10, 11, 12, 13, 14 };
+            gfp->compression_ratio = cmp[gfp->VBR_q];
+        }
+        break;
+    case vbr_abr:
+        gfp->compression_ratio =
+            gfp->out_samplerate * 16 * gfc->channels_out / (1.e3 *
+                                                            gfp->
+                                                            VBR_mean_bitrate_kbps);
+        break;
+    default:
+        gfp->compression_ratio =
+            gfp->out_samplerate * 16 * gfc->channels_out / (1.e3 * gfp->brate);
+        break;
+    }
+
+
+    /* mode = -1 (not set by user) or 
+     * mode = MONO (because of only 1 input channel).  
+     * If mode has been set, then select between STEREO or J-STEREO
+     * At higher quality (lower compression) use STEREO instead of J-STEREO.
+     * (unless the user explicitly specified a mode)
+     *
+     * The threshold to switch to STEREO is:
+     *    48 kHz:   171 kbps (used at 192+)
+     *    44.1 kHz: 160 kbps (used at 160+)
+     *    32 kHz:   119 kbps (used at 128+)
+     *
+     *   Note, that for 32 kHz/128 kbps J-STEREO FM recordings sound much
+     *   better than STEREO, so I'm not so very happy with that. 
+     *   fs < 32 kHz I have not tested.
+     */
+    if (gfp->mode == NOT_SET) {
+        if (gfp->compression_ratio < 8)
+            gfp->mode = STEREO;
+        else
+            gfp->mode = JOINT_STEREO;
+    }
+
+    /* KLEMM's jstereo with ms threshold adjusted via compression ratio */
+    if (gfp->mode_automs) {
+        if (gfp->mode != MONO && gfp->compression_ratio < 6.6)
+            gfp->mode = STEREO;
+    }
+
+
+
+
+
+
+  /****************************************************************/
+  /* if a filter has not been enabled, see if we should add one: */
+  /****************************************************************/
+    if (gfp->lowpassfreq == 0) {
+        double  lowpass;
+        double  highpass;
+        double  channels;
+
+        switch (gfp->mode) {
+        case MONO:
+            channels = 1.;
+            break;
+        case JOINT_STEREO:
+            channels = 2. + 0.00;
+            break;
+        case DUAL_CHANNEL:
+        case STEREO:
+            channels = 3.;
+            break;
+        default:    
+            channels = 1.;  // just to make data flow analysis happy :-)
+            assert(0);
+            break;
+        }
+
+        optimum_bandwidth(&lowpass,
+                          &highpass,
+                          gfp->out_samplerate * 16 * gfc->channels_out /
+                          gfp->compression_ratio, gfp->out_samplerate, channels);
+                       
+/*  roel - is this still needed?
+               if (lowpass > 0.5 * gfp->out_samplerate) {
+            //MSGF(gfc,"Lowpass @ %7.1f Hz\n", lowpass);
+            gfc->lowpass1 = gfc->lowpass2 =
+                lowpass / (0.5 * gfp->out_samplerate);
+        }
+*/
+        gfp->lowpassfreq = lowpass;
+
+#if 0
+        if (gfp->out_samplerate !=
+            optimum_samplefreq(lowpass, gfp->in_samplerate)) {
+            MSGF(gfc,
+                 "I would suggest to use %u Hz instead of %u Hz sample frequency\n",
+                 optimum_samplefreq(lowpass, gfp->in_samplerate),
+                 gfp->out_samplerate);
+        }
+        fflush(stderr);
+#endif
+    }
+
+    /* apply user driven high pass filter */
+    if (gfp->highpassfreq > 0) {
+        gfc->highpass1 = 2. * gfp->highpassfreq / gfp->out_samplerate; /* will always be >=0 */
+        if (gfp->highpasswidth >= 0)
+            gfc->highpass2 =
+                2. * (gfp->highpassfreq +
+                      gfp->highpasswidth) / gfp->out_samplerate;
+        else            /* 0% above on default */
+            gfc->highpass2 =
+                (1 + 0.00) * 2. * gfp->highpassfreq / gfp->out_samplerate;
+    }
+
+    /* apply user driven low pass filter */
+    if (gfp->lowpassfreq > 0) {
+        gfc->lowpass2 = 2. * gfp->lowpassfreq / gfp->out_samplerate; /* will always be >=0 */
+        if (gfp->lowpasswidth >= 0) {
+            gfc->lowpass1 =
+                2. * (gfp->lowpassfreq -
+                      gfp->lowpasswidth) / gfp->out_samplerate;
+            if (gfc->lowpass1 < 0) /* has to be >= 0 */
+                gfc->lowpass1 = 0;
+        }
+        else {          /* 0% below on default */
+            gfc->lowpass1 =
+                (1 - 0.00) * 2. * gfp->lowpassfreq / gfp->out_samplerate;
+        }
+    }
+
+
+
+
+  /**********************************************************************/
+  /* compute info needed for polyphase filter (filter type==0, default) */
+  /**********************************************************************/
+    lame_init_params_ppflt(gfp);
+
+
+  /*******************************************************/
+  /* compute info needed for FIR filter (filter_type==1) */
+  /*******************************************************/
+   /* not yet coded */
+
+
+
+  /*******************************************************
+   * samplerate and bitrate index
+   *******************************************************/
+    gfc->samplerate_index = SmpFrqIndex(gfp->out_samplerate, &gfp->version);
+    if (gfc->samplerate_index < 0)
+        return -1;
+
+    if (gfp->VBR == vbr_off) {
+        if (gfp->free_format) {
+            gfc->bitrate_index = 0;
+        }
+        else {
+            gfc->bitrate_index = BitrateIndex(gfp->brate, gfp->version,
+                                              gfp->out_samplerate);
+            if (gfc->bitrate_index < 0)
+                return -1;
+        }
+    }
+    else {              /* choose a min/max bitrate for VBR */
+        /* if the user didn't specify VBR_max_bitrate: */
+        gfc->VBR_min_bitrate = 1; /* default: allow   8 kbps (MPEG-2) or  32 kbps (MPEG-1) */
+        gfc->VBR_max_bitrate = 14; /* default: allow 160 kbps (MPEG-2) or 320 kbps (MPEG-1) */
+
+        if (gfp->VBR_min_bitrate_kbps)
+            if (
+                (gfc->VBR_min_bitrate =
+                 BitrateIndex(gfp->VBR_min_bitrate_kbps, gfp->version,
+                              gfp->out_samplerate)) < 0) return -1;
+        if (gfp->VBR_max_bitrate_kbps)
+            if (
+                (gfc->VBR_max_bitrate =
+                 BitrateIndex(gfp->VBR_max_bitrate_kbps, gfp->version,
+                              gfp->out_samplerate)) < 0) return -1;
+
+        gfp->VBR_min_bitrate_kbps =
+            bitrate_table[gfp->version][gfc->VBR_min_bitrate];
+        gfp->VBR_max_bitrate_kbps =
+            bitrate_table[gfp->version][gfc->VBR_max_bitrate];
+
+        gfp->VBR_mean_bitrate_kbps =
+            Min(bitrate_table[gfp->version][gfc->VBR_max_bitrate],
+                gfp->VBR_mean_bitrate_kbps);
+        gfp->VBR_mean_bitrate_kbps =
+            Max(bitrate_table[gfp->version][gfc->VBR_min_bitrate],
+                gfp->VBR_mean_bitrate_kbps);
+
+
+    }
+
+    /* for CBR, we will write an "info" tag. */
+    //    if ((gfp->VBR == vbr_off)) 
+    //  gfp->bWriteVbrTag = 0;
+
+    if (gfp->ogg)
+        gfp->bWriteVbrTag = 0;
+#if defined(HAVE_GTK)
+    if (gfp->analysis)
+        gfp->bWriteVbrTag = 0;
+#endif
+
+    /* some file options not allowed if output is: not specified or stdout */
+    if (gfc->pinfo != NULL)
+        gfp->bWriteVbrTag = 0; /* disable Xing VBR tag */
+
+    init_bit_stream_w(gfc);
+
+    j =
+        gfc->samplerate_index + (3 * gfp->version) + 6 * (gfp->out_samplerate <
+                                                          16000);
+    for (i = 0; i < SBMAX_l + 1; i++)
+        gfc->scalefac_band.l[i] = sfBandIndex[j].l[i];
+    for (i = 0; i < SBMAX_s + 1; i++)
+        gfc->scalefac_band.s[i] = sfBandIndex[j].s[i];
+
+    /* determine the mean bitrate for main data */
+    if (gfp->version == 1) /* MPEG 1 */
+        gfc->sideinfo_len = (gfc->channels_out == 1) ? 4 + 17 : 4 + 32;
+    else                /* MPEG 2 */
+        gfc->sideinfo_len = (gfc->channels_out == 1) ? 4 + 9 : 4 + 17;
+
+    if (gfp->error_protection)
+        gfc->sideinfo_len += 2;
+
+    lame_init_bitstream(gfp);
+
+
+    if (gfp->version == 1) /* 0 indicates use lower sample freqs algorithm */
+        gfc->is_mpeg1 = 1; /* yes */
+    else
+        gfc->is_mpeg1 = 0; /* no */
+
+    gfc->Class_ID = LAME_ID;
+
+
+    if (gfp->exp_nspsytune & 1) {
+        int     i,j;
+
+        gfc->nsPsy.use = 1;
+        gfc->nsPsy.safejoint = (gfp->exp_nspsytune & 2) != 0;
+        for (i = 0; i < 19; i++)
+            gfc->nsPsy.pefirbuf[i] = 700;
+
+        if (gfp->ATHtype == -1)
+            gfp->ATHtype = 4;
+
+        gfc->nsPsy.bass = gfc->nsPsy.alto = gfc->nsPsy.treble = 0;
+
+        i = (gfp->exp_nspsytune >> 2) & 63;
+        if (i >= 32)
+            i -= 64;
+        gfc->nsPsy.bass = pow(10, i / 4.0 / 10.0);
+        i = (gfp->exp_nspsytune >> 8) & 63;
+        if (i >= 32)
+            i -= 64;
+        gfc->nsPsy.alto = pow(10, i / 4.0 / 10.0);
+        i = (gfp->exp_nspsytune >> 14) & 63;
+        if (i >= 32)
+            i -= 64;
+        gfc->nsPsy.treble = pow(10, i / 4.0 / 10.0);
+        /*  to be compatible with Naoki's original code, the next 6 bits
+         *  define only the amount of changing treble for sfb21 */
+        j = (gfp->exp_nspsytune >> 20) & 63;
+        if (j >= 32)
+            j -= 64;
+        gfc->nsPsy.sfb21 = pow(10, (i+j) / 4.0 / 10.0);
+    }
+
+    assert( gfp->VBR_q <= 9 );
+    assert( gfp->VBR_q >= 0 );
+    
+    gfc->PSY->tonalityPatch = 0;
+  
+    switch (gfp->VBR) {
+
+    case vbr_mt:
+        gfp->VBR = vbr_mtrh;
+        
+    case vbr_mtrh:
+
+        if (gfp->ATHtype < 0) gfp->ATHtype = 4;
+        if (gfp->quality < 0) gfp->quality = 2;
+        if (gfp->quality > 7) {
+            gfp->quality = 7;     // needs psymodel
+            ERRORF( gfc, "VBR needs a psymodel, switching to quality level 7\n");
+        }
+
+        /*  tonality
+         */
+        if (gfp->cwlimit <= 0) gfp->cwlimit = 0.42 * gfp->out_samplerate;
+        gfc->PSY->tonalityPatch = 1;
+
+        if ( gfp->experimentalX <= 4 && gfp->experimentalX >= 0 )
+        {   /* map experimentalX settings to internal secltions */
+            static char const map[] = {2,1,0,3,6};
+            gfc->VBR->quality = map[gfp->experimentalX];
+        }
+        else    /* defaulting to */
+        {
+            gfc->VBR->quality = 2;
+        }   
+        if ( gfc->VBR->quality > 5 ) {
+            static float const dbQ[10] = { -6,-4.75,-3.5,-2.25,-1,.25,1.5,2.75,4,5.25 };
+            gfc->VBR->mask_adjust = dbQ[gfp->VBR_q];
+            gfc->VBR->smooth = 1;   // not finally
+        }
+        else {
+            static const float dbQ[10]={-2.,-1.0,-.66,-.33,0.,0.33,.66,1.0,1.33,1.66};
+            gfc->VBR->mask_adjust = dbQ[gfp->VBR_q];
+            gfc->VBR->smooth = 1;
+        }
+        if ( gfc->VBR->quality == 1 ) {
+            static float const dbQ[10] = { -2., -1.4, -.7, 0, .7, 1.5, 2.3, 3.1, 4., 5 };
+            gfc->VBR->mask_adjust = dbQ[gfp->VBR_q];
+            gfc->VBR->smooth = 0;    
+        }
+        if ( gfc->VBR->quality == 0 ) {
+            static float const dbQ[10] = { -1., -.6, -.3, 0, 1, 2, 3, 4, 5, 6};
+            gfc->VBR->mask_adjust = dbQ[gfp->VBR_q];
+            gfc->VBR->smooth = 0;    
+            gfc->PSY->tonalityPatch = 0;
+        }
+        
+        gfc->VBR->bitpressure = 1;
+        
+        if (gfp->experimentalY)
+            gfc->sfb21_extra = 0;
+        else
+            gfc->sfb21_extra = (gfp->out_samplerate > 44000);
+        
+        if ( gfp->athaa_type < 0 )
+            gfc->ATH->use_adjust = 3;
+        else
+            gfc->ATH->use_adjust = gfp->athaa_type;
+        
+        break;
+        
+
+    case vbr_rh:
+
+        if (gfp->VBR == vbr_rh) /* because of above fall thru */
+        {   static const FLOAT8 dbQ[10]={-2.,-1.0,-.66,-.33,0.,0.33,.66,1.0,1.33,1.66};
+            static const FLOAT8 dbQns[10]={- 4,- 3,-2,-1,0,0.7,1.4,2.1,2.8,3.5};
+            /*static const FLOAT8 atQns[10]={-16,-12,-8,-4,0,  1,  2,  3,  4,  5};*/
+            if ( gfc->nsPsy.use )
+                gfc->VBR->mask_adjust = dbQns[gfp->VBR_q];
+            else {
+                gfc->PSY->tonalityPatch = 1;
+                gfc->VBR->mask_adjust = dbQ[gfp->VBR_q]; 
+            }
+        }
+        gfc->VBR->bitpressure = 1;
+        
+        /*  use Gabriel's adaptative ATH shape for VBR by default
+         */
+        if (gfp->ATHtype == -1)
+            gfp->ATHtype = 4;
+
+        /*  automatic ATH adjustment on, VBR modes need it
+         */
+        if ( gfp->athaa_type < 0 )
+            gfc->ATH->use_adjust = 3;
+        else
+            gfc->ATH->use_adjust = gfp->athaa_type;
+
+        /*  sfb21 extra only with MPEG-1 at higher sampling rates
+         */
+        if ( gfp->experimentalY )
+            gfc->sfb21_extra = 0;
+        else 
+            gfc->sfb21_extra = (gfp->out_samplerate > 44000);
+
+        /*  VBR needs at least the output of GPSYCHO,
+         *  so we have to garantee that by setting a minimum 
+         *  quality level, actually level 5 does it.
+         *  the -v and -V x settings switch the quality to level 2
+         *  you would have to add a -q 5 to reduce the quality
+         *  down to level 5
+         */
+        if (gfp->quality > 5)
+            gfp->quality = 5;
+
+
+        /*  default quality setting is 2
+         */
+        if (gfp->quality < 0)
+            gfp->quality = 2;
+
+        break;
+
+    default:
+
+        if (gfp->ATHtype == -1)
+            gfp->ATHtype = 2;
+
+        /*  automatic ATH adjustment off by default
+         *  not so important for CBR code?
+         */
+        if ( gfp->athaa_type < 0 )
+            gfc->ATH->use_adjust = 0;
+        else
+            gfc->ATH->use_adjust = gfp->athaa_type;
+
+
+        /*  no sfb21 extra with CBR code
+         */
+        gfc->sfb21_extra = 0;
+
+        /*  default quality setting for CBR/ABR is 5
+         */
+        if (gfp->quality < 0)
+            gfp->quality = 5;
+
+        break;
+    }
+    /*  just another daily changing developer switch  */
+    if ( gfp->tune ) gfc->VBR->mask_adjust = gfp->tune_value_a;
+
+    /* initialize internal qval settings */
+    lame_init_qval(gfp);
+
+#ifdef KLEMM_44
+    gfc->mfbuf[0] = (sample_t *) calloc(sizeof(sample_t), MFSIZE);
+    gfc->mfbuf[1] = (sample_t *) calloc(sizeof(sample_t), MFSIZE);
+    gfc->sampfreq_in = unround_samplefrequency(gfp->in_samplerate);
+    gfc->sampfreq_out = gfp->out_samplerate;
+    gfc->resample_in = resample_open(gfc->sampfreq_in,
+                                     gfc->sampfreq_out, -1.0 /* Auto */, 32);
+#endif
+
+    /* initialize internal adaptive ATH settings  -jd */
+    gfc->athaa_sensitivity_p = pow( 10.0, gfp->athaa_sensitivity / -10.0 );
+
+
+    gfc->PSY->cwlimit = gfp->cwlimit <= 0 ? 8871.7f : gfp->cwlimit;
+    
+    if (gfp->short_blocks == short_block_not_set) {
+        gfp->short_blocks =  short_block_allowed;
+    }
+    if (gfp->short_blocks == short_block_allowed && gfp->mode == JOINT_STEREO) {
+        gfp->short_blocks =  short_block_coupled;
+    }    
+    
+    if ( gfp->athaa_loudapprox < 0 ) gfp->athaa_loudapprox = 2;
+    
+    if (gfp->useTemporal < 0 ) gfp->useTemporal = 1;  // on by default
+
+
+    if ( gfp->experimentalY )
+        MSGF(gfc,"\n *** WARNING *** the meaning of the experimental -Y has changed!\n"
+                   "                 now it tells LAME to ignore sfb21 noise shaping (VBR)\n\n");
+
+    if ( gfp->preset_expopts && gfc->presetTune.use < 1 )
+        MSGF(gfc,"\n*** WARNING ***\n\n"
+                        "Specialized tunings for the preset you are using have been deactivated.\n"
+                 "This is *NOT* recommended and will lead to a decrease in quality!\n"
+                    "\n*** WARNING ***\n\n");
+
+    return 0;
+}
+
+/*}}}*/
+/* void          lame_print_config              (lame_global_flags *gfp)                                                                                          *//*{{{ */
+
+/*
+ *  print_config
+ *
+ *  Prints some selected information about the coding parameters via 
+ *  the macro command MSGF(), which is currently mapped to lame_errorf 
+ *  (reports via a error function?), which is a printf-like function 
+ *  for <stderr>.
+ */
+
+void
+lame_print_config(const lame_global_flags * gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    double  out_samplerate = gfp->out_samplerate;
+    double  in_samplerate = gfp->out_samplerate * gfc->resample_ratio;
+
+    MSGF(gfc, "LAME version %s (%s)\n", get_lame_version(), get_lame_url());
+
+    if (gfc->CPU_features.MMX
+        || gfc->CPU_features.AMD_3DNow
+        || gfc->CPU_features.SIMD || gfc->CPU_features.SIMD2) {
+        MSGF(gfc, "CPU features:");
+
+        if (gfc->CPU_features.i387)
+            MSGF(gfc, " i387");
+        if (gfc->CPU_features.MMX)
+#ifdef MMX_choose_table
+            MSGF(gfc, ", MMX (ASM used)");
+#else
+            MSGF(gfc, ", MMX");
+#endif
+        if (gfc->CPU_features.AMD_3DNow)
+            MSGF(gfc, ", 3DNow!");
+        if (gfc->CPU_features.SIMD)
+            MSGF(gfc, ", SIMD");
+        if (gfc->CPU_features.SIMD2)
+            MSGF(gfc, ", SIMD2");
+        MSGF(gfc, "\n");
+    }
+
+    if (gfp->num_channels == 2 && gfc->channels_out == 1 /* mono */ ) {
+        MSGF
+            (gfc,
+             "Autoconverting from stereo to mono. Setting encoding to mono mode.\n");
+    }
+
+    if (gfc->resample_ratio != 1.) {
+        MSGF(gfc, "Resampling:  input %g kHz  output %g kHz\n",
+             1.e-3 * in_samplerate, 1.e-3 * out_samplerate);
+    }
+
+    if (gfc->filter_type == 0) {
+        if (gfc->highpass2 > 0.)
+            MSGF
+                (gfc,
+                 "Using polyphase highpass filter, transition band: %5.0f Hz - %5.0f Hz\n",
+                 0.5 * gfc->highpass1 * out_samplerate,
+                 0.5 * gfc->highpass2 * out_samplerate);
+        if (gfc->lowpass1 > 0.) {
+            MSGF
+                (gfc,
+                 "Using polyphase lowpass  filter, transition band: %5.0f Hz - %5.0f Hz\n",
+                 0.5 * gfc->lowpass1 * out_samplerate,
+                 0.5 * gfc->lowpass2 * out_samplerate);
+        }
+        else {
+            MSGF(gfc, "polyphase lowpass filter disabled\n");
+        }
+    }
+    else {
+        MSGF(gfc, "polyphase filters disabled\n");
+    }
+
+    if (gfp->free_format) {
+        MSGF(gfc,
+             "Warning: many decoders cannot handle free format bitstreams\n");
+        if (gfp->brate > 320) {
+            MSGF
+                (gfc,
+                 "Warning: many decoders cannot handle free format bitrates >320 kbps (see documentation)\n");
+        }
+    }
+}
+
+
+/**     rh:
+ *      some pretty printing is very welcome at this point!
+ *      so, if someone is willing to do so, please do it!
+ *      add more, if you see more...
+ */
+void 
+lame_print_internals( const lame_global_flags * gfp )
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    const char * pc = "";
+
+    /*  compiler/processor optimizations, operational, etc.
+     */
+    MSGF( gfc, "\nmisc:\n\n" );
+    
+    MSGF( gfc, "\tscaling: %f\n", gfp->scale );
+    MSGF( gfc, "\tch0 (left) scaling: %f\n", gfp->scale_left );
+    MSGF( gfc, "\tch1 (right) scaling: %f\n", gfp->scale_right );
+    MSGF( gfc, "\tfilter type: %d\n", gfc->filter_type );
+    pc = gfc->quantization ? "xr^3/4" : "ISO";
+    MSGF( gfc, "\tquantization: %s\n", pc );
+    switch( gfc->use_best_huffman ) {
+    default: pc = "normal"; break;
+    case  1: pc = "best (outside loop)"; break;
+    case  2: pc = "best (inside loop, slow)"; break;
+    } 
+    MSGF( gfc, "\thuffman search: %s\n", pc ); 
+    MSGF( gfc, "\texperimental X=%d Y=%d Z=%d\n", gfp->experimentalX, gfp->experimentalY, gfp->experimentalZ );
+    MSGF( gfc, "\t...\n" );
+
+    /*  everything controlling the stream format 
+     */
+    MSGF( gfc, "\nstream format:\n\n" );
+    switch ( gfp->version ) {
+    case 0:  pc = "2.5"; break;
+    case 1:  pc = "1";   break;
+    case 2:  pc = "2";   break;
+    default: pc = "?";   break;
+    }
+    MSGF( gfc, "\tMPEG-%s Layer 3\n", pc );
+    switch ( gfp->mode ) {
+    case JOINT_STEREO: pc = "joint stereo";   break;
+    case STEREO      : pc = "stereo";         break;
+    case DUAL_CHANNEL: pc = "dual channel";   break;
+    case MONO        : pc = "mono";           break;
+    case NOT_SET     : pc = "not set (error)"; break;
+    default          : pc = "unknown (error)"; break;
+    }
+    MSGF( gfc, "\t%d channel - %s\n", gfc->channels_out, pc );
+    switch ( gfp->padding_type ) {
+    case PAD_NO    : pc = "off";    break;
+    case PAD_ALL   : pc = "all";    break;
+    case PAD_ADJUST: pc = "auto";   break;
+    default        : pc = "(error)"; break;
+    }
+    MSGF( gfc, "\tpadding: %s\n", pc );
+    
+    if ( vbr_default == gfp->VBR )  pc = "(default)";
+    else if ( gfp->free_format )    pc = "(free format)";
+    else pc = "";
+    switch ( gfp->VBR ) {
+    case vbr_off : MSGF( gfc, "\tconstant bitrate - CBR %s\n",      pc ); break;
+    case vbr_abr : MSGF( gfc, "\tvariable bitrate - ABR %s\n",      pc ); break;
+    case vbr_rh  : MSGF( gfc, "\tvariable bitrate - VBR rh %s\n",   pc ); break;
+    case vbr_mt  : MSGF( gfc, "\tvariable bitrate - VBR mt %s\n",   pc ); break;
+    case vbr_mtrh: MSGF( gfc, "\tvariable bitrate - VBR mtrh %s\n", pc ); break; 
+    default      : MSGF( gfc, "\t ?? oops, some new one ?? \n" );         break;
+    }
+    if (gfp->bWriteVbrTag) 
+    MSGF( gfc, "\tusing LAME Tag\n" );
+    MSGF( gfc, "\t...\n" );
+    
+    /*  everything controlling psychoacoustic settings, like ATH, etc.
+     */
+    MSGF( gfc, "\npsychoacoustic:\n\n" );
+    
+    MSGF( gfc, "\ttonality estimation limit: %f Hz\n", gfc->PSY->cwlimit );
+    switch ( gfp->short_blocks ) {
+    default:
+    case short_block_not_set:   pc = "?";               break;
+    case short_block_allowed:   pc = "allowed";         break;
+    case short_block_coupled:   pc = "channel coupled"; break;
+    case short_block_dispensed: pc = "dispensed";       break;
+    case short_block_forced:    pc = "forced";          break;
+    }
+    MSGF( gfc, "\tusing short blocks: %s\n", pc );    
+    MSGF( gfc, "\tadjust masking: %f dB\n", gfc->VBR->mask_adjust );
+    MSGF( gfc, "\tpsymodel: %d\n", gfc->psymodel );
+    MSGF( gfc, "\tnoise shaping: %d\n", gfc->noise_shaping );
+    MSGF( gfc, "\t ^ amplification: %d\n", gfc->noise_shaping_amp );
+    MSGF( gfc, "\t ^ stopping: %d\n", gfc->noise_shaping_stop );
+    
+    pc = "using";
+    if ( gfp->ATHshort ) pc = "the only masking for short blocks";
+    if ( gfp->ATHonly  ) pc = "the only masking";
+    if ( gfp->noATH    ) pc = "not used";
+    MSGF( gfc, "\tATH: %s\n", pc );
+    MSGF( gfc, "\t ^ type: %d\n", gfp->ATHtype );
+    MSGF( gfc, "\t ^ adjust type: %d\n", gfc->ATH->use_adjust );
+    MSGF( gfc, "\t ^ adapt threshold type: %d\n", gfp->athaa_loudapprox );
+    
+    if ( gfc->nsPsy.use ) {
+    MSGF( gfc, "\texperimental psy tunings by Naoki Shibata\n" ); 
+    MSGF( gfc, "\t   adjust masking bass=%g dB, alto=%g dB, treble=%g dB, sfb21=%g dB\n", 
+        10*log10(gfc->nsPsy.bass),   10*log10(gfc->nsPsy.alto), 
+        10*log10(gfc->nsPsy.treble), 10*log10(gfc->nsPsy.sfb21) );
+    }
+    pc = gfp->useTemporal ? "yes" : "no";
+    MSGF( gfc, "\tusing temporal masking effect: %s\n", pc );
+    MSGF( gfc, "\t...\n" );
+    
+    /*  that's all ?
+     */
+    MSGF( gfc, "\n" );
+    return;
+}
+
+
+
+/* int           lame_encode_frame              (lame_global_flags *gfp, sample_t inbuf_l[],sample_t inbuf_r[], char *mp3buf, int mp3buf_size)                    *//*{{{ */
+
+/* routine to feed exactly one frame (gfp->framesize) worth of data to the 
+encoding engine.  All buffering, resampling, etc, handled by calling
+program.  
+*/
+int
+lame_encode_frame(lame_global_flags * gfp,
+                  sample_t inbuf_l[], sample_t inbuf_r[],
+                  unsigned char *mp3buf, int mp3buf_size)
+{
+    int     ret;
+    if (gfp->ogg) {
+#ifdef HAVE_VORBIS_ENCODER
+        ret = lame_encode_ogg_frame(gfp, inbuf_l, inbuf_r, mp3buf, mp3buf_size);
+#else
+        return -5;      /* wanna encode ogg without vorbis */
+#endif
+    }
+    else {
+        ret = lame_encode_mp3_frame(gfp, inbuf_l, inbuf_r, mp3buf, mp3buf_size);
+    }
+
+
+
+    gfp->frameNum++;
+    return ret;
+}
+
+/*}}}*/
+/* int           lame_encode_buffer             (lame_global_flags* gfp, short int buffer_l[], short int buffer_r[], int nsamples, char* mp3buf, int mp3buf_size )*//*{{{ */
+
+
+
+/*
+ * THE MAIN LAME ENCODING INTERFACE
+ * mt 3/00
+ *
+ * input pcm data, output (maybe) mp3 frames.
+ * This routine handles all buffering, resampling and filtering for you.
+ * The required mp3buffer_size can be computed from num_samples,
+ * samplerate and encoding rate, but here is a worst case estimate:
+ *
+ * mp3buffer_size in bytes = 1.25*num_samples + 7200
+ *
+ * return code = number of bytes output in mp3buffer.  can be 0
+*/
+int
+lame_encode_buffer_sample_t(lame_global_flags * gfp,
+                   sample_t buffer_l[],
+                   sample_t buffer_r[],
+                   int nsamples, unsigned char *mp3buf, const int mp3buf_size)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    int     mp3size = 0, ret, i, ch, mf_needed;
+    int mp3out;
+    sample_t *mfbuf[2];
+    sample_t *in_buffer[2];
+
+    if (gfc->Class_ID != LAME_ID)
+        return -3;
+
+    if (nsamples == 0)
+        return 0;
+
+    /* copy out any tags that may have been written into bitstream */
+    mp3out = copy_buffer(gfc,mp3buf,mp3buf_size,0);
+    if (mp3out<0) return mp3out;  // not enough buffer space
+    mp3buf += mp3out;
+    mp3size += mp3out;
+
+
+    in_buffer[0]=buffer_l;
+    in_buffer[1]=buffer_r;  
+
+
+    /* some sanity checks */
+#if ENCDELAY < MDCTDELAY
+# error ENCDELAY is less than MDCTDELAY, see encoder.h
+#endif
+#if FFTOFFSET > BLKSIZE
+# error FFTOFFSET is greater than BLKSIZE, see encoder.h
+#endif
+
+    mf_needed = BLKSIZE + gfp->framesize - FFTOFFSET; /* amount needed for FFT */
+    mf_needed = Max(mf_needed, 286 + 576 * (1 + gfc->mode_gr)); /* amount needed for MDCT/filterbank */
+    assert(MFSIZE >= mf_needed);
+
+    mfbuf[0] = gfc->mfbuf[0];
+    mfbuf[1] = gfc->mfbuf[1];
+
+    if (gfp->num_channels == 2 && gfc->channels_out == 1) {
+        /* downsample to mono */
+        for (i = 0; i < nsamples; ++i) {
+            in_buffer[0][i] =
+                0.5 * ((FLOAT8) in_buffer[0][i] + in_buffer[1][i]);
+            in_buffer[1][i] = 0.0;
+        }
+    }
+
+
+    while (nsamples > 0) {
+        int     n_in = 0;    /* number of input samples processed with fill_buffer */
+        int     n_out = 0;   /* number of samples output with fill_buffer */
+        /* n_in <> n_out if we are resampling */
+
+        /* copy in new samples into mfbuf, with resampling & scaling if necessary */
+        fill_buffer(gfp, mfbuf, in_buffer, nsamples, &n_in, &n_out);
+
+        /* update in_buffer counters */
+        nsamples -= n_in;
+        in_buffer[0] += n_in;
+        if (gfc->channels_out == 2)
+            in_buffer[1] += n_in;
+
+        /* update mfbuf[] counters */
+        gfc->mf_size += n_out;
+        assert(gfc->mf_size <= MFSIZE);
+        gfc->mf_samples_to_encode += n_out;
+
+
+        if (gfc->mf_size >= mf_needed) {
+            /* encode the frame.  */
+            // mp3buf              = pointer to current location in buffer
+            // mp3buf_size         = size of original mp3 output buffer
+            //                     = 0 if we should not worry about the
+            //                       buffer size because calling program is 
+            //                       to lazy to compute it
+            // mp3size             = size of data written to buffer so far
+            // mp3buf_size-mp3size = amount of space avalable 
+
+            int buf_size=mp3buf_size - mp3size;
+            if (mp3buf_size==0) buf_size=0;
+
+            ret =
+                lame_encode_frame(gfp, mfbuf[0], mfbuf[1], mp3buf,buf_size);
+
+            if (ret < 0) goto retr;
+            mp3buf += ret;
+            mp3size += ret;
+
+            /* shift out old samples */
+            gfc->mf_size -= gfp->framesize;
+            gfc->mf_samples_to_encode -= gfp->framesize;
+            for (ch = 0; ch < gfc->channels_out; ch++)
+                for (i = 0; i < gfc->mf_size; i++)
+                    mfbuf[ch][i] = mfbuf[ch][i + gfp->framesize];
+        }
+    }
+    assert(nsamples == 0);
+    ret = mp3size;
+
+  retr:
+    return ret;
+}
+
+
+int
+lame_encode_buffer(lame_global_flags * gfp,
+                   const short int buffer_l[],
+                   const short int buffer_r[],
+                   const int nsamples, unsigned char *mp3buf, const int mp3buf_size)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    int     ret, i;
+    sample_t *in_buffer[2];
+
+    if (gfc->Class_ID != LAME_ID)
+        return -7; //-3
+
+    if (nsamples == 0)
+        return 0;
+
+    in_buffer[0] = calloc(sizeof(sample_t), nsamples);
+    in_buffer[1] = calloc(sizeof(sample_t), nsamples);
+
+    if (in_buffer[0] == NULL || in_buffer[1] == NULL) {
+        ERRORF(gfc, "Error: can't allocate in_buffer buffer\n");
+        return -2;
+    }
+
+    /* make a copy of input buffer, changing type to sample_t */
+    for (i = 0; i < nsamples; i++) {
+        in_buffer[0][i] = buffer_l[i];
+        in_buffer[1][i] = buffer_r[i];
+    }
+
+    ret = lame_encode_buffer_sample_t(gfp,in_buffer[0],in_buffer[1],
+                                     nsamples, mp3buf, mp3buf_size);
+    
+    free(in_buffer[0]);
+    free(in_buffer[1]);
+    return ret;
+}
+
+
+int
+lame_encode_buffer_float(lame_global_flags * gfp,
+                   const float buffer_l[],
+                   const float buffer_r[],
+                   const int nsamples, unsigned char *mp3buf, const int mp3buf_size)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    int     ret, i;
+    sample_t *in_buffer[2];
+
+    if (gfc->Class_ID != LAME_ID)
+        return -3;
+
+    if (nsamples == 0)
+        return 0;
+
+    in_buffer[0] = calloc(sizeof(sample_t), nsamples);
+    in_buffer[1] = calloc(sizeof(sample_t), nsamples);
+
+    if (in_buffer[0] == NULL || in_buffer[1] == NULL) {
+        ERRORF(gfc, "Error: can't allocate in_buffer buffer\n");
+        return -2;
+    }
+
+    /* make a copy of input buffer, changing type to sample_t */
+    for (i = 0; i < nsamples; i++) {
+        in_buffer[0][i] = buffer_l[i];
+        in_buffer[1][i] = buffer_r[i];
+    }
+
+    ret = lame_encode_buffer_sample_t(gfp,in_buffer[0],in_buffer[1],
+                                     nsamples, mp3buf, mp3buf_size);
+    
+    free(in_buffer[0]);
+    free(in_buffer[1]);
+    return ret;
+}
+
+
+
+int
+lame_encode_buffer_int(lame_global_flags * gfp,
+                   const int buffer_l[],
+                   const int buffer_r[],
+                   const int nsamples, unsigned char *mp3buf, const int mp3buf_size)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    int     ret, i;
+    sample_t *in_buffer[2];
+
+    if (gfc->Class_ID != LAME_ID)
+        return -3;
+
+    if (nsamples == 0)
+        return 0;
+
+    in_buffer[0] = calloc(sizeof(sample_t), nsamples);
+    in_buffer[1] = calloc(sizeof(sample_t), nsamples);
+
+    if (in_buffer[0] == NULL || in_buffer[1] == NULL) {
+        ERRORF(gfc, "Error: can't allocate in_buffer buffer\n");
+        return -2;
+    }
+
+    /* make a copy of input buffer, changing type to sample_t */
+    for (i = 0; i < nsamples; i++) {
+                                /* internal code expects +/- 32768.0 */
+      in_buffer[0][i] = buffer_l[i] * (1.0 / ( 1 << (8 * sizeof(int) - 16)));
+      in_buffer[1][i] = buffer_r[i] * (1.0 / ( 1 << (8 * sizeof(int) - 16)));
+    }
+
+    ret = lame_encode_buffer_sample_t(gfp,in_buffer[0],in_buffer[1],
+                                     nsamples, mp3buf, mp3buf_size);
+    
+    free(in_buffer[0]);
+    free(in_buffer[1]);
+    return ret;
+
+}
+
+
+
+
+int
+lame_encode_buffer_long2(lame_global_flags * gfp,
+                   const long buffer_l[],
+                   const long buffer_r[],
+                   const int nsamples, unsigned char *mp3buf, const int mp3buf_size)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    int     ret, i;
+    sample_t *in_buffer[2];
+
+    if (gfc->Class_ID != LAME_ID)
+        return -3;
+
+    if (nsamples == 0)
+        return 0;
+
+    in_buffer[0] = calloc(sizeof(sample_t), nsamples);
+    in_buffer[1] = calloc(sizeof(sample_t), nsamples);
+
+    if (in_buffer[0] == NULL || in_buffer[1] == NULL) {
+        ERRORF(gfc, "Error: can't allocate in_buffer buffer\n");
+        return -2;
+    }
+
+    /* make a copy of input buffer, changing type to sample_t */
+    for (i = 0; i < nsamples; i++) {
+                                /* internal code expects +/- 32768.0 */
+      in_buffer[0][i] = buffer_l[i] * (1.0 / ( 1 << (8 * sizeof(long) - 16)));
+      in_buffer[1][i] = buffer_r[i] * (1.0 / ( 1 << (8 * sizeof(long) - 16)));
+    }
+
+    ret = lame_encode_buffer_sample_t(gfp,in_buffer[0],in_buffer[1],
+                                     nsamples, mp3buf, mp3buf_size);
+    
+    free(in_buffer[0]);
+    free(in_buffer[1]);
+    return ret;
+
+}
+
+
+
+int
+lame_encode_buffer_long(lame_global_flags * gfp,
+                   const long buffer_l[],
+                   const long buffer_r[],
+                   const int nsamples, unsigned char *mp3buf, const int mp3buf_size)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    int     ret, i;
+    sample_t *in_buffer[2];
+
+    if (gfc->Class_ID != LAME_ID)
+        return -3;
+
+    if (nsamples == 0)
+        return 0;
+
+    in_buffer[0] = calloc(sizeof(sample_t), nsamples);
+    in_buffer[1] = calloc(sizeof(sample_t), nsamples);
+
+    if (in_buffer[0] == NULL || in_buffer[1] == NULL) {
+        ERRORF(gfc, "Error: can't allocate in_buffer buffer\n");
+        return -2;
+    }
+
+    /* make a copy of input buffer, changing type to sample_t */
+    for (i = 0; i < nsamples; i++) {
+        in_buffer[0][i] = buffer_l[i];
+        in_buffer[1][i] = buffer_r[i];
+    }
+
+    ret = lame_encode_buffer_sample_t(gfp,in_buffer[0],in_buffer[1],
+                                     nsamples, mp3buf, mp3buf_size);
+    
+    free(in_buffer[0]);
+    free(in_buffer[1]);
+    return ret;
+}
+
+
+
+
+
+
+
+
+
+
+
+int
+lame_encode_buffer_interleaved(lame_global_flags * gfp,
+                               short int buffer[],
+                               int nsamples,
+                               unsigned char *mp3buf, int mp3buf_size)
+{
+    int     ret, i;
+    short int *buffer_l;
+    short int *buffer_r;
+
+    buffer_l = malloc(sizeof(short int) * nsamples);
+    buffer_r = malloc(sizeof(short int) * nsamples);
+    if (buffer_l == NULL || buffer_r == NULL) {
+        return -2;
+    }
+    for (i = 0; i < nsamples; i++) {
+        buffer_l[i] = buffer[2 * i];
+        buffer_r[i] = buffer[2 * i + 1];
+    }
+    ret =
+        lame_encode_buffer(gfp, buffer_l, buffer_r, nsamples, mp3buf,
+                           mp3buf_size);
+    free(buffer_l);
+    free(buffer_r);
+    return ret;
+
+}
+
+
+/*}}}*/
+/* int           lame_encode                    (lame_global_flags* gfp, short int in_buffer[2][1152], char* mp3buf, int size )                                   *//*{{{ */
+
+
+/* old LAME interface.  use lame_encode_buffer instead */
+
+int
+lame_encode(lame_global_flags * const gfp,
+            const short int in_buffer[2][1152],
+            unsigned char *const mp3buf, const int size)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+
+    if (gfc->Class_ID != LAME_ID)
+        return -3;
+
+    return lame_encode_buffer(gfp, in_buffer[0], in_buffer[1], gfp->framesize,
+                              mp3buf, size);
+}
+
+/*}}}*/
+/* int           lame_encode_flush              (lame_global_flags* gfp, char* mp3buffer, int mp3buffer_size )                                                    *//*{{{ */
+
+
+
+/*****************************************************************
+ Flush mp3 buffer, pad with ancillary data so last frame is complete.
+ Reset reservoir size to 0                  
+ but keep all PCM samples and MDCT data in memory             
+ This option is used to break a large file into several mp3 files 
+ that when concatenated together will decode with no gaps         
+ Because we set the reservoir=0, they will also decode seperately 
+ with no errors. 
+*********************************************************************/
+int
+lame_encode_flush_nogap(lame_global_flags * gfp,
+                  unsigned char *mp3buffer, int mp3buffer_size)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    flush_bitstream(gfp);
+    return copy_buffer(gfc,mp3buffer, mp3buffer_size,1);
+}
+
+
+/* called by lame_init_params.  You can also call this after flush_nogap 
+   if you want to write new id3v2 and Xing VBR tags into the bitstream */
+int
+lame_init_bitstream(lame_global_flags * gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    int i;
+    gfp->frameNum=0;
+
+    if (!gfp->ogg)
+       id3tag_write_v2(gfp);
+
+    /* initialize histogram data optionally used by frontend */
+    for ( i = 0; i < 16; i++ ) 
+       gfc->bitrate_stereoMode_Hist [i] [0] =
+           gfc->bitrate_stereoMode_Hist [i] [1] =
+           gfc->bitrate_stereoMode_Hist [i] [2] =
+           gfc->bitrate_stereoMode_Hist [i] [3] =
+           gfc->bitrate_stereoMode_Hist [i] [4] = 0;
+
+    /* Write initial VBR Header to bitstream and init VBR data */
+    if (gfp->bWriteVbrTag)
+        InitVbrTag(gfp);
+
+    
+    return 0;
+}
+
+
+/*****************************************************************/
+/* flush internal PCM sample buffers, then mp3 buffers           */
+/* then write id3 v1 tags into bitstream.                        */
+/*****************************************************************/
+
+int
+lame_encode_flush(lame_global_flags * gfp,
+                  unsigned char *mp3buffer, int mp3buffer_size)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    short int buffer[2][1152];
+    int     imp3 = 0, mp3count, mp3buffer_size_remaining;
+
+    /* we always add POSTDELAY=288 padding to make sure granule with real
+     * data can be complety decoded (because of 50% overlap with next granule */
+    int end_padding=POSTDELAY;  
+
+    memset(buffer, 0, sizeof(buffer));
+    mp3count = 0;
+
+
+    while (gfc->mf_samples_to_encode > 0) {
+
+        mp3buffer_size_remaining = mp3buffer_size - mp3count;
+
+        /* if user specifed buffer size = 0, dont check size */
+        if (mp3buffer_size == 0)
+            mp3buffer_size_remaining = 0;
+
+        /* send in a frame of 0 padding until all internal sample buffers
+         * are flushed 
+         */
+        imp3 = lame_encode_buffer(gfp, buffer[0], buffer[1], gfp->framesize,
+                                  mp3buffer, mp3buffer_size_remaining);
+
+        /* don't count the above padding: */
+        gfc->mf_samples_to_encode -= gfp->framesize;
+        if (gfc->mf_samples_to_encode < 0) {
+            /* we added extra padding to the end */
+            end_padding += -gfc->mf_samples_to_encode;  
+        }
+
+
+        if (imp3 < 0) {
+            /* some type of fatal error */
+            return imp3;
+        }
+        mp3buffer += imp3;
+        mp3count += imp3;
+    }
+
+    mp3buffer_size_remaining = mp3buffer_size - mp3count;
+    /* if user specifed buffer size = 0, dont check size */
+    if (mp3buffer_size == 0)
+        mp3buffer_size_remaining = 0;
+
+    if (gfp->ogg) {
+#ifdef HAVE_VORBIS_ENCODER
+        /* ogg related stuff */
+        imp3 = lame_encode_ogg_finish(gfp, mp3buffer, mp3buffer_size_remaining);
+#endif
+    }
+    else {
+        /* mp3 related stuff.  bit buffer might still contain some mp3 data */
+        flush_bitstream(gfp);
+        imp3 = copy_buffer(gfc,mp3buffer, mp3buffer_size_remaining, 1);
+        if (imp3 < 0) {
+            /* some type of fatal error */
+            return imp3;
+        }
+        mp3buffer += imp3;
+        mp3count += imp3;
+        mp3buffer_size_remaining = mp3buffer_size - mp3count;
+        /* if user specifed buffer size = 0, dont check size */
+        if (mp3buffer_size == 0)
+            mp3buffer_size_remaining = 0;
+
+
+        /* write a id3 tag to the bitstream */
+        id3tag_write_v1(gfp);
+        imp3 = copy_buffer(gfc,mp3buffer, mp3buffer_size_remaining, 0);
+    }
+
+    if (imp3 < 0) {
+        return imp3;
+    }
+    mp3count += imp3;
+    gfp->encoder_padding=end_padding;
+    return mp3count;
+}
+
+/*}}}*/
+/* void          lame_close                     (lame_global_flags *gfp)                                                                                          *//*{{{ */
+
+/***********************************************************************
+ *
+ *      lame_close ()
+ *
+ *  frees internal buffers
+ *
+ ***********************************************************************/
+
+int
+lame_close(lame_global_flags * gfp)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+
+    if (gfc->Class_ID != LAME_ID)
+        return -3;
+
+    gfc->Class_ID = 0;
+
+    // this routien will free all malloc'd data in gfc, and then free gfc:
+    freegfc(gfc);
+
+    gfp->internal_flags = NULL;
+
+    if (gfp->lame_allocated_gfp)
+        free(gfp);
+
+    return 0;
+}
+
+
+/*}}}*/
+/* int           lame_encode_finish             (lame_global_flags* gfp, char* mp3buffer, int mp3buffer_size )                                                    *//*{{{ */
+
+
+/*****************************************************************/
+/* flush internal mp3 buffers, and free internal buffers         */
+/*****************************************************************/
+
+int
+lame_encode_finish(lame_global_flags * gfp,
+                   unsigned char *mp3buffer, int mp3buffer_size)
+{
+    int     ret = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
+
+    lame_close(gfp);
+
+    return ret;
+}
+
+/*}}}*/
+/* void          lame_mp3_tags_fid              (lame_global_flags *gfp,FILE *fpStream)                                                                           *//*{{{ */
+
+/*****************************************************************/
+/* write VBR Xing header, and ID3 version 1 tag, if asked for    */
+/*****************************************************************/
+void
+lame_mp3_tags_fid(lame_global_flags * gfp, FILE * fpStream)
+{
+    if (gfp->bWriteVbrTag) {
+        /* Map VBR_q to Xing quality value: 0=worst, 100=best */
+        int     nQuality = ((9-gfp->VBR_q) * 100) / 9;
+
+        /* Write Xing header again */
+        if (fpStream && !fseek(fpStream, 0, SEEK_SET))
+            PutVbrTag(gfp, fpStream, nQuality);
+    }
+
+
+}
+/*}}}*/
+/* lame_global_flags *lame_init                 (void)                                                                                                            *//*{{{ */
+
+lame_global_flags *
+lame_init(void)
+{
+    lame_global_flags *gfp;
+    int     ret;
+
+    gfp = calloc(1, sizeof(lame_global_flags));
+    if (gfp == NULL)
+        return NULL;
+
+    ret = lame_init_old(gfp);
+    if (ret != 0) {
+        free(gfp);
+        return NULL;
+    }
+
+    gfp->lame_allocated_gfp = 1;
+    return gfp;
+}
+
+/*}}}*/
+/* int           lame_init_old                  (lame_global_flags *gfp)                                                                                          *//*{{{ */
+
+/* initialize mp3 encoder */
+int
+lame_init_old(lame_global_flags * gfp)
+{
+    lame_internal_flags *gfc;
+
+    disable_FPE();      // disable floating point exceptions
+
+    memset(gfp, 0, sizeof(lame_global_flags));
+
+    if (NULL ==
+        (gfc = gfp->internal_flags =
+         calloc(1, sizeof(lame_internal_flags)))) return -1;
+
+    /* Global flags.  set defaults here for non-zero values */
+    /* see lame.h for description */
+    /* set integer values to -1 to mean that LAME will compute the
+     * best value, UNLESS the calling program as set it
+     * (and the value is no longer -1)
+     */
+
+
+    gfp->mode = NOT_SET;
+    gfp->original = 1;
+    gfp->in_samplerate = 1000 * 44.1;
+    gfp->num_channels = 2;
+    gfp->num_samples = MAX_U_32_NUM;
+
+    gfp->bWriteVbrTag = 1;
+    gfp->quality = -1;
+    gfp->short_blocks = short_block_not_set;
+
+    gfp->lowpassfreq = 0;
+    gfp->highpassfreq = 0;
+    gfp->lowpasswidth = -1;
+    gfp->highpasswidth = -1;
+
+    gfp->padding_type = PAD_ADJUST;
+    gfp->VBR = vbr_off;
+    gfp->VBR_q = 4;
+    gfp->VBR_mean_bitrate_kbps = 128;
+    gfp->VBR_min_bitrate_kbps = 0;
+    gfp->VBR_max_bitrate_kbps = 0;
+    gfp->VBR_hard_min = 0;
+
+
+    gfc->resample_ratio = 1;
+    gfc->lowpass_band = 32;
+    gfc->highpass_band = -1;
+    gfc->VBR_min_bitrate = 1; /* not  0 ????? */
+    gfc->VBR_max_bitrate = 13; /* not 14 ????? */
+
+    gfc->OldValue[0] = 180;
+    gfc->OldValue[1] = 180;
+    gfc->CurrentStep = 4;
+    gfc->masking_lower = 1;
+
+    gfp->athaa_type = -1;
+    gfp->ATHtype = -1;  /* default = -1 = set in lame_init_params */
+    gfp->athaa_loudapprox = -1;        /* 1 = flat loudness approx. (total energy) */
+                                /* 2 = equal loudness curve */
+    gfp->athaa_sensitivity = 0.0; /* no offset */
+    gfp->useTemporal = -1;
+
+    /* The reason for
+     *       int mf_samples_to_encode = ENCDELAY + POSTDELAY;
+     * ENCDELAY = internal encoder delay.  And then we have to add POSTDELAY=288
+     * because of the 50% MDCT overlap.  A 576 MDCT granule decodes to
+     * 1152 samples.  To synthesize the 576 samples centered under this granule
+     * we need the previous granule for the first 288 samples (no problem), and
+     * the next granule for the next 288 samples (not possible if this is last
+     * granule).  So we need to pad with 288 samples to make sure we can
+     * encode the 576 samples we are interested in.
+     */
+    gfc->mf_samples_to_encode = ENCDELAY + POSTDELAY;
+    gfp->encoder_padding = 0;
+    gfc->mf_size = ENCDELAY - MDCTDELAY; /* we pad input with this many 0's */
+
+#ifdef KLEMM_44
+    /* XXX: this wasn't protectes by KLEMM_44 initially! */
+    gfc->last_ampl = gfc->ampl = +1.0;
+#endif
+    return 0;
+}
+
+/*}}}*/
+
+/***********************************************************************
+ *
+ *  some simple statistics
+ *
+ *  Robert Hegemann 2000-10-11
+ *
+ ***********************************************************************/
+
+/*  histogram of used bitrate indexes:
+ *  One has to weight them to calculate the average bitrate in kbps
+ *
+ *  bitrate indices:
+ *  there are 14 possible bitrate indices, 0 has the special meaning 
+ *  "free format" which is not possible to mix with VBR and 15 is forbidden
+ *  anyway.
+ *
+ *  stereo modes:
+ *  0: LR   number of left-right encoded frames
+ *  1: LR-I number of left-right and intensity encoded frames
+ *  2: MS   number of mid-side encoded frames
+ *  3: MS-I number of mid-side and intensity encoded frames
+ *
+ *  4: number of encoded frames
+ *
+ */
+
+void
+lame_bitrate_hist(const lame_global_flags * const gfp, int bitrate_count[14])
+{
+    const lame_internal_flags *gfc;
+    int     i;
+
+    if (NULL == bitrate_count)
+        return;
+    if (NULL == gfp)
+        return;
+    gfc = gfp->internal_flags;
+    if (NULL == gfc)
+        return;
+
+    for (i = 0; i < 14; i++)
+        bitrate_count[i] = gfc->bitrate_stereoMode_Hist[i + 1][4];
+}
+
+
+void
+lame_bitrate_kbps(const lame_global_flags * const gfp, int bitrate_kbps[14])
+{
+    const lame_internal_flags *gfc;
+    int     i;
+
+    if (NULL == bitrate_kbps)
+        return;
+    if (NULL == gfp)
+        return;
+    gfc = gfp->internal_flags;
+    if (NULL == gfc)
+        return;
+
+    for (i = 0; i < 14; i++)
+        bitrate_kbps[i] = bitrate_table[gfp->version][i + 1];
+}
+
+
+
+void
+lame_stereo_mode_hist(const lame_global_flags * const gfp, int stmode_count[4])
+{
+    const lame_internal_flags *gfc;
+    int     i;
+
+    if (NULL == stmode_count)
+        return;
+    if (NULL == gfp)
+        return;
+    gfc = gfp->internal_flags;
+    if (NULL == gfc)
+        return;
+
+    for (i = 0; i < 4; i++) {
+        int     j, sum = 0;
+        for (j = 0; j < 14; j++)
+            sum += gfc->bitrate_stereoMode_Hist[j + 1][i];
+        stmode_count[i] = sum;
+    }
+}
+
+
+
+void
+lame_bitrate_stereo_mode_hist(const lame_global_flags * const gfp,
+                              int bitrate_stmode_count[14][4])
+{
+    const lame_internal_flags *gfc;
+    int     i;
+    int     j;
+
+    if (NULL == bitrate_stmode_count)
+        return;
+    if (NULL == gfp)
+        return;
+    gfc = gfp->internal_flags;
+    if (NULL == gfc)
+        return;
+
+    for (j = 0; j < 14; j++)
+        for (i = 0; i < 4; i++)
+            bitrate_stmode_count[j][i] = gfc->bitrate_stereoMode_Hist[j + 1][i];
+}
+
+/* end of lame.c */
diff --git a/lib/lame/lame.h b/lib/lame/lame.h
new file mode 100644 (file)
index 0000000..3354ec7
--- /dev/null
@@ -0,0 +1,902 @@
+/*
+ *     Interface to MP3 LAME encoding engine
+ *
+ *     Copyright (c) 1999 Mark Taylor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* $Id: lame.h,v 1.1 2002/04/28 17:30:20 kramm Exp $ */
+
+#ifndef LAME_LAME_H
+#define LAME_LAME_H
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(WIN32)
+#undef CDECL
+#define CDECL _cdecl
+#else
+#define CDECL
+#endif
+
+
+typedef enum vbr_mode_e {
+  vbr_off=0,
+  vbr_mt,               /* obsolete, same as vbr_mtrh */
+  vbr_rh,
+  vbr_abr,
+  vbr_mtrh,
+  vbr_max_indicator,    /* Don't use this! It's used for sanity checks.       */
+  vbr_default=vbr_rh    /* change this to change the default VBR mode of LAME */
+} vbr_mode;
+
+
+/* MPEG modes */
+typedef enum MPEG_mode_e {
+  STEREO = 0,
+  JOINT_STEREO,
+  DUAL_CHANNEL,   /* LAME doesn't supports this! */
+  MONO,
+  NOT_SET,
+  MAX_INDICATOR   /* Don't use this! It's used for sanity checks. */ 
+} MPEG_mode;
+
+/* Padding types */
+typedef enum Padding_type_e {
+  PAD_NO = 0,
+  PAD_ALL,
+  PAD_ADJUST,
+  PAD_MAX_INDICATOR   /* Don't use this! It's used for sanity checks. */
+} Padding_type;
+
+
+
+struct lame_global_struct;
+typedef struct lame_global_struct lame_global_flags;
+typedef lame_global_flags *lame_t;
+
+
+
+
+/***********************************************************************
+ *
+ *  The LAME API
+ *  These functions should be called, in this order, for each
+ *  MP3 file to be encoded 
+ *
+ ***********************************************************************/
+
+
+/*
+ * REQUIRED:
+ * initialize the encoder.  sets default for all encoder paramters,
+ * returns -1 if some malloc()'s failed
+ * otherwise returns 0
+ */
+lame_global_flags * CDECL lame_init(void);
+/* obsolete version */
+int CDECL lame_init_old(lame_global_flags *);
+
+
+/*
+ * OPTIONAL:
+ * set as needed to override defaults
+ */
+
+/********************************************************************
+ *  input stream description
+ ***********************************************************************/
+// number of samples.  default = 2^32-1  
+int CDECL lame_set_num_samples(lame_global_flags *, unsigned long);
+unsigned long CDECL lame_get_num_samples(const lame_global_flags *);
+
+// input sample rate in Hz.  default = 44100hz
+int CDECL lame_set_in_samplerate(lame_global_flags *, int);
+int CDECL lame_get_in_samplerate(const lame_global_flags *);
+
+// number of channels in input stream. default=2 
+int CDECL lame_set_num_channels(lame_global_flags *, int);
+int CDECL lame_get_num_channels(const lame_global_flags *);
+
+// scale the input by this amount before encoding.  default=0 (disabled)
+// (not used by decoding routines)
+int CDECL lame_set_scale(lame_global_flags *, float);
+float CDECL lame_get_scale(const lame_global_flags *);
+    
+// scale the channel 0 (left) input by this amount before encoding.
+//   default=0 (disabled)
+// (not used by decoding routines)
+int CDECL lame_set_scale_left(lame_global_flags *, float);
+float CDECL lame_get_scale_left(const lame_global_flags *);
+
+// scale the channel 1 (right) input by this amount before encoding.
+//   default=0 (disabled)
+// (not used by decoding routines)
+int CDECL lame_set_scale_right(lame_global_flags *, float);
+float CDECL lame_get_scale_right(const lame_global_flags *);
+
+// output sample rate in Hz.  default = 0, which means LAME picks best value 
+// based on the amount of compression.  MPEG only allows:
+// MPEG1    32, 44.1,   48khz
+// MPEG2    16, 22.05,  24
+// MPEG2.5   8, 11.025, 12
+// (not used by decoding routines)
+int CDECL lame_set_out_samplerate(lame_global_flags *, int);
+int CDECL lame_get_out_samplerate(const lame_global_flags *);
+
+
+/********************************************************************
+ *  general control parameters
+ ***********************************************************************/
+// 1=cause LAME to collect data for an MP3 frame analyzer. default=0
+int CDECL lame_set_analysis(lame_global_flags *, int);
+int CDECL lame_get_analysis(const lame_global_flags *);
+
+// 1 = write a Xing VBR header frame.
+// default = 1 for VBR/ABR modes, 0 for CBR mode
+// this variable must have been added by a Hungarian notation Windows programmer :-)
+int CDECL lame_set_bWriteVbrTag(lame_global_flags *, int);
+int CDECL lame_get_bWriteVbrTag(const lame_global_flags *);
+
+// 1=decode only.  use lame/mpglib to convert mp3/ogg to wav.  default=0
+int CDECL lame_set_decode_only(lame_global_flags *, int);
+int CDECL lame_get_decode_only(const lame_global_flags *);
+
+// 1=encode a Vorbis .ogg file.  default=0
+int CDECL lame_set_ogg(lame_global_flags *, int);
+int CDECL lame_get_ogg(const lame_global_flags *);
+
+// internal algorithm selection.  True quality is determined by the bitrate
+// but this variable will effect quality by selecting expensive or cheap algorithms.
+// quality=0..9.  0=best (very slow).  9=worst.  
+// recommended:  2     near-best quality, not too slow
+//               5     good quality, fast
+//               7     ok quality, really fast
+int CDECL lame_set_quality(lame_global_flags *, int);
+int CDECL lame_get_quality(const lame_global_flags *);
+
+// mode = 0,1,2,3 = stereo, jstereo, dual channel (not supported), mono
+// default: lame picks based on compression ration and input channels
+int CDECL lame_set_mode(lame_global_flags *, MPEG_mode);
+MPEG_mode CDECL lame_get_mode(const lame_global_flags *);
+
+// mode_automs.  Use a M/S mode with a switching threshold based on 
+// compression ratio
+// default = 0 (disabled)
+int CDECL lame_set_mode_automs(lame_global_flags *, int);
+int CDECL lame_get_mode_automs(const lame_global_flags *);
+
+// force_ms.  Force M/S for all frames.  For testing only.
+// default = 0 (disabled)
+int CDECL lame_set_force_ms(lame_global_flags *, int);
+int CDECL lame_get_force_ms(const lame_global_flags *);
+
+// use free_format?  default = 0 (disabled)
+int CDECL lame_set_free_format(lame_global_flags *, int);
+int CDECL lame_get_free_format(const lame_global_flags *);
+
+/*
+ * OPTIONAL:
+ * Set printf like error/debug/message reporting functions.
+ * The second argument has to be a pointer to a function which looks like
+ *   void my_debugf(const char *format, va_list ap)
+ *   {
+ *       (void) vfprintf(stdout, format, ap);
+ *   }
+ * If you use NULL as the value of the pointer in the set function, the
+ * lame buildin function will be used (prints to stderr).
+ * To quiet any output you have to replace the body of the example function
+ * with just "return;" and use it in the set function.
+ */
+int CDECL lame_set_errorf(lame_global_flags *,
+                          void (*func)(const char *, va_list));
+int CDECL lame_set_debugf(lame_global_flags *,
+                          void (*func)(const char *, va_list));
+int CDECL lame_set_msgf  (lame_global_flags *,
+                          void (*func)(const char *, va_list));
+
+
+
+/* set one of brate compression ratio.  default is compression ratio of 11.  */
+int CDECL lame_set_brate(lame_global_flags *, int);
+int CDECL lame_get_brate(const lame_global_flags *);
+int CDECL lame_set_compression_ratio(lame_global_flags *, float);
+float CDECL lame_get_compression_ratio(const lame_global_flags *);
+
+/********************************************************************
+ *  frame params
+ ***********************************************************************/
+// mark as copyright.  default=0
+int CDECL lame_set_copyright(lame_global_flags *, int);
+int CDECL lame_get_copyright(const lame_global_flags *);
+
+// mark as original.  default=1
+int CDECL lame_set_original(lame_global_flags *, int);
+int CDECL lame_get_original(const lame_global_flags *);
+
+// error_protection.  Use 2 bytes from each frame for CRC checksum. default=0
+int CDECL lame_set_error_protection(lame_global_flags *, int);
+int CDECL lame_get_error_protection(const lame_global_flags *);
+
+// padding_type.  0=pad no frames  1=pad all frames 2=adjust padding(default)
+int CDECL lame_set_padding_type(lame_global_flags *, Padding_type);
+Padding_type CDECL lame_get_padding_type(const lame_global_flags *);
+
+// MP3 'private extension' bit  Meaningless.  default=0
+int CDECL lame_set_extension(lame_global_flags *, int);
+int CDECL lame_get_extension(const lame_global_flags *);
+
+// enforce strict ISO compliance.  default=0
+int CDECL lame_set_strict_ISO(lame_global_flags *, int);
+int CDECL lame_get_strict_ISO(const lame_global_flags *);
+
+/********************************************************************
+ * quantization/noise shaping 
+ ***********************************************************************/
+
+// disable the bit reservoir. For testing only. default=0
+int CDECL lame_set_disable_reservoir(lame_global_flags *, int);
+int CDECL lame_get_disable_reservoir(const lame_global_flags *);
+
+// select a different "best quantization" function. default=0 
+int CDECL lame_set_experimentalX(lame_global_flags *, int);
+int CDECL lame_get_experimentalX(const lame_global_flags *);
+
+// another experimental option.  for testing only
+int CDECL lame_set_experimentalY(lame_global_flags *, int);
+int CDECL lame_get_experimentalY(const lame_global_flags *);
+
+// another experimental option.  for testing only
+int CDECL lame_set_experimentalZ(lame_global_flags *, int);
+int CDECL lame_get_experimentalZ(const lame_global_flags *);
+
+// Naoki's psycho acoustic model.  default=0
+int CDECL lame_set_exp_nspsytune(lame_global_flags *, int);
+int CDECL lame_get_exp_nspsytune(const lame_global_flags *);
+
+
+
+/********************************************************************
+ * VBR control
+ ***********************************************************************/
+// Types of VBR.  default = vbr_off = CBR
+int CDECL lame_set_VBR(lame_global_flags *, vbr_mode);
+vbr_mode CDECL lame_get_VBR(const lame_global_flags *);
+
+// VBR quality level.  0=highest  9=lowest 
+int CDECL lame_set_VBR_q(lame_global_flags *, int);
+int CDECL lame_get_VBR_q(const lame_global_flags *);
+
+// Ignored except for VBR=vbr_abr (ABR mode)
+int CDECL lame_set_VBR_mean_bitrate_kbps(lame_global_flags *, int);
+int CDECL lame_get_VBR_mean_bitrate_kbps(const lame_global_flags *);
+
+int CDECL lame_set_VBR_min_bitrate_kbps(lame_global_flags *, int);
+int CDECL lame_get_VBR_min_bitrate_kbps(const lame_global_flags *);
+
+int CDECL lame_set_VBR_max_bitrate_kbps(lame_global_flags *, int);
+int CDECL lame_get_VBR_max_bitrate_kbps(const lame_global_flags *);
+
+// 1=stricetly enforce VBR_min_bitrate.  Normally it will be violated for
+// analog silence
+int CDECL lame_set_VBR_hard_min(lame_global_flags *, int);
+int CDECL lame_get_VBR_hard_min(const lame_global_flags *);
+
+
+/********************************************************************
+ * Filtering control
+ ***********************************************************************/
+// freq in Hz to apply lowpass. Default = 0 = lame chooses.  -1 = disabled
+int CDECL lame_set_lowpassfreq(lame_global_flags *, int);
+int CDECL lame_get_lowpassfreq(const lame_global_flags *);
+// width of transition band, in Hz.  Default = one polyphase filter band
+int CDECL lame_set_lowpasswidth(lame_global_flags *, int);
+int CDECL lame_get_lowpasswidth(const lame_global_flags *);
+
+// freq in Hz to apply highpass. Default = 0 = lame chooses.  -1 = disabled
+int CDECL lame_set_highpassfreq(lame_global_flags *, int);
+int CDECL lame_get_highpassfreq(const lame_global_flags *);
+// width of transition band, in Hz.  Default = one polyphase filter band
+int CDECL lame_set_highpasswidth(lame_global_flags *, int);
+int CDECL lame_get_highpasswidth(const lame_global_flags *);
+
+
+/********************************************************************
+ * psycho acoustics and other arguments which you should not change 
+ * unless you know what you are doing
+ ***********************************************************************/
+// only use ATH for masking
+int CDECL lame_set_ATHonly(lame_global_flags *, int);
+int CDECL lame_get_ATHonly(const lame_global_flags *);
+
+// only use ATH for short blocks
+int CDECL lame_set_ATHshort(lame_global_flags *, int);
+int CDECL lame_get_ATHshort(const lame_global_flags *);
+
+// disable ATH
+int CDECL lame_set_noATH(lame_global_flags *, int);
+int CDECL lame_get_noATH(const lame_global_flags *);
+
+// select ATH formula
+int CDECL lame_set_ATHtype(lame_global_flags *, int);
+int CDECL lame_get_ATHtype(const lame_global_flags *);
+
+// lower ATH by this many db
+int CDECL lame_set_ATHlower(lame_global_flags *, float);
+float CDECL lame_get_ATHlower(const lame_global_flags *);
+
+// select ATH adaptive adjustment type
+int CDECL lame_set_athaa_type( lame_global_flags *, int);
+int CDECL lame_get_athaa_type( const lame_global_flags *);
+
+// select the loudness approximation used by the ATH adaptive auto-leveling 
+int CDECL lame_set_athaa_loudapprox( lame_global_flags *, int);
+int CDECL lame_get_athaa_loudapprox( const lame_global_flags *);
+
+// adjust (in dB) the point below which adaptive ATH level adjustment occurs
+int CDECL lame_set_athaa_sensitivity( lame_global_flags *, float);
+float CDECL lame_get_athaa_sensitivity( const lame_global_flags* );
+
+// predictability limit (ISO tonality formula)
+int CDECL lame_set_cwlimit(lame_global_flags *, int);
+int CDECL lame_get_cwlimit(const lame_global_flags *);
+
+// allow blocktypes to differ between channels?
+// default: 0 for jstereo, 1 for stereo
+int CDECL lame_set_allow_diff_short(lame_global_flags *, int);
+int CDECL lame_get_allow_diff_short(const lame_global_flags *);
+
+// use temporal masking effect (default = 1)
+int CDECL lame_set_useTemporal(lame_global_flags *, int);
+int CDECL lame_get_useTemporal(const lame_global_flags *);
+
+// disable short blocks
+int CDECL lame_set_no_short_blocks(lame_global_flags *, int);
+int CDECL lame_get_no_short_blocks(const lame_global_flags *);
+
+// force short blocks
+int CDECL lame_set_force_short_blocks(lame_global_flags *, int);
+int CDECL lame_get_force_short_blocks(const lame_global_flags *);
+
+/* Input PCM is emphased PCM (for instance from one of the rarely
+   emphased CDs), it is STRONGLY not recommended to use this, because
+   psycho does not take it into account, and last but not least many decoders
+   ignore these bits */
+int CDECL lame_set_emphasis(lame_global_flags *, int);
+int CDECL lame_get_emphasis(const lame_global_flags *);
+
+
+
+/************************************************************************/
+/* internal variables, cannot be set...                                 */
+/* provided because they may be of use to calling application           */
+/************************************************************************/
+// version  0=MPEG-2  1=MPEG-1  (2=MPEG-2.5)    
+int CDECL lame_get_version(const lame_global_flags *);
+
+// encoder delay  
+int CDECL lame_get_encoder_delay(const lame_global_flags *);
+
+// padding appended to the input to make sure decoder can fully decode
+// all input.  Note that this value can only be calculated during the
+// call to lame_encoder_flush().  Before lame_encoder_flush() has
+// been called, the value of encoder_padding = 0.
+int CDECL lame_get_encoder_padding(const lame_global_flags *);
+
+// size of MPEG frame
+int CDECL lame_get_framesize(const lame_global_flags *);
+
+// number of PCM samples buffered, but not yet encoded to mp3 data.
+int CDECL lame_get_mf_samples_to_encode( const lame_global_flags*  gfp );
+
+// size (bytes) of mp3 data buffered, but not yet encoded.
+// this is the number of bytes which would be output by a call to 
+// lame_encode_flush_nogap.  NOTE: lame_encode_flush() will return
+// more bytes than this because it will encode the reamining buffered
+// PCM samples before flushing the mp3 buffers.
+int CDECL lame_get_size_mp3buffer( const lame_global_flags*  gfp );
+
+// number of frames encoded so far
+int CDECL lame_get_frameNum(const lame_global_flags *);
+
+// lame's estimate of the total number of frames to be encoded
+// only valid if calling program set num_samples 
+int CDECL lame_get_totalframes(const lame_global_flags *);
+
+
+
+
+
+
+
+
+/*
+ * REQUIRED:
+ * sets more internal configuration based on data provided above.
+ * returns -1 if something failed.
+ */
+int CDECL lame_init_params(lame_global_flags * const );
+
+
+/*
+ * OPTIONAL:
+ * get the version number, in a string. of the form:  
+ * "3.63 (beta)" or just "3.63". 
+ */
+const char*  CDECL get_lame_version       ( void );
+const char*  CDECL get_lame_short_version ( void );
+const char*  CDECL get_lame_very_short_version ( void );
+const char*  CDECL get_psy_version        ( void );
+const char*  CDECL get_lame_url           ( void );
+
+/*
+ * OPTIONAL:
+ * get the version numbers in numerical form.
+ */
+typedef struct {
+    /* generic LAME version */
+    int major;
+    int minor;
+    int alpha;               /* 0 if not an alpha version                  */
+    int beta;                /* 0 if not a beta version                    */
+
+    /* version of the psy model */
+    int psy_major;
+    int psy_minor;
+    int psy_alpha;           /* 0 if not an alpha version                  */
+    int psy_beta;            /* 0 if not a beta version                    */
+
+    /* compile time features */
+    const char *features;    /* Don't make assumptions about the contents! */
+} lame_version_t;
+void CDECL get_lame_version_numerical ( lame_version_t *const );
+
+
+/*
+ * OPTIONAL:
+ * print internal lame configuration to message handler
+ */
+void CDECL lame_print_config(const lame_global_flags*  gfp);
+
+void CDECL lame_print_internals( const lame_global_flags *gfp);
+
+
+/*
+ * input pcm data, output (maybe) mp3 frames.
+ * This routine handles all buffering, resampling and filtering for you.
+ * 
+ * return code     number of bytes output in mp3buf. Can be 0 
+ *                 -1:  mp3buf was too small
+ *                 -2:  malloc() problem
+ *                 -3:  lame_init_params() not called
+ *                 -4:  psycho acoustic problems 
+ *                 -5:  ogg cleanup encoding error
+ *                 -6:  ogg frame encoding error
+ *
+ * The required mp3buf_size can be computed from num_samples, 
+ * samplerate and encoding rate, but here is a worst case estimate:
+ *
+ * mp3buf_size in bytes = 1.25*num_samples + 7200
+ *
+ * I think a tighter bound could be:  (mt, March 2000)
+ * MPEG1:
+ *    num_samples*(bitrate/8)/samplerate + 4*1152*(bitrate/8)/samplerate + 512
+ * MPEG2:
+ *    num_samples*(bitrate/8)/samplerate + 4*576*(bitrate/8)/samplerate + 256
+ *
+ * but test first if you use that!
+ *
+ * set mp3buf_size = 0 and LAME will not check if mp3buf_size is
+ * large enough.
+ *
+ * NOTE:
+ * if gfp->num_channels=2, but gfp->mode = 3 (mono), the L & R channels
+ * will be averaged into the L channel before encoding only the L channel
+ * This will overwrite the data in buffer_l[] and buffer_r[].
+ * 
+*/
+int CDECL lame_encode_buffer (
+        lame_global_flags*  gfp,           /* global context handle         */
+        const short int     buffer_l [],   /* PCM data for left channel     */
+        const short int     buffer_r [],   /* PCM data for right channel    */
+        const int           nsamples,      /* number of samples per channel */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        const int           mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+/*
+ * as above, but input has L & R channel data interleaved.
+ * NOTE: 
+ * num_samples = number of samples in the L (or R)
+ * channel, not the total number of samples in pcm[]  
+ */
+int CDECL lame_encode_buffer_interleaved(
+        lame_global_flags*  gfp,           /* global context handlei        */
+        short int           pcm[],         /* PCM data for left and right
+                                              channel, interleaved          */
+        int                 num_samples,   /* number of samples per channel,
+                                              _not_ number of samples in
+                                              pcm[]                         */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        int                 mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+
+/* as lame_encode_buffer, but for 'float's.
+ * !! NOTE: !! data must still be scaled to be in the same range as 
+ * short int, +/- 32768  
+ */
+int CDECL lame_encode_buffer_float(
+        lame_global_flags*  gfp,           /* global context handle         */
+        const float     buffer_l [],       /* PCM data for left channel     */
+        const float     buffer_r [],       /* PCM data for right channel    */
+        const int           nsamples,      /* number of samples per channel */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        const int           mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+
+/* as lame_encode_buffer, but for long's 
+ * !! NOTE: !! data must still be scaled to be in the same range as 
+ * short int, +/- 32768  
+ *
+ * This scaling was a mistake (doesn't allow one to exploit full
+ * precision of type 'long'.  Use lame_encode_buffer_long2() instead.
+ *
+ */
+int CDECL lame_encode_buffer_long(
+        lame_global_flags*  gfp,           /* global context handle         */
+        const long     buffer_l [],       /* PCM data for left channel     */
+        const long     buffer_r [],       /* PCM data for right channel    */
+        const int           nsamples,      /* number of samples per channel */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        const int           mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+/* Same as lame_encode_buffer_long(), but with correct scaling. 
+ * !! NOTE: !! data must still be scaled to be in the same range as  
+ * type 'long'.   Data should be in the range:  +/- 2^(8*size(long)-1)
+ *
+ */
+int CDECL lame_encode_buffer_long2(
+        lame_global_flags*  gfp,           /* global context handle         */
+        const long     buffer_l [],       /* PCM data for left channel     */
+        const long     buffer_r [],       /* PCM data for right channel    */
+        const int           nsamples,      /* number of samples per channel */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        const int           mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+/* as lame_encode_buffer, but for int's 
+ * !! NOTE: !! input should be scaled to the maximum range of 'int'
+ * If int is 4 bytes, then the values should range from
+ * +/- 2147483648.  
+ *
+ * This routine does not (and cannot, without loosing precision) use
+ * the same scaling as the rest of the lame_encode_buffer() routines.
+ * 
+ */   
+int CDECL lame_encode_buffer_int(
+        lame_global_flags*  gfp,           /* global context handle         */
+        const int      buffer_l [],       /* PCM data for left channel     */
+        const int      buffer_r [],       /* PCM data for right channel    */
+        const int           nsamples,      /* number of samples per channel */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        const int           mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+
+
+
+
+/*
+ * REQUIRED:
+ * lame_encode_flush will flush the intenal PCM buffers, padding with 
+ * 0's to make sure the final frame is complete, and then flush
+ * the internal MP3 buffers, and thus may return a 
+ * final few mp3 frames.  'mp3buf' should be at least 7200 bytes long
+ * to hold all possible emitted data.
+ *
+ * will also write id3v1 tags (if any) into the bitstream       
+ *
+ * return code = number of bytes output to mp3buf. Can be 0
+ */
+int CDECL lame_encode_flush(
+        lame_global_flags *  gfp,    /* global context handle                 */
+        unsigned char*       mp3buf, /* pointer to encoded MP3 stream         */
+        int                  size);  /* number of valid octets in this stream */
+
+/*
+ * OPTIONAL:
+ * lame_encode_flush_nogap will flush the internal mp3 buffers and pad
+ * the last frame with ancillary data so it is a complete mp3 frame.
+ * 
+ * 'mp3buf' should be at least 7200 bytes long
+ * to hold all possible emitted data.
+ *
+ * After a call to this routine, the outputed mp3 data is complete, but
+ * you may continue to encode new PCM samples and write future mp3 data
+ * to a different file.  The two mp3 files will play back with no gaps
+ * if they are concatenated together.
+ *
+ * This routine will NOT write id3v1 tags into the bitstream.
+ *
+ * return code = number of bytes output to mp3buf. Can be 0
+ */
+int CDECL lame_encode_flush_nogap(
+        lame_global_flags *  gfp,    /* global context handle                 */
+        unsigned char*       mp3buf, /* pointer to encoded MP3 stream         */
+        int                  size);  /* number of valid octets in this stream */
+
+/*
+ * OPTIONAL:
+ * Normally, this is called by lame_init_params().  It writes id3v2 and
+ * Xing headers into the front of the bitstream, and sets frame counters
+ * and bitrate histogram data to 0.  You can also call this after 
+ * lame_encode_flush_nogap().  
+ */
+int CDECL lame_init_bitstream(
+        lame_global_flags *  gfp);    /* global context handle                 */
+
+
+
+/*
+ * OPTIONAL:    some simple statistics
+ * a bitrate histogram to visualize the distribution of used frame sizes
+ * a stereo mode histogram to visualize the distribution of used stereo
+ *   modes, useful in joint-stereo mode only
+ *   0: LR    left-right encoded
+ *   1: LR-I  left-right and intensity encoded (currently not supported)
+ *   2: MS    mid-side encoded
+ *   3: MS-I  mid-side and intensity encoded (currently not supported)
+ *
+ * attention: don't call them after lame_encode_finish
+ * suggested: lame_encode_flush -> lame_*_hist -> lame_close
+ */
+
+void CDECL lame_bitrate_hist( 
+        const lame_global_flags *const gfp, 
+              int                      bitrate_count[14] );
+void CDECL lame_bitrate_kbps( 
+        const lame_global_flags *const gfp, 
+              int                      bitrate_kbps [14] );
+void CDECL lame_stereo_mode_hist( 
+        const lame_global_flags *const gfp, 
+              int                      stereo_mode_count[4] );
+
+void CDECL lame_bitrate_stereo_mode_hist ( 
+        const lame_global_flags * const gfp, 
+        int  bitrate_stmode_count [14] [4] );
+
+
+/*
+ * OPTIONAL:
+ * lame_mp3_tags_fid will append a Xing VBR tag to the mp3 file with file
+ * pointer fid.  These calls perform forward and backwards seeks, so make
+ * sure fid is a real file.  Make sure lame_encode_flush has been called,
+ * and all mp3 data has been written to the file before calling this
+ * function.
+ * NOTE:
+ * if VBR  tags are turned off by the user, or turned off by LAME because
+ * the output is not a regular file, this call does nothing
+*/
+void CDECL lame_mp3_tags_fid(lame_global_flags *,FILE* fid);
+
+
+/*
+ * REQUIRED:
+ * final call to free all remaining buffers
+ */
+int  CDECL lame_close (lame_global_flags *);
+
+/*
+ * OBSOLETE:
+ * lame_encode_finish combines lame_encode_flush() and lame_close() in
+ * one call.  However, once this call is made, the statistics routines
+ * will no longer work because the data will have been cleared
+ */
+int CDECL lame_encode_finish(
+        lame_global_flags*  gfp,
+        unsigned char*      mp3buf,
+        int                 size );
+
+
+
+
+
+
+
+/*********************************************************************
+ *
+ * decoding 
+ *
+ * a simple interface to mpglib, part of mpg123, is also included if
+ * libmp3lame is compiled with HAVE_MPGLIB
+ *
+ *********************************************************************/
+typedef struct {
+  int header_parsed;   /* 1 if header was parsed and following data was
+                          computed                                       */
+  int stereo;          /* number of channels                             */
+  int samplerate;      /* sample rate                                    */
+  int bitrate;         /* bitrate                                        */
+  int mode;            /* mp3 frame type                                 */
+  int mode_ext;        /* mp3 frame type                                 */
+  int framesize;       /* number of samples per mp3 frame                */
+
+  /* this data is only computed if mpglib detects a Xing VBR header */
+  unsigned long nsamp; /* number of samples in mp3 file.                 */
+  int totalframes;     /* total number of frames in mp3 file             */
+
+  /* this data is not currently computed by the mpglib routines */
+  int framenum;        /* frames decoded counter                         */
+} mp3data_struct;
+
+
+/* required call to initialize decoder */
+int CDECL lame_decode_init(void);
+
+/*********************************************************************
+ * input 1 mp3 frame, output (maybe) pcm data.  
+ * lame_decode() return code:
+ *   -1: error
+ *    0: need more data
+ *  n>0: size of pcm output
+ *********************************************************************/
+int CDECL lame_decode(
+        unsigned char *  mp3buf,
+        int              len,
+        short            pcm_l[],
+        short            pcm_r[] );
+
+/* same as lame_decode, and also returns mp3 header data */
+int CDECL lame_decode_headers(
+        unsigned char*   mp3buf,
+        int              len,
+        short            pcm_l[],
+        short            pcm_r[],
+        mp3data_struct*  mp3data );
+
+/* same as lame_decode, but returns at most one frame */
+int CDECL lame_decode1(
+        unsigned char*  mp3buf,
+        int             len,
+        short           pcm_l[],
+        short           pcm_r[] );
+
+/* same as lame_decode1, but returns at most one frame and mp3 header data */
+int CDECL lame_decode1_headers(
+        unsigned char*   mp3buf,
+        int              len,
+        short            pcm_l[],
+        short            pcm_r[],
+        mp3data_struct*  mp3data );
+
+/* same as lame_decode1_headers, but also returns enc_delay and enc_padding
+   from VBR Info tag, (-1 if no info tag was found) */
+int CDECL lame_decode1_headersB(
+        unsigned char*   mp3buf,
+        int              len,
+        short            pcm_l[],
+        short            pcm_r[],
+        mp3data_struct*  mp3data,
+        int              *enc_delay,
+        int              *enc_padding );
+
+
+
+
+
+/*********************************************************************
+ *
+ * id3tag stuff
+ *
+ *********************************************************************/
+
+/*
+ * id3tag.h -- Interface to write ID3 version 1 and 2 tags.
+ *
+ * Copyright (C) 2000 Don Melton.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* utility to obtain alphabetically sorted list of genre names with numbers */
+extern void id3tag_genre_list(
+        void (*handler)(int, const char *, void *),
+        void*  cookie);
+
+extern void id3tag_init   (lame_global_flags *gfp);
+
+/* force addition of version 2 tag */
+extern void id3tag_add_v2   (lame_global_flags *gfp);
+
+/* add only a version 1 tag */
+extern void id3tag_v1_only  (lame_global_flags *gfp);
+
+/* add only a version 2 tag */
+extern void id3tag_v2_only  (lame_global_flags *gfp);
+
+/* pad version 1 tag with spaces instead of nulls */
+extern void id3tag_space_v1 (lame_global_flags *gfp);
+
+/* pad version 2 tag with extra 128 bytes */
+extern void id3tag_pad_v2   (lame_global_flags *gfp);
+
+extern void id3tag_set_title(
+        lame_global_flags*  gfp,
+        const char*         title );
+extern void id3tag_set_artist(
+        lame_global_flags*  gfp,
+        const char*         artist );
+extern void id3tag_set_album(
+        lame_global_flags*  gfp,
+        const char*         album );
+extern void id3tag_set_year(
+        lame_global_flags*  gfp,
+        const char*         year );
+extern void id3tag_set_comment(
+        lame_global_flags*  gfp,
+        const char*         comment );
+extern void id3tag_set_track(
+        lame_global_flags*  gfp,
+        const char*         track );
+
+/* return non-zero result if genre name or number is invalid */
+extern int id3tag_set_genre(
+        lame_global_flags*  gfp,
+        const char*         genre );
+
+/***********************************************************************
+*
+*  list of valid bitrates [kbps] & sample frequencies [Hz].
+*  first index: 0: MPEG-2   values  (sample frequencies 16...24 kHz) 
+*               1: MPEG-1   values  (sample frequencies 32...48 kHz)
+*               2: MPEG-2.5 values  (sample frequencies  8...12 kHz)
+***********************************************************************/
+extern const int      bitrate_table    [3] [16];
+extern const int      samplerate_table [3] [ 4];
+
+
+
+/* maximum size of mp3buffer needed if you encode at most 1152 samples for
+   each call to lame_encode_buffer.  see lame_encode_buffer() below  
+   (LAME_MAXMP3BUFFER is now obsolete)  */
+#define LAME_MAXMP3BUFFER   16384
+
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* LAME_LAME_H */
diff --git a/lib/lame/lame_global_flags.h b/lib/lame/lame_global_flags.h
new file mode 100644 (file)
index 0000000..7267c93
--- /dev/null
@@ -0,0 +1,178 @@
+
+#ifndef LAME_GLOBAL_FLAGS_H
+#define LAME_GLOBAL_FLAGS_H
+
+struct lame_internal_flags;
+typedef struct lame_internal_flags lame_internal_flags;
+
+
+typedef enum short_block_e {
+    short_block_not_set = -1,   /* allow LAME to decide */
+    short_block_allowed = 0,    /* LAME may use them, even different block types for L/R */
+    short_block_coupled,        /* LAME may use them, but always same block types in L/R */
+    short_block_dispensed,      /* LAME will not use short blocks, long blocks only */
+    short_block_forced          /* LAME will not use long blocks, short blocks only */
+} short_block_t;
+
+/***********************************************************************
+*
+*  Control Parameters set by User.  These parameters are here for
+*  backwards compatibility with the old, non-shared lib API.  
+*  Please use the lame_set_variablename() functions below
+*
+*
+***********************************************************************/
+struct lame_global_struct {
+  /* input description */
+  unsigned long num_samples;  /* number of samples. default=2^32-1           */
+  int num_channels;           /* input number of channels. default=2         */
+  int in_samplerate;          /* input_samp_rate in Hz. default=44.1 kHz     */
+  int out_samplerate;         /* output_samp_rate.
+                                   default: LAME picks best value 
+                                   at least not used for MP3 decoding:
+                                   Remember 44.1 kHz MP3s and AC97           */
+  float scale;                /* scale input by this amount before encoding
+                                 at least not used for MP3 decoding          */
+  float scale_left;           /* scale input of channel 0 (left) by this
+                                amount before encoding                      */
+  float scale_right;          /* scale input of channel 1 (right) by this
+                                amount before encoding                      */
+
+  /* general control params */
+  int analysis;               /* collect data for a MP3 frame analyzer?      */
+  int bWriteVbrTag;           /* add Xing VBR tag?                           */
+  int decode_only;            /* use lame/mpglib to convert mp3/ogg to wav   */
+  int ogg;                    /* encode to Vorbis .ogg file                  */
+
+  int quality;                /* quality setting 0=best,  9=worst  default=5 */
+  MPEG_mode mode;             /* see enum in lame.h
+                                 default = LAME picks best value             */
+  int mode_fixed;             /* ignored                                     */
+  int mode_automs;            /* use a m/s threshold based on compression
+                                 ratio                                       */
+  int force_ms;               /* force M/S mode.  requires mode=1            */
+  int free_format;            /* use free format? default=0                  */
+
+  /*
+   * set either brate>0  or compression_ratio>0, LAME will compute
+   * the value of the variable not set.
+   * Default is compression_ratio = 11.025
+   */
+  int brate;                  /* bitrate                                    */
+  float compression_ratio;    /* sizeof(wav file)/sizeof(mp3 file)          */
+
+
+  /* frame params */
+  int copyright;                  /* mark as copyright. default=0           */
+  int original;                   /* mark as original. default=1            */
+  int error_protection;           /* use 2 bytes per frame for a CRC
+                                     checksum. default=0                    */
+  Padding_type padding_type;      /* PAD_NO = no padding,
+                                     PAD_ALL = always pad,
+                                     PAD_ADJUST = adjust padding,
+                                     default=2                              */
+  int extension;                  /* the MP3 'private extension' bit.
+                                     Meaningless                            */
+  int strict_ISO;                 /* enforce ISO spec as much as possible   */
+
+  /* quantization/noise shaping */
+  int disable_reservoir;          /* use bit reservoir?                     */
+  int experimentalX;            
+  int experimentalY;
+  int experimentalZ;
+  int exp_nspsytune;
+
+  double newmsfix;
+  int preset_expopts;
+
+  /* VBR control */
+  vbr_mode VBR;
+  int VBR_q;
+  int VBR_mean_bitrate_kbps;
+  int VBR_min_bitrate_kbps;
+  int VBR_max_bitrate_kbps;
+  int VBR_hard_min;             /* strictly enforce VBR_min_bitrate
+                                   normaly, it will be violated for analog
+                                   silence                                 */
+
+
+  /* resampling and filtering */
+  int lowpassfreq;                /* freq in Hz. 0=lame choses.
+                                     -1=no filter                          */
+  int highpassfreq;               /* freq in Hz. 0=lame choses.
+                                     -1=no filter                          */
+  int lowpasswidth;               /* freq width of filter, in Hz
+                                     (default=15%)                         */
+  int highpasswidth;              /* freq width of filter, in Hz
+                                     (default=15%)                         */
+
+
+
+  /*
+   * psycho acoustics and other arguments which you should not change 
+   * unless you know what you are doing
+   */
+  int ATHonly;                    /* only use ATH                         */
+  int ATHshort;                   /* only use ATH for short blocks        */
+  int noATH;                      /* disable ATH                          */
+  int ATHtype;                    /* select ATH formula                   */
+  float ATHlower;                 /* lower ATH by this many db            */
+  int athaa_type;                 /* select ATH auto-adjust scheme        */
+  int athaa_loudapprox;           /* select ATH auto-adjust loudness calc */
+  float athaa_sensitivity;        /* dB, tune active region of auto-level */
+  int cwlimit;                    /* predictability limit                 */
+  short_block_t short_blocks;
+/*  int allow_diff_short;            allow blocktypes to differ between
+                                     channels?                            */
+  int useTemporal;                /* use temporal masking effect          */
+/*  int no_short_blocks;             disable short blocks                 */
+  int emphasis;                   /* Input PCM is emphased PCM (for
+                                     instance from one of the rarely
+                                     emphased CDs), it is STRONGLY not
+                                     recommended to use this, because
+                                    psycho does not take it into account,
+                                    and last but not least many decoders
+                                     don't care about these bits          */
+  float msfix;              /* Naoki's adjustment of Mid/Side maskings */
+
+  int   tune;               /* 0 off, 1 on */
+  float tune_value_a;       /* used to pass values for debugging and stuff */
+
+  
+  struct {
+    void (*msgf)  (const char *format, va_list ap);
+    void (*debugf)(const char *format, va_list ap);
+    void (*errorf)(const char *format, va_list ap);
+  } report;
+
+  /************************************************************************/
+  /* internal variables, do not set...                                    */
+  /* provided because they may be of use to calling application           */
+  /************************************************************************/
+
+  int version;                    /* 0=MPEG-2/2.5  1=MPEG-1               */
+  int encoder_delay;
+  int encoder_padding;  /* number of samples of padding appended to input */
+  int framesize;                  
+  int frameNum;                   /* number of frames encoded             */
+  int lame_allocated_gfp;         /* is this struct owned by calling
+                                     program or lame?                     */
+
+
+
+  /****************************************************************************/
+  /* more internal variables, which will not exist after lame_encode_finish() */
+  /****************************************************************************/
+  lame_internal_flags *internal_flags;
+
+  /* VBR tags.  This data is here because VBR header is writen after
+   * input file is closed and *internal_flags struct is free'd */
+  int TotalFrameSize;
+  //int* pVbrFrames;
+  int nVbrNumFrames;
+  int nVbrFrameBufferSize;
+
+
+} ;
+
+#endif /* LAME_GLOBAL_FLAGS_H */
diff --git a/lib/lame/lameerror.h b/lib/lame/lameerror.h
new file mode 100644 (file)
index 0000000..a4b9757
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  A collection of LAME Error Codes
+ *
+ *  Please use the constants defined here instead of some arbitrary
+ *  values. Currently the values starting at -10 to avoid intersection
+ *  with the -1, -2, -3 and -4 used in the current code.
+ *
+ *  May be this should be a part of the include/lame.h.
+ */
+
+typedef enum {
+    LAME_OKAY             =   0,
+    LAME_NOERROR          =   0,
+    LAME_GENERICERROR     =  -1,
+    LAME_NOMEM            = -10,
+    LAME_BADBITRATE       = -11,
+    LAME_BADSAMPFREQ      = -12,
+    LAME_INTERNALERROR    = -13,
+    
+    FRONTEND_READERROR    = -80,
+    FRONTEND_WRITEERROR   = -81,
+    FRONTEND_FILETOOLARGE = -82,
+    
+} lame_errorcodes_t;
+
+/* end of lameerror.h */
diff --git a/lib/lame/machine.h b/lib/lame/machine.h
new file mode 100644 (file)
index 0000000..109f291
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ *     Machine dependent defines/includes for LAME.
+ *
+ *     Copyright (c) 1999 A.L. Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_MACHINE_H
+#define LAME_MACHINE_H
+
+#include <stdio.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+# ifndef HAVE_STRCHR
+#  define strchr index
+#  define strrchr rindex
+# endif
+char *strchr (), *strrchr ();
+# ifndef HAVE_MEMCPY
+#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+#  define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if  defined(__riscos__)  &&  defined(FPA10)
+# include "ymath.h"
+#else
+# include <math.h>
+#endif
+
+#include <ctype.h>
+
+#ifdef HAVE_ERRNO_H
+# include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if defined(macintosh)
+# include <types.h>
+# include <stat.h>
+#else
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+
+/* 
+ * 3 different types of pow() functions:
+ *   - table lookup
+ *   - pow()
+ *   - exp()   on some machines this is claimed to be faster than pow()
+ */
+
+#define POW20(x)  pow20[x]
+//#define POW20(x)  pow(2.0,((double)(x)-210)*.25)
+//#define POW20(x)  exp( ((double)(x)-210)*(.25*LOG2) )
+
+#define IPOW20(x)  ipow20[x]
+//#define IPOW20(x)  exp( -((double)(x)-210)*.1875*LOG2 )
+//#define IPOW20(x)  pow(2.0,-((double)(x)-210)*.1875)
+
+#define IIPOW20_(x) iipow20_[x]
+
+/* in case this is used without configure */
+#ifndef inline
+# define inline
+#endif
+/* compatibility */
+#define INLINE inline
+
+#if defined(_MSC_VER)
+# undef inline
+# define inline _inline
+#elif defined(__SASC) || defined(__GNUC__) || defined(__ICC) || defined(__ECC)
+/* if __GNUC__ we always want to inline, not only if the user requests it */
+# undef inline
+# define inline __inline
+#endif
+
+#if    defined(_MSC_VER)
+# pragma warning( disable : 4244 )
+//# pragma warning( disable : 4305 )
+#endif
+
+/*
+ * FLOAT    for variables which require at least 32 bits
+ * FLOAT8   for variables which require at least 64 bits
+ *
+ * On some machines, 64 bit will be faster than 32 bit.  Also, some math
+ * routines require 64 bit float, so setting FLOAT=float will result in a
+ * lot of conversions.
+ */
+
+#if ( defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) )
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#else
+# ifndef FLOAT
+typedef float   FLOAT;
+#  ifdef FLT_MAX
+#   define FLOAT_MAX FLT_MAX
+#  else
+#   define FLOAT_MAX 1e99 /* approx */
+#  endif
+# endif
+#endif
+
+#ifndef FLOAT8  /* NOTE: RH: 7/00:  if FLOAT8=float, it breaks resampling and VBR code */
+typedef double  FLOAT8;
+# ifdef DBL_MAX
+#  define FLOAT8_MAX DBL_MAX
+# else
+#  define FLOAT8_MAX 1e99 /* approx */
+# endif
+#else
+# ifdef FLT_MAX
+#  define FLOAT8_MAX FLT_MAX
+# else
+#  define FLOAT8_MAX 1e99 /* approx */
+# endif
+#endif
+
+/* Various integer types */
+
+#if   defined _WIN32 && !defined __CYGWIN__
+typedef unsigned char  u_char;
+#elif defined __DECALPHA__
+// do nothing
+#elif defined OS_AMIGAOS
+// do nothing
+#elif defined __DJGPP__
+typedef unsigned char  u_char;
+#elif !defined __GNUC__  ||  defined __STRICT_ANSI__
+typedef unsigned char  u_char;
+#else
+// do nothing
+#endif
+
+/* sample_t must be floating point, at least 32 bits */
+typedef FLOAT     sample_t;
+typedef sample_t  stereo_t [2];
+
+#endif
+
+/* end of machine.h */
diff --git a/lib/lame/newmdct.c b/lib/lame/newmdct.c
new file mode 100644 (file)
index 0000000..7c5a55a
--- /dev/null
@@ -0,0 +1,790 @@
+/*
+ *     MP3 window subband -> subband filtering -> mdct routine
+ *
+ *     Copyright (c) 1999 Takehiro TOMINAGA
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ *         Special Thanks to Patrick De Smet for your advices.
+ */
+
+/* $Id: newmdct.c,v 1.1 2002/04/28 17:30:23 kramm Exp $ */
+
+#include "config_static.h"
+
+#include "util.h"
+#include "l3side.h"
+#include "newmdct.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#define SCALE (32768.0/ 2.384e-06)
+
+#ifndef USE_GOGO_SUBBAND
+static const FLOAT8 enwindow[] = 
+{
+      -4.77e-07*0.740951125354959/2.384e-06,  1.03951e-04*0.740951125354959/2.384e-06,  9.53674e-04*0.740951125354959/2.384e-06, 2.841473e-03*0.740951125354959/2.384e-06,
+  3.5758972e-02*0.740951125354959/2.384e-06, 3.401756e-03*0.740951125354959/2.384e-06,  9.83715e-04*0.740951125354959/2.384e-06,   9.9182e-05*0.740951125354959/2.384e-06, /* 15*/
+     1.2398e-05*0.740951125354959/2.384e-06,  1.91212e-04*0.740951125354959/2.384e-06, 2.283096e-03*0.740951125354959/2.384e-06,1.6994476e-02*0.740951125354959/2.384e-06,
+ -1.8756866e-02*0.740951125354959/2.384e-06,-2.630711e-03*0.740951125354959/2.384e-06, -2.47478e-04*0.740951125354959/2.384e-06,  -1.4782e-05*0.740951125354959/2.384e-06,
+      9.063471690191471e-01,
+      1.960342806591213e-01,
+
+
+      -4.77e-07*0.773010453362737/2.384e-06,  1.05858e-04*0.773010453362737/2.384e-06,  9.30786e-04*0.773010453362737/2.384e-06, 2.521515e-03*0.773010453362737/2.384e-06,
+  3.5694122e-02*0.773010453362737/2.384e-06, 3.643036e-03*0.773010453362737/2.384e-06,  9.91821e-04*0.773010453362737/2.384e-06,   9.6321e-05*0.773010453362737/2.384e-06, /* 14*/
+     1.1444e-05*0.773010453362737/2.384e-06,  1.65462e-04*0.773010453362737/2.384e-06, 2.110004e-03*0.773010453362737/2.384e-06,1.6112804e-02*0.773010453362737/2.384e-06,
+ -1.9634247e-02*0.773010453362737/2.384e-06,-2.803326e-03*0.773010453362737/2.384e-06, -2.77042e-04*0.773010453362737/2.384e-06,  -1.6689e-05*0.773010453362737/2.384e-06,
+      8.206787908286602e-01,
+      3.901806440322567e-01,
+
+
+      -4.77e-07*0.803207531480645/2.384e-06,  1.07288e-04*0.803207531480645/2.384e-06,  9.02653e-04*0.803207531480645/2.384e-06, 2.174854e-03*0.803207531480645/2.384e-06,
+  3.5586357e-02*0.803207531480645/2.384e-06, 3.858566e-03*0.803207531480645/2.384e-06,  9.95159e-04*0.803207531480645/2.384e-06,   9.3460e-05*0.803207531480645/2.384e-06, /* 13*/
+     1.0014e-05*0.803207531480645/2.384e-06,  1.40190e-04*0.803207531480645/2.384e-06, 1.937389e-03*0.803207531480645/2.384e-06,1.5233517e-02*0.803207531480645/2.384e-06,
+ -2.0506859e-02*0.803207531480645/2.384e-06,-2.974033e-03*0.803207531480645/2.384e-06, -3.07560e-04*0.803207531480645/2.384e-06,  -1.8120e-05*0.803207531480645/2.384e-06,
+      7.416505462720353e-01,
+      5.805693545089249e-01,
+
+
+      -4.77e-07*0.831469612302545/2.384e-06,  1.08242e-04*0.831469612302545/2.384e-06,  8.68797e-04*0.831469612302545/2.384e-06, 1.800537e-03*0.831469612302545/2.384e-06,
+  3.5435200e-02*0.831469612302545/2.384e-06, 4.049301e-03*0.831469612302545/2.384e-06,  9.94205e-04*0.831469612302545/2.384e-06,   9.0599e-05*0.831469612302545/2.384e-06, /* 12*/
+      9.060e-06*0.831469612302545/2.384e-06,  1.16348e-04*0.831469612302545/2.384e-06, 1.766682e-03*0.831469612302545/2.384e-06,1.4358521e-02*0.831469612302545/2.384e-06,
+ -2.1372318e-02*0.831469612302545/2.384e-06, -3.14188e-03*0.831469612302545/2.384e-06, -3.39031e-04*0.831469612302545/2.384e-06,  -1.9550e-05*0.831469612302545/2.384e-06,
+      6.681786379192989e-01,
+      7.653668647301797e-01,
+
+
+      -4.77e-07*0.857728610000272/2.384e-06,  1.08719e-04*0.857728610000272/2.384e-06,  8.29220e-04*0.857728610000272/2.384e-06, 1.399517e-03*0.857728610000272/2.384e-06,
+  3.5242081e-02*0.857728610000272/2.384e-06, 4.215240e-03*0.857728610000272/2.384e-06,  9.89437e-04*0.857728610000272/2.384e-06,   8.7261e-05*0.857728610000272/2.384e-06, /* 11*/
+      8.106e-06*0.857728610000272/2.384e-06,   9.3937e-05*0.857728610000272/2.384e-06, 1.597881e-03*0.857728610000272/2.384e-06,1.3489246e-02*0.857728610000272/2.384e-06,
+ -2.2228718e-02*0.857728610000272/2.384e-06,-3.306866e-03*0.857728610000272/2.384e-06, -3.71456e-04*0.857728610000272/2.384e-06,  -2.1458e-05*0.857728610000272/2.384e-06,
+      5.993769336819237e-01,
+      9.427934736519954e-01,
+
+
+      -4.77e-07*0.881921264348355/2.384e-06,  1.08719e-04*0.881921264348355/2.384e-06,   7.8392e-04*0.881921264348355/2.384e-06,  9.71317e-04*0.881921264348355/2.384e-06,
+  3.5007000e-02*0.881921264348355/2.384e-06, 4.357815e-03*0.881921264348355/2.384e-06,  9.80854e-04*0.881921264348355/2.384e-06,   8.3923e-05*0.881921264348355/2.384e-06, /* 10*/
+      7.629e-06*0.881921264348355/2.384e-06,   7.2956e-05*0.881921264348355/2.384e-06, 1.432419e-03*0.881921264348355/2.384e-06,1.2627602e-02*0.881921264348355/2.384e-06,
+ -2.3074150e-02*0.881921264348355/2.384e-06,-3.467083e-03*0.881921264348355/2.384e-06, -4.04358e-04*0.881921264348355/2.384e-06,  -2.3365e-05*0.881921264348355/2.384e-06,
+      5.345111359507916e-01,
+      1.111140466039205e+00,
+
+
+      -9.54e-07*0.903989293123443/2.384e-06,  1.08242e-04*0.903989293123443/2.384e-06,  7.31945e-04*0.903989293123443/2.384e-06,  5.15938e-04*0.903989293123443/2.384e-06,
+  3.4730434e-02*0.903989293123443/2.384e-06, 4.477024e-03*0.903989293123443/2.384e-06,  9.68933e-04*0.903989293123443/2.384e-06,   8.0585e-05*0.903989293123443/2.384e-06, /* 9*/
+      6.676e-06*0.903989293123443/2.384e-06,   5.2929e-05*0.903989293123443/2.384e-06, 1.269817e-03*0.903989293123443/2.384e-06,1.1775017e-02*0.903989293123443/2.384e-06,
+ -2.3907185e-02*0.903989293123443/2.384e-06,-3.622532e-03*0.903989293123443/2.384e-06, -4.38213e-04*0.903989293123443/2.384e-06,  -2.5272e-05*0.903989293123443/2.384e-06,
+      4.729647758913199e-01,
+      1.268786568327291e+00,
+
+
+      -9.54e-07*0.92387953251128675613/2.384e-06,  1.06812e-04*0.92387953251128675613/2.384e-06,  6.74248e-04*0.92387953251128675613/2.384e-06,   3.3379e-05*0.92387953251128675613/2.384e-06,
+  3.4412861e-02*0.92387953251128675613/2.384e-06, 4.573822e-03*0.92387953251128675613/2.384e-06,  9.54151e-04*0.92387953251128675613/2.384e-06,   7.6771e-05*0.92387953251128675613/2.384e-06,
+      6.199e-06*0.92387953251128675613/2.384e-06,   3.4332e-05*0.92387953251128675613/2.384e-06, 1.111031e-03*0.92387953251128675613/2.384e-06,1.0933399e-02*0.92387953251128675613/2.384e-06,
+ -2.4725437e-02*0.92387953251128675613/2.384e-06,-3.771782e-03*0.92387953251128675613/2.384e-06, -4.72546e-04*0.92387953251128675613/2.384e-06,  -2.7657e-05*0.92387953251128675613/2.384e-06,
+      4.1421356237309504879e-01,  /* tan(PI/8) */
+      1.414213562373095e+00,
+
+
+      -9.54e-07*0.941544065183021/2.384e-06,  1.05381e-04*0.941544065183021/2.384e-06,  6.10352e-04*0.941544065183021/2.384e-06, -4.75883e-04*0.941544065183021/2.384e-06,
+  3.4055710e-02*0.941544065183021/2.384e-06, 4.649162e-03*0.941544065183021/2.384e-06,  9.35555e-04*0.941544065183021/2.384e-06,   7.3433e-05*0.941544065183021/2.384e-06, /* 7*/
+      5.245e-06*0.941544065183021/2.384e-06,   1.7166e-05*0.941544065183021/2.384e-06,  9.56535e-04*0.941544065183021/2.384e-06,1.0103703e-02*0.941544065183021/2.384e-06,
+ -2.5527000e-02*0.941544065183021/2.384e-06,-3.914356e-03*0.941544065183021/2.384e-06, -5.07355e-04*0.941544065183021/2.384e-06,  -3.0041e-05*0.941544065183021/2.384e-06,
+      3.578057213145241e-01,
+      1.546020906725474e+00,
+
+
+      -9.54e-07*0.956940335732209/2.384e-06,  1.02520e-04*0.956940335732209/2.384e-06,  5.39303e-04*0.956940335732209/2.384e-06,-1.011848e-03*0.956940335732209/2.384e-06,
+  3.3659935e-02*0.956940335732209/2.384e-06, 4.703045e-03*0.956940335732209/2.384e-06,  9.15051e-04*0.956940335732209/2.384e-06,   7.0095e-05*0.956940335732209/2.384e-06, /* 6*/
+      4.768e-06*0.956940335732209/2.384e-06,     9.54e-07*0.956940335732209/2.384e-06,  8.06808e-04*0.956940335732209/2.384e-06, 9.287834e-03*0.956940335732209/2.384e-06,
+ -2.6310921e-02*0.956940335732209/2.384e-06,-4.048824e-03*0.956940335732209/2.384e-06, -5.42164e-04*0.956940335732209/2.384e-06,  -3.2425e-05*0.956940335732209/2.384e-06,
+      3.033466836073424e-01,
+      1.662939224605090e+00,
+
+
+     -1.431e-06*0.970031253194544/2.384e-06,   9.9182e-05*0.970031253194544/2.384e-06,  4.62532e-04*0.970031253194544/2.384e-06,-1.573563e-03*0.970031253194544/2.384e-06,
+  3.3225536e-02*0.970031253194544/2.384e-06, 4.737377e-03*0.970031253194544/2.384e-06,  8.91685e-04*0.970031253194544/2.384e-06,   6.6280e-05*0.970031253194544/2.384e-06,  /* 5*/
+      4.292e-06*0.970031253194544/2.384e-06,  -1.3828e-05*0.970031253194544/2.384e-06,  6.61850e-04*0.970031253194544/2.384e-06, 8.487225e-03*0.970031253194544/2.384e-06,
+ -2.7073860e-02*0.970031253194544/2.384e-06,-4.174709e-03*0.970031253194544/2.384e-06, -5.76973e-04*0.970031253194544/2.384e-06,  -3.4809e-05*0.970031253194544/2.384e-06,
+      2.504869601913055e-01,
+      1.763842528696710e+00,
+
+
+     -1.431e-06*0.98078528040323/2.384e-06,   9.5367e-05*0.98078528040323/2.384e-06,  3.78609e-04*0.98078528040323/2.384e-06,-2.161503e-03*0.98078528040323/2.384e-06,
+  3.2754898e-02*0.98078528040323/2.384e-06, 4.752159e-03*0.98078528040323/2.384e-06,  8.66413e-04*0.98078528040323/2.384e-06,   6.2943e-05*0.98078528040323/2.384e-06, /* 4*/
+      3.815e-06*0.98078528040323/2.384e-06,   -2.718e-05*0.98078528040323/2.384e-06,  5.22137e-04*0.98078528040323/2.384e-06, 7.703304e-03*0.98078528040323/2.384e-06,
+ -2.7815342e-02*0.98078528040323/2.384e-06,-4.290581e-03*0.98078528040323/2.384e-06, -6.11782e-04*0.98078528040323/2.384e-06,  -3.7670e-05*0.98078528040323/2.384e-06,
+      1.989123673796580e-01,
+      1.847759065022573e+00,
+
+
+     -1.907e-06*0.989176509964781/2.384e-06,   9.0122e-05*0.989176509964781/2.384e-06,  2.88486e-04*0.989176509964781/2.384e-06,-2.774239e-03*0.989176509964781/2.384e-06,
+  3.2248020e-02*0.989176509964781/2.384e-06, 4.748821e-03*0.989176509964781/2.384e-06,  8.38757e-04*0.989176509964781/2.384e-06,   5.9605e-05*0.989176509964781/2.384e-06, /* 3*/
+      3.338e-06*0.989176509964781/2.384e-06,  -3.9577e-05*0.989176509964781/2.384e-06,  3.88145e-04*0.989176509964781/2.384e-06, 6.937027e-03*0.989176509964781/2.384e-06,
+ -2.8532982e-02*0.989176509964781/2.384e-06,-4.395962e-03*0.989176509964781/2.384e-06, -6.46591e-04*0.989176509964781/2.384e-06,  -4.0531e-05*0.989176509964781/2.384e-06,
+      1.483359875383474e-01,
+      1.913880671464418e+00,
+
+
+     -1.907e-06*0.995184726672197/2.384e-06,   8.4400e-05*0.995184726672197/2.384e-06,  1.91689e-04*0.995184726672197/2.384e-06,-3.411293e-03*0.995184726672197/2.384e-06,
+  3.1706810e-02*0.995184726672197/2.384e-06, 4.728317e-03*0.995184726672197/2.384e-06,  8.09669e-04*0.995184726672197/2.384e-06,    5.579e-05*0.995184726672197/2.384e-06,
+      3.338e-06*0.995184726672197/2.384e-06,  -5.0545e-05*0.995184726672197/2.384e-06,  2.59876e-04*0.995184726672197/2.384e-06, 6.189346e-03*0.995184726672197/2.384e-06,
+ -2.9224873e-02*0.995184726672197/2.384e-06,-4.489899e-03*0.995184726672197/2.384e-06, -6.80923e-04*0.995184726672197/2.384e-06,  -4.3392e-05*0.995184726672197/2.384e-06,
+      9.849140335716425e-02,
+      1.961570560806461e+00,
+
+
+     -2.384e-06*0.998795456205172/2.384e-06,   7.7724e-05*0.998795456205172/2.384e-06,   8.8215e-05*0.998795456205172/2.384e-06,-4.072189e-03*0.998795456205172/2.384e-06,
+      3.1132698e-02*0.998795456205172/2.384e-06, 4.691124e-03*0.998795456205172/2.384e-06,  7.79152e-04*0.998795456205172/2.384e-06,   5.2929e-05*0.998795456205172/2.384e-06,
+      2.861e-06*0.998795456205172/2.384e-06,  -6.0558e-05*0.998795456205172/2.384e-06,  1.37329e-04*0.998795456205172/2.384e-06, 5.462170e-03*0.998795456205172/2.384e-06,
+      -2.9890060e-02*0.998795456205172/2.384e-06,-4.570484e-03*0.998795456205172/2.384e-06, -7.14302e-04*0.998795456205172/2.384e-06,  -4.6253e-05*0.998795456205172/2.384e-06,
+      4.912684976946725e-02,
+      1.990369453344394e+00,
+
+
+      3.5780907e-02 * SQRT2*0.5/2.384e-06,1.7876148e-02 * SQRT2*0.5/2.384e-06, 3.134727e-03 * SQRT2*0.5/2.384e-06, 2.457142e-03 * SQRT2*0.5/2.384e-06,
+      9.71317e-04 * SQRT2*0.5/2.384e-06,  2.18868e-04 * SQRT2*0.5/2.384e-06,  1.01566e-04 * SQRT2*0.5/2.384e-06,   1.3828e-05 * SQRT2*0.5/2.384e-06,
+
+      3.0526638e-02/2.384e-06, 4.638195e-03/2.384e-06,  7.47204e-04/2.384e-06,   4.9591e-05/2.384e-06,
+      4.756451e-03/2.384e-06,   2.1458e-05/2.384e-06,  -6.9618e-05/2.384e-06,/*    2.384e-06/2.384e-06*/
+};
+#endif
+
+
+#define NS 12
+#define NL 36
+
+static const FLOAT8 win[4][NL] = {
+  {
+    2.382191739347913e-13,
+    6.423305872147834e-13,
+    9.400849094049688e-13,
+    1.122435026096556e-12,
+    1.183840321267481e-12,
+    1.122435026096556e-12,
+    9.400849094049690e-13,
+    6.423305872147839e-13,
+    2.382191739347918e-13,
+
+    5.456116108943412e-12,
+    4.878985199565852e-12,
+    4.240448995017367e-12,
+    3.559909094758252e-12,
+    2.858043359288075e-12,
+    2.156177623817898e-12,
+    1.475637723558783e-12,
+    8.371015190102974e-13,
+    2.599706096327376e-13,
+
+    -5.456116108943412e-12,
+    -4.878985199565852e-12,
+    -4.240448995017367e-12,
+    -3.559909094758252e-12,
+    -2.858043359288076e-12,
+    -2.156177623817898e-12,
+    -1.475637723558783e-12,
+    -8.371015190102975e-13,
+    -2.599706096327376e-13,
+
+    -2.382191739347923e-13,
+    -6.423305872147843e-13,
+    -9.400849094049696e-13,
+    -1.122435026096556e-12,
+    -1.183840321267481e-12,
+    -1.122435026096556e-12,
+    -9.400849094049694e-13,
+    -6.423305872147840e-13,
+    -2.382191739347918e-13,
+  },
+  {
+    2.382191739347913e-13,
+    6.423305872147834e-13,
+    9.400849094049688e-13,
+    1.122435026096556e-12,
+    1.183840321267481e-12,
+    1.122435026096556e-12,
+    9.400849094049688e-13,
+    6.423305872147841e-13,
+    2.382191739347918e-13,
+
+    5.456116108943413e-12,
+    4.878985199565852e-12,
+    4.240448995017367e-12,
+    3.559909094758253e-12,
+    2.858043359288075e-12,
+    2.156177623817898e-12,
+    1.475637723558782e-12,
+    8.371015190102975e-13,
+    2.599706096327376e-13,
+
+    -5.461314069809755e-12,
+    -4.921085770524055e-12,
+    -4.343405037091838e-12,
+    -3.732668368707687e-12,
+    -3.093523840190885e-12,
+    -2.430835727329465e-12,
+    -1.734679010007751e-12,
+    -9.748253656609281e-13,
+    -2.797435120168326e-13,
+
+    0.000000000000000e+00,
+    0.000000000000000e+00,
+    0.000000000000000e+00,
+    0.000000000000000e+00,
+    0.000000000000000e+00,
+    0.000000000000000e+00,
+    -2.283748241799531e-13,
+    -4.037858874020686e-13,
+    -2.146547464825323e-13,
+  },
+  {
+    1.316524975873958e-01, /* win[SHORT_TYPE] */
+    4.142135623730950e-01,
+    7.673269879789602e-01,
+
+    1.091308501069271e+00, /* tantab_l */
+    1.303225372841206e+00,
+    1.569685577117490e+00,
+    1.920982126971166e+00,
+    2.414213562373094e+00,
+    3.171594802363212e+00,
+    4.510708503662055e+00,
+    7.595754112725146e+00,
+    2.290376554843115e+01,
+
+    0.98480775301220802032, /* cx */
+    0.64278760968653936292,
+    0.34202014332566882393,
+    0.93969262078590842791,
+    -0.17364817766693030343,
+    -0.76604444311897790243,
+    0.86602540378443870761,
+    0.500000000000000e+00,
+
+    -5.144957554275265e-01, /* ca */
+    -4.717319685649723e-01,
+    -3.133774542039019e-01,
+    -1.819131996109812e-01,
+    -9.457419252642064e-02,
+    -4.096558288530405e-02,
+    -1.419856857247115e-02,
+    -3.699974673760037e-03,
+
+     8.574929257125442e-01, /* cs */
+     8.817419973177052e-01,
+     9.496286491027329e-01,
+     9.833145924917901e-01,
+     9.955178160675857e-01,
+     9.991605581781475e-01,
+     9.998991952444470e-01,
+     9.999931550702802e-01,
+  },
+  {
+    0.000000000000000e+00,
+    0.000000000000000e+00,
+    0.000000000000000e+00,
+    0.000000000000000e+00,
+    0.000000000000000e+00,
+    0.000000000000000e+00,
+    2.283748241799531e-13,
+    4.037858874020686e-13,
+    2.146547464825323e-13,
+
+    5.461314069809755e-12,
+    4.921085770524055e-12,
+    4.343405037091838e-12,
+    3.732668368707687e-12,
+    3.093523840190885e-12,
+    2.430835727329466e-12,
+    1.734679010007751e-12,
+    9.748253656609281e-13,
+    2.797435120168326e-13,
+
+    -5.456116108943413e-12,
+    -4.878985199565852e-12,
+    -4.240448995017367e-12,
+    -3.559909094758253e-12,
+    -2.858043359288075e-12,
+    -2.156177623817898e-12,
+    -1.475637723558782e-12,
+    -8.371015190102975e-13,
+    -2.599706096327376e-13,
+
+    -2.382191739347913e-13,
+    -6.423305872147834e-13,
+    -9.400849094049688e-13,
+    -1.122435026096556e-12,
+    -1.183840321267481e-12,
+    -1.122435026096556e-12,
+    -9.400849094049688e-13,
+    -6.423305872147841e-13,
+    -2.382191739347918e-13,
+  }
+};
+
+#define tantab_l (win[SHORT_TYPE]+3)
+#define cx (win[SHORT_TYPE]+12)
+#define ca (win[SHORT_TYPE]+20)
+#define cs (win[SHORT_TYPE]+28)
+
+/************************************************************************
+*
+* window_subband()
+*
+* PURPOSE:  Overlapping window on PCM samples
+*
+* SEMANTICS:
+* 32 16-bit pcm samples are scaled to fractional 2's complement and
+* concatenated to the end of the window buffer #x#. The updated window
+* buffer #x# is then windowed by the analysis window #c# to produce the
+* windowed sample #z#
+*
+************************************************************************/
+
+/*
+ *      new IDCT routine written by Takehiro TOMINAGA
+ */
+static const int order[] = {
+  0, 1,16,17, 8, 9,24,25, 4, 5,20,21,12,13,28,29,
+  2, 3,18,19,10,11,26,27, 6, 7,22,23,14,15,30,31
+};
+
+
+/* returns sum_j=0^31 a[j]*cos(PI*j*(k+1/2)/32), 0<=k<32 */
+INLINE static void
+window_subband(const sample_t *x1, FLOAT8 a[SBLIMIT])
+{
+    int i;
+    FLOAT8 const *wp = enwindow+10;
+
+    const sample_t *x2 = &x1[238-14-286];
+
+    for (i = -15; i < 0; i++) {
+       FLOAT8 w, s, t;
+
+       w = wp[-10]; s = x2[-224] * w; t  = x1[ 224] * w;
+       w = wp[-9]; s += x2[-160] * w; t += x1[ 160] * w;
+       w = wp[-8]; s += x2[- 96] * w; t += x1[  96] * w;
+       w = wp[-7]; s += x2[- 32] * w; t += x1[  32] * w;
+       w = wp[-6]; s += x2[  32] * w; t += x1[- 32] * w;
+       w = wp[-5]; s += x2[  96] * w; t += x1[- 96] * w;
+       w = wp[-4]; s += x2[ 160] * w; t += x1[-160] * w;
+       w = wp[-3]; s += x2[ 224] * w; t += x1[-224] * w;
+
+       w = wp[-2]; s += x1[-256] * w; t -= x2[ 256] * w;
+       w = wp[-1]; s += x1[-192] * w; t -= x2[ 192] * w;
+       w = wp[ 0]; s += x1[-128] * w; t -= x2[ 128] * w;
+       w = wp[ 1]; s += x1[- 64] * w; t -= x2[  64] * w;
+       w = wp[ 2]; s += x1[   0] * w; t -= x2[   0] * w;
+       w = wp[ 3]; s += x1[  64] * w; t -= x2[- 64] * w;
+       w = wp[ 4]; s += x1[ 128] * w; t -= x2[-128] * w;
+       w = wp[ 5]; s += x1[ 192] * w; t -= x2[-192] * w;
+
+       /*
+        * this multiplyer could be removed, but it needs more 256 FLOAT data.
+        * thinking about the data cache performance, I think we should not
+        * use such a huge table. tt 2000/Oct/25
+        */
+       s *= wp[6];
+       w = t - s;
+       a[30+i*2] = t + s;
+       a[31+i*2] = wp[7] * w;
+       wp += 18;
+       x1--;
+       x2++;
+    }
+    {
+       FLOAT8 s,t,u,v;
+       t  =  x1[- 16] * wp[-10];              s  = x1[ -32] * wp[-2];
+       t += (x1[- 48] - x1[ 16]) * wp[-9];    s += x1[ -96] * wp[-1];
+       t += (x1[- 80] + x1[ 48]) * wp[-8];    s += x1[-160] * wp[ 0];
+       t += (x1[-112] - x1[ 80]) * wp[-7];    s += x1[-224] * wp[ 1];
+       t += (x1[-144] + x1[112]) * wp[-6];    s -= x1[  32] * wp[ 2];
+       t += (x1[-176] - x1[144]) * wp[-5];    s -= x1[  96] * wp[ 3];
+       t += (x1[-208] + x1[176]) * wp[-4];    s -= x1[ 160] * wp[ 4];
+       t += (x1[-240] - x1[208]) * wp[-3];    s -= x1[ 224];
+
+       u = s - t;
+       v = s + t;
+
+       t = a[14];
+       s = a[15] - t;
+
+       a[31] = v + t;   // A0
+       a[30] = u + s;   // A1
+       a[15] = u - s;   // A2
+       a[14] = v - t;   // A3
+    }
+{
+    FLOAT8 xr;
+    xr = a[28] - a[ 0]; a[ 0] += a[28]; a[28] = xr * wp[-2*18+7];
+    xr = a[29] - a[ 1]; a[ 1] += a[29]; a[29] = xr * wp[-2*18+7];
+
+    xr = a[26] - a[ 2]; a[ 2] += a[26]; a[26] = xr * wp[-4*18+7];
+    xr = a[27] - a[ 3]; a[ 3] += a[27]; a[27] = xr * wp[-4*18+7];
+
+    xr = a[24] - a[ 4]; a[ 4] += a[24]; a[24] = xr * wp[-6*18+7];
+    xr = a[25] - a[ 5]; a[ 5] += a[25]; a[25] = xr * wp[-6*18+7];
+
+    xr = a[22] - a[ 6]; a[ 6] += a[22]; a[22] = xr * SQRT2;
+    xr = a[23] - a[ 7]; a[ 7] += a[23]; a[23] = xr * SQRT2 - a[ 7];
+    a[ 7] -= a[ 6];
+    a[22] -= a[ 7];
+    a[23] -= a[22];
+
+    xr = a[ 6]; a[ 6] = a[31] - xr; a[31] = a[31] + xr;
+    xr = a[ 7]; a[ 7] = a[30] - xr; a[30] = a[30] + xr;
+    xr = a[22]; a[22] = a[15] - xr; a[15] = a[15] + xr;
+    xr = a[23]; a[23] = a[14] - xr; a[14] = a[14] + xr;
+
+    xr = a[20] - a[ 8]; a[ 8] += a[20]; a[20] = xr * wp[-10*18+7];
+    xr = a[21] - a[ 9]; a[ 9] += a[21]; a[21] = xr * wp[-10*18+7];
+
+    xr = a[18] - a[10]; a[10] += a[18]; a[18] = xr * wp[-12*18+7];
+    xr = a[19] - a[11]; a[11] += a[19]; a[19] = xr * wp[-12*18+7];
+
+    xr = a[16] - a[12]; a[12] += a[16]; a[16] = xr * wp[-14*18+7];
+    xr = a[17] - a[13]; a[13] += a[17]; a[17] = xr * wp[-14*18+7];
+
+    xr = -a[20] + a[24]; a[20] += a[24]; a[24] = xr * wp[-12*18+7];
+    xr = -a[21] + a[25]; a[21] += a[25]; a[25] = xr * wp[-12*18+7];
+
+    xr = a[ 4] - a[ 8]; a[ 4] += a[ 8]; a[ 8] = xr * wp[-12*18+7];
+    xr = a[ 5] - a[ 9]; a[ 5] += a[ 9]; a[ 9] = xr * wp[-12*18+7];
+
+    xr = a[ 0] - a[12]; a[ 0] += a[12]; a[12] = xr * wp[-4*18+7];
+    xr = a[ 1] - a[13]; a[ 1] += a[13]; a[13] = xr * wp[-4*18+7];
+    xr = a[16] - a[28]; a[16] += a[28]; a[28] = xr * wp[-4*18+7];
+    xr = -a[17] + a[29]; a[17] += a[29]; a[29] = xr * wp[-4*18+7];
+
+    xr = SQRT2 * (a[ 2] - a[10]); a[ 2] += a[10]; a[10] = xr;
+    xr = SQRT2 * (a[ 3] - a[11]); a[ 3] += a[11]; a[11] = xr;
+    xr = SQRT2 * (-a[18] + a[26]); a[18] += a[26]; a[26] = xr - a[18];
+    xr = SQRT2 * (-a[19] + a[27]); a[19] += a[27]; a[27] = xr - a[19];
+
+    xr = a[ 2]; a[19] -= a[ 3]; a[ 3] -= xr; a[ 2] = a[31] - xr; a[31] += xr;
+    xr = a[ 3]; a[11] -= a[19]; a[18] -= xr; a[ 3] = a[30] - xr; a[30] += xr;
+    xr = a[18]; a[27] -= a[11]; a[19] -= xr; a[18] = a[15] - xr; a[15] += xr;
+
+    xr = a[19]; a[10] -= xr; a[19] = a[14] - xr; a[14] += xr;
+    xr = a[10]; a[11] -= xr; a[10] = a[23] - xr; a[23] += xr;
+    xr = a[11]; a[26] -= xr; a[11] = a[22] - xr; a[22] += xr;
+    xr = a[26]; a[27] -= xr; a[26] = a[ 7] - xr; a[ 7] += xr;
+
+    xr = a[27]; a[27] = a[ 6] - xr; a[ 6] += xr;
+
+    xr = SQRT2 * (a[ 0] - a[ 4]); a[ 0] += a[ 4]; a[ 4] = xr;
+    xr = SQRT2 * (a[ 1] - a[ 5]); a[ 1] += a[ 5]; a[ 5] = xr;
+    xr = SQRT2 * (a[16] - a[20]); a[16] += a[20]; a[20] = xr;
+    xr = SQRT2 * (a[17] - a[21]); a[17] += a[21]; a[21] = xr;
+
+    xr = -SQRT2 * (a[ 8] - a[12]); a[ 8] += a[12]; a[12] = xr - a[ 8];
+    xr = -SQRT2 * (a[ 9] - a[13]); a[ 9] += a[13]; a[13] = xr - a[ 9];
+    xr = -SQRT2 * (a[25] - a[29]); a[25] += a[29]; a[29] = xr - a[25];
+    xr = -SQRT2 * (a[24] + a[28]); a[24] -= a[28]; a[28] = xr - a[24];
+
+    xr = a[24] - a[16]; a[24] = xr;
+    xr = a[20] - xr;    a[20] = xr;
+    xr = a[28] - xr;    a[28] = xr;
+
+    xr = a[25] - a[17]; a[25] = xr;
+    xr = a[21] - xr;    a[21] = xr;
+    xr = a[29] - xr;    a[29] = xr;
+
+    xr = a[17] - a[ 1]; a[17] = xr;
+    xr = a[ 9] - xr;    a[ 9] = xr;
+    xr = a[25] - xr;    a[25] = xr;
+    xr = a[ 5] - xr;    a[ 5] = xr;
+    xr = a[21] - xr;    a[21] = xr;
+    xr = a[13] - xr;    a[13] = xr;
+    xr = a[29] - xr;    a[29] = xr;
+
+    xr = a[ 1] - a[ 0]; a[ 1] = xr;
+    xr = a[16] - xr;    a[16] = xr;
+    xr = a[17] - xr;    a[17] = xr;
+    xr = a[ 8] - xr;    a[ 8] = xr;
+    xr = a[ 9] - xr;    a[ 9] = xr;
+    xr = a[24] - xr;    a[24] = xr;
+    xr = a[25] - xr;    a[25] = xr;
+    xr = a[ 4] - xr;    a[ 4] = xr;
+    xr = a[ 5] - xr;    a[ 5] = xr;
+    xr = a[20] - xr;    a[20] = xr;
+    xr = a[21] - xr;    a[21] = xr;
+    xr = a[12] - xr;    a[12] = xr;
+    xr = a[13] - xr;    a[13] = xr;
+    xr = a[28] - xr;    a[28] = xr;
+    xr = a[29] - xr;    a[29] = xr;
+
+    xr = a[ 0]; a[ 0] += a[31]; a[31] -= xr;
+    xr = a[ 1]; a[ 1] += a[30]; a[30] -= xr;
+    xr = a[16]; a[16] += a[15]; a[15] -= xr;
+    xr = a[17]; a[17] += a[14]; a[14] -= xr;
+    xr = a[ 8]; a[ 8] += a[23]; a[23] -= xr;
+    xr = a[ 9]; a[ 9] += a[22]; a[22] -= xr;
+    xr = a[24]; a[24] += a[ 7]; a[ 7] -= xr;
+    xr = a[25]; a[25] += a[ 6]; a[ 6] -= xr;
+    xr = a[ 4]; a[ 4] += a[27]; a[27] -= xr;
+    xr = a[ 5]; a[ 5] += a[26]; a[26] -= xr;
+    xr = a[20]; a[20] += a[11]; a[11] -= xr;
+    xr = a[21]; a[21] += a[10]; a[10] -= xr;
+    xr = a[12]; a[12] += a[19]; a[19] -= xr;
+    xr = a[13]; a[13] += a[18]; a[18] -= xr;
+    xr = a[28]; a[28] += a[ 3]; a[ 3] -= xr;
+    xr = a[29]; a[29] += a[ 2]; a[ 2] -= xr;
+}
+
+}
+
+
+/*-------------------------------------------------------------------*/
+/*                                                                   */
+/*   Function: Calculation of the MDCT                               */
+/*   In the case of long blocks (type 0,1,3) there are               */
+/*   36 coefficents in the time domain and 18 in the frequency       */
+/*   domain.                                                         */
+/*   In the case of short blocks (type 2) there are 3                */
+/*   transformations with short length. This leads to 12 coefficents */
+/*   in the time and 6 in the frequency domain. In this case the     */
+/*   results are stored side by side in the vector out[].            */
+/*                                                                   */
+/*   New layer3                                                      */
+/*                                                                   */
+/*-------------------------------------------------------------------*/
+
+inline static void mdct_short(FLOAT8 *inout)
+{
+    int l;
+    for ( l = 0; l < 3; l++ ) {
+       FLOAT8 tc0,tc1,tc2,ts0,ts1,ts2;
+
+       ts0 = inout[2*3] * win[SHORT_TYPE][0] - inout[5*3];
+       tc0 = inout[0*3] * win[SHORT_TYPE][2] - inout[3*3];
+       tc1 = ts0 + tc0;
+       tc2 = ts0 - tc0;
+
+       ts0 = inout[5*3] * win[SHORT_TYPE][0] + inout[2*3];
+       tc0 = inout[3*3] * win[SHORT_TYPE][2] + inout[0*3];
+       ts1 = ts0 + tc0;
+       ts2 = -ts0 + tc0;
+
+       tc0 = (inout[1*3] * win[SHORT_TYPE][1] - inout[4*3]) * 2.069978111953089e-11; /* tritab_s[1] */
+       ts0 = (inout[4*3] * win[SHORT_TYPE][1] + inout[1*3]) * 2.069978111953089e-11; /* tritab_s[1] */
+
+       inout[3*0] = tc1 * 1.907525191737280e-11 /* tritab_s[2] */ + tc0;
+       inout[3*5] = -ts1 * 1.907525191737280e-11 /* tritab_s[0] */ + ts0;
+
+       tc2 = tc2 * 0.86602540378443870761 * 1.907525191737281e-11 /* tritab_s[2] */;
+       ts1 = ts1 * 0.5 * 1.907525191737281e-11 + ts0;
+       inout[3*1] = tc2-ts1;
+       inout[3*2] = tc2+ts1;
+
+       tc1 = tc1 * 0.5 * 1.907525191737281e-11 - tc0;
+       ts2 = ts2 * 0.86602540378443870761 * 1.907525191737281e-11 /* tritab_s[0] */;
+       inout[3*3] = tc1+ts2;
+       inout[3*4] = tc1-ts2;
+
+       inout++;
+    }
+}
+
+inline static void mdct_long(FLOAT8 *out, FLOAT8 *in)
+{
+    FLOAT8 ct,st;
+  {
+    FLOAT8 tc1, tc2, tc3, tc4, ts5, ts6, ts7, ts8;
+    // 1,2, 5,6, 9,10, 13,14, 17
+    tc1 = in[17]-in[ 9];
+    tc3 = in[15]-in[11];
+    tc4 = in[14]-in[12];
+    ts5 = in[ 0]+in[ 8];
+    ts6 = in[ 1]+in[ 7];
+    ts7 = in[ 2]+in[ 6];
+    ts8 = in[ 3]+in[ 5];
+
+    out[17] = (ts5+ts7-ts8)-(ts6-in[4]);
+    st = (ts5+ts7-ts8)*cx[7]+(ts6-in[4]);
+    ct = (tc1-tc3-tc4)*cx[6];
+    out[5] = ct+st;
+    out[6] = ct-st;
+
+    tc2 = (in[16]-in[10])*cx[6];
+    ts6 = ts6*cx[7] + in[4];
+    ct =  tc1*cx[0] + tc2 + tc3*cx[1] + tc4*cx[2];
+    st = -ts5*cx[4] + ts6 - ts7*cx[5] + ts8*cx[3];
+    out[1] = ct+st;
+    out[2] = ct-st;
+
+    ct =  tc1*cx[1] - tc2 - tc3*cx[2] + tc4*cx[0];
+    st = -ts5*cx[5] + ts6 - ts7*cx[3] + ts8*cx[4];
+    out[ 9] = ct+st;
+    out[10] = ct-st;
+
+    ct = tc1*cx[2] - tc2 + tc3*cx[0] - tc4*cx[1];
+    st = ts5*cx[3] - ts6 + ts7*cx[4] - ts8*cx[5];
+    out[13] = ct+st;
+    out[14] = ct-st;
+  }
+  {
+    FLOAT8 ts1, ts2, ts3, ts4, tc5, tc6, tc7, tc8;
+
+    ts1 = in[ 8]-in[ 0];
+    ts3 = in[ 6]-in[ 2];
+    ts4 = in[ 5]-in[ 3];
+    tc5 = in[17]+in[ 9];
+    tc6 = in[16]+in[10];
+    tc7 = in[15]+in[11];
+    tc8 = in[14]+in[12];
+
+    out[0]  = (tc5+tc7+tc8)+(tc6+in[13]);
+    ct = (tc5+tc7+tc8)*cx[7]-(tc6+in[13]);
+    st = (ts1-ts3+ts4)*cx[6];
+    out[11] = ct+st;
+    out[12] = ct-st;
+
+    ts2 = (in[7]-in[1])*cx[6];
+    tc6 = in[13] - tc6*cx[7];
+    ct = tc5*cx[3] - tc6 + tc7*cx[4] + tc8*cx[5];
+    st = ts1*cx[2] + ts2 + ts3*cx[0] + ts4*cx[1];
+    out[3] = ct+st;
+    out[4] = ct-st;
+
+    ct = -tc5*cx[5] + tc6 - tc7*cx[3] - tc8*cx[4];
+    st =  ts1*cx[1] + ts2 - ts3*cx[2] - ts4*cx[0];
+    out[7] = ct+st;
+    out[8] = ct-st;
+
+    ct = -tc5*cx[4] + tc6 - tc7*cx[5] - tc8*cx[3];
+    st =  ts1*cx[0] - ts2 + ts3*cx[1] - ts4*cx[2];
+    out[15] = ct+st;
+    out[16] = ct-st;
+  }
+}
+
+
+void mdct_sub48( lame_internal_flags *gfc, const sample_t *w0, const sample_t *w1, 
+                 FLOAT8 mdct_freq[2][2][576] )
+{
+    int gr, k, ch;
+    const sample_t *wk;
+
+    wk = w0 + 286;
+    /* thinking cache performance, ch->gr loop is better than gr->ch loop */
+    for (ch = 0; ch < gfc->channels_out; ch++) {
+       for (gr = 0; gr < gfc->mode_gr; gr++) {
+           int band;
+           FLOAT8 *mdct_enc = &mdct_freq[gr][ch][0];
+           gr_info *gi = &(gfc->l3_side.gr[gr].ch[ch].tt);
+           FLOAT8 *samp = gfc->sb_sample[ch][1 - gr][0];
+
+           for (k = 0; k < 18 / 2; k++) {
+               window_subband(wk, samp);
+               window_subband(wk + 32, samp + 32);
+               samp += 64;
+               wk += 64;
+               /*
+                * Compensate for inversion in the analysis filter
+                */
+               for (band = 1; band < 32; band+=2) {
+                   samp[band-32] *= -1;
+               }
+           }
+
+
+           /* apply filters on the polyphase filterbank outputs */
+           /* bands <= gfc->highpass_band will be zeroed out below */
+           /* bands >= gfc->lowpass_band  will be zeroed out below */
+           if (gfc->filter_type==0) {
+              for (band=gfc->highpass_start_band;  band <= gfc->highpass_end_band; band++) { 
+                 for (k=0; k<18; k++) 
+                   gfc->sb_sample[ch][1-gr][k][order[band]]*=gfc->amp_highpass[band];
+             }
+              for (band=gfc->lowpass_start_band;  band <= gfc->lowpass_end_band; band++) { 
+                 for (k=0; k<18; k++) 
+                   gfc->sb_sample[ch][1-gr][k][order[band]]*=gfc->amp_lowpass[band];
+             }
+           }
+           
+
+
+           /*
+            * Perform imdct of 18 previous subband samples
+            * + 18 current subband samples
+            */
+           for (band = 0; band < 32; band++, mdct_enc += 18) {
+               int type = gi->block_type;
+               FLOAT8 *band0, *band1;
+               band0 = gfc->sb_sample[ch][  gr][0] + order[band];
+               band1 = gfc->sb_sample[ch][1-gr][0] + order[band];
+               if (gi->mixed_block_flag && band < 2)
+                   type = 0;
+               if (band >= gfc->lowpass_band || band <= gfc->highpass_band) {
+                   memset((char *)mdct_enc,0,18*sizeof(FLOAT8));
+               } else {
+                 if (type == SHORT_TYPE) {
+                   for (k = -NS/4; k < 0; k++) {
+                       FLOAT8 w = win[SHORT_TYPE][k+3];
+                       mdct_enc[k*3+ 9] = band0[( 9+k)*32] * w - band0[( 8-k)*32];
+                       mdct_enc[k*3+18] = band0[(14-k)*32] * w + band0[(15+k)*32];
+                       mdct_enc[k*3+10] = band0[(15+k)*32] * w - band0[(14-k)*32];
+                       mdct_enc[k*3+19] = band1[( 2-k)*32] * w + band1[( 3+k)*32];
+                       mdct_enc[k*3+11] = band1[( 3+k)*32] * w - band1[( 2-k)*32];
+                       mdct_enc[k*3+20] = band1[( 8-k)*32] * w + band1[( 9+k)*32];
+                   }
+                   mdct_short(mdct_enc);
+                 } else {
+                   FLOAT8 work[18];
+                   for (k = -NL/4; k < 0; k++) {
+                       FLOAT8 a, b;
+                       a = win[type][k+27] * band1[(k+9)*32]
+                         + win[type][k+36] * band1[(8-k)*32];
+                       b = win[type][k+ 9] * band0[(k+9)*32]
+                         - win[type][k+18] * band0[(8-k)*32];
+                       work[k+ 9] = a - b*tantab_l[k+9];
+                       work[k+18] = a*tantab_l[k+9] + b;
+                   }
+
+                   mdct_long(mdct_enc, work);
+                 }
+               }
+               /*
+                * Perform aliasing reduction butterfly
+                */
+               if (type != SHORT_TYPE) {
+                 if (band == 0)
+                   continue;
+                 for (k = 7; k >= 0; --k) {
+                   FLOAT8 bu,bd;
+                   bu = mdct_enc[k] * ca[k] + mdct_enc[-1-k] * cs[k];
+                   bd = mdct_enc[k] * cs[k] - mdct_enc[-1-k] * ca[k];
+                   
+                   mdct_enc[-1-k] = bu;
+                   mdct_enc[k]    = bd;
+                 }
+               }
+             }
+       }
+       wk = w1 + 286;
+       if (gfc->mode_gr == 1) {
+           memcpy(gfc->sb_sample[ch][0], gfc->sb_sample[ch][1], 576 * sizeof(FLOAT8));
+       }
+    }
+}
diff --git a/lib/lame/newmdct.h b/lib/lame/newmdct.h
new file mode 100644 (file)
index 0000000..14344f7
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *     New Modified DCT include file
+ *
+ *     Copyright (c) 1999 Takehiro TOMINAGA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_NEWMDCT_H
+#define LAME_NEWMDCT_H
+
+void mdct_sub48(lame_internal_flags *gfc,const sample_t *w0, const sample_t *w1,
+               FLOAT8 mdct_freq[2][2][576]);
+
+#endif /* LAME_NEWMDCT_H */
diff --git a/lib/lame/psymodel.c b/lib/lame/psymodel.c
new file mode 100644 (file)
index 0000000..b4c770e
--- /dev/null
@@ -0,0 +1,2538 @@
+/*
+ *     psymodel.c
+ *
+ *     Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: psymodel.c,v 1.1 2002/04/28 17:30:23 kramm Exp $ */
+
+
+/*
+PSYCHO ACOUSTICS
+
+
+This routine computes the psycho acoustics, delayed by
+one granule.  
+
+Input: buffer of PCM data (1024 samples).  
+
+This window should be centered over the 576 sample granule window.
+The routine will compute the psycho acoustics for
+this granule, but return the psycho acoustics computed
+for the *previous* granule.  This is because the block
+type of the previous granule can only be determined
+after we have computed the psycho acoustics for the following
+granule.  
+
+Output:  maskings and energies for each scalefactor band.
+block type, PE, and some correlation measures.  
+The PE is used by CBR modes to determine if extra bits
+from the bit reservoir should be used.  The correlation
+measures are used to determine mid/side or regular stereo.
+
+
+Notation:
+
+barks:  a non-linear frequency scale.  Mapping from frequency to
+        barks is given by freq2bark()
+
+scalefactor bands: The spectrum (frequencies) are broken into 
+                   SBMAX "scalefactor bands".  Thes bands
+                   are determined by the MPEG ISO spec.  In
+                   the noise shaping/quantization code, we allocate
+                   bits among the partition bands to achieve the
+                   best possible quality
+
+partition bands:   The spectrum is also broken into about
+                   64 "partition bands".  Each partition 
+                   band is about .34 barks wide.  There are about 2-5
+                   partition bands for each scalefactor band.
+
+LAME computes all psycho acoustic information for each partition
+band.  Then at the end of the computations, this information
+is mapped to scalefactor bands.  The energy in each scalefactor
+band is taken as the sum of the energy in all partition bands
+which overlap the scalefactor band.  The maskings can be computed
+in the same way (and thus represent the average masking in that band)
+or by taking the minmum value multiplied by the number of
+partition bands used (which represents a minimum masking in that band).
+
+
+The general outline is as follows:
+
+
+1. compute the energy in each partition band
+2. compute the tonality in each partition band
+3. compute the strength of each partion band "masker"
+4. compute the masking (via the spreading function applied to each masker)
+5. Modifications for mid/side masking.  
+
+Each partition band is considiered a "masker".  The strength
+of the i'th masker in band j is given by:
+
+    s3(bark(i)-bark(j))*strength(i)
+
+The strength of the masker is a function of the energy and tonality.
+The more tonal, the less masking.  LAME uses a simple linear formula
+(controlled by NMT and TMN) which says the strength is given by the
+energy divided by a linear function of the tonality.
+
+
+s3() is the "spreading function".  It is given by a formula
+determined via listening tests.  
+
+The total masking in the j'th partition band is the sum over
+all maskings i.  It is thus given by the convolution of
+the strength with s3(), the "spreading function."
+
+masking(j) = sum_over_i  s3(i-j)*strength(i)  = s3 o strength
+
+where "o" = convolution operator.  s3 is given by a formula determined
+via listening tests.  It is normalized so that s3 o 1 = 1.
+
+Note: instead of a simple convolution, LAME also has the
+option of using "additive masking"
+
+The most critical part is step 2, computing the tonality of each
+partition band.  LAME has two tonality estimators.  The first
+is based on the ISO spec, and measures how predictiable the
+signal is over time.  The more predictable, the more tonal.
+The second measure is based on looking at the spectrum of
+a single granule.  The more peaky the spectrum, the more
+tonal.  By most indications, the latter approach is better.
+
+Finally, in step 5, the maskings for the mid and side
+channel are possibly increased.  Under certain circumstances,
+noise in the mid & side channels is assumed to also
+be masked by strong maskers in the L or R channels.
+
+
+Other data computed by the psy-model:
+
+ms_ratio        side-channel / mid-channel masking ratio (for previous granule)
+ms_ratio_next   side-channel / mid-channel masking ratio for this granule
+
+percep_entropy[2]     L and R values (prev granule) of PE - A measure of how 
+                      much pre-echo is in the previous granule
+percep_entropy_MS[2]  mid and side channel values (prev granule) of percep_entropy
+energy[4]             L,R,M,S energy in each channel, prev granule
+blocktype_d[2]        block type to use for previous granule
+
+
+*/
+
+
+
+
+#include "config_static.h"
+
+#include "util.h"
+#include "encoder.h"
+#include "psymodel.h"
+#include "l3side.h"
+#include <assert.h>
+#include "tables.h"
+#include "fft.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#define NSFIRLEN 21
+#define rpelev 2
+#define rpelev2 16
+#define rpelev_s 2
+#define rpelev2_s 16
+
+/* size of each partition band, in barks: */
+#define DELBARK .34
+
+
+#if 1
+    /* AAC values, results in more masking over MP3 values */
+# define TMN 18
+# define NMT 6
+#else
+    /* MP3 values */
+# define TMN 29
+# define NMT 6
+#endif
+
+#define NBPSY_l  (SBMAX_l)
+#define NBPSY_s  (SBMAX_s)
+
+
+#ifdef M_LN10
+#define                LN_TO_LOG10             (M_LN10/10)
+#else
+#define         LN_TO_LOG10             0.2302585093
+#endif
+
+FLOAT
+psycho_loudness_approx( FLOAT *energy, lame_global_flags *gfp );
+
+
+
+
+
+/*
+   L3psycho_anal.  Compute psycho acoustics.
+
+   Data returned to the calling program must be delayed by one 
+   granule. 
+
+   This is done in two places.  
+   If we do not need to know the blocktype, the copying
+   can be done here at the top of the program: we copy the data for
+   the last granule (computed during the last call) before it is
+   overwritten with the new data.  It looks like this:
+  
+   0. static psymodel_data 
+   1. calling_program_data = psymodel_data
+   2. compute psymodel_data
+    
+   For data which needs to know the blocktype, the copying must be
+   done at the end of this loop, and the old values must be saved:
+   
+   0. static psymodel_data_old 
+   1. compute psymodel_data
+   2. compute possible block type of this granule
+   3. compute final block type of previous granule based on #2.
+   4. calling_program_data = psymodel_data_old
+   5. psymodel_data_old = psymodel_data
+*/
+int L3psycho_anal( lame_global_flags * gfp,
+                    const sample_t *buffer[2], int gr_out, 
+                    FLOAT8 *ms_ratio,
+                    FLOAT8 *ms_ratio_next,
+                   III_psy_ratio masking_ratio[2][2],
+                   III_psy_ratio masking_MS_ratio[2][2],
+                   FLOAT8 percep_entropy[2],FLOAT8 percep_MS_entropy[2], 
+                    FLOAT8 energy[4],
+                    int blocktype_d[2])
+{
+/* to get a good cache performance, one has to think about
+ * the sequence, in which the variables are used.  
+ * (Note: these static variables have been moved to the gfc-> struct,
+ * and their order in memory is layed out in util.h)
+ */
+  lame_internal_flags *gfc=gfp->internal_flags;
+
+
+  /* fft and energy calculation   */
+  FLOAT (*wsamp_l)[BLKSIZE];
+  FLOAT (*wsamp_s)[3][BLKSIZE_s];
+
+  /* convolution   */
+  FLOAT8 eb[CBANDS];
+  FLOAT8 cb[CBANDS];
+  FLOAT8 thr[CBANDS];
+  
+  /* ratios    */
+  FLOAT8 ms_ratio_l=0,ms_ratio_s=0;
+
+  /* block type  */
+  int blocktype[2],uselongblock[2];
+  
+  /* usual variables like loop indices, etc..    */
+  int numchn, chn;
+  int   b, i, j, k;
+  int  sb,sblock;
+
+
+  if(gfc->psymodel_init==0) {
+      psymodel_init(gfp);
+      init_fft(gfc);
+      gfc->psymodel_init=1;
+      
+      for (chn = 0; chn < 4; ++chn )
+      for (b = 0; b < CBANDS; ++b ) 
+        gfc->nb_s1[chn][b] = gfc->nb_s2[chn][b] = 1.0;
+      
+  }
+  
+
+
+  
+  
+  numchn = gfc->channels_out;
+  /* chn=2 and 3 = Mid and Side channels */
+  if (gfp->mode == JOINT_STEREO) numchn=4;
+
+  for (chn=0; chn<numchn; chn++) {
+      for (i=0; i<numchn; ++i) {
+         energy[chn]=gfc->tot_ener[chn];
+      }
+  }
+  
+  for (chn=0; chn<numchn; chn++) {
+
+      /* there is a one granule delay.  Copy maskings computed last call
+       * into masking_ratio to return to calling program.
+       */
+      if (chn < 2) {    
+         /* LR maskings  */
+         percep_entropy            [chn]       = gfc -> pe  [chn]; 
+         masking_ratio    [gr_out] [chn]  .en  = gfc -> en  [chn];
+         masking_ratio    [gr_out] [chn]  .thm = gfc -> thm [chn];
+      } else {
+         /* MS maskings  */
+         percep_MS_entropy         [chn-2]     = gfc -> pe  [chn]; 
+         masking_MS_ratio [gr_out] [chn-2].en  = gfc -> en  [chn];
+         masking_MS_ratio [gr_out] [chn-2].thm = gfc -> thm [chn];
+      }
+      
+      
+
+    /**********************************************************************
+     *  compute FFTs
+     **********************************************************************/
+    wsamp_s = gfc->wsamp_S+(chn & 1);
+    wsamp_l = gfc->wsamp_L+(chn & 1);
+    if (chn<2) {    
+      fft_long ( gfc, *wsamp_l, chn, buffer);
+      fft_short( gfc, *wsamp_s, chn, buffer);
+    } 
+    /* FFT data for mid and side channel is derived from L & R */
+    if (chn == 2)
+      {
+        for (j = BLKSIZE-1; j >=0 ; --j)
+        {
+          FLOAT l = gfc->wsamp_L[0][j];
+          FLOAT r = gfc->wsamp_L[1][j];
+          gfc->wsamp_L[0][j] = (l+r)*(FLOAT)(SQRT2*0.5);
+          gfc->wsamp_L[1][j] = (l-r)*(FLOAT)(SQRT2*0.5);
+        }
+        for (b = 2; b >= 0; --b)
+        {
+          for (j = BLKSIZE_s-1; j >= 0 ; --j)
+          {
+            FLOAT l = gfc->wsamp_S[0][b][j];
+            FLOAT r = gfc->wsamp_S[1][b][j];
+            gfc->wsamp_S[0][b][j] = (l+r)*(FLOAT)(SQRT2*0.5);
+            gfc->wsamp_S[1][b][j] = (l-r)*(FLOAT)(SQRT2*0.5);
+          }
+        }
+      }
+
+
+    /**********************************************************************
+     *  compute energies
+     **********************************************************************/
+    
+    
+    
+    gfc->energy[0]  = (*wsamp_l)[0];
+    gfc->energy[0] *= gfc->energy[0];
+    
+    gfc->tot_ener[chn] = gfc->energy[0]; /* sum total energy at nearly no extra cost */
+    
+    for (j=BLKSIZE/2-1; j >= 0; --j)
+    {
+      FLOAT re = (*wsamp_l)[BLKSIZE/2-j];
+      FLOAT im = (*wsamp_l)[BLKSIZE/2+j];
+      gfc->energy[BLKSIZE/2-j] = (re * re + im * im) * (FLOAT)0.5;
+
+      if (BLKSIZE/2-j > 10)
+       gfc->tot_ener[chn] += gfc->energy[BLKSIZE/2-j];
+    }
+    for (b = 2; b >= 0; --b)
+    {
+      gfc->energy_s[b][0]  = (*wsamp_s)[b][0];
+      gfc->energy_s[b][0] *=  gfc->energy_s [b][0];
+      for (j=BLKSIZE_s/2-1; j >= 0; --j)
+      {
+        FLOAT re = (*wsamp_s)[b][BLKSIZE_s/2-j];
+        FLOAT im = (*wsamp_s)[b][BLKSIZE_s/2+j];
+        gfc->energy_s[b][BLKSIZE_s/2-j] = (re * re + im * im) * (FLOAT)0.5;
+      }
+    }
+
+#if defined(HAVE_GTK)
+    if (gfp->analysis) {
+      for (j=0; j<HBLKSIZE ; j++) {
+        gfc->pinfo->energy[gr_out][chn][j]=gfc->energy_save[chn][j];
+        gfc->energy_save[chn][j]=gfc->energy[j];
+      }
+    }
+#endif
+
+
+
+    /**********************************************************************
+     * compute loudness approximation (used for ATH auto-level adjustment) 
+     **********************************************************************/
+    if( gfp->athaa_loudapprox == 2 ) {
+      if( chn < 2 ) {          /* no loudness for mid and side channels */
+       gfc->loudness_sq[gr_out][chn] = gfc->loudness_sq_save[chn];
+       gfc->loudness_sq_save[chn]
+         = psycho_loudness_approx( gfc->energy, gfp);
+      }
+    }
+
+
+
+    /**********************************************************************
+     *    compute unpredicatability of first six spectral lines            * 
+     **********************************************************************/
+    for ( j = 0; j < gfc->cw_lower_index; j++ )
+      {         /* calculate unpredictability measure cw */
+       FLOAT an, a1, a2;
+       FLOAT bn, b1, b2;
+       FLOAT rn, r1, r2;
+       FLOAT numre, numim, den;
+
+       a2 = gfc-> ax_sav[chn][1][j];
+       b2 = gfc-> bx_sav[chn][1][j];
+       r2 = gfc-> rx_sav[chn][1][j];
+       a1 = gfc-> ax_sav[chn][1][j] = gfc-> ax_sav[chn][0][j];
+       b1 = gfc-> bx_sav[chn][1][j] = gfc-> bx_sav[chn][0][j];
+       r1 = gfc-> rx_sav[chn][1][j] = gfc-> rx_sav[chn][0][j];
+       an = gfc-> ax_sav[chn][0][j] = (*wsamp_l)[j];
+       bn = gfc-> bx_sav[chn][0][j] = j==0 ? (*wsamp_l)[0] : (*wsamp_l)[BLKSIZE-j];  
+       rn = gfc-> rx_sav[chn][0][j] = sqrt(gfc->energy[j]);
+
+       { /* square (x1,y1) */
+         if( r1 != 0 ) {
+           numre = (a1*b1);
+           numim = (a1*a1-b1*b1)*(FLOAT)0.5;
+           den = r1*r1;
+         } else {
+           numre = 1;
+           numim = 0;
+           den = 1;
+         }
+       }
+       
+       { /* multiply by (x2,-y2) */
+         if( r2 != 0 ) {
+           FLOAT tmp2 = (numim+numre)*(a2+b2)*(FLOAT)0.5;
+           FLOAT tmp1 = -a2*numre+tmp2;
+           numre =       -b2*numim+tmp2;
+           numim = tmp1;
+           den *= r2;
+         } else {
+           /* do nothing */
+         }
+       }
+       
+       { /* r-prime factor */
+         FLOAT tmp = (2*r1-r2)/den;
+         numre *= tmp;
+         numim *= tmp;
+       }
+       den=rn+fabs(2*r1-r2);
+       if( den != 0 ) {
+         numre = (an+bn)*(FLOAT)0.5-numre;
+         numim = (an-bn)*(FLOAT)0.5-numim;
+         den = sqrt(numre*numre+numim*numim)/den;
+       }
+       gfc->cw[j] = den;
+      }
+
+
+
+    /**********************************************************************
+     *     compute unpredicatibility of next 200 spectral lines            *
+     **********************************************************************/ 
+    for ( j = gfc->cw_lower_index; j < gfc->cw_upper_index; j += 4 )
+      {/* calculate unpredictability measure cw */
+       FLOAT rn, r1, r2;
+       FLOAT numre, numim, den;
+       
+       k = (j+2) / 4; 
+       
+       { /* square (x1,y1) */
+         r1 = gfc->energy_s[0][k];
+         if( r1 != 0 ) {
+           FLOAT a1 = (*wsamp_s)[0][k]; 
+           FLOAT b1 = (*wsamp_s)[0][BLKSIZE_s-k]; /* k is never 0 */
+           numre = (a1*b1);
+           numim = (a1*a1-b1*b1)*(FLOAT)0.5;
+           den = r1;
+           r1 = sqrt(r1);
+         } else {
+           numre = 1;
+           numim = 0;
+           den = 1;
+         }
+       }
+       
+       
+       { /* multiply by (x2,-y2) */
+         r2 = gfc->energy_s[2][k];
+         if( r2 != 0 ) {
+           FLOAT a2 = (*wsamp_s)[2][k]; 
+           FLOAT b2 = (*wsamp_s)[2][BLKSIZE_s-k];
+           
+           
+           FLOAT tmp2 = (numim+numre)*(a2+b2)*(FLOAT)0.5;
+           FLOAT tmp1 = -a2*numre+tmp2;
+           numre =       -b2*numim+tmp2;
+           numim = tmp1;
+           
+           r2 = sqrt(r2);
+           den *= r2;
+         } else {
+           /* do nothing */
+         }
+       }
+       
+       { /* r-prime factor */
+         FLOAT tmp = (2*r1-r2)/den;
+         numre *= tmp;
+         numim *= tmp;
+       }
+       
+       rn = sqrt(gfc->energy_s[1][k]);
+       den=rn+fabs(2*r1-r2);
+       if( den != 0 ) {
+         FLOAT an = (*wsamp_s)[1][k]; 
+         FLOAT bn = (*wsamp_s)[1][BLKSIZE_s-k];
+         numre = (an+bn)*(FLOAT)0.5-numre;
+         numim = (an-bn)*(FLOAT)0.5-numim;
+         den = sqrt(numre*numre+numim*numim)/den;
+       }
+       
+       gfc->cw[j+1] = gfc->cw[j+2] = gfc->cw[j+3] = gfc->cw[j] = den;
+      }
+    
+#if 0
+    for ( j = 14; j < HBLKSIZE-4; j += 4 )
+      {/* calculate energy from short ffts */
+       FLOAT8 tot,ave;
+       k = (j+2) / 4; 
+       for (tot=0, sblock=0; sblock < 3; sblock++)
+         tot+=gfc->energy_s[sblock][k];
+       ave = gfc->energy[j+1]+ gfc->energy[j+2]+ gfc->energy[j+3]+ gfc->energy[j];
+       ave /= 4.;
+       gfc->energy[j+1] = gfc->energy[j+2] = gfc->energy[j+3] =  gfc->energy[j]=tot;
+      }
+#endif
+    
+    /**********************************************************************
+     *    Calculate the energy and the unpredictability in the threshold   *
+     *    calculation partitions                                           *
+     **********************************************************************/
+
+    b = 0;
+    for (j = 0; j < gfc->cw_upper_index && gfc->numlines_l[b] && b<gfc->npart_l_orig; )
+      {
+       FLOAT8 ebb, cbb;
+
+       ebb = gfc->energy[j];
+       cbb = gfc->energy[j] * gfc->cw[j];
+       j++;
+
+       for (i = gfc->numlines_l[b] - 1; i > 0; i--)
+         {
+           ebb += gfc->energy[j];
+           cbb += gfc->energy[j] * gfc->cw[j];
+           j++;
+         }
+       eb[b] = ebb;
+       cb[b] = cbb;
+       b++;
+      }
+
+    for (; b < gfc->npart_l_orig; b++ )
+      {
+       FLOAT8 ebb = gfc->energy[j++];
+       assert(gfc->numlines_l[b]);
+       for (i = gfc->numlines_l[b] - 1; i > 0; i--)
+         {
+           ebb += gfc->energy[j++];
+         }
+       eb[b] = ebb;
+       cb[b] = ebb * 0.4;
+      }
+
+    /**********************************************************************
+     *      convolve the partitioned energy and unpredictability          *
+     *      with the spreading function, s3_l[b][k](packed into s3_ll)    *
+     ******************************************************************** */
+    gfc->pe[chn] = 0;          /*  calculate percetual entropy */
+    {
+      int kk = 0;
+      for ( b = 0;b < gfc->npart_l; b++ )
+       {
+         FLOAT8 tbb,ecb,ctb;
+
+         ecb = 0;
+         ctb = 0;
+
+         for ( k = gfc->s3ind[b][0]; k <= gfc->s3ind[b][1]; k++ )
+           {
+             ecb += gfc->s3_ll[kk] * eb[k];    /* sprdngf for Layer III */
+             ctb += gfc->s3_ll[kk] * cb[k];
+             kk++;
+           }
+
+         /* calculate the tonality of each threshold calculation partition 
+          * calculate the SNR in each threshold calculation partition 
+          * tonality = -0.299 - .43*log(ctb/ecb);
+          * tonality = 0:           use NMT   (lots of masking)
+          * tonality = 1:           use TMN   (little masking)
+          */
+
+/* ISO values */
+#define CONV1 (-.299)
+#define CONV2 (-.43)
+
+         tbb = ecb;
+         if (tbb != 0)
+           {
+             tbb = ctb / tbb;
+             if (tbb <= exp((1-CONV1)/CONV2)) 
+               { /* tonality near 1 */
+                 tbb = exp(-LN_TO_LOG10 * TMN);
+               }
+             else if (tbb >= exp((0-CONV1)/CONV2)) 
+               {/* tonality near 0 */
+                 tbb = exp(-LN_TO_LOG10 * NMT);
+               }
+             else
+               {
+                 /* convert to tonality index */
+                 /* tonality small:   tbb=1 */
+                 /* tonality large:   tbb=-.299 */
+                 tbb = CONV1 + CONV2*log(tbb);
+                 tbb = exp(-LN_TO_LOG10 * ( TMN*tbb + (1-tbb)*NMT) );
+               }
+           }
+
+         /* at this point, tbb represents the amount the spreading function
+          * will be reduced.  The smaller the value, the less masking.
+          * minval[] = 1 (0db)     says just use tbb.
+          * minval[]= .01 (-20db)  says reduce spreading function by 
+          *                        at least 20db.  
+          */
+
+         tbb = Min(gfc->minval[b], tbb);
+          
+            /* stabilize tonality estimation */
+            if ( gfc->PSY->tonalityPatch ) {
+                if ( b > 5 ) 
+                {
+                    FLOAT8 const x = 1.8699422;
+                    FLOAT8 w = gfc->PSY->prvTonRed[b/2] * x;
+                    if (tbb > w) 
+                        tbb = w;
+                }
+                gfc->PSY->prvTonRed[b] = tbb;
+            }
+            
+         ecb *= tbb;
+
+         /* long block pre-echo control.   */
+         /* rpelev=2.0, rpelev2=16.0 */
+         /* note: all surges in PE are because of this pre-echo formula
+          * for thr[b].  If it this is not used, PE is always around 600
+          */
+         /* dont use long block pre-echo control if previous granule was 
+          * a short block.  This is to avoid the situation:   
+          * frame0:  quiet (very low masking)  
+          * frame1:  surge  (triggers short blocks)
+          * frame2:  regular frame.  looks like pre-echo when compared to 
+          *          frame0, but all pre-echo was in frame1.
+          */
+         /* chn=0,1   L and R channels
+            chn=2,3   S and M channels.  
+         */
+        
+            if (gfc->blocktype_old[chn>1 ? chn-2 : chn] == SHORT_TYPE )
+                thr[b] = ecb; /* Min(ecb, rpelev*gfc->nb_1[chn][b]); */
+            else
+                thr[b] = Min(ecb, Min(rpelev*gfc->nb_1[chn][b],rpelev2*gfc->nb_2[chn][b]) );
+                
+         {
+           FLOAT8 thrpe;
+           thrpe = Max(thr[b],gfc->ATH->cb[b]);
+           /*
+             printf("%i thr=%e   ATH=%e  \n",b,thr[b],gfc->ATH->cb[b]);
+           */
+           if (thrpe < eb[b])
+             gfc->pe[chn] -= gfc->numlines_l[b] * log(thrpe / eb[b]);
+         }
+          
+            if ( gfp->VBR == vbr_rh || gfp->VBR == vbr_mtrh ) {
+                thr[b] = Min(ecb, rpelev*gfc->nb_1[chn][b]);
+                if (gfc->blocktype_old[chn>1 ? chn-2 : chn] != SHORT_TYPE )
+                    thr[b] = Min(thr[b], rpelev2*gfc->nb_2[chn][b]);
+                thr[b] = Max( thr[b], 1e-37 );
+            }
+          
+          gfc->nb_2[chn][b] = gfc->nb_1[chn][b];
+         gfc->nb_1[chn][b] = ecb;
+       }
+    }
+
+    /*************************************************************** 
+     * determine the block type (window type) based on L & R channels
+     * 
+     ***************************************************************/
+    {  /* compute PE for all 4 channels */
+      FLOAT mn,mx,ma=0,mb=0,mc=0;
+      
+      for ( j = HBLKSIZE_s/2; j < HBLKSIZE_s; j ++)
+       {
+         ma += gfc->energy_s[0][j];
+         mb += gfc->energy_s[1][j];
+         mc += gfc->energy_s[2][j];
+       }
+      mn = Min(ma,mb);
+      mn = Min(mn,mc);
+      mx = Max(ma,mb);
+      mx = Max(mx,mc);
+      
+      /* bit allocation is based on pe.  */
+      if (mx>mn) {
+       FLOAT8 tmp = 400*log(mx/(1e-12+mn));
+       if (tmp>gfc->pe[chn]) gfc->pe[chn]=tmp;
+      }
+
+      /* block type is based just on L or R channel */      
+      if (chn<2) {
+       uselongblock[chn] = 1;
+       
+       /* tuned for t1.wav.  doesnt effect most other samples */
+       if (gfc->pe[chn] > 3000) 
+           uselongblock[chn]=0;
+       
+       if ( mx > 30*mn ) 
+         {/* big surge of energy - always use short blocks */
+           uselongblock[chn] = 0;
+         } 
+       else if ((mx > 10*mn) && (gfc->pe[chn] > 1000))
+         {/* medium surge, medium pe - use short blocks */
+           uselongblock[chn] = 0;
+         }
+       
+       /* disable short blocks */
+       if (gfp->short_blocks == short_block_dispensed)
+         uselongblock[chn]=1;
+       if (gfp->short_blocks == short_block_forced)
+         uselongblock[chn]=0;
+      }
+    }
+
+#if defined(HAVE_GTK)
+    if (gfp->analysis) {
+      FLOAT mn,mx,ma=0,mb=0,mc=0;
+
+      for ( j = HBLKSIZE_s/2; j < HBLKSIZE_s; j ++)
+      {
+        ma += gfc->energy_s[0][j];
+        mb += gfc->energy_s[1][j];
+        mc += gfc->energy_s[2][j];
+      }
+      mn = Min(ma,mb);
+      mn = Min(mn,mc);
+      mx = Max(ma,mb);
+      mx = Max(mx,mc);
+
+      gfc->pinfo->ers[gr_out][chn]=gfc->ers_save[chn];
+      gfc->ers_save[chn]=(mx/(1e-12+mn));
+      gfc->pinfo->pe[gr_out][chn]=gfc->pe_save[chn];
+      gfc->pe_save[chn]=gfc->pe[chn];
+    }
+#endif
+
+
+    /*************************************************************** 
+     * compute masking thresholds for both short and long blocks
+     ***************************************************************/
+    /* longblock threshold calculation (part 2) */
+    for ( sb = 0; sb < NBPSY_l; sb++ )
+      {
+       FLOAT8 enn = gfc->w1_l[sb] * eb[gfc->bu_l[sb]] + gfc->w2_l[sb] * eb[gfc->bo_l[sb]];
+       FLOAT8 thmm = gfc->w1_l[sb] *thr[gfc->bu_l[sb]] + gfc->w2_l[sb] * thr[gfc->bo_l[sb]];
+
+        for ( b = gfc->bu_l[sb]+1; b < gfc->bo_l[sb]; b++ )
+          {
+            enn  += eb[b];
+            thmm += thr[b];
+          }
+
+       gfc->en [chn].l[sb] = enn;
+       gfc->thm[chn].l[sb] = thmm;
+      }
+    
+
+    /* threshold calculation for short blocks */
+    for ( sblock = 0; sblock < 3; sblock++ )
+      {
+       j = 0;
+       for ( b = 0; b < gfc->npart_s_orig; b++ )
+         {
+           FLOAT ecb = gfc->energy_s[sblock][j++];
+           for (i = 1 ; i<gfc->numlines_s[b]; ++i)
+             {
+               ecb += gfc->energy_s[sblock][j++];
+             }
+           eb[b] = ecb;
+         }
+       {
+         int kk = 0;
+         for ( b = 0; b < gfc->npart_s; b++ )
+           {
+             FLOAT8 ecb = 0;
+             for ( k = gfc->s3ind_s[b][0]; k <= gfc->s3ind_s[b][1]; k++ ) {
+               ecb += gfc->s3_ss[kk++] * eb[k];
+             }
+             ecb *= gfc->SNR_s[b];
+
+/* 2001-07-13 */
+        if ( gfp->VBR == vbr_off || gfp->VBR == vbr_abr ) {
+            /* this looks like a BUG to me. robert */
+            thr[b] = Max (1e-6, ecb);
+        }
+        else {
+            thr[b] = Min( ecb, rpelev_s  * gfc->nb_s1[chn][b] );
+            if (gfc->blocktype_old[chn>1 ? chn-2 : chn] == SHORT_TYPE ) {
+                thr[b] = Min( thr[b], rpelev2_s * gfc->nb_s2[chn][b] );
+            }
+            thr[b] = Max( thr[b], 1e-37 );
+            gfc->nb_s2[chn][b] = gfc->nb_s1[chn][b];
+            gfc->nb_s1[chn][b] = ecb;
+        }
+        
+           }
+
+         for ( sb = 0; sb < NBPSY_s; sb++ )
+           {
+             FLOAT8 enn  = gfc->w1_s[sb] * eb[gfc->bu_s[sb]] + gfc->w2_s[sb] * eb[gfc->bo_s[sb]];
+             FLOAT8 thmm = gfc->w1_s[sb] *thr[gfc->bu_s[sb]] + gfc->w2_s[sb] * thr[gfc->bo_s[sb]];
+
+             for ( b = gfc->bu_s[sb]+1; b < gfc->bo_s[sb]; b++ ) {
+               enn  += eb[b];
+               thmm += thr[b];
+             }
+
+             gfc->en [chn].s[sb][sblock] = enn;
+             gfc->thm[chn].s[sb][sblock] = thmm;
+           }
+       }
+      }
+  } /* end loop over chn */
+
+
+
+  /*************************************************************** 
+   * compute M/S thresholds
+   ***************************************************************/
+  /* compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper */
+  if (gfp->mode == JOINT_STEREO) {
+    FLOAT8 rside,rmid,mld;
+    int chmid=2,chside=3; 
+    
+    for ( sb = 0; sb < NBPSY_l; sb++ ) {
+      /* use this fix if L & R masking differs by 2db or less */
+      /* if db = 10*log10(x2/x1) < 2 */
+      /* if (x2 < 1.58*x1) { */
+      if (gfc->thm[0].l[sb] <= 1.58*gfc->thm[1].l[sb]
+         && gfc->thm[1].l[sb] <= 1.58*gfc->thm[0].l[sb]) {
+
+       mld = gfc->mld_l[sb]*gfc->en[chside].l[sb];
+       rmid = Max(gfc->thm[chmid].l[sb], Min(gfc->thm[chside].l[sb],mld));
+
+       mld = gfc->mld_l[sb]*gfc->en[chmid].l[sb];
+       rside = Max(gfc->thm[chside].l[sb],Min(gfc->thm[chmid].l[sb],mld));
+
+       gfc->thm[chmid].l[sb]=rmid;
+       gfc->thm[chside].l[sb]=rside;
+      }
+    }
+    for ( sb = 0; sb < NBPSY_s; sb++ ) {
+      for ( sblock = 0; sblock < 3; sblock++ ) {
+       if (gfc->thm[0].s[sb][sblock] <= 1.58*gfc->thm[1].s[sb][sblock]
+           && gfc->thm[1].s[sb][sblock] <= 1.58*gfc->thm[0].s[sb][sblock]) {
+
+         mld = gfc->mld_s[sb]*gfc->en[chside].s[sb][sblock];
+         rmid = Max(gfc->thm[chmid].s[sb][sblock],Min(gfc->thm[chside].s[sb][sblock],mld));
+
+         mld = gfc->mld_s[sb]*gfc->en[chmid].s[sb][sblock];
+         rside = Max(gfc->thm[chside].s[sb][sblock],Min(gfc->thm[chmid].s[sb][sblock],mld));
+
+         gfc->thm[chmid].s[sb][sblock]=rmid;
+         gfc->thm[chside].s[sb][sblock]=rside;
+       }
+      }
+    }
+  }
+
+
+
+  /*************************************************************** 
+   * Adjust M/S maskings if user set "msfix"
+   ***************************************************************/
+  /* Naoki Shibata 2000 */
+  if (numchn == 4 && gfp->msfix!=0) {
+      FLOAT msfix = gfp->msfix;
+
+    for ( sb = 0; sb < NBPSY_l; sb++ )
+      {
+       FLOAT8 thmL,thmR,thmM,thmS,ath;
+       ath  = (gfc->ATH->cb[(gfc->bu_l[sb] + gfc->bo_l[sb])/2])*pow(10,-gfp->ATHlower/10.0);
+       thmL = Max(gfc->thm[0].l[sb],ath);
+       thmR = Max(gfc->thm[1].l[sb],ath);
+       thmM = Max(gfc->thm[2].l[sb],ath);
+       thmS = Max(gfc->thm[3].l[sb],ath);
+
+       if (thmL*msfix < (thmM+thmS)/2) {
+         FLOAT8 f = thmL*msfix / ((thmM+thmS)/2);
+         thmM *= f;
+         thmS *= f;
+       }
+       if (thmR*msfix < (thmM+thmS)/2) {
+         FLOAT8 f = thmR*msfix / ((thmM+thmS)/2);
+         thmM *= f;
+         thmS *= f;
+       }
+
+       gfc->thm[2].l[sb] = Min(thmM,gfc->thm[2].l[sb]);
+       gfc->thm[3].l[sb] = Min(thmS,gfc->thm[3].l[sb]);
+      }
+
+    for ( sb = 0; sb < NBPSY_s; sb++ ) {
+      for ( sblock = 0; sblock < 3; sblock++ ) {
+       FLOAT8 thmL,thmR,thmM,thmS,ath;
+       ath  = (gfc->ATH->cb[(gfc->bu_s[sb] + gfc->bo_s[sb])/2])*pow(10,-gfp->ATHlower/10.0);
+       thmL = Max(gfc->thm[0].s[sb][sblock],ath);
+       thmR = Max(gfc->thm[1].s[sb][sblock],ath);
+       thmM = Max(gfc->thm[2].s[sb][sblock],ath);
+       thmS = Max(gfc->thm[3].s[sb][sblock],ath);
+
+       if (thmL*msfix < (thmM+thmS)/2) {
+         FLOAT8 f = thmL*msfix / ((thmM+thmS)/2);
+         thmM *= f;
+         thmS *= f;
+       }
+       if (thmR*msfix < (thmM+thmS)/2) {
+         FLOAT8 f = thmR*msfix / ((thmM+thmS)/2);
+         thmM *= f;
+         thmS *= f;
+       }
+
+       gfc->thm[2].s[sb][sblock] = Min(gfc->thm[2].s[sb][sblock],thmM);
+       gfc->thm[3].s[sb][sblock] = Min(gfc->thm[3].s[sb][sblock],thmS);
+      }
+    }
+  }
+
+
+
+
+
+
+
+
+
+
+
+  if (gfp->mode == JOINT_STEREO)  {
+    /* determin ms_ratio from masking thresholds*/
+    /* use ms_stereo (ms_ratio < .35) if average thresh. diff < 5 db */
+    FLOAT8 db,x1,x2,sidetot=0,tot=0;
+    for (sb= NBPSY_l/4 ; sb< NBPSY_l; sb ++ ) {
+      x1 = Min(gfc->thm[0].l[sb],gfc->thm[1].l[sb]);
+      x2 = Max(gfc->thm[0].l[sb],gfc->thm[1].l[sb]);
+      /* thresholds difference in db */
+      if (x2 >= 1000*x1)  db=3;
+      else db = log10(x2/x1);  
+      /*  DEBUGF(gfc,"db = %f %e %e  \n",db,gfc->thm[0].l[sb],gfc->thm[1].l[sb]);*/
+      sidetot += db;
+      tot++;
+    }
+    ms_ratio_l= (sidetot/tot)*0.7; /* was .35*(sidetot/tot)/5.0*10 */
+    ms_ratio_l = Min(ms_ratio_l,0.5);
+    
+    sidetot=0; tot=0;
+    for ( sblock = 0; sblock < 3; sblock++ )
+      for ( sb = NBPSY_s/4; sb < NBPSY_s; sb++ ) {
+       x1 = Min(gfc->thm[0].s[sb][sblock],gfc->thm[1].s[sb][sblock]);
+       x2 = Max(gfc->thm[0].s[sb][sblock],gfc->thm[1].s[sb][sblock]);
+       /* thresholds difference in db */
+       if (x2 >= 1000*x1)  db=3;
+       else db = log10(x2/x1);  
+       sidetot += db;
+       tot++;
+      }
+    ms_ratio_s = (sidetot/tot)*0.7; /* was .35*(sidetot/tot)/5.0*10 */
+    ms_ratio_s = Min(ms_ratio_s,.5);
+  }
+
+  /*************************************************************** 
+   * determine final block type
+   ***************************************************************/
+
+  for (chn=0; chn<gfc->channels_out; chn++) {
+    blocktype[chn] = NORM_TYPE;
+  }
+
+
+  if (gfp->short_blocks == short_block_coupled) {
+      /* force both channels to use the same block type */
+      /* this is necessary if the frame is to be encoded in ms_stereo.  */
+      /* But even without ms_stereo, FhG  does this */
+      int bothlong= (uselongblock[0] && uselongblock[1]);
+      if (!bothlong) {
+       uselongblock[0]=0;
+       uselongblock[1]=0;
+      }
+  }
+
+  
+  
+  /* update the blocktype of the previous granule, since it depends on what
+   * happend in this granule */
+  for (chn=0; chn<gfc->channels_out; chn++) {
+    if ( uselongblock[chn])
+      {                                /* no attack : use long blocks */
+       assert( gfc->blocktype_old[chn] != START_TYPE );
+       switch( gfc->blocktype_old[chn] ) 
+         {
+         case NORM_TYPE:
+         case STOP_TYPE:
+           blocktype[chn] = NORM_TYPE;
+           break;
+         case SHORT_TYPE:
+           blocktype[chn] = STOP_TYPE; 
+           break;
+         }
+      } else   {
+       /* attack : use short blocks */
+       blocktype[chn] = SHORT_TYPE;
+       if ( gfc->blocktype_old[chn] == NORM_TYPE ) {
+         gfc->blocktype_old[chn] = START_TYPE;
+       }
+       if ( gfc->blocktype_old[chn] == STOP_TYPE ) {
+         gfc->blocktype_old[chn] = SHORT_TYPE ;
+       }
+      }
+    
+    blocktype_d[chn] = gfc->blocktype_old[chn];  /* value returned to calling program */
+    gfc->blocktype_old[chn] = blocktype[chn];    /* save for next call to l3psy_anal */
+  }
+  
+  if (blocktype_d[0]==2 && blocktype_d[1]==2)
+    *ms_ratio = gfc->ms_ratio_s_old;
+  else
+    *ms_ratio = gfc->ms_ratio_l_old;
+
+  gfc->ms_ratio_s_old = ms_ratio_s;
+  gfc->ms_ratio_l_old = ms_ratio_l;
+
+  /* we dont know the block type of this frame yet - assume long */
+  *ms_ratio_next = ms_ratio_l;
+
+  return 0;
+}
+
+/* addition of simultaneous masking   Naoki Shibata 2000/7 */
+inline static FLOAT8 mask_add(FLOAT8 m1,FLOAT8 m2,int k,int b, lame_internal_flags * const gfc)
+{
+  static const FLOAT8 table1[] = {
+    3.3246 *3.3246 ,3.23837*3.23837,3.15437*3.15437,3.00412*3.00412,2.86103*2.86103,2.65407*2.65407,2.46209*2.46209,2.284  *2.284  ,
+    2.11879*2.11879,1.96552*1.96552,1.82335*1.82335,1.69146*1.69146,1.56911*1.56911,1.46658*1.46658,1.37074*1.37074,1.31036*1.31036,
+    1.25264*1.25264,1.20648*1.20648,1.16203*1.16203,1.12765*1.12765,1.09428*1.09428,1.0659 *1.0659 ,1.03826*1.03826,1.01895*1.01895,
+    1
+  };
+
+  static const FLOAT8 table2[] = {
+    1.33352*1.33352,1.35879*1.35879,1.38454*1.38454,1.39497*1.39497,1.40548*1.40548,1.3537 *1.3537 ,1.30382*1.30382,1.22321*1.22321,
+    1.14758*1.14758
+  };
+
+  static const FLOAT8 table3[] = {
+    2.35364*2.35364,2.29259*2.29259,2.23313*2.23313,2.12675*2.12675,2.02545*2.02545,1.87894*1.87894,1.74303*1.74303,1.61695*1.61695,
+    1.49999*1.49999,1.39148*1.39148,1.29083*1.29083,1.19746*1.19746,1.11084*1.11084,1.03826*1.03826
+  };
+
+
+  int i;
+  FLOAT8 m;
+
+  if (m1 == 0) return m2;
+
+  if (b < 0) b = -b;
+
+  i = 10*log10(m2 / m1)/10*16;
+  m = 10*log10((m1+m2)/gfc->ATH->cb[k]);
+
+  if (i < 0) i = -i;
+
+  if (b <= 3) {  /* approximately, 1 bark = 3 partitions */
+    if (i > 8) return m1+m2;
+    return (m1+m2)*table2[i];
+  }
+
+  if (m<15) {
+    if (m > 0) {
+      FLOAT8 f=1.0,r;
+      if (i > 24) return m1+m2;
+      if (i > 13) f = 1; else f = table3[i];
+      r = (m-0)/15;
+      return (m1+m2)*(table1[i]*r+f*(1-r));
+    }
+    if (i > 13) return m1+m2;
+    return (m1+m2)*table3[i];
+  }
+
+  if (i > 24) return m1+m2;
+  return (m1+m2)*table1[i];
+}
+
+int L3psycho_anal_ns( lame_global_flags * gfp,
+                    const sample_t *buffer[2], int gr_out, 
+                    FLOAT8 *ms_ratio,
+                    FLOAT8 *ms_ratio_next,
+                   III_psy_ratio masking_ratio[2][2],
+                   III_psy_ratio masking_MS_ratio[2][2],
+                   FLOAT8 percep_entropy[2],FLOAT8 percep_MS_entropy[2], 
+                   FLOAT8 energy[4], 
+                    int blocktype_d[2])
+{
+/* to get a good cache performance, one has to think about
+ * the sequence, in which the variables are used.  
+ * (Note: these static variables have been moved to the gfc-> struct,
+ * and their order in memory is layed out in util.h)
+ */
+  lame_internal_flags *gfc=gfp->internal_flags;
+
+  /* fft and energy calculation   */
+  FLOAT (*wsamp_l)[BLKSIZE];
+  FLOAT (*wsamp_s)[3][BLKSIZE_s];
+
+  /* convolution   */
+  FLOAT8 eb[CBANDS],eb2[CBANDS];
+  FLOAT8 thr[CBANDS];
+  
+  FLOAT8 max[CBANDS],avg[CBANDS],tonality2[CBANDS];
+
+  /* ratios    */
+  FLOAT8 ms_ratio_l=0,ms_ratio_s=0;
+
+  /* block type  */
+  int blocktype[2],uselongblock[2];
+  
+  /* usual variables like loop indices, etc..    */
+  int numchn, chn;
+  int   b, i, j, k;
+  int  sb,sblock;
+
+  /* variables used for --nspsytune */
+  int ns_attacks[4];
+  FLOAT ns_hpfsmpl[4][576+576/3+NSFIRLEN];
+  FLOAT pe_l[4],pe_s[4];
+  FLOAT pcfact;
+
+
+  if(gfc->psymodel_init==0) {
+    psymodel_init(gfp);
+    init_fft(gfc);
+    gfc->psymodel_init=1;
+  }
+
+
+  numchn = gfc->channels_out;
+  /* chn=2 and 3 = Mid and Side channels */
+  if (gfp->mode == JOINT_STEREO) numchn=4;
+
+  if (gfp->VBR==vbr_off) pcfact = gfc->ResvMax == 0 ? 0 : ((FLOAT)gfc->ResvSize)/gfc->ResvMax*0.5;
+  else if (gfp->VBR == vbr_rh  ||  gfp->VBR == vbr_mtrh  ||  gfp->VBR == vbr_mt) {
+    static const FLOAT8 pcQns[10]={1.0,1.0,1.0,0.8,0.6,0.5,0.4,0.3,0.2,0.1};
+    pcfact = pcQns[gfp->VBR_q];
+  } else pcfact = 1;
+
+  /**********************************************************************
+   *  Apply HPF of fs/4 to the input signal.
+   *  This is used for attack detection / handling.
+   **********************************************************************/
+
+  {
+    static const FLOAT fircoef[] = {
+      -8.65163e-18,-0.00851586,-6.74764e-18, 0.0209036,
+      -3.36639e-17,-0.0438162 ,-1.54175e-17, 0.0931738,
+      -5.52212e-17,-0.313819  , 0.5        ,-0.313819,
+      -5.52212e-17, 0.0931738 ,-1.54175e-17,-0.0438162,
+      -3.36639e-17, 0.0209036 ,-6.74764e-18,-0.00851586,
+      -8.65163e-18,
+    };
+
+    for(chn=0;chn<gfc->channels_out;chn++)
+      {
+       FLOAT firbuf[576+576/3+NSFIRLEN];
+
+       /* apply high pass filter of fs/4 */
+       
+       for(i=-NSFIRLEN;i<576+576/3;i++)
+         firbuf[i+NSFIRLEN] = buffer[chn][576-350+(i)];
+
+       for(i=0;i<576+576/3-NSFIRLEN;i++)
+          {
+           FLOAT sum = 0;
+           for(j=0;j<NSFIRLEN;j++)
+             sum += fircoef[j] * firbuf[i+j];
+           ns_hpfsmpl[chn][i] = sum;
+         }
+       for(;i<576+576/3;i++)
+         ns_hpfsmpl[chn][i] = 0;
+      }
+
+    if (gfp->mode == JOINT_STEREO) {
+      for(i=0;i<576+576/3;i++)
+       {
+         ns_hpfsmpl[2][i] = ns_hpfsmpl[0][i]+ns_hpfsmpl[1][i];
+         ns_hpfsmpl[3][i] = ns_hpfsmpl[0][i]-ns_hpfsmpl[1][i];
+       }
+    }
+  }
+  
+
+
+  /* there is a one granule delay.  Copy maskings computed last call
+   * into masking_ratio to return to calling program.
+   */
+  for (chn=0; chn<numchn; chn++) {
+      for (i=0; i<numchn; ++i) {
+         energy[chn]=gfc->tot_ener[chn];
+      }
+  }
+
+
+  for (chn=0; chn<numchn; chn++) {
+    /* there is a one granule delay.  Copy maskings computed last call
+     * into masking_ratio to return to calling program.
+     */
+    pe_l[chn] = gfc->nsPsy.pe_l[chn];
+    pe_s[chn] = gfc->nsPsy.pe_s[chn];
+
+    if (chn < 2) {    
+      /* LR maskings  */
+      //percep_entropy            [chn]       = gfc -> pe  [chn]; 
+      masking_ratio    [gr_out] [chn]  .en  = gfc -> en  [chn];
+      masking_ratio    [gr_out] [chn]  .thm = gfc -> thm [chn];
+    } else {
+      /* MS maskings  */
+      //percep_MS_entropy         [chn-2]     = gfc -> pe  [chn]; 
+      masking_MS_ratio [gr_out] [chn-2].en  = gfc -> en  [chn];
+      masking_MS_ratio [gr_out] [chn-2].thm = gfc -> thm [chn];
+    }
+  }
+
+  for (chn=0; chn<numchn; chn++) {
+
+    /**********************************************************************
+     *  compute FFTs
+     **********************************************************************/
+
+    wsamp_s = gfc->wsamp_S+(chn & 1);
+    wsamp_l = gfc->wsamp_L+(chn & 1);
+
+    if (chn<2) {    
+      fft_long ( gfc, *wsamp_l, chn, buffer);
+      fft_short( gfc, *wsamp_s, chn, buffer);
+    } 
+
+    /* FFT data for mid and side channel is derived from L & R */
+
+    if (chn == 2)
+      {
+        for (j = BLKSIZE-1; j >=0 ; --j)
+         {
+           FLOAT l = gfc->wsamp_L[0][j];
+           FLOAT r = gfc->wsamp_L[1][j];
+           gfc->wsamp_L[0][j] = (l+r)*(FLOAT)(SQRT2*0.5);
+           gfc->wsamp_L[1][j] = (l-r)*(FLOAT)(SQRT2*0.5);
+         }
+        for (b = 2; b >= 0; --b)
+         {
+           for (j = BLKSIZE_s-1; j >= 0 ; --j)
+             {
+               FLOAT l = gfc->wsamp_S[0][b][j];
+               FLOAT r = gfc->wsamp_S[1][b][j];
+               gfc->wsamp_S[0][b][j] = (l+r)*(FLOAT)(SQRT2*0.5);
+               gfc->wsamp_S[1][b][j] = (l-r)*(FLOAT)(SQRT2*0.5);
+             }
+         }
+      }
+
+
+    /**********************************************************************
+     *  compute energies for each spectral line
+     **********************************************************************/
+    
+    /* long block */
+
+    gfc->energy[0]  = (*wsamp_l)[0];
+    gfc->energy[0] *= gfc->energy[0];
+    
+    gfc->tot_ener[chn] = gfc->energy[0]; /* sum total energy at nearly no extra cost */
+    
+    for (j=BLKSIZE/2-1; j >= 0; --j)
+    {
+      FLOAT re = (*wsamp_l)[BLKSIZE/2-j];
+      FLOAT im = (*wsamp_l)[BLKSIZE/2+j];
+      gfc->energy[BLKSIZE/2-j] = (re * re + im * im) * (FLOAT)0.5;
+
+      if (BLKSIZE/2-j > 10)
+       gfc->tot_ener[chn] += gfc->energy[BLKSIZE/2-j];
+    }
+
+
+    /* short block */
+
+    for (b = 2; b >= 0; --b)
+    {
+      gfc->energy_s[b][0]  = (*wsamp_s)[b][0];
+      gfc->energy_s[b][0] *=  gfc->energy_s [b][0];
+      for (j=BLKSIZE_s/2-1; j >= 0; --j)
+      {
+        FLOAT re = (*wsamp_s)[b][BLKSIZE_s/2-j];
+        FLOAT im = (*wsamp_s)[b][BLKSIZE_s/2+j];
+        gfc->energy_s[b][BLKSIZE_s/2-j] = (re * re + im * im) * (FLOAT)0.5;
+      }
+    }
+
+
+    /* output data for analysis */
+
+#if defined(HAVE_GTK)
+    if (gfp->analysis) {
+      for (j=0; j<HBLKSIZE ; j++) {
+       gfc->pinfo->energy[gr_out][chn][j]=gfc->energy_save[chn][j];
+       gfc->energy_save[chn][j]=gfc->energy[j];
+      }
+    }
+#endif
+    
+
+    /**********************************************************************
+     * compute loudness approximation (used for ATH auto-level adjustment) 
+     **********************************************************************/
+    if( gfp->athaa_loudapprox == 2 ) {
+      if( chn < 2 ) {          /* no loudness for mid and side channels */
+       gfc->loudness_sq[gr_out][chn] = gfc->loudness_sq_save[chn];
+       gfc->loudness_sq_save[chn]
+         = psycho_loudness_approx( gfc->energy, gfp);
+      }
+    }
+
+
+
+    /**********************************************************************
+     *    Calculate the energy and the tonality of each partition.
+     **********************************************************************/
+
+    for (b=0, j=0; b<gfc->npart_l_orig; b++)
+      {
+       FLOAT8 ebb,m,a;
+  
+       ebb = gfc->energy[j];
+       m = a = gfc->energy[j];
+       j++;
+  
+       for (i = gfc->numlines_l[b] - 1; i > 0; i--)
+         {
+           FLOAT8 el = gfc->energy[j];
+           ebb += gfc->energy[j];
+           a += el;
+           m = m < el ? el : m;
+           j++;
+         }
+       eb[b] = ebb;
+       max[b] = m;
+       avg[b] = a / gfc->numlines_l[b];
+      }
+  
+    j = 0;
+    for (b=0; b < gfc->npart_l_orig; b++ )
+      {
+       int c1,c2;
+       FLOAT8 m,a;
+       tonality2[b] = 0;
+       c1 = c2 = 0;
+       m = a = 0;
+       for(k=b-1;k<=b+1;k++)
+         {
+           if (k >= 0 && k < gfc->npart_l_orig) {
+             c1++;
+             c2 += gfc->numlines_l[k];
+             a += avg[k];
+             m = m < max[k] ? max[k] : m;
+           }
+         }
+       a /= c1;
+       tonality2[b] = a == 0 ? 0 : (m / a - 1)/(c2-1);
+      }
+
+    for (b=0; b < gfc->npart_l_orig; b++ )
+      {
+#if 0
+       static FLOAT8 tab[20] =
+       {  0,  1,  2,  2,  2,  2,  2,  6,9.3,9.3,9.3,9.3,9.3,9.3,9.3,9.3,9.3,9.3,9.3,9.3};
+
+       static int init = 1;
+       if (init) {
+         int j;
+         for(j=0;j<20;j++) {
+           tab[j] = pow(10.0,-tab[j]/10.0);
+         }
+         init = 0;
+       }
+#else
+       static FLOAT8 tab[20] = {
+         1,0.79433,0.63096,0.63096,0.63096,0.63096,0.63096,0.25119,0.11749,0.11749,
+         0.11749,0.11749,0.11749,0.11749,0.11749,0.11749,0.11749,0.11749,0.11749,0.11749
+       };
+#endif
+
+       int t = 20*tonality2[b];
+       if (t > 19) t = 19;
+       eb2[b] = eb[b] * tab[t];
+      }
+
+
+    /**********************************************************************
+     *      convolve the partitioned energy and unpredictability
+     *      with the spreading function, s3_l[b][k]
+     ******************************************************************** */
+    {
+    int kk = 0;
+    for ( b = 0;b < gfc->npart_l; b++ )
+      {
+       FLOAT8 ecb;
+
+       /****   convolve the partitioned energy with the spreading function   ****/
+
+       ecb = 0;
+
+#if 1
+       for ( k = gfc->s3ind[b][0]; k <= gfc->s3ind[b][1]; k++ )
+         {
+           ecb = mask_add(ecb,gfc->s3_ll[kk++] * eb2[k],k,k-b,gfc);
+         }
+
+       ecb *= 0.158489319246111; // pow(10,-0.8)
+#endif
+
+#if 0
+       for ( k = gfc->s3ind[b][0]; k <= gfc->s3ind[b][1]; k++ )
+         {
+           ecb += gfc->s3_ll[kk++] * eb2[k];
+         }
+
+       ecb *= 0.223872113856834; // pow(10,-0.65);
+#endif
+
+       /****   long block pre-echo control   ****/
+
+       /* dont use long block pre-echo control if previous granule was 
+        * a short block.  This is to avoid the situation:   
+        * frame0:  quiet (very low masking)  
+        * frame1:  surge  (triggers short blocks)
+        * frame2:  regular frame.  looks like pre-echo when compared to 
+        *          frame0, but all pre-echo was in frame1.
+        */
+
+       /* chn=0,1   L and R channels
+          chn=2,3   S and M channels.  
+       */
+
+#define NS_INTERP(x,y,r) (pow((x),(r))*pow((y),1-(r)))
+
+       if (gfc->blocktype_old[chn>1 ? chn-2 : chn] == SHORT_TYPE )
+         thr[b] = ecb; /* Min(ecb, rpelev*gfc->nb_1[chn][b]); */
+       else
+         thr[b] = NS_INTERP(Min(ecb, Min(rpelev*gfc->nb_1[chn][b],rpelev2*gfc->nb_2[chn][b])),ecb,pcfact);
+
+       gfc->nb_2[chn][b] = gfc->nb_1[chn][b];
+       gfc->nb_1[chn][b] = ecb;
+      }
+    }
+
+    /*************************************************************** 
+     * determine the block type (window type)
+     ***************************************************************/
+
+    {
+      static int count=0;
+      FLOAT en_subshort[12];
+      FLOAT attack_intensity[12];
+      int ns_uselongblock = 1;
+
+      /* calculate energies of each sub-shortblocks */
+
+      k = 0;
+      for(i=0;i<12;i++)
+       {
+         en_subshort[i] = 0;
+         for(j=0;j<576/9;j++)
+           {
+             en_subshort[i] += ns_hpfsmpl[chn][k] * ns_hpfsmpl[chn][k];
+             k++;
+           }
+
+         if (en_subshort[i] < 100) en_subshort[i] = 100;
+       }
+
+      /* compare energies between sub-shortblocks */
+
+#define NSATTACKTHRE 150
+#define NSATTACKTHRE_S 300
+
+      for(i=0;i<2;i++) {
+       attack_intensity[i] = en_subshort[i] / gfc->nsPsy.last_en_subshort[chn][7+i];
+      }
+
+      for(;i<12;i++) {
+       attack_intensity[i] = en_subshort[i] / en_subshort[i-2];
+      }
+
+      ns_attacks[0] = ns_attacks[1] = ns_attacks[2] = ns_attacks[3] = 0;
+
+      for(i=0;i<12;i++)
+       {
+         if (!ns_attacks[i/3] && attack_intensity[i] > (chn == 3 ? (gfc->presetTune.use ? gfc->presetTune.attackthre_s : NSATTACKTHRE_S)
+                                                              : (gfc->presetTune.use ? gfc->presetTune.attackthre   : NSATTACKTHRE))) ns_attacks[i/3] = (i % 3)+1;
+       }
+
+      if (ns_attacks[0] && gfc->nsPsy.last_attacks[chn][2]) ns_attacks[0] = 0;
+      if (ns_attacks[1] && ns_attacks[0]) ns_attacks[1] = 0;
+      if (ns_attacks[2] && ns_attacks[1]) ns_attacks[2] = 0;
+      if (ns_attacks[3] && ns_attacks[2]) ns_attacks[3] = 0;
+
+      if (gfc->nsPsy.last_attacks[chn][2] == 3 ||
+         ns_attacks[0] || ns_attacks[1] || ns_attacks[2] || ns_attacks[3]) ns_uselongblock = 0;
+
+      if (chn < 4) count++;
+
+      for(i=0;i<9;i++)
+       {
+         gfc->nsPsy.last_en_subshort[chn][i] = en_subshort[i];
+         gfc->nsPsy.last_attack_intensity[chn][i] = attack_intensity[i];
+       }
+
+      if (gfp->short_blocks == short_block_dispensed) {
+       uselongblock[chn] = 1;
+      } 
+      else if (gfp->short_blocks == short_block_forced) {
+       uselongblock[chn] = 0;
+      }
+      else {
+       if (chn < 2) {
+         uselongblock[chn] = ns_uselongblock;
+       } else {
+         if (ns_uselongblock == 0) uselongblock[0] = uselongblock[1] = 0;
+       }
+      }
+    }
+
+#if defined(HAVE_GTK)
+    if (gfp->analysis) {
+      FLOAT mn,mx,ma=0,mb=0,mc=0;
+
+      for ( j = HBLKSIZE_s/2; j < HBLKSIZE_s; j ++)
+      {
+        ma += gfc->energy_s[0][j];
+        mb += gfc->energy_s[1][j];
+        mc += gfc->energy_s[2][j];
+      }
+      mn = Min(ma,mb);
+      mn = Min(mn,mc);
+      mx = Max(ma,mb);
+      mx = Max(mx,mc);
+
+      gfc->pinfo->ers[gr_out][chn]=gfc->ers_save[chn];
+      gfc->ers_save[chn]=(mx/(1e-12+mn));
+    }
+#endif
+
+
+    /*************************************************************** 
+     * compute masking thresholds for long blocks
+     ***************************************************************/
+
+    for ( sb = 0; sb < NBPSY_l; sb++ )
+      {
+       FLOAT8 enn = gfc->w1_l[sb] * eb[gfc->bu_l[sb]] + gfc->w2_l[sb] * eb[gfc->bo_l[sb]];
+       FLOAT8 thmm = gfc->w1_l[sb] *thr[gfc->bu_l[sb]] + gfc->w2_l[sb] * thr[gfc->bo_l[sb]];
+
+        for ( b = gfc->bu_l[sb]+1; b < gfc->bo_l[sb]; b++ )
+          {
+            enn  += eb[b];
+            thmm += thr[b];
+          }
+
+       gfc->en [chn].l[sb] = enn;
+       gfc->thm[chn].l[sb] = thmm;
+      }
+    
+
+    /*************************************************************** 
+     * compute masking thresholds for short blocks
+     ***************************************************************/
+
+    for ( sblock = 0; sblock < 3; sblock++ )
+      {
+       j = 0;
+       for ( b = 0; b < gfc->npart_s_orig; b++ )
+         {
+           FLOAT ecb = gfc->energy_s[sblock][j++];
+           for (i = 1 ; i<gfc->numlines_s[b]; ++i)
+             {
+               ecb += gfc->energy_s[sblock][j++];
+             }
+           eb[b] = ecb;
+         }
+
+       {
+         int kk = 0;
+         for ( b = 0; b < gfc->npart_s; b++ )
+           {
+             FLOAT8 ecb = 0;
+             for ( k = gfc->s3ind_s[b][0]; k <= gfc->s3ind_s[b][1]; k++ )
+               {
+                 ecb += gfc->s3_ss[kk++] * eb[k];
+               }
+
+/* 2001-07-13 */
+            /* this looks like a BUG  */
+            thr[b] = Max (1e-6, ecb);
+            
+            if (gfp->VBR == vbr_mtrh) {
+                thr[b] = Min( ecb, rpelev_s  * gfc->nb_s1[chn][b] );
+                if (gfc->blocktype_old[chn>1 ? chn-2 : chn] == SHORT_TYPE ) {
+                   thr[b] = Min( thr[b], rpelev2_s * gfc->nb_s2[chn][b] );
+                }
+                thr[b] = Max( thr[b], 1e-37 );
+                gfc->nb_s2[chn][b] = gfc->nb_s1[chn][b];
+                gfc->nb_s1[chn][b] = ecb;
+                }
+           }
+       }
+       for ( sb = 0; sb < NBPSY_s; sb++ )
+         {
+            FLOAT8 enn  = gfc->w1_s[sb] * eb[gfc->bu_s[sb]] + gfc->w2_s[sb] * eb[gfc->bo_s[sb]];
+           FLOAT8 thmm = gfc->w1_s[sb] *thr[gfc->bu_s[sb]] + gfc->w2_s[sb] * thr[gfc->bo_s[sb]];
+           
+            for ( b = gfc->bu_s[sb]+1; b < gfc->bo_s[sb]; b++ )
+             {
+               enn  += eb[b];
+               thmm += thr[b];
+             }
+
+           /****   short block pre-echo control   ****/
+
+#define NS_PREECHO_ATT0 0.8
+#define NS_PREECHO_ATT1 0.6
+#define NS_PREECHO_ATT2 0.3
+
+           thmm *= NS_PREECHO_ATT0;
+
+           if (ns_attacks[sblock] >= 2) {
+             if (sblock != 0) {
+               double p = NS_INTERP(gfc->thm[chn].s[sb][sblock-1],thmm,NS_PREECHO_ATT1*pcfact);
+               thmm = Min(thmm,p);
+             } else {
+               double p = NS_INTERP(gfc->nsPsy.last_thm[chn][sb][2],thmm,NS_PREECHO_ATT1*pcfact);
+               thmm = Min(thmm,p);
+             }
+           } else if (ns_attacks[sblock+1] == 1) {
+             if (sblock != 0) {
+               double p = NS_INTERP(gfc->thm[chn].s[sb][sblock-1],thmm,NS_PREECHO_ATT1*pcfact);
+               thmm = Min(thmm,p);
+             } else {
+               double p = NS_INTERP(gfc->nsPsy.last_thm[chn][sb][2],thmm,NS_PREECHO_ATT1*pcfact);
+               thmm = Min(thmm,p);
+             }
+           }
+
+           if (ns_attacks[sblock] == 1) {
+             double p = sblock == 0 ? gfc->nsPsy.last_thm[chn][sb][2] : gfc->thm[chn].s[sb][sblock-1];
+             p = NS_INTERP(p,thmm,NS_PREECHO_ATT2*pcfact);
+             thmm = Min(thmm,p);
+           } else if ((sblock != 0 && ns_attacks[sblock-1] == 3) ||
+                      (sblock == 0 && gfc->nsPsy.last_attacks[chn][2] == 3)) {
+             double p = sblock <= 1 ? gfc->nsPsy.last_thm[chn][sb][sblock+1] : gfc->thm[chn].s[sb][0];
+             p = NS_INTERP(p,thmm,NS_PREECHO_ATT2*pcfact);
+             thmm = Min(thmm,p);
+           }
+
+           gfc->en [chn].s[sb][sblock] = enn;
+           gfc->thm[chn].s[sb][sblock] = thmm;
+         }
+      }
+
+
+    /*************************************************************** 
+     * save some values for analysis of the next granule
+     ***************************************************************/
+
+    for ( sblock = 0; sblock < 3; sblock++ )
+      {
+       for ( sb = 0; sb < NBPSY_s; sb++ )
+         {
+           gfc->nsPsy.last_thm[chn][sb][sblock] = gfc->thm[chn].s[sb][sblock];
+         }
+      }
+
+    for(i=0;i<3;i++)
+      gfc->nsPsy.last_attacks[chn][i] = ns_attacks[i];
+
+  } /* end loop over chn */
+
+
+
+  /*************************************************************** 
+   * compute M/S thresholds
+   ***************************************************************/
+
+  /* from Johnston & Ferreira 1992 ICASSP paper */
+
+  if ( numchn==4 /* mid/side and r/l */) {
+    FLOAT8 rside,rmid,mld;
+    int chmid=2,chside=3; 
+    
+    for ( sb = 0; sb < NBPSY_l; sb++ ) {
+      /* use this fix if L & R masking differs by 2db or less */
+      /* if db = 10*log10(x2/x1) < 2 */
+      /* if (x2 < 1.58*x1) { */
+      if (gfc->thm[0].l[sb] <= 1.58*gfc->thm[1].l[sb]
+         && gfc->thm[1].l[sb] <= 1.58*gfc->thm[0].l[sb]) {
+
+       mld = gfc->mld_l[sb]*gfc->en[chside].l[sb];
+       rmid = Max(gfc->thm[chmid].l[sb], Min(gfc->thm[chside].l[sb],mld));
+
+       mld = gfc->mld_l[sb]*gfc->en[chmid].l[sb];
+       rside = Max(gfc->thm[chside].l[sb],Min(gfc->thm[chmid].l[sb],mld));
+
+       gfc->thm[chmid].l[sb]=rmid;
+       gfc->thm[chside].l[sb]=rside;
+      }
+    }
+    for ( sb = 0; sb < NBPSY_s; sb++ ) {
+      for ( sblock = 0; sblock < 3; sblock++ ) {
+       if (gfc->thm[0].s[sb][sblock] <= 1.58*gfc->thm[1].s[sb][sblock]
+           && gfc->thm[1].s[sb][sblock] <= 1.58*gfc->thm[0].s[sb][sblock]) {
+
+         mld = gfc->mld_s[sb]*gfc->en[chside].s[sb][sblock];
+         rmid = Max(gfc->thm[chmid].s[sb][sblock],Min(gfc->thm[chside].s[sb][sblock],mld));
+
+         mld = gfc->mld_s[sb]*gfc->en[chmid].s[sb][sblock];
+         rside = Max(gfc->thm[chside].s[sb][sblock],Min(gfc->thm[chmid].s[sb][sblock],mld));
+
+         gfc->thm[chmid].s[sb][sblock]=rmid;
+         gfc->thm[chside].s[sb][sblock]=rside;
+       }
+      }
+    }
+  }
+
+
+  /* Naoki Shibata 2000 */
+
+#define NS_MSFIX 3.5
+  
+  if (numchn == 4) {
+    FLOAT msfix = NS_MSFIX;
+    if (gfc->nsPsy.safejoint) msfix = 1;
+    if (gfp->msfix) msfix = gfp->msfix;
+
+    if (gfc->presetTune.use && gfc->ATH->adjust >=
+                                      gfc->presetTune.athadjust_switch_level && 
+                                                          gfc->presetTune.athadjust_msfix > 0)
+               msfix = gfc->presetTune.athadjust_msfix;
+    
+    for ( sb = 0; sb < NBPSY_l; sb++ )
+      {
+       FLOAT8 thmL,thmR,thmM,thmS,ath;
+       ath  = (gfc->ATH->cb[(gfc->bu_l[sb] + gfc->bo_l[sb])/2])*pow(10,-gfp->ATHlower/10.0);
+       thmL = Max(gfc->thm[0].l[sb],ath);
+       thmR = Max(gfc->thm[1].l[sb],ath);
+       thmM = Max(gfc->thm[2].l[sb],ath);
+       thmS = Max(gfc->thm[3].l[sb],ath);
+
+       if (thmL*msfix < (thmM+thmS)/2) {
+         FLOAT8 f = thmL * (gfc->presetTune.use ? gfc->presetTune.ms_maskadjust : msfix) / ((thmM+thmS)/2);
+         thmM *= f;
+         thmS *= f;
+       }
+       if (thmR*msfix < (thmM+thmS)/2) {
+         FLOAT8 f = thmR * (gfc->presetTune.use ? gfc->presetTune.ms_maskadjust : msfix) / ((thmM+thmS)/2);
+         thmM *= f;
+         thmS *= f;
+       }
+
+       gfc->thm[2].l[sb] = Min(thmM,gfc->thm[2].l[sb]);
+       gfc->thm[3].l[sb] = Min(thmS,gfc->thm[3].l[sb]);
+      }
+
+    for ( sb = 0; sb < NBPSY_s; sb++ ) {
+      for ( sblock = 0; sblock < 3; sblock++ ) {
+       FLOAT8 thmL,thmR,thmM,thmS,ath;
+       ath  = (gfc->ATH->cb[(gfc->bu_s[sb] + gfc->bo_s[sb])/2])*pow(10,-gfp->ATHlower/10.0);
+       thmL = Max(gfc->thm[0].s[sb][sblock],ath);
+       thmR = Max(gfc->thm[1].s[sb][sblock],ath);
+       thmM = Max(gfc->thm[2].s[sb][sblock],ath);
+       thmS = Max(gfc->thm[3].s[sb][sblock],ath);
+
+       if (thmL*msfix < (thmM+thmS)/2) {
+         FLOAT8 f = thmL*msfix / ((thmM+thmS)/2);
+         thmM *= f;
+         thmS *= f;
+       }
+       if (thmR*msfix < (thmM+thmS)/2) {
+         FLOAT8 f = thmR*msfix / ((thmM+thmS)/2);
+         thmM *= f;
+         thmS *= f;
+       }
+
+       gfc->thm[2].s[sb][sblock] = Min(gfc->thm[2].s[sb][sblock],thmM);
+       gfc->thm[3].s[sb][sblock] = Min(gfc->thm[3].s[sb][sblock],thmS);
+      }
+    }
+  }
+
+  ms_ratio_l = 0;
+  ms_ratio_s = 0;
+
+
+  /*************************************************************** 
+   * compute estimation of the amount of bit used in the granule
+   ***************************************************************/
+
+  for(chn=0;chn<numchn;chn++)
+    {
+      {
+       static FLOAT8 regcoef[] = {
+         1124.23,10.0583,10.7484,7.29006,16.2714,6.2345,4.09743,3.05468,3.33196,2.54688,
+         3.68168,5.83109,2.93817,-8.03277,-10.8458,8.48777,9.13182,2.05212,8.6674,50.3937,73.267,97.5664,0
+       };
+
+       FLOAT8 msum = regcoef[0]/4;
+       int sb;
+
+       for ( sb = 0; sb < NBPSY_l; sb++ )
+         {
+           FLOAT8 t;
+             
+           if (gfc->thm[chn].l[sb]*gfc->masking_lower != 0 &&
+               gfc->en[chn].l[sb]/(gfc->thm[chn].l[sb]*gfc->masking_lower) > 1)
+             t = log(gfc->en[chn].l[sb]/(gfc->thm[chn].l[sb]*gfc->masking_lower));
+           else
+             t = 0;
+           msum += regcoef[sb+1] * t;
+         }
+
+       gfc->nsPsy.pe_l[chn] = msum;
+      }
+
+      {
+       static FLOAT8 regcoef[] = {
+         1236.28,0,0,0,0.434542,25.0738,0,0,0,19.5442,19.7486,60,100,0
+       };
+
+       FLOAT8 msum = regcoef[0]/4;
+       int sb,sblock;
+
+       for(sblock=0;sblock<3;sblock++)
+         {
+           for ( sb = 0; sb < NBPSY_s; sb++ )
+             {
+               FLOAT8 t;
+             
+               if (gfc->thm[chn].s[sb][sblock] * gfc->masking_lower != 0 &&
+                   gfc->en[chn].s[sb][sblock] / (gfc->thm[chn].s[sb][sblock] * gfc->masking_lower) > 1)
+                 t = log(gfc->en[chn].s[sb][sblock] / (gfc->thm[chn].s[sb][sblock] * gfc->masking_lower));
+               else
+                 t = 0;
+               msum += regcoef[sb+1] * t;
+             }
+         }
+
+       gfc->nsPsy.pe_s[chn] = msum;
+      }
+
+      //gfc->pe[chn] -= 150;
+    }
+
+  /*************************************************************** 
+   * determine final block type
+   ***************************************************************/
+
+  for (chn=0; chn<gfc->channels_out; chn++) {
+    blocktype[chn] = NORM_TYPE;
+  }
+
+  if (gfp->short_blocks == short_block_coupled) {
+      /* force both channels to use the same block type */
+      /* this is necessary if the frame is to be encoded in ms_stereo.  */
+      /* But even without ms_stereo, FhG  does this */
+      int bothlong= (uselongblock[0] && uselongblock[1]);
+      if (!bothlong) {
+       uselongblock[0]=0;
+       uselongblock[1]=0;
+      }
+  }
+
+  /* update the blocktype of the previous granule, since it depends on what
+   * happend in this granule */
+  for (chn=0; chn<gfc->channels_out; chn++) {
+    if ( uselongblock[chn])
+      {                                /* no attack : use long blocks */
+       assert( gfc->blocktype_old[chn] != START_TYPE );
+       switch( gfc->blocktype_old[chn] ) 
+         {
+         case NORM_TYPE:
+         case STOP_TYPE:
+           blocktype[chn] = NORM_TYPE;
+           break;
+         case SHORT_TYPE:
+           blocktype[chn] = STOP_TYPE; 
+           break;
+         }
+      } else   {
+       /* attack : use short blocks */
+       blocktype[chn] = SHORT_TYPE;
+       if ( gfc->blocktype_old[chn] == NORM_TYPE ) {
+         gfc->blocktype_old[chn] = START_TYPE;
+       }
+       if ( gfc->blocktype_old[chn] == STOP_TYPE ) {
+         gfc->blocktype_old[chn] = SHORT_TYPE ;
+       }
+      }
+    
+    blocktype_d[chn] = gfc->blocktype_old[chn];  /* value returned to calling program */
+    gfc->blocktype_old[chn] = blocktype[chn];    /* save for next call to l3psy_anal */
+
+    if (gfc->presetTune.use) {
+        if (blocktype_d[chn] != NORM_TYPE)
+            gfc->presetTune.quantcomp_current = gfc->presetTune.quantcomp_type_s;
+        else
+            gfc->presetTune.quantcomp_current = gfp->experimentalX;
+    
+        if (gfc->ATH->adjust >= gfc->presetTune.athadjust_switch_level && 
+                                                    blocktype_d[chn] == NORM_TYPE &&
+                                                                                gfc->presetTune.quantcomp_alt_type > -1) {
+                   gfc->presetTune.quantcomp_current = gfc->presetTune.quantcomp_alt_type;
+               }
+    }
+  }
+  
+  /*********************************************************************
+   * compute the value of PE to return (one granule delay)
+   *********************************************************************/
+  for(chn=0;chn<numchn;chn++)
+    {
+      if (chn < 2) {
+       if (blocktype_d[chn] == SHORT_TYPE) {
+         percep_entropy[chn] = pe_s[chn];
+       } else {
+         percep_entropy[chn] = pe_l[chn];
+       }
+       if (gfp->analysis) gfc->pinfo->pe[gr_out][chn] = percep_entropy[chn];
+      } else {
+       if (blocktype_d[0] == SHORT_TYPE) {
+         percep_MS_entropy[chn-2] = pe_s[chn];
+       } else {
+         percep_MS_entropy[chn-2] = pe_l[chn];
+       }
+       if (gfp->analysis) gfc->pinfo->pe[gr_out][chn] = percep_MS_entropy[chn-2];
+      }
+    }
+
+  return 0;
+}
+
+
+
+
+
+/* 
+ *   The spreading function.  Values returned in units of energy
+ */
+FLOAT8 s3_func(FLOAT8 bark) {
+    
+    FLOAT8 tempx,x,tempy,temp;
+    tempx = bark;
+    if (tempx>=0) tempx *= 3;
+    else tempx *=1.5; 
+    
+    if(tempx>=0.5 && tempx<=2.5)
+       {
+           temp = tempx - 0.5;
+           x = 8.0 * (temp*temp - 2.0 * temp);
+       }
+    else x = 0.0;
+    tempx += 0.474;
+    tempy = 15.811389 + 7.5*tempx - 17.5*sqrt(1.0+tempx*tempx);
+    
+    if (tempy <= -60.0) return  0.0;
+
+    tempx = exp( (x + tempy)*LN_TO_LOG10 ); 
+
+    /* Normalization.  The spreading function should be normalized so that:
+         +inf
+           /
+           |  s3 [ bark ]  d(bark)   =  1
+           /
+         -inf
+    */
+    tempx /= .6609193;
+    return tempx;
+    
+}
+
+
+
+
+
+
+
+
+int L3para_read(lame_global_flags * gfp, FLOAT8 sfreq, int *numlines_l,int *numlines_s, 
+FLOAT8 *minval,
+FLOAT8 s3_l[CBANDS][CBANDS], FLOAT8 s3_s[CBANDS][CBANDS],
+FLOAT8 *SNR, 
+int *bu_l, int *bo_l, FLOAT8 *w1_l, FLOAT8 *w2_l, 
+int *bu_s, int *bo_s, FLOAT8 *w1_s, FLOAT8 *w2_s,
+int *npart_l_orig,int *npart_l,int *npart_s_orig,int *npart_s)
+{
+  lame_internal_flags *gfc=gfp->internal_flags;
+
+
+  FLOAT8 bval_l[CBANDS], bval_s[CBANDS];
+  FLOAT8 bval_l_width[CBANDS], bval_s_width[CBANDS];
+  int  i,j;
+  int partition[HBLKSIZE]; 
+
+
+
+  /* compute numlines, the number of spectral lines in each partition band */
+  /* each partition band should be about DELBARK wide. */
+  j=0;
+  for(i=0;i<CBANDS;i++)
+    {
+      FLOAT8 ji, bark1,bark2;
+      int k,j2;
+
+      j2 = j;
+      j2 = Min(j2,BLKSIZE/2);
+      
+      do {
+       /* find smallest j2 >= j so that  (bark - bark_l[i-1]) < DELBARK */
+       ji = j;
+       bark1 = freq2bark(sfreq*ji/BLKSIZE);
+       
+       ++j2;
+       ji = j2;
+       bark2  = freq2bark(sfreq*ji/BLKSIZE);
+      } while ((bark2 - bark1) < DELBARK  && j2<=BLKSIZE/2);
+
+      for (k=j; k<j2; ++k)
+       partition[k]=i;
+      numlines_l[i]=(j2-j);
+      j = j2;
+      if (j > BLKSIZE/2) break;
+    }
+  *npart_l_orig = i+1;
+  assert(*npart_l_orig <= CBANDS);
+
+  /* compute which partition bands are in which scalefactor bands */
+  { int i1,i2,sfb,start,end;
+    FLOAT8 freq1,freq2;
+    for ( sfb = 0; sfb < SBMAX_l; sfb++ ) {
+      start = gfc->scalefac_band.l[ sfb ];
+      end   = gfc->scalefac_band.l[ sfb+1 ];
+      freq1 = sfreq*(start-.5)/(2*576);
+      freq2 = sfreq*(end-1+.5)/(2*576);
+                    
+      i1 = floor(.5 + BLKSIZE*freq1/sfreq);
+      if (i1<0) i1=0;
+      i2 = floor(.5 + BLKSIZE*freq2/sfreq);
+      if (i2>BLKSIZE/2) i2=BLKSIZE/2;
+
+      //      DEBUGF(gfc,"longblock:  old: (%i,%i)  new: (%i,%i) %i %i \n",bu_l[sfb],bo_l[sfb],partition[i1],partition[i2],i1,i2);
+
+      w1_l[sfb]=.5;
+      w2_l[sfb]=.5;
+      bu_l[sfb]=partition[i1];
+      bo_l[sfb]=partition[i2];
+
+    }
+  }
+
+
+  /* compute bark value and ATH of each critical band */
+  j = 0;
+  for ( i = 0; i < *npart_l_orig; i++ ) {
+      int     k;
+      FLOAT8  bark1,bark2;
+      /* FLOAT8 mval,freq; */
+
+      // Calculating the medium bark scaled frequency of the spectral lines
+      // from j ... j + numlines[i]-1  (=spectral lines in parition band i)
+
+      k         = numlines_l[i] - 1;
+      bark1 = freq2bark(sfreq*(j+0)/BLKSIZE);
+      bark2 = freq2bark(sfreq*(j+k)/BLKSIZE);
+      bval_l[i] = .5*(bark1+bark2);
+
+      bark1 = freq2bark(sfreq*(j+0-.5)/BLKSIZE);
+      bark2 = freq2bark(sfreq*(j+k+.5)/BLKSIZE);
+      bval_l_width[i] = bark2-bark1;
+
+      gfc->ATH->cb [i] = 1.e37; // preinit for minimum search
+      for (k=0; k < numlines_l[i]; k++, j++) {
+       FLOAT8  freq = sfreq*j/(1000.0*BLKSIZE);
+       FLOAT8  level;
+       assert( freq <= 24 );              // or only '<'
+       //      freq = Min(.1,freq);       // ATH below 100 Hz constant, not further climbing
+       level  = ATHformula (freq*1000, gfp) - 20;   // scale to FFT units; returned value is in dB
+       level  = pow ( 10., 0.1*level );   // convert from dB -> energy
+       level *= numlines_l [i];
+       if ( level < gfc->ATH->cb [i] )
+           gfc->ATH->cb [i] = level;
+      }
+
+
+    }
+
+  /* MINVAL.  For low freq, the strength of the masking is limited by minval
+   * this is an ISO MPEG1 thing, dont know if it is really needed */
+  for(i=0;i<*npart_l_orig;i++){
+    double x = (-20+bval_l[i]*20.0/10.0);
+    if (bval_l[i]>10) x = 0;
+    minval[i]=pow(10.0,x/10);
+    gfc->PSY->prvTonRed[i] = minval[i];
+  }
+
+
+
+
+
+
+
+  /************************************************************************/
+  /* SHORT BLOCKS */
+  /************************************************************************/
+
+  /* compute numlines */
+  j=0;
+  for(i=0;i<CBANDS;i++)
+    {
+      FLOAT8 ji, bark1,bark2;
+      int k,j2;
+
+      j2 = j;
+      j2 = Min(j2,BLKSIZE_s/2);
+      
+      do {
+       /* find smallest j2 >= j so that  (bark - bark_s[i-1]) < DELBARK */
+       ji = j;
+       bark1  = freq2bark(sfreq*ji/BLKSIZE_s);
+       
+       ++j2;
+       ji = j2;
+       bark2  = freq2bark(sfreq*ji/BLKSIZE_s);
+
+      } while ((bark2 - bark1) < DELBARK  && j2<=BLKSIZE_s/2);
+
+      for (k=j; k<j2; ++k)
+       partition[k]=i;
+      numlines_s[i]=(j2-j);
+      j = j2;
+      if (j > BLKSIZE_s/2) break;
+    }
+  *npart_s_orig = i+1;
+  assert(*npart_s_orig <= CBANDS);
+
+  /* compute which partition bands are in which scalefactor bands */
+  { int i1,i2,sfb,start,end;
+    FLOAT8 freq1,freq2;
+    for ( sfb = 0; sfb < SBMAX_s; sfb++ ) {
+      start = gfc->scalefac_band.s[ sfb ];
+      end   = gfc->scalefac_band.s[ sfb+1 ];
+      freq1 = sfreq*(start-.5)/(2*192);
+      freq2 = sfreq*(end-1+.5)/(2*192);
+                    
+      i1 = floor(.5 + BLKSIZE_s*freq1/sfreq);
+      if (i1<0) i1=0;
+      i2 = floor(.5 + BLKSIZE_s*freq2/sfreq);
+      if (i2>BLKSIZE_s/2) i2=BLKSIZE_s/2;
+
+      //DEBUGF(gfc,"shortblock: old: (%i,%i)  new: (%i,%i) %i %i \n",bu_s[sfb],bo_s[sfb], partition[i1],partition[i2],i1,i2);
+
+      w1_s[sfb]=.5;
+      w2_s[sfb]=.5;
+      bu_s[sfb]=partition[i1];
+      bo_s[sfb]=partition[i2];
+
+    }
+  }
+
+
+
+
+
+  /* compute bark values of each critical band */
+  j = 0;
+  for(i=0;i<*npart_s_orig;i++)
+    {
+      int     k;
+      FLOAT8  bark1,bark2,snr;
+      k    = numlines_s[i] - 1;
+
+      bark1 = freq2bark (sfreq*(j+0)/BLKSIZE_s);
+      bark2 = freq2bark (sfreq*(j+k)/BLKSIZE_s); 
+      bval_s[i] = .5*(bark1+bark2);
+
+      bark1 = freq2bark (sfreq*(j+0-.5)/BLKSIZE_s);
+      bark2 = freq2bark (sfreq*(j+k+.5)/BLKSIZE_s); 
+      bval_s_width[i] = bark2-bark1;
+      j        += k+1;
+      
+      /* SNR formula */
+      if (bval_s[i]<13)
+          snr=-8.25;
+      else 
+         snr  = -4.5 * (bval_s[i]-13)/(24.0-13.0)  + 
+             -8.25*(bval_s[i]-24)/(13.0-24.0);
+
+      SNR[i]=pow(10.0,snr/10.0);
+    }
+
+
+
+
+
+
+  /************************************************************************
+   * Now compute the spreading function, s[j][i], the value of the spread-*
+   * ing function, centered at band j, for band i, store for later use    *
+   ************************************************************************/
+  /* i.e.: sum over j to spread into signal barkval=i  
+     NOTE: i and j are used opposite as in the ISO docs */
+  for(i=0;i<*npart_l_orig;i++)    {
+      for(j=0;j<*npart_l_orig;j++)     {
+         s3_l[i][j]=s3_func(bval_l[i]-bval_l[j])*bval_l_width[j];
+      }
+  }
+  for(i=0;i<*npart_s_orig;i++)     {
+      for(j=0;j<*npart_s_orig;j++)     {
+         s3_s[i][j]=s3_func(bval_s[i]-bval_s[j])*bval_s_width[j];
+      }
+  }
+  
+
+
+
+  /* compute: */
+  /* npart_l_orig   = number of partition bands before convolution */
+  /* npart_l  = number of partition bands after convolution */
+  
+  *npart_l=bo_l[NBPSY_l-1]+1;
+  *npart_s=bo_s[NBPSY_s-1]+1;
+  
+  assert(*npart_l <= *npart_l_orig);
+  assert(*npart_s <= *npart_s_orig);
+
+
+    /* setup stereo demasking thresholds */
+    /* formula reverse enginerred from plot in paper */
+    for ( i = 0; i < NBPSY_s; i++ ) {
+      FLOAT8 arg,mld;
+      arg = freq2bark(sfreq*gfc->scalefac_band.s[i]/(2*192));
+      arg = (Min(arg, 15.5)/15.5);
+
+      mld = 1.25*(1-cos(PI*arg))-2.5;
+      gfc->mld_s[i] = pow(10.0,mld);
+    }
+    for ( i = 0; i < NBPSY_l; i++ ) {
+      FLOAT8 arg,mld;
+      arg = freq2bark(sfreq*gfc->scalefac_band.l[i]/(2*576));
+      arg = (Min(arg, 15.5)/15.5);
+
+      mld = 1.25*(1-cos(PI*arg))-2.5;
+      gfc->mld_l[i] = pow(10.0,mld);
+    }
+
+#define temporalmask_sustain_sec 0.01
+
+    /* setup temporal masking */
+    gfc->decay = exp(-1.0*LOG10/(temporalmask_sustain_sec*sfreq/192.0));
+
+    return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+int psymodel_init(lame_global_flags *gfp)
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    int i,j,b,sb,k,samplerate;
+
+    FLOAT8 s3_s[CBANDS][CBANDS];
+    FLOAT8 s3_l[CBANDS][CBANDS];
+    int numberOfNoneZero;
+
+    samplerate = gfp->out_samplerate;
+    gfc->ms_ener_ratio_old=.25;
+    gfc->blocktype_old[0]=STOP_TYPE;
+    gfc->blocktype_old[1]=STOP_TYPE;
+    gfc->blocktype_old[0]=SHORT_TYPE;
+    gfc->blocktype_old[1]=SHORT_TYPE;
+
+    for (i=0; i<4; ++i) {
+      for (j=0; j<CBANDS; ++j) {
+       gfc->nb_1[i][j]=1e20;
+       gfc->nb_2[i][j]=1e20;
+      }
+      for ( sb = 0; sb < NBPSY_l; sb++ ) {
+       gfc->en[i].l[sb] = 1e20;
+       gfc->thm[i].l[sb] = 1e20;
+      }
+      for (j=0; j<3; ++j) {
+       for ( sb = 0; sb < NBPSY_s; sb++ ) {
+         gfc->en[i].s[sb][j] = 1e20;
+         gfc->thm[i].s[sb][j] = 1e20;
+       }
+      }
+    }
+    for (i=0; i<4; ++i) {
+      for (j=0; j<3; ++j) {
+       for ( sb = 0; sb < NBPSY_s; sb++ ) {
+         gfc->nsPsy.last_thm[i][sb][j] = 1e20;
+       }
+      }
+    }
+    for(i=0;i<4;i++) {
+      for(j=0;j<9;j++)
+       gfc->nsPsy.last_en_subshort[i][j] = 100;
+      for(j=0;j<3;j++)
+       gfc->nsPsy.last_attacks[i][j] = 0;
+      gfc->nsPsy.pe_l[i] = gfc->nsPsy.pe_s[i] = 0;
+    }
+
+
+
+    
+    /*  gfp->cwlimit = sfreq*j/1024.0;  */
+    gfc->cw_lower_index=6;
+    gfc->cw_upper_index = gfc->PSY->cwlimit*1024.0/gfp->out_samplerate;
+    gfc->cw_upper_index=Min(HBLKSIZE-4,gfc->cw_upper_index);      /* j+3 < HBLKSIZE-1 */
+    gfc->cw_upper_index=Max(6,gfc->cw_upper_index);
+
+    for ( j = 0; j < HBLKSIZE; j++ )
+      gfc->cw[j] = 0.4f;
+    
+    
+
+    i=L3para_read( gfp,(FLOAT8) samplerate,gfc->numlines_l,gfc->numlines_s,
+          gfc->minval,s3_l,s3_s,gfc->SNR_s,gfc->bu_l,
+          gfc->bo_l,gfc->w1_l,gfc->w2_l, gfc->bu_s,gfc->bo_s,
+          gfc->w1_s,gfc->w2_s,&gfc->npart_l_orig,&gfc->npart_l,
+          &gfc->npart_s_orig,&gfc->npart_s );
+    if (i!=0) return -1;
+    
+
+
+    /* npart_l_orig   = number of partition bands before convolution */
+    /* npart_l  = number of partition bands after convolution */
+    
+    numberOfNoneZero = 0;
+    for (i=0; i<gfc->npart_l; i++) {
+      for (j = 0; j < gfc->npart_l_orig; j++) {
+       if (s3_l[i][j] != 0.0)
+         break;
+      }
+      gfc->s3ind[i][0] = j;
+      
+      for (j = gfc->npart_l_orig - 1; j > 0; j--) {
+       if (s3_l[i][j] != 0.0)
+         break;
+      }
+      gfc->s3ind[i][1] = j;
+      numberOfNoneZero += (gfc->s3ind[i][1] - gfc->s3ind[i][0] + 1);
+    }
+    gfc->s3_ll = malloc(sizeof(FLOAT8)*numberOfNoneZero);
+    if (!gfc->s3_ll)
+      return -1;
+
+    k = 0;
+    for (i=0; i<gfc->npart_l; i++) {
+      for (j = gfc->s3ind[i][0]; j <= gfc->s3ind[i][1]; j++) {
+       gfc->s3_ll[k++] = s3_l[i][j];
+      }
+    }
+
+
+
+    numberOfNoneZero = 0;
+    for (i=0; i<gfc->npart_s; i++) {
+      for (j = 0; j < gfc->npart_s_orig; j++) {
+       if (s3_s[i][j] != 0.0)
+         break;
+      }
+      gfc->s3ind_s[i][0] = j;
+      
+      for (j = gfc->npart_s_orig - 1; j > 0; j--) {
+       if (s3_s[i][j] != 0.0)
+         break;
+      }
+      gfc->s3ind_s[i][1] = j;
+      numberOfNoneZero += (gfc->s3ind_s[i][1] - gfc->s3ind_s[i][0] + 1);
+    }
+    gfc->s3_ss = malloc(sizeof(FLOAT8)*numberOfNoneZero);
+    if (!gfc->s3_ss)
+      return -1;
+
+
+    
+    
+    /*  
+      #include "debugscalefac.c"
+    */
+    
+
+
+    if (gfc->nsPsy.use) {
+       /* long block spreading function normalization */
+       for ( b = 0;b < gfc->npart_l; b++ ) {
+           for ( k = gfc->s3ind[b][0]; k <= gfc->s3ind[b][1]; k++ ) {
+               // spreading function has been properly normalized by
+               // multiplying by DELBARK/.6609193 = .515.  
+               // It looks like Naoki was
+                // way ahead of me and added this factor here!
+               // it is no longer needed.
+               //gfc->s3_l[b][k] *= 0.5;
+           }
+       }
+       /* short block spreading function normalization */
+       // no longer needs to be normalized, but nspsytune wants 
+       // SNR_s applied here istead of later to save CPU cycles
+       for ( b = 0;b < gfc->npart_s; b++ ) {
+           FLOAT8 norm=0;
+           for ( k = gfc->s3ind_s[b][0]; k <= gfc->s3ind_s[b][1]; k++ ) {
+               norm += s3_s[b][k];
+           }
+           for ( k = gfc->s3ind_s[b][0]; k <= gfc->s3ind_s[b][1]; k++ ) {
+               s3_s[b][k] *= gfc->SNR_s[b] /* / norm */;
+           }
+       }
+    }
+
+
+
+    if (gfc->nsPsy.use) {
+#if 1
+       /* spread only from npart_l bands.  Normally, we use the spreading
+        * function to convolve from npart_l_orig down to npart_l bands 
+        */
+       for(b=0;b<gfc->npart_l;b++)
+           if (gfc->s3ind[b][1] > gfc->npart_l-1) gfc->s3ind[b][1] = gfc->npart_l-1;
+#endif
+    }
+    k = 0;
+    for (i=0; i<gfc->npart_s; i++) {
+      for (j = gfc->s3ind_s[i][0]; j <= gfc->s3ind_s[i][1]; j++) {
+       gfc->s3_ss[k++] = s3_s[i][j];
+      }
+    }
+
+
+
+                               /* init. for loudness approx. -jd 2001 mar 27*/
+    gfc->loudness_sq_save[0] = 0.0;
+    gfc->loudness_sq_save[1] = 0.0;
+
+
+
+    return 0;
+}
+
+
+
+
+
+/* psycho_loudness_approx
+   jd - 2001 mar 12
+in:  energy   - BLKSIZE/2 elements of frequency magnitudes ^ 2
+     gfp      - uses out_samplerate, ATHtype (also needed for ATHformula)
+returns: loudness^2 approximation, a positive value roughly tuned for a value
+         of 1.0 for signals near clipping.
+notes:   When calibrated, feeding this function binary white noise at sample
+         values +32767 or -32768 should return values that approach 3.
+         ATHformula is used to approximate an equal loudness curve.
+future:  Data indicates that the shape of the equal loudness curve varies
+         with intensity.  This function might be improved by using an equal
+         loudness curve shaped for typical playback levels (instead of the
+         ATH, that is shaped for the threshold).  A flexible realization might
+         simply bend the existing ATH curve to achieve the desired shape.
+         However, the potential gain may not be enough to justify an effort.
+*/
+FLOAT
+psycho_loudness_approx( FLOAT *energy, lame_global_flags *gfp )
+{
+  int i;
+  static int eql_type = -1;
+  static FLOAT eql_w[BLKSIZE/2];/* equal loudness weights (based on ATH) */
+  const FLOAT vo_scale= 1./( 14752 ); /* tuned for output level */
+                                     /* (sensitive to energy scale) */
+  FLOAT loudness_power;
+
+  if( eql_type != gfp->ATHtype ) { 
+                               /* compute equal loudness weights (eql_w) */
+    FLOAT freq;
+    FLOAT freq_inc = gfp->out_samplerate / (BLKSIZE);
+    FLOAT eql_balance = 0.0;
+    eql_type = gfp->ATHtype;
+    freq = 0.0;
+    for( i = 0; i < BLKSIZE/2; ++i ) {
+      freq += freq_inc;
+                               /* convert ATH dB to relative power (not dB) */
+                               /*  to determine eql_w */
+      eql_w[i] = 1. / pow( 10, ATHformula( freq, gfp ) / 10 );
+      eql_balance += eql_w[i];
+    }
+    eql_balance = 1 / eql_balance;
+    for( i = BLKSIZE/2; --i >= 0; ) { /* scale weights */
+      eql_w[i] *= eql_balance;
+    }
+  }
+
+  loudness_power = 0.0;
+  for( i = 0; i < BLKSIZE/2; ++i ) { /* apply weights to power in freq. bands*/
+    loudness_power += energy[i] * eql_w[i];
+  }
+  loudness_power /= (BLKSIZE/2);
+  loudness_power *= vo_scale * vo_scale;
+
+  return( loudness_power );
+}
diff --git a/lib/lame/psymodel.h b/lib/lame/psymodel.h
new file mode 100644 (file)
index 0000000..e1c267c
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *     psymodel.h
+ *
+ *     Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_PSYMODEL_H
+#define LAME_PSYMODEL_H
+
+#include "l3side.h"
+
+int L3psycho_anal( lame_global_flags *gfc,
+                    const sample_t *buffer[2], int gr, 
+                   FLOAT8 *ms_ratio, 
+                   FLOAT8 *ms_ratio_next, 
+                   III_psy_ratio ratio[2][2],
+                   III_psy_ratio MS_ratio[2][2],
+                  FLOAT8 pe[2], FLOAT8 pe_MS[2], FLOAT8 ener[2],
+                    int blocktype_d[2]); 
+
+int L3psycho_anal_ns( lame_global_flags *gfc,
+                     const sample_t *buffer[2], int gr, 
+                     FLOAT8 *ms_ratio, 
+                     FLOAT8 *ms_ratio_next, 
+                     III_psy_ratio ratio[2][2],
+                     III_psy_ratio MS_ratio[2][2],
+                     FLOAT8 pe[2], FLOAT8 pe_MS[2], FLOAT8 ener[2],
+                     int blocktype_d[2]); 
+
+
+int psymodel_init(lame_global_flags *gfp);
+
+
+#endif /* LAME_PSYMODEL_H */
diff --git a/lib/lame/quantize.c b/lib/lame/quantize.c
new file mode 100644 (file)
index 0000000..0095bb7
--- /dev/null
@@ -0,0 +1,1776 @@
+/*
+ * MP3 quantization
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: quantize.c,v 1.1 2002/04/28 17:30:24 kramm Exp $ */
+
+#include "config_static.h"
+
+#include <math.h>
+#include <assert.h>
+#include "util.h"
+#include "l3side.h"
+#include "quantize.h"
+#include "reservoir.h"
+#include "quantize_pvt.h"
+#include "lame-analysis.h"
+#include "vbrquantize.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+
+/************************************************************************
+ *
+ *      init_outer_loop()
+ *  mt 6/99                                    
+ *
+ *  initializes cod_info, scalefac and xrpow
+ *
+ *  returns 0 if all energies in xr are zero, else 1                    
+ *
+ ************************************************************************/
+
+static int 
+init_outer_loop(
+    lame_internal_flags *gfc,
+    gr_info *const cod_info, 
+    III_scalefac_t *const scalefac, 
+    const FLOAT8 xr[576], 
+    FLOAT8 xrpow[576] )
+{
+    FLOAT8 tmp, sum = 0;
+    int i;
+
+    /*  initialize fresh cod_info
+     */
+    cod_info->part2_3_length      = 0;
+    cod_info->big_values          = 0;
+    cod_info->count1              = 0;
+    cod_info->global_gain         = 210;
+    cod_info->scalefac_compress   = 0;
+    /* window_switching_flag was set in psymodel.c? */
+    /* block_type            was set in psymodel.c? */
+    /* mixed_block_flag      would be set in ^      */
+    cod_info->table_select [0]    = 0;
+    cod_info->table_select [1]    = 0;
+    cod_info->table_select [2]    = 0;
+    cod_info->subblock_gain[0]    = 0;
+    cod_info->subblock_gain[1]    = 0;
+    cod_info->subblock_gain[2]    = 0;
+    cod_info->region0_count       = 0;
+    cod_info->region1_count       = 0;
+    cod_info->preflag             = 0;
+    cod_info->scalefac_scale      = 0;
+    cod_info->count1table_select  = 0;
+    cod_info->part2_length        = 0;
+    if (cod_info->block_type == SHORT_TYPE) {
+        cod_info->sfb_lmax        = 0;
+        cod_info->sfb_smin        = 0;
+       if (cod_info->mixed_block_flag) {
+            /*
+             *  MPEG-1:      sfbs 0-7 long block, 3-12 short blocks 
+             *  MPEG-2(.5):  sfbs 0-5 long block, 3-12 short blocks
+             */ 
+            cod_info->sfb_lmax    = gfc->is_mpeg1 ? 8 : 6;
+           cod_info->sfb_smin    = 3;
+       }
+    } else {
+        cod_info->sfb_lmax        = SBPSY_l;
+        cod_info->sfb_smin        = SBPSY_s;
+    }   
+    cod_info->count1bits          = 0;  
+    cod_info->sfb_partition_table = nr_of_sfb_block[0][0];
+    cod_info->slen[0]             = 0;
+    cod_info->slen[1]             = 0;
+    cod_info->slen[2]             = 0;
+    cod_info->slen[3]             = 0;
+
+    /*  fresh scalefactors are all zero
+     */
+    memset(scalefac, 0, sizeof(III_scalefac_t));
+    memset(&gfc->pseudohalf, 0, sizeof(gfc->pseudohalf));
+
+    /*  check if there is some energy we have to quantize
+     *  and calculate xrpow matching our fresh scalefactors
+     */
+    for (i = 0; i < 576; ++i) {
+        tmp = fabs (xr[i]);
+       sum += tmp;
+        xrpow[i] = sqrt (tmp * sqrt(tmp));
+    }
+   /*  return 1 if we have something to quantize, else 0
+    */
+   return sum > (FLOAT8)1E-20;
+}
+
+
+
+/************************************************************************
+ *
+ *      bin_search_StepSize()
+ *
+ *  author/date??
+ *
+ *  binary step size search
+ *  used by outer_loop to get a quantizer step size to start with
+ *
+ ************************************************************************/
+
+typedef enum {
+    BINSEARCH_NONE,
+    BINSEARCH_UP, 
+    BINSEARCH_DOWN
+} binsearchDirection_t;
+
+int 
+bin_search_StepSize(
+          lame_internal_flags * const gfc,
+          gr_info * const cod_info,
+    const int             desired_rate, 
+    const int             start, 
+    const FLOAT8          xrpow [576],
+          int             l3enc [576] ) 
+{
+    int nBits;
+    int CurrentStep;
+    int flag_GoneOver = 0;
+    int StepSize      = start;
+
+    binsearchDirection_t Direction = BINSEARCH_NONE;
+    assert(gfc->CurrentStep);
+    CurrentStep = gfc->CurrentStep;
+
+    do {
+        cod_info->global_gain = StepSize;
+        nBits = count_bits(gfc,l3enc,xrpow,cod_info);  
+
+        if (CurrentStep == 1) break; /* nothing to adjust anymore */
+    
+        if (flag_GoneOver) CurrentStep /= 2;
+        if (nBits > desired_rate) {  
+            /* increase Quantize_StepSize */
+            if (Direction == BINSEARCH_DOWN && !flag_GoneOver) {
+                flag_GoneOver = 1;
+                CurrentStep  /= 2; /* late adjust */
+            }
+            Direction = BINSEARCH_UP;
+            StepSize += CurrentStep;
+            if (StepSize > 255) break;
+        }
+        else if (nBits < desired_rate) {
+            /* decrease Quantize_StepSize */
+            if (Direction == BINSEARCH_UP && !flag_GoneOver) {
+                flag_GoneOver = 1;
+                CurrentStep  /= 2; /* late adjust */
+            }
+            Direction = BINSEARCH_DOWN;
+            StepSize -= CurrentStep;
+            if (StepSize < 0) break;
+        }
+        else break; /* nBits == desired_rate;; most unlikely to happen.*/
+    } while (1); /* For-ever, break is adjusted. */
+
+    CurrentStep = start - StepSize;
+    
+    gfc->CurrentStep = CurrentStep/4 != 0 ? 4 : 2;
+
+    return nBits;
+}
+
+
+
+
+/*************************************************************************** 
+ *
+ *         inner_loop ()                                                     
+ *
+ *  author/date??
+ *
+ *  The code selects the best global gain for a particular set of scalefacs 
+ *
+ ***************************************************************************/ 
+
+int 
+inner_loop(
+          lame_internal_flags * const gfc,
+          gr_info * const cod_info,
+    const int             max_bits,
+    const FLOAT8          xrpow [576],
+          int             l3enc [576] )
+{
+    int bits;
+    
+    assert(max_bits >= 0);
+
+    /*  scalefactors may have changed, so count bits
+     */
+    bits=count_bits(gfc,l3enc,xrpow,cod_info);
+
+    /*  increase quantizer stepsize until needed bits are below maximum
+     */
+    while (bits > max_bits) {
+        cod_info->global_gain++;
+        bits = count_bits (gfc, l3enc, xrpow, cod_info);
+    } 
+
+    return bits;
+}
+
+
+
+/*************************************************************************
+ *
+ *      loop_break()                                               
+ *
+ *  author/date??
+ *
+ *  Function: Returns zero if there is a scalefac which has not been
+ *            amplified. Otherwise it returns one. 
+ *
+ *************************************************************************/
+
+inline 
+static int
+loop_break( 
+    const gr_info        * const cod_info,
+    const III_scalefac_t * const scalefac ) 
+{
+    int i, sfb;
+
+    for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++)
+        if (scalefac->l[sfb] == 0)
+            return 0;
+
+    for (sfb = cod_info->sfb_smin; sfb < SBPSY_s; sfb++)
+        for (i = 0; i < 3; i++) 
+            if (scalefac->s[sfb][i] == 0 && cod_info->subblock_gain[i] == 0)
+                return 0;
+
+    return 1;
+}
+
+
+
+
+/*************************************************************************
+ *
+ *      quant_compare()                                               
+ *
+ *  author/date??
+ *
+ *  several different codes to decide which quantization is better
+ *
+ *************************************************************************/
+
+inline 
+static int 
+quant_compare(
+    const int                       experimentalX,
+          lame_internal_flags * const gfc,
+    const calc_noise_result * const best,
+    const calc_noise_result   * const calc,
+       const int                         block_type )
+{
+    /*
+       noise is given in decibels (dB) relative to masking thesholds.
+
+       over_noise:  ??? (the previous comment is fully wrong)
+       tot_noise:   ??? (the previous comment is fully wrong)
+       max_noise:   max quantization noise 
+
+     */
+    int better;
+
+    switch (experimentalX) {
+        default:
+        case 0: 
+           better = calc->over_count  < best->over_count
+               ||  ( calc->over_count == best->over_count  &&
+                     calc->over_noise  < best->over_noise )
+               ||  ( calc->over_count == best->over_count  &&
+                     calc->over_noise == best->over_noise  &&
+                     calc->tot_noise   < best->tot_noise  ); 
+           break;
+        case 1: 
+           better = calc->max_noise < best->max_noise; 
+           break;
+        case 2: 
+           better = calc->tot_noise < best->tot_noise; 
+           break;
+        case 3: 
+               better = ( calc->tot_noise < (gfc->presetTune.use &&
+                                      block_type != NORM_TYPE ? (best->tot_noise - gfc->presetTune.quantcomp_adjust_rh_tot)
+                                                          :  best->tot_noise ) &&
+                   calc->max_noise < (gfc->presetTune.use &&
+                                      block_type != NORM_TYPE ? (best->max_noise - gfc->presetTune.quantcomp_adjust_rh_max)
+                                                          :  best->max_noise ));
+           break;
+        case 4: 
+           better = ( calc->max_noise <= 0  &&
+                       best->max_noise >  2 )
+                 ||  ( calc->max_noise <= 0  &&
+                       best->max_noise <  0  &&
+                       best->max_noise >  calc->max_noise-2  &&
+                       calc->tot_noise <  best->tot_noise )
+                 ||  ( calc->max_noise <= 0  &&
+                       best->max_noise >  0  &&
+                       best->max_noise >  calc->max_noise-2  &&
+                       calc->tot_noise <  best->tot_noise+best->over_noise )
+                 ||  ( calc->max_noise >  0  &&
+                       best->max_noise > -0.5  &&
+                       best->max_noise >  calc->max_noise-1  &&
+                       calc->tot_noise+calc->over_noise < best->tot_noise+best->over_noise )
+                 ||  ( calc->max_noise >  0  &&
+                       best->max_noise > -1  &&
+                       best->max_noise >  calc->max_noise-1.5  &&
+                       calc->tot_noise+calc->over_noise+calc->over_noise < best->tot_noise+best->over_noise+best->over_noise );
+            break;
+        case 5: 
+           better =   calc->over_noise  < best->over_noise
+                 ||  ( calc->over_noise == best->over_noise  &&
+                       calc->tot_noise   < best->tot_noise ); 
+           break;
+        case 6: 
+           better =   calc->over_noise  < best->over_noise
+                 ||  ( calc->over_noise == best->over_noise  &&
+                     ( calc->max_noise   < best->max_noise  
+                    ||  ( calc->max_noise  == best->max_noise  &&
+                           calc->tot_noise  <= best->tot_noise )
+                     )); 
+           break;
+        case 7: 
+           better =   calc->over_count < best->over_count
+                   ||  calc->over_noise < best->over_noise; 
+           break;
+        case 8: 
+           better =   calc->klemm_noise < best->klemm_noise;
+            break;
+    }   
+
+    return better;
+}
+
+
+
+/*************************************************************************
+ *
+ *          amp_scalefac_bands() 
+ *
+ *  author/date??
+ *        
+ *  Amplify the scalefactor bands that violate the masking threshold.
+ *  See ISO 11172-3 Section C.1.5.4.3.5
+ * 
+ *  distort[] = noise/masking
+ *  distort[] > 1   ==> noise is not masked
+ *  distort[] < 1   ==> noise is masked
+ *  max_dist = maximum value of distort[]
+ *  
+ *  Three algorithms:
+ *  noise_shaping_amp
+ *        0             Amplify all bands with distort[]>1.
+ *
+ *        1             Amplify all bands with distort[] >= max_dist^(.5);
+ *                     ( 50% in the db scale)
+ *
+ *        2             Amplify first band with distort[] >= max_dist;
+ *                       
+ *
+ *  For algorithms 0 and 1, if max_dist < 1, then amplify all bands 
+ *  with distort[] >= .95*max_dist.  This is to make sure we always
+ *  amplify at least one band.  
+ * 
+ *
+ *************************************************************************/
+static void 
+amp_scalefac_bands(
+    lame_global_flags *gfp,
+    const gr_info  *const cod_info, 
+    III_scalefac_t *const scalefac,
+    III_psy_xmin *distort,
+    FLOAT8 xrpow[576] )
+{
+  lame_internal_flags *gfc=gfp->internal_flags;
+  int start, end, l,i,j,sfb;
+  FLOAT8 ifqstep34, trigger;
+
+  if (cod_info->scalefac_scale == 0) {
+    ifqstep34 = 1.29683955465100964055; /* 2**(.75*.5)*/
+  } else {
+    ifqstep34 = 1.68179283050742922612;  /* 2**(.75*1) */
+  }
+
+  /* compute maximum value of distort[]  */
+  trigger = 0;
+  for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) {
+    if (trigger < distort->l[sfb])
+        trigger = distort->l[sfb];
+  }
+  for (sfb = cod_info->sfb_smin; sfb < SBPSY_s; sfb++) {
+    for (i = 0; i < 3; i++ ) {
+      if (trigger < distort->s[sfb][i])
+          trigger = distort->s[sfb][i];
+    }
+  }
+
+  switch (gfc->noise_shaping_amp) {
+
+  case 3:
+  case 2:
+    /* amplify exactly 1 band */
+    //trigger = distort_thresh;
+    break;
+
+  case 1:
+    /* amplify bands within 50% of max (on db scale) */
+    if (trigger>1.0)
+        trigger = pow(trigger, .5);
+    else
+      trigger *= .95;
+    break;
+
+  case 0:
+  default:
+    /* ISO algorithm.  amplify all bands with distort>1 */
+    if (trigger>1.0)
+        trigger=1.0;
+    else
+        trigger *= .95;
+    break;
+  }
+
+  for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++ ) {
+    start = gfc->scalefac_band.l[sfb];
+    end   = gfc->scalefac_band.l[sfb+1];
+    if (distort->l[sfb]>=trigger  ) {
+      if (gfc->noise_shaping_amp==3) {
+       if (gfc->pseudohalf.l[sfb]) {
+         gfc->pseudohalf.l[sfb] = 0;
+         goto done;
+       }
+       gfc->pseudohalf.l[sfb] = 1;
+      }
+      scalefac->l[sfb]++;
+      for ( l = start; l < end; l++ )
+       xrpow[l] *= ifqstep34;
+      if (gfc->noise_shaping_amp==2
+         ||gfc->noise_shaping_amp==3) goto done;
+    }
+  }
+  
+  for ( j=0,sfb = cod_info->sfb_smin; sfb < SBPSY_s; sfb++ ) {
+    start = gfc->scalefac_band.s[sfb];
+    end   = gfc->scalefac_band.s[sfb+1];
+    for ( i = 0; i < 3; i++ ) {
+      int j2 = j;
+      if ( distort->s[sfb][i]>=trigger) {
+       if (gfc->noise_shaping_amp==3) {
+         if (gfc->pseudohalf.s[sfb][i]) {
+           gfc->pseudohalf.s[sfb][i] = 0;
+           goto done;
+         }
+         gfc->pseudohalf.s[sfb][i] = 1;
+       }
+       scalefac->s[sfb][i]++;
+       for (l = start; l < end; l++) 
+         xrpow[j2++] *= ifqstep34;
+       if (gfc->noise_shaping_amp==2
+           ||gfc->noise_shaping_amp==3) goto done;
+      }
+      j += end-start;
+    }
+  }
+ done:
+ return;
+}
+
+/*************************************************************************
+ *
+ *      inc_scalefac_scale()
+ *
+ *  Takehiro Tominaga 2000-xx-xx
+ *
+ *  turns on scalefac scale and adjusts scalefactors
+ *
+ *************************************************************************/
+static void
+inc_scalefac_scale (
+    const lame_internal_flags        * const gfc, 
+          gr_info        * const cod_info, 
+          III_scalefac_t * const scalefac,
+          FLOAT8                 xrpow[576] )
+{
+    int start, end, l,i,j;
+    int sfb;
+    const FLOAT8 ifqstep34 = 1.29683955465100964055;
+
+    for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) {
+        int s = scalefac->l[sfb] + (cod_info->preflag ? pretab[sfb] : 0);
+        if (s & 1) {
+            s++;
+            start = gfc->scalefac_band.l[sfb];
+            end   = gfc->scalefac_band.l[sfb+1];
+            for (l = start; l < end; l++) 
+                xrpow[l] *= ifqstep34;
+        }
+        scalefac->l[sfb]  = s >> 1;
+        cod_info->preflag = 0;
+    }
+
+    for (j = 0, sfb = cod_info->sfb_smin; sfb < SBPSY_s; sfb++) {
+    start = gfc->scalefac_band.s[sfb];
+    end   = gfc->scalefac_band.s[sfb+1];
+    for (i = 0; i < 3; i++) {
+        int j2 = j;
+        if (scalefac->s[sfb][i] & 1) {
+        scalefac->s[sfb][i]++;
+        for (l = start; l < end; l++) 
+            xrpow[j2++] *= ifqstep34;
+        }
+        scalefac->s[sfb][i] >>= 1;
+        j += end-start;
+    }
+    }
+    cod_info->scalefac_scale = 1;
+}
+
+
+
+/*************************************************************************
+ *
+ *      inc_subblock_gain()
+ *
+ *  Takehiro Tominaga 2000-xx-xx
+ *
+ *  increases the subblock gain and adjusts scalefactors
+ *
+ *************************************************************************/
+static int 
+inc_subblock_gain (
+    const lame_internal_flags        * const gfc,
+          gr_info        * const cod_info,
+          III_scalefac_t * const scalefac,
+          FLOAT8                 xrpow[576] )
+{
+    int window;
+
+    for (window = 0; window < 3; window++) {
+        int s1, s2, l;
+        int sfb;
+        s1 = s2 = 0;
+
+        for (sfb = cod_info->sfb_smin; sfb < 6; sfb++) {
+            if (s1 < scalefac->s[sfb][window])
+            s1 = scalefac->s[sfb][window];
+        }
+        for (; sfb < SBPSY_s; sfb++) {
+            if (s2 < scalefac->s[sfb][window])
+            s2 = scalefac->s[sfb][window];
+        }
+
+        if (s1 < 16 && s2 < 8)
+            continue;
+
+        if (cod_info->subblock_gain[window] >= 7)
+            return 1;
+
+        /* even though there is no scalefactor for sfb12
+         * subblock gain affects upper frequencies too, that's why
+         * we have to go up to SBMAX_s
+         */
+        cod_info->subblock_gain[window]++;
+        for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) {
+            int i, width;
+            int s = scalefac->s[sfb][window];
+            FLOAT8 amp;
+
+            if (s < 0)
+                continue;
+            s = s - (4 >> cod_info->scalefac_scale);
+            if (s >= 0) {
+                scalefac->s[sfb][window] = s;
+                continue;
+            }
+
+            scalefac->s[sfb][window] = 0;
+            width = gfc->scalefac_band.s[sfb] - gfc->scalefac_band.s[sfb+1];
+            i = gfc->scalefac_band.s[sfb] * 3 + width * window;
+            amp = IPOW20(210 + (s << (cod_info->scalefac_scale + 1)));
+            for (l = 0; l < width; l++) {
+                xrpow[i++] *= amp;
+            }
+        }
+    }
+    return 0;
+}
+
+
+
+/********************************************************************
+ *
+ *      balance_noise()
+ *
+ *  Takehiro Tominaga /date??
+ *  Robert Hegemann 2000-09-06: made a function of it
+ *
+ *  amplifies scalefactor bands, 
+ *   - if all are already amplified returns 0
+ *   - if some bands are amplified too much:
+ *      * try to increase scalefac_scale
+ *      * if already scalefac_scale was set
+ *          try on short blocks to increase subblock gain
+ *
+ ********************************************************************/
+inline
+static int 
+balance_noise (
+    lame_global_flags  *const gfp,
+    gr_info        * const cod_info,
+    III_scalefac_t * const scalefac, 
+    III_psy_xmin           *distort,
+    FLOAT8                 xrpow[576] )
+{
+    lame_internal_flags *const gfc = (lame_internal_flags *)gfp->internal_flags;
+    int status;
+    
+    amp_scalefac_bands ( gfp, cod_info, scalefac, distort, xrpow);
+    
+    /* check to make sure we have not amplified too much 
+     * loop_break returns 0 if there is an unamplified scalefac
+     * scale_bitcount returns 0 if no scalefactors are too large
+     */
+    
+    status = loop_break (cod_info, scalefac);
+    
+    if (status) 
+        return 0; /* all bands amplified */
+    
+    /* not all scalefactors have been amplified.  so these 
+     * scalefacs are possibly valid.  encode them: 
+     */
+    if (gfc->is_mpeg1)
+        status = scale_bitcount (scalefac, cod_info);
+    else 
+        status = scale_bitcount_lsf (gfc, scalefac, cod_info);
+    
+    if (!status) 
+        return 1; /* amplified some bands not exceeding limits */
+    
+    /*  some scalefactors are too large.
+     *  lets try setting scalefac_scale=1 
+     */
+    if ((gfc->noise_shaping > 1) && (!(gfc->presetTune.use &&
+                                      gfc->ATH->adjust < gfc->presetTune.athadjust_switch_level))) {
+       memset(&gfc->pseudohalf, 0, sizeof(gfc->pseudohalf));
+       if (!cod_info->scalefac_scale) {
+           inc_scalefac_scale (gfc, cod_info, scalefac, xrpow);
+           status = 0;
+       } else {
+           if (cod_info->block_type == SHORT_TYPE ) {
+               status = inc_subblock_gain (gfc, cod_info, scalefac, xrpow)
+                   || loop_break (cod_info, scalefac);
+           }
+       }
+    }
+
+    if (!status) {
+        if (gfc->is_mpeg1 == 1) 
+            status = scale_bitcount (scalefac, cod_info);
+        else 
+            status = scale_bitcount_lsf (gfc, scalefac, cod_info);
+    }
+    return !status;
+}
+
+
+
+/************************************************************************
+ *
+ *  outer_loop ()                                                       
+ *
+ *  Function: The outer iteration loop controls the masking conditions  
+ *  of all scalefactorbands. It computes the best scalefac and          
+ *  global gain. This module calls the inner iteration loop             
+ * 
+ *  mt 5/99 completely rewritten to allow for bit reservoir control,   
+ *  mid/side channels with L/R or mid/side masking thresholds, 
+ *  and chooses best quantization instead of last quantization when 
+ *  no distortion free quantization can be found.  
+ *  
+ *  added VBR support mt 5/99
+ *
+ *  some code shuffle rh 9/00
+ ************************************************************************/
+
+static int 
+outer_loop (
+   lame_global_flags *gfp,
+          gr_info        * const cod_info,
+    const FLOAT8                 xr[576],   /* magnitudes of spectral values */
+    const III_psy_xmin   * const l3_xmin,   /* allowed distortion of the scalefactor */
+          III_scalefac_t * const scalefac,  /* scalefactors */
+          FLOAT8                 xrpow[576], /* coloured magnitudes of spectral values */
+          int                    l3enc[576], /* vector of quantized values ix(0..575) */
+    const int                    ch, 
+    const int                    targ_bits )  /* maximum allowed bits */
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    III_scalefac_t save_scalefac;
+    gr_info save_cod_info;
+    FLOAT8 save_xrpow[576];
+    III_psy_xmin   distort;
+    calc_noise_result noise_info;
+    calc_noise_result best_noise_info;
+    int l3_enc_w[576]; 
+    int iteration = 0;
+    int bits_found;
+    int huff_bits;
+    int real_bits;
+    int better;
+    int over;
+
+    int copy = 0;
+    int age = 0;
+
+    noise_info.over_count = 100;
+    noise_info.max_noise  = 0;
+    noise_info.tot_noise  = 0;
+    noise_info.over_noise = 0;
+    
+    best_noise_info.over_count = 100;
+
+    bits_found = bin_search_StepSize (gfc, cod_info, targ_bits, 
+                                      gfc->OldValue[ch], xrpow, l3_enc_w);
+    gfc->OldValue[ch] = cod_info->global_gain;
+
+    /* BEGIN MAIN LOOP */
+    do {
+        iteration ++;
+
+        /* inner_loop starts with the initial quantization step computed above
+         * and slowly increases until the bits < huff_bits.
+         * Thus it is important not to start with too large of an inital
+         * quantization step.  Too small is ok, but inner_loop will take longer 
+         */
+        huff_bits = targ_bits - cod_info->part2_length;
+        if (huff_bits < 0) {
+            assert(iteration != 1);
+            /*  scale factors too large, not enough bits. 
+             *  use previous quantizaton */
+            break;
+        }
+        /*  if this is the first iteration, 
+         *  see if we can reuse the quantization computed in 
+         *  bin_search_StepSize above */
+
+        if (iteration == 1) {
+            if (bits_found > huff_bits) {
+                cod_info->global_gain++;
+                real_bits = inner_loop (gfc, cod_info, huff_bits, xrpow, 
+                                        l3_enc_w);
+            } else {
+                real_bits = bits_found;
+            }
+        } else {
+            real_bits = inner_loop (gfc, cod_info, huff_bits, xrpow,
+                                    l3_enc_w);
+        }
+
+        cod_info->part2_3_length = real_bits;
+
+        /* compute the distortion in this quantization */
+        if (gfc->noise_shaping) 
+            /* coefficients and thresholds both l/r (or both mid/side) */
+            over = calc_noise (gfc, xr, l3_enc_w, cod_info, l3_xmin, 
+                               scalefac, &distort, &noise_info);
+        else {
+            /* fast mode, no noise shaping, we are ready */
+            best_noise_info = noise_info;
+            copy = 0;
+            memcpy(l3enc, l3_enc_w, sizeof(int)*576);
+            break;
+        }
+
+
+        /* check if this quantization is better
+         * than our saved quantization */
+        if (iteration == 1) /* the first iteration is always better */
+            better = 1;
+        else
+            better = quant_compare ((gfc->presetTune.use ? gfc->presetTune.quantcomp_current
+                                                         : gfp->experimentalX), 
+                                     gfc, &best_noise_info, &noise_info, cod_info->block_type);
+        
+        /* save data so we can restore this quantization later */    
+        if (better) {
+            copy = 0;
+            best_noise_info = noise_info;
+            memcpy(l3enc, l3_enc_w, sizeof(int)*576);
+            age = 0;
+        }
+        else
+            age ++;
+
+
+        /******************************************************************/
+        /* stopping criterion */
+        /******************************************************************/
+        /* if no bands with distortion and -X0, we are done */
+        if (0==gfc->noise_shaping_stop && 
+            0==gfp->experimentalX &&
+           (over == 0 || best_noise_info.over_count == 0) )
+            break;
+        /* Otherwise, allow up to 3 unsuccesful tries in serial, then stop 
+         * if our best quantization so far had no distorted bands. This
+         * gives us more possibilities for different quant_compare modes.
+         * Much more than 3 makes not a big difference, it is only slower.
+         */
+        if (age > 3 && best_noise_info.over_count == 0) 
+            break;    
+    
+        /* Check if the last scalefactor band is distorted.
+         * in VBR mode we can't get rid of the distortion, so quit now
+         * and VBR mode will try again with more bits.  
+         * (makes a 10% speed increase, the files I tested were
+         * binary identical, 2000/05/20 Robert.Hegemann@gmx.de)
+         * distort[] > 1 means noise > allowed noise
+         */
+        if (gfc->sfb21_extra) {
+            if (cod_info->block_type == SHORT_TYPE) {
+                if (distort.s[SBMAX_s-1][0] > 1 ||
+                    distort.s[SBMAX_s-1][1] > 1 ||
+                    distort.s[SBMAX_s-1][2] > 1) break;
+            } else {
+                if (distort.l[SBMAX_l-1] > 1) break;
+            }
+        }
+
+        /* save data so we can restore this quantization later */    
+        if (better) {
+            copy = 1;
+            save_scalefac = *scalefac;
+            save_cod_info = *cod_info;
+            if (gfp->VBR == vbr_rh || gfp->VBR == vbr_mtrh) {
+                /* store for later reuse */
+                memcpy(save_xrpow, xrpow, sizeof(FLOAT8)*576);
+            }
+        }
+            
+        if (balance_noise (gfp, cod_info, scalefac, &distort, xrpow) == 0) 
+            break;
+    }
+    while (1); /* main iteration loop, breaks adjusted */
+    
+    /*  finish up
+     */
+    if (copy) {
+        *cod_info = save_cod_info;
+        *scalefac = save_scalefac;
+        if (gfp->VBR == vbr_rh || gfp->VBR == vbr_mtrh)
+            /* restore for reuse on next try */
+            memcpy(xrpow, save_xrpow, sizeof(FLOAT8)*576);
+    }
+    cod_info->part2_3_length += cod_info->part2_length;
+    
+    assert (cod_info->global_gain < 256);
+    
+    return best_noise_info.over_count;
+}
+
+
+
+
+/************************************************************************
+ *
+ *      iteration_finish()                                                    
+ *
+ *  Robert Hegemann 2000-09-06
+ *
+ *  update reservoir status after FINAL quantization/bitrate 
+ *
+ *  rh 2000-09-06: it will not work with CBR due to the bitstream formatter
+ *            you will get "Error: MAX_HEADER_BUF too small in bitstream.c"
+ *
+ ************************************************************************/
+
+static void 
+iteration_finish (
+    lame_internal_flags *gfc,
+    FLOAT8          xr      [2][2][576],
+    int             l3_enc  [2][2][576],
+    III_scalefac_t  scalefac[2][2],
+    const int       mean_bits )
+{
+    III_side_info_t *l3_side = &gfc->l3_side;
+    int gr, ch, i;
+    
+    for (gr = 0; gr < gfc->mode_gr; gr++) {
+        for (ch = 0; ch < gfc->channels_out; ch++) {
+            gr_info *cod_info = &l3_side->gr[gr].ch[ch].tt;
+
+            /*  try some better scalefac storage
+             */
+            best_scalefac_store (gfc, gr, ch, l3_enc, l3_side, scalefac);
+            
+            /*  best huffman_divide may save some bits too
+             */
+            if (gfc->use_best_huffman == 1) 
+                best_huffman_divide (gfc, cod_info, l3_enc[gr][ch]);
+            
+            /*  update reservoir status after FINAL quantization/bitrate
+             */
+            ResvAdjust (gfc, cod_info, l3_side, mean_bits);
+      
+            /*  set the sign of l3_enc from the sign of xr
+             */
+            for (i = 0; i < 576; i++) {
+                if (xr[gr][ch][i] < 0) l3_enc[gr][ch][i] *= -1; 
+            }
+        } /* for ch */
+    }    /* for gr */
+    
+    ResvFrameEnd (gfc, l3_side, mean_bits);
+}
+
+
+
+/*********************************************************************
+ *
+ *      VBR_encode_granule()
+ *
+ *  2000-09-04 Robert Hegemann
+ *
+ *********************************************************************/
+static void
+VBR_encode_granule (
+          lame_global_flags *gfp,
+          gr_info        * const cod_info,
+          FLOAT8                 xr[576],     /* magnitudes of spectral values */
+    const III_psy_xmin   * const l3_xmin,     /* allowed distortion of the scalefactor */
+          III_scalefac_t * const scalefac,    /* scalefactors */
+          FLOAT8                 xrpow[576],  /* coloured magnitudes of spectral values */
+          int                    l3_enc[576], /* vector of quantized values ix(0..575) */
+    const int                    ch, 
+          int                    min_bits, 
+          int                    max_bits )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    gr_info         bst_cod_info;
+    III_scalefac_t  bst_scalefac;
+    FLOAT8          bst_xrpow [576]; 
+    int             bst_l3_enc[576];
+    int Max_bits  = max_bits;
+    int real_bits = max_bits+1;
+    int this_bits = (max_bits+min_bits)/2;
+    int dbits, over, found = 0;
+    int sfb21_extra = gfc->sfb21_extra;
+
+    assert(Max_bits <= MAX_BITS);
+
+    /*  search within round about 40 bits of optimal
+     */
+    do {
+        assert(this_bits >= min_bits);
+        assert(this_bits <= max_bits);
+        assert(min_bits <= max_bits);
+
+        if (this_bits > Max_bits-42) 
+            gfc->sfb21_extra = 0;
+        else
+            gfc->sfb21_extra = sfb21_extra;
+
+        over = outer_loop ( gfp, cod_info, xr, l3_xmin, scalefac,
+                            xrpow, l3_enc, ch, this_bits );
+
+        /*  is quantization as good as we are looking for ?
+         *  in this case: is no scalefactor band distorted?
+         */
+        if (over <= 0) {
+            found = 1;
+            /*  now we know it can be done with "real_bits"
+             *  and maybe we can skip some iterations
+             */
+            real_bits = cod_info->part2_3_length;
+
+            /*  store best quantization so far
+             */
+            bst_cod_info = *cod_info;
+            bst_scalefac = *scalefac;
+            memcpy(bst_xrpow, xrpow, sizeof(FLOAT8)*576);
+            memcpy(bst_l3_enc, l3_enc, sizeof(int)*576);
+
+            /*  try with fewer bits
+             */
+            max_bits  = real_bits-32;
+            dbits     = max_bits-min_bits;
+            this_bits = (max_bits+min_bits)/2;
+        } 
+        else {
+            /*  try with more bits
+             */
+            min_bits  = this_bits+32;
+            dbits     = max_bits-min_bits;
+            this_bits = (max_bits+min_bits)/2;
+            
+            if (found) {
+                found = 2;
+                /*  start again with best quantization so far
+                 */
+                *cod_info = bst_cod_info;
+                *scalefac = bst_scalefac;
+                memcpy(xrpow, bst_xrpow, sizeof(FLOAT8)*576);
+            }
+        }
+    } while (dbits>12);
+
+    gfc->sfb21_extra = sfb21_extra;
+
+    /*  found=0 => nothing found, use last one
+     *  found=1 => we just found the best and left the loop
+     *  found=2 => we restored a good one and have now l3_enc to restore too
+     */
+    if (found==2) {
+        memcpy(l3_enc, bst_l3_enc, sizeof(int)*576);
+    }
+    assert(cod_info->part2_3_length <= Max_bits);
+
+}
+
+
+
+/************************************************************************
+ *
+ *      get_framebits()   
+ *
+ *  Robert Hegemann 2000-09-05
+ *
+ *  calculates
+ *  * how many bits are available for analog silent granules
+ *  * how many bits to use for the lowest allowed bitrate
+ *  * how many bits each bitrate would provide
+ *
+ ************************************************************************/
+
+static void 
+get_framebits (
+    lame_global_flags *gfp,
+    int     * const analog_mean_bits,
+    int     * const min_mean_bits,
+    int             frameBits[15] )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    int bitsPerFrame, mean_bits, i;
+    III_side_info_t *l3_side = &gfc->l3_side;
+    
+    /*  always use at least this many bits per granule per channel 
+     *  unless we detect analog silence, see below 
+     */
+    gfc->bitrate_index = gfc->VBR_min_bitrate;
+    getframebits (gfp, &bitsPerFrame, &mean_bits);
+    *min_mean_bits = mean_bits / gfc->channels_out;
+
+    /*  bits for analog silence 
+     */
+    gfc->bitrate_index = 1;
+    getframebits (gfp, &bitsPerFrame, &mean_bits);
+    *analog_mean_bits = mean_bits / gfc->channels_out;
+
+    for (i = 1; i <= gfc->VBR_max_bitrate; i++) {
+        gfc->bitrate_index = i;
+        getframebits (gfp, &bitsPerFrame, &mean_bits);
+        frameBits[i] = ResvFrameBegin (gfp, l3_side, mean_bits, bitsPerFrame);
+    }
+}
+
+
+
+/************************************************************************
+ *
+ *      calc_min_bits()   
+ *
+ *  Robert Hegemann 2000-09-04
+ *
+ *  determine minimal bit skeleton
+ *
+ ************************************************************************/
+inline
+static int 
+calc_min_bits (
+    lame_global_flags *gfp,
+    const gr_info * const cod_info,
+    const int             pe,
+    const FLOAT8          ms_ener_ratio, 
+    const int             bands,    
+    const int             mch_bits,
+    const int             analog_mean_bits,
+    const int             min_mean_bits,
+    const int             analog_silence,
+    const int             ch )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    int min_bits, min_pe_bits;
+    
+    if (gfc->nsPsy.use) return 126;
+                    /*  changed minimum from 1 to 126 bits
+                     *  the iteration loops require a minimum of bits
+                     *  for each granule to start with; robert 2001-07-02 */
+
+    /*  base amount of minimum bits
+     */
+    min_bits = Max (126, min_mean_bits);
+
+    if (gfc->mode_ext == MPG_MD_MS_LR && ch == 1)  
+        min_bits = Max (min_bits, mch_bits/5);
+
+    /*  bit skeleton based on PE
+     */
+    if (cod_info->block_type == SHORT_TYPE) 
+        /*  if LAME switches to short blocks then pe is
+         *  >= 1000 on medium surge
+         *  >= 3000 on big surge
+         */
+        min_pe_bits = (pe-350) * bands/39;
+    else 
+        min_pe_bits = (pe-350) * bands/22;
+    
+    if (gfc->mode_ext == MPG_MD_MS_LR && ch == 1) {
+        /*  side channel will use a lower bit skeleton based on PE
+         */ 
+        FLOAT8 fac  = .33 * (.5 - ms_ener_ratio) / .5;
+        min_pe_bits = (int)(min_pe_bits * ((1-fac)/(1+fac)));
+    }
+    min_pe_bits = Min (min_pe_bits, (1820 * gfp->out_samplerate / 44100));
+
+    /*  determine final minimum bits
+     */
+    if (analog_silence && !gfp->VBR_hard_min) 
+        min_bits = analog_mean_bits;
+    else 
+        min_bits = Max (min_bits, min_pe_bits);
+    
+    return min_bits;
+}
+
+
+
+/*********************************************************************
+ *
+ *      VBR_prepare()
+ *
+ *  2000-09-04 Robert Hegemann
+ *
+ *  * converts LR to MS coding when necessary 
+ *  * calculates allowed/adjusted quantization noise amounts
+ *  * detects analog silent frames
+ *
+ *  some remarks:
+ *  - lower masking depending on Quality setting
+ *  - quality control together with adjusted ATH MDCT scaling
+ *    on lower quality setting allocate more noise from
+ *    ATH masking, and on higher quality setting allocate
+ *    less noise from ATH masking.
+ *  - experiments show that going more than 2dB over GPSYCHO's
+ *    limits ends up in very annoying artefacts
+ *
+ *********************************************************************/
+
+/* RH: this one needs to be overhauled sometime */
+static int 
+VBR_prepare (
+          lame_global_flags *gfp,
+          FLOAT8          pe            [2][2],
+          FLOAT8          ms_ener_ratio [2], 
+          FLOAT8          xr            [2][2][576],
+          III_psy_ratio   ratio         [2][2], 
+          III_psy_xmin    l3_xmin       [2][2],
+          int             frameBits     [16],
+          int            *analog_mean_bits,
+          int            *min_mean_bits,
+          int             min_bits      [2][2],
+          int             max_bits      [2][2],
+          int             bands         [2][2] )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    
+    
+    FLOAT8  masking_lower_db, adjust = 0.0;
+    int     gr, ch;
+    int     analog_silence = 1;
+    int     bpf, avg, mxb, bits = 0;
+  
+    gfc->bitrate_index = gfc->VBR_max_bitrate;
+    getframebits (gfp, &bpf, &avg);
+    bpf = ResvFrameBegin (gfp, &gfc->l3_side, avg, bpf );
+    avg = (bpf - 8*gfc->sideinfo_len) / gfc->mode_gr;
+
+    get_framebits (gfp, analog_mean_bits, min_mean_bits, frameBits);
+    
+    for (gr = 0; gr < gfc->mode_gr; gr++) {
+        mxb = on_pe (gfp, pe, &gfc->l3_side, max_bits[gr], avg, gr);
+        if (gfc->mode_ext == MPG_MD_MS_LR) {
+            ms_convert (xr[gr], xr[gr]); 
+            reduce_side (max_bits[gr], ms_ener_ratio[gr], avg, mxb);
+        }
+        for (ch = 0; ch < gfc->channels_out; ++ch) {
+            gr_info *cod_info = &gfc->l3_side.gr[gr].ch[ch].tt;
+      
+            if (gfc->nsPsy.use && gfp->VBR == vbr_rh) {
+            if (cod_info->block_type == NORM_TYPE) 
+                adjust = 1.28/(1+exp(3.5-pe[gr][ch]/300.))-0.05;
+            else 
+                adjust = 2.56/(1+exp(3.5-pe[gr][ch]/300.))-0.14;
+            }
+            masking_lower_db   = gfc->VBR->mask_adjust - adjust; 
+            gfc->masking_lower = pow (10.0, masking_lower_db * 0.1);
+      
+            bands[gr][ch] = calc_xmin (gfp, xr[gr][ch], ratio[gr]+ch, 
+                                       cod_info, l3_xmin[gr]+ch);
+            if (bands[gr][ch]) 
+                analog_silence = 0;
+
+            min_bits[gr][ch] = calc_min_bits (gfp, cod_info, (int)pe[gr][ch],
+                                      ms_ener_ratio[gr], bands[gr][ch],
+                                      0, *analog_mean_bits, 
+                                      *min_mean_bits, analog_silence, ch);
+      
+            bits += max_bits[gr][ch];
+        }
+    }
+    for (gr = 0; gr < gfc->mode_gr; gr++) {
+        for (ch = 0; ch < gfc->channels_out; ch++) {            
+            if (bits > frameBits[gfc->VBR_max_bitrate]) {
+                max_bits[gr][ch] *= frameBits[gfc->VBR_max_bitrate];
+                max_bits[gr][ch] /= bits;
+            }
+            if (min_bits[gr][ch] > max_bits[gr][ch]) 
+                min_bits[gr][ch] = max_bits[gr][ch];
+            
+        } /* for ch */
+    }  /* for gr */
+    
+    *min_mean_bits = Max(*min_mean_bits, 126);
+
+    return analog_silence;
+}
+inline
+void bitpressure_strategy1(
+    lame_internal_flags * gfc,
+    III_psy_xmin l3_xmin[2][2],
+    int min_bits[2][2],  
+    int max_bits[2][2] )  
+{
+    int gr, ch, sfb;
+    for (gr = 0; gr < gfc->mode_gr; gr++) {
+        for (ch = 0; ch < gfc->channels_out; ch++) {
+            if (gfc->l3_side.gr[gr].ch[ch].tt.block_type == SHORT_TYPE) {
+                for (sfb = 0; sfb < SBMAX_s; sfb++) {
+                    l3_xmin[gr][ch].s[sfb][0] *= 1.+.029*sfb*sfb/SBMAX_s/SBMAX_s;
+                    l3_xmin[gr][ch].s[sfb][1] *= 1.+.029*sfb*sfb/SBMAX_s/SBMAX_s;
+                    l3_xmin[gr][ch].s[sfb][2] *= 1.+.029*sfb*sfb/SBMAX_s/SBMAX_s;
+                }
+            }
+            else {
+                for (sfb = 0; sfb < SBMAX_l; sfb++) 
+                    l3_xmin[gr][ch].l[sfb] *= 1.+.029*sfb*sfb/SBMAX_l/SBMAX_l;
+            }
+            max_bits[gr][ch] = Max(min_bits[gr][ch], 0.9*max_bits[gr][ch]);
+        }
+    }
+}
+
+inline
+void bitpressure_strategy2( 
+    lame_internal_flags * gfc,
+    int bpf, int used, int save_bits[2][2],
+    int min_bits[2][2], int max_bits[2][2] )  
+{
+    int gr, ch;
+    for (gr = 0; gr < gfc->mode_gr; gr++) {
+        for (ch = 0; ch < gfc->channels_out; ch++) {
+            max_bits[gr][ch]  = save_bits[gr][ch];
+            max_bits[gr][ch] *= bpf;
+            max_bits[gr][ch] /= used;
+            max_bits[gr][ch]  = Max(min_bits[gr][ch],max_bits[gr][ch]);
+        }
+    }
+}
+
+/************************************************************************
+ *
+ *      VBR_iteration_loop()   
+ *
+ *  tries to find out how many bits are needed for each granule and channel
+ *  to get an acceptable quantization. An appropriate bitrate will then be
+ *  choosed for quantization.  rh 8/99                          
+ *
+ *  Robert Hegemann 2000-09-06 rewrite
+ *
+ ************************************************************************/
+
+void 
+VBR_iteration_loop (
+    lame_global_flags *gfp,
+    FLOAT8             pe           [2][2],
+    FLOAT8             ms_ener_ratio[2], 
+    FLOAT8             xr           [2][2][576],
+    III_psy_ratio      ratio        [2][2], 
+    int                l3_enc       [2][2][576],
+    III_scalefac_t     scalefac     [2][2] )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    III_psy_xmin l3_xmin[2][2];
+  
+    FLOAT8    xrpow[576];
+    int       bands[2][2];
+    int       frameBits[15];
+    int       bitsPerFrame;
+    int       save_bits[2][2];
+    int       used_bits, used_bits2;
+    int       bits;
+    int       min_bits[2][2], max_bits[2][2];
+    int       analog_mean_bits, min_mean_bits;
+    int       mean_bits;
+    int       ch, gr, analog_silence;
+    gr_info             *cod_info;
+    III_side_info_t     *l3_side  = &gfc->l3_side;
+
+    analog_silence = VBR_prepare (gfp, pe, ms_ener_ratio, xr, ratio, 
+                                  l3_xmin, frameBits, &analog_mean_bits,
+                                  &min_mean_bits, min_bits, max_bits, bands);
+
+    /*---------------------------------*/
+    for(;;) {  
+    
+    /*  quantize granules with lowest possible number of bits
+     */
+    
+    used_bits = 0;
+    used_bits2 = 0;
+   
+    for (gr = 0; gr < gfc->mode_gr; gr++) {
+        for (ch = 0; ch < gfc->channels_out; ch++) {
+            int ret; 
+            cod_info = &l3_side->gr[gr].ch[ch].tt;
+      
+            /*  init_outer_loop sets up cod_info, scalefac and xrpow 
+             */
+            ret = init_outer_loop(gfc, cod_info, &scalefac[gr][ch],
+                                 xr[gr][ch], xrpow);
+            if (ret == 0 || max_bits[gr][ch] == 0) {
+                /*  xr contains no energy 
+                 *  l3_enc, our encoding data, will be quantized to zero
+                 */
+                memset(l3_enc[gr][ch], 0, sizeof(int)*576);
+                save_bits[gr][ch] = 0;
+                continue; /* with next channel */
+            }
+      
+            if (gfp->VBR == vbr_mtrh) {
+                ret = VBR_noise_shaping2 (gfp, xr[gr][ch], xrpow, l3_enc[gr][ch],  
+                                        min_bits[gr][ch], max_bits[gr][ch], 
+                                        &scalefac[gr][ch],
+                                        &l3_xmin[gr][ch], gr, ch );
+                if (ret < 0)
+                    cod_info->part2_3_length = 100000;
+            } 
+            else
+                VBR_encode_granule (gfp, cod_info, xr[gr][ch], &l3_xmin[gr][ch],
+                                    &scalefac[gr][ch], xrpow, l3_enc[gr][ch],
+                                    ch, min_bits[gr][ch], max_bits[gr][ch] );
+
+            used_bits += cod_info->part2_3_length;
+            save_bits[gr][ch] = Min(MAX_BITS, cod_info->part2_3_length);
+            used_bits2 += Min(MAX_BITS, cod_info->part2_3_length);
+        } /* for ch */
+    }    /* for gr */
+
+    /*  find lowest bitrate able to hold used bits
+     */
+    if (analog_silence && !gfp->VBR_hard_min) 
+        /*  we detected analog silence and the user did not specify 
+         *  any hard framesize limit, so start with smallest possible frame
+         */
+        gfc->bitrate_index = 1;
+    else
+        gfc->bitrate_index = gfc->VBR_min_bitrate;
+     
+    for( ; gfc->bitrate_index < gfc->VBR_max_bitrate; gfc->bitrate_index++) {
+        if (used_bits <= frameBits[gfc->bitrate_index]) break; 
+    }
+
+    getframebits (gfp, &bitsPerFrame, &mean_bits);
+    bits = ResvFrameBegin (gfp, l3_side, mean_bits, bitsPerFrame);
+    
+    if (used_bits <= bits) break;
+
+    switch ( gfc -> VBR -> bitpressure ) {
+    default:
+    case  1:    bitpressure_strategy1( gfc, l3_xmin, min_bits, max_bits );
+                break;
+    case  2:    bitpressure_strategy2( gfc, frameBits[gfc->bitrate_index], 
+                               used_bits2, save_bits, min_bits, max_bits );
+                break;
+    }
+
+    }   /* breaks adjusted */
+    /*--------------------------------------*/
+    
+    iteration_finish (gfc, xr, l3_enc, scalefac, mean_bits);
+}
+
+
+
+
+
+
+/********************************************************************
+ *
+ *  calc_target_bits()
+ *
+ *  calculates target bits for ABR encoding
+ *
+ *  mt 2000/05/31
+ *
+ ********************************************************************/
+
+static void 
+calc_target_bits (
+    lame_global_flags * gfp,
+    FLOAT8               pe            [2][2],
+    FLOAT8               ms_ener_ratio [2],
+    int                  targ_bits     [2][2],
+    int                 *analog_silence_bits,
+    int                 *max_frame_bits )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    III_side_info_t *l3_side = &gfc->l3_side;
+    FLOAT8 res_factor;
+    int gr, ch, totbits, mean_bits, bitsPerFrame;
+    
+    gfc->bitrate_index = gfc->VBR_max_bitrate;
+    getframebits (gfp, &bitsPerFrame, &mean_bits);
+    *max_frame_bits = ResvFrameBegin (gfp, l3_side, mean_bits, bitsPerFrame);
+
+    gfc->bitrate_index = 1;
+    getframebits (gfp, &bitsPerFrame, &mean_bits);
+    *analog_silence_bits = mean_bits / gfc->channels_out;
+
+    mean_bits  = gfp->VBR_mean_bitrate_kbps * gfp->framesize * 1000;
+    mean_bits /= gfp->out_samplerate;
+    mean_bits -= gfc->sideinfo_len*8;
+    mean_bits /= gfc->mode_gr;
+
+    /*
+        res_factor is the percentage of the target bitrate that should
+        be used on average.  the remaining bits are added to the
+        bitreservoir and used for difficult to encode frames.  
+
+        Since we are tracking the average bitrate, we should adjust
+        res_factor "on the fly", increasing it if the average bitrate
+        is greater than the requested bitrate, and decreasing it
+        otherwise.  Reasonable ranges are from .9 to 1.0
+        
+        Until we get the above suggestion working, we use the following
+        tuning:
+        compression ratio    res_factor
+          5.5  (256kbps)         1.0      no need for bitreservoir 
+          11   (128kbps)         .93      7% held for reservoir
+   
+        with linear interpolation for other values.
+
+     */
+    res_factor = .93 + .07 * (11.0 - gfp->compression_ratio) / (11.0 - 5.5);
+    if (res_factor <  .90)
+        res_factor =  .90; 
+    if (res_factor > 1.00) 
+        res_factor = 1.00;
+
+    for (gr = 0; gr < gfc->mode_gr; gr++) {
+        for (ch = 0; ch < gfc->channels_out; ch++) {
+            targ_bits[gr][ch] = res_factor * (mean_bits / gfc->channels_out);
+            
+            if (pe[gr][ch] > 700) {
+                int add_bits = (pe[gr][ch] - 700) / 1.4;
+  
+                gr_info *cod_info = &l3_side->gr[gr].ch[ch].tt;
+                targ_bits[gr][ch] = res_factor * (mean_bits / gfc->channels_out);
+                /* short blocks use a little extra, no matter what the pe */
+                if (cod_info->block_type == SHORT_TYPE) {
+                    if (add_bits < mean_bits/4) 
+                        add_bits = mean_bits/4; 
+                }
+                /* at most increase bits by 1.5*average */
+                if (add_bits > mean_bits*3/4)
+                    add_bits = mean_bits*3/4;
+                else
+                if (add_bits < 0) 
+                    add_bits = 0;
+
+                targ_bits[gr][ch] += add_bits;
+            }
+        }/* for ch */
+    }   /* for gr */
+    
+    if (gfc->mode_ext == MPG_MD_MS_LR) 
+        for (gr = 0; gr < gfc->mode_gr; gr++) {
+            reduce_side (targ_bits[gr], ms_ener_ratio[gr], mean_bits,
+                        MAX_BITS);
+        }
+
+    /*  sum target bits
+     */
+    totbits=0;
+    for (gr = 0; gr < gfc->mode_gr; gr++) {
+        for (ch = 0; ch < gfc->channels_out; ch++) {
+            if (targ_bits[gr][ch] > MAX_BITS) 
+                targ_bits[gr][ch] = MAX_BITS;
+            totbits += targ_bits[gr][ch];
+        }
+    }
+
+    /*  repartion target bits if needed
+     */
+    if (totbits > *max_frame_bits) {
+        for(gr = 0; gr < gfc->mode_gr; gr++) {
+            for(ch = 0; ch < gfc->channels_out; ch++) {
+                targ_bits[gr][ch] *= *max_frame_bits; 
+                targ_bits[gr][ch] /= totbits; 
+            }
+        }
+    }
+}
+
+
+
+
+
+
+/********************************************************************
+ *
+ *  ABR_iteration_loop()
+ *
+ *  encode a frame with a disired average bitrate
+ *
+ *  mt 2000/05/31
+ *
+ ********************************************************************/
+
+void 
+ABR_iteration_loop(
+    lame_global_flags *gfp,
+    FLOAT8             pe           [2][2],
+    FLOAT8             ms_ener_ratio[2], 
+    FLOAT8             xr           [2][2][576],
+    III_psy_ratio      ratio        [2][2], 
+    int                l3_enc       [2][2][576],
+    III_scalefac_t     scalefac     [2][2] )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    III_psy_xmin l3_xmin;
+    FLOAT8    xrpow[576];
+    int       targ_bits[2][2];
+    int       bitsPerFrame, mean_bits, totbits, max_frame_bits;
+    int       ch, gr, ath_over, ret;
+    int       analog_silence_bits;
+    gr_info             *cod_info;
+    III_side_info_t     *l3_side  = &gfc->l3_side;
+
+    calc_target_bits (gfp, pe, ms_ener_ratio, targ_bits, 
+                      &analog_silence_bits, &max_frame_bits);
+    
+    /*  encode granules
+     */
+    totbits=0;
+    for (gr = 0; gr < gfc->mode_gr; gr++) {
+
+        if (gfc->mode_ext == MPG_MD_MS_LR) 
+            ms_convert (xr[gr], xr[gr]);
+
+        for (ch = 0; ch < gfc->channels_out; ch++) {
+            cod_info = &l3_side->gr[gr].ch[ch].tt;
+
+            /*  cod_info, scalefac and xrpow get initialized in init_outer_loop
+             */
+            ret = init_outer_loop(gfc, cod_info, &scalefac[gr][ch],
+                                 xr[gr][ch], xrpow);
+            if (ret == 0) {
+                /*  xr contains no energy 
+                 *  l3_enc, our encoding data, will be quantized to zero
+                 */
+                memset(l3_enc[gr][ch], 0, sizeof(int)*576);
+            } 
+            else {
+                /*  xr contains energy we will have to encode 
+                 *  calculate the masking abilities
+                 *  find some good quantization in outer_loop 
+                 */
+                ath_over = calc_xmin (gfp, xr[gr][ch], &ratio[gr][ch],
+                                      cod_info, &l3_xmin);
+                if (0 == ath_over) /* analog silence */
+                    targ_bits[gr][ch] = analog_silence_bits;
+
+                outer_loop (gfp, cod_info, xr[gr][ch], &l3_xmin,
+                            &scalefac[gr][ch], xrpow, l3_enc[gr][ch],
+                            ch, targ_bits[gr][ch]);
+            }
+
+            totbits += cod_info->part2_3_length;
+        } /* ch */
+    }  /* gr */
+  
+    /*  find a bitrate which can handle totbits 
+     */
+    for (gfc->bitrate_index =  gfc->VBR_min_bitrate ;
+         gfc->bitrate_index <= gfc->VBR_max_bitrate;
+         gfc->bitrate_index++    ) {
+        getframebits (gfp, &bitsPerFrame, &mean_bits);
+        max_frame_bits = ResvFrameBegin (gfp, l3_side, mean_bits, bitsPerFrame);
+        if (totbits <= max_frame_bits) break; 
+    }
+    assert (gfc->bitrate_index <= gfc->VBR_max_bitrate);
+
+    iteration_finish (gfc, xr, l3_enc, scalefac, mean_bits);
+}
+
+
+
+
+
+
+/************************************************************************
+ *
+ *      iteration_loop()                                                    
+ *
+ *  author/date??
+ *
+ *  encodes one frame of MP3 data with constant bitrate
+ *
+ ************************************************************************/
+
+void 
+iteration_loop(
+    lame_global_flags *gfp, 
+    FLOAT8             pe           [2][2],
+    FLOAT8             ms_ener_ratio[2],  
+    FLOAT8             xr           [2][2][576],
+    III_psy_ratio      ratio        [2][2],  
+    int                l3_enc       [2][2][576],
+    III_scalefac_t     scalefac     [2][2] )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    III_psy_xmin l3_xmin[2];
+    FLOAT8 xrpow[576];
+    int    targ_bits[2];
+    int    bitsPerFrame;
+    int    mean_bits, max_bits;
+    int    gr, ch, i;
+    III_side_info_t     *l3_side = &gfc->l3_side;
+    gr_info             *cod_info;
+
+    getframebits (gfp, &bitsPerFrame, &mean_bits);
+    ResvFrameBegin (gfp, l3_side, mean_bits, bitsPerFrame );
+
+    /* quantize! */
+    for (gr = 0; gr < gfc->mode_gr; gr++) {
+
+        /*  calculate needed bits
+         */
+        max_bits = on_pe (gfp, pe, l3_side, targ_bits, mean_bits, gr);
+        
+        if (gfc->mode_ext == MPG_MD_MS_LR) {
+            ms_convert (xr[gr], xr[gr]);
+            reduce_side (targ_bits, ms_ener_ratio[gr], mean_bits, max_bits);
+        }
+        
+        for (ch=0 ; ch < gfc->channels_out ; ch ++) {
+            cod_info = &l3_side->gr[gr].ch[ch].tt; 
+
+            /*  init_outer_loop sets up cod_info, scalefac and xrpow 
+             */
+            i = init_outer_loop(gfc, cod_info, &scalefac[gr][ch],
+                               xr[gr][ch], xrpow);
+            if (i == 0) {
+                /*  xr contains no energy, l3_enc will be quantized to zero
+                 */
+                memset(l3_enc[gr][ch], 0, sizeof(int)*576);
+            }
+            else {
+                /*  xr contains energy we will have to encode 
+                 *  calculate the masking abilities
+                 *  find some good quantization in outer_loop 
+                 */
+                calc_xmin (gfp, xr[gr][ch], &ratio[gr][ch], cod_info, 
+                           &l3_xmin[ch]);
+                outer_loop (gfp, cod_info, xr[gr][ch], &l3_xmin[ch], 
+                            &scalefac[gr][ch], xrpow, l3_enc[gr][ch],
+                            ch, targ_bits[ch]);
+            }
+            assert (cod_info->part2_3_length <= MAX_BITS);
+
+            /*  try some better scalefac storage
+             */
+            best_scalefac_store (gfc, gr, ch, l3_enc, l3_side, scalefac);
+            
+            /*  best huffman_divide may save some bits too
+             */
+            if (gfc->use_best_huffman == 1) 
+                best_huffman_divide (gfc, cod_info, l3_enc[gr][ch]);
+            
+            /*  update reservoir status after FINAL quantization/bitrate
+             */
+#undef  NORES_TEST
+#ifndef NORES_TEST
+            ResvAdjust (gfc, cod_info, l3_side, mean_bits);
+#endif      
+            /*  set the sign of l3_enc from the sign of xr
+             */
+            for (i = 0; i < 576; i++) {
+                if (xr[gr][ch][i] < 0) l3_enc[gr][ch][i] *= -1; 
+            }
+        } /* for ch */
+    }    /* for gr */
+    
+#ifdef NORES_TEST
+    /* replace ResvAdjust above with this code if you do not want
+       the second granule to use bits saved by the first granule.
+       Requires using the --nores.  This is useful for testing only */
+    for (gr = 0; gr < gfc->mode_gr; gr++) {
+        for (ch =  0; ch < gfc->channels_out; ch++) {
+            cod_info = &l3_side->gr[gr].ch[ch].tt;
+            ResvAdjust (gfc, cod_info, l3_side, mean_bits);
+        }
+    }
+#endif
+
+    ResvFrameEnd (gfc, l3_side, mean_bits);
+}
+
+
+
diff --git a/lib/lame/quantize.h b/lib/lame/quantize.h
new file mode 100644 (file)
index 0000000..832f92f
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * MP3 quantization
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_QUANTIZE_H
+#define LAME_QUANTIZE_H
+
+#include "util.h"
+
+void iteration_loop( lame_global_flags *gfp,
+                     FLOAT8 pe[2][2], FLOAT8 ms_ratio[2], 
+                    FLOAT8 xr_org[2][2][576], III_psy_ratio ratio[2][2],
+                    int l3_enc[2][2][576], 
+                    III_scalefac_t scalefac[2][2]);
+
+void VBR_iteration_loop( lame_global_flags *gfp,
+                     FLOAT8 pe[2][2], FLOAT8 ms_ratio[2], 
+                    FLOAT8 xr_org[2][2][576], III_psy_ratio ratio[2][2],
+                    int l3_enc[2][2][576], 
+                    III_scalefac_t scalefac[2][2]);
+
+void ABR_iteration_loop( lame_global_flags *gfp,
+                     FLOAT8 pe[2][2], FLOAT8 ms_ratio[2], 
+                    FLOAT8 xr_org[2][2][576], III_psy_ratio ratio[2][2],
+                    int l3_enc[2][2][576], 
+                    III_scalefac_t scalefac[2][2]);
+
+#endif /* LAME_QUANTIZE_H */
diff --git a/lib/lame/quantize_pvt.c b/lib/lame/quantize_pvt.c
new file mode 100644 (file)
index 0000000..df775f7
--- /dev/null
@@ -0,0 +1,1206 @@
+/*
+ *     quantize_pvt source file
+ *
+ *     Copyright (c) 1999 Takehiro TOMINAGA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: quantize_pvt.c,v 1.1 2002/04/28 17:30:26 kramm Exp $ */
+#include "config_static.h"
+
+#include <assert.h>
+#include "util.h"
+#include "lame-analysis.h"
+#include "tables.h"
+#include "reservoir.h"
+#include "quantize_pvt.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+
+#define NSATHSCALE 100 // Assuming dynamic range=96dB, this value should be 92
+
+const char  slen1_tab [16] = { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 };
+const char  slen2_tab [16] = { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 };
+
+
+/*
+  The following table is used to implement the scalefactor
+  partitioning for MPEG2 as described in section
+  2.4.3.2 of the IS. The indexing corresponds to the
+  way the tables are presented in the IS:
+
+  [table_number][row_in_table][column of nr_of_sfb]
+*/
+const int  nr_of_sfb_block [6] [3] [4] =
+{
+  {
+    {6, 5, 5, 5},
+    {9, 9, 9, 9},
+    {6, 9, 9, 9}
+  },
+  {
+    {6, 5, 7, 3},
+    {9, 9, 12, 6},
+    {6, 9, 12, 6}
+  },
+  {
+    {11, 10, 0, 0},
+    {18, 18, 0, 0},
+    {15,18,0,0}
+  },
+  {
+    {7, 7, 7, 0},
+    {12, 12, 12, 0},
+    {6, 15, 12, 0}
+  },
+  {
+    {6, 6, 6, 3},
+    {12, 9, 9, 6},
+    {6, 12, 9, 6}
+  },
+  {
+    {8, 8, 5, 0},
+    {15,12,9,0},
+    {6,18,9,0}
+  }
+};
+
+
+/* Table B.6: layer3 preemphasis */
+const char  pretab [SBMAX_l] =
+{
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0
+};
+
+/*
+  Here are MPEG1 Table B.8 and MPEG2 Table B.1
+  -- Layer III scalefactor bands. 
+  Index into this using a method such as:
+    idx  = fr_ps->header->sampling_frequency
+           + (fr_ps->header->version * 3)
+*/
+
+
+const scalefac_struct sfBandIndex[9] =
+{
+  { /* Table B.2.b: 22.05 kHz */
+    {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
+    {0,4,8,12,18,24,32,42,56,74,100,132,174,192}
+  },
+  { /* Table B.2.c: 24 kHz */                 /* docs: 332. mpg123(broken): 330 */
+    {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278, 332, 394,464,540,576},
+    {0,4,8,12,18,26,36,48,62,80,104,136,180,192}
+  },
+  { /* Table B.2.a: 16 kHz */
+    {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
+    {0,4,8,12,18,26,36,48,62,80,104,134,174,192}
+  },
+  { /* Table B.8.b: 44.1 kHz */
+    {0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576},
+    {0,4,8,12,16,22,30,40,52,66,84,106,136,192}
+  },
+  { /* Table B.8.c: 48 kHz */
+    {0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576},
+    {0,4,8,12,16,22,28,38,50,64,80,100,126,192}
+  },
+  { /* Table B.8.a: 32 kHz */
+    {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576},
+    {0,4,8,12,16,22,30,42,58,78,104,138,180,192}
+  },
+  { /* MPEG-2.5 11.025 kHz */
+    {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
+    {0/3,12/3,24/3,36/3,54/3,78/3,108/3,144/3,186/3,240/3,312/3,402/3,522/3,576/3}
+  },
+  { /* MPEG-2.5 12 kHz */
+    {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
+    {0/3,12/3,24/3,36/3,54/3,78/3,108/3,144/3,186/3,240/3,312/3,402/3,522/3,576/3}
+  },
+  { /* MPEG-2.5 8 kHz */
+    {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576},
+    {0/3,24/3,48/3,72/3,108/3,156/3,216/3,288/3,372/3,480/3,486/3,492/3,498/3,576/3}
+  }
+};
+
+
+
+FLOAT8 pow20[Q_MAX];
+FLOAT8 ipow20[Q_MAX];
+FLOAT8 iipow20[Q_MAX];
+FLOAT8 *iipow20_;
+FLOAT8 pow43[PRECALC_SIZE];
+/* initialized in first call to iteration_init */
+FLOAT8 adj43asm[PRECALC_SIZE];
+FLOAT8 adj43[PRECALC_SIZE];
+
+/************************************************************************/
+/*  initialization for iteration_loop */
+/************************************************************************/
+void
+iteration_init( lame_global_flags *gfp)
+{
+  lame_internal_flags *gfc=gfp->internal_flags;
+  III_side_info_t * const l3_side = &gfc->l3_side;
+  int i;
+
+  if ( gfc->iteration_init_init==0 ) {
+    gfc->iteration_init_init=1;
+
+    l3_side->main_data_begin = 0;
+    compute_ath(gfp,gfc->ATH->l,gfc->ATH->s);
+
+    pow43[0] = 0.0;
+    for(i=1;i<PRECALC_SIZE;i++)
+        pow43[i] = pow((FLOAT8)i, 4.0/3.0);
+
+    adj43asm[0] = 0.0;
+    for (i = 1; i < PRECALC_SIZE; i++)
+      adj43asm[i] = i - 0.5 - pow(0.5 * (pow43[i - 1] + pow43[i]),0.75);
+    for (i = 0; i < PRECALC_SIZE-1; i++)
+       adj43[i] = (i + 1) - pow(0.5 * (pow43[i] + pow43[i + 1]), 0.75);
+    adj43[i] = 0.5;
+    iipow20_ = &iipow20[210];
+    for (i = 0; i < Q_MAX; i++) {
+        iipow20[i] = pow(2.0, (double)(i - 210) * 0.1875);
+       ipow20[i] = pow(2.0, (double)(i - 210) * -0.1875);
+       pow20[i] = pow(2.0, (double)(i - 210) * 0.25);
+    }
+    huffman_init(gfc);
+  }
+}
+
+
+
+
+
+/* 
+compute the ATH for each scalefactor band 
+cd range:  0..96db
+
+Input:  3.3kHz signal  32767 amplitude  (3.3kHz is where ATH is smallest = -5db)
+longblocks:  sfb=12   en0/bw=-11db    max_en0 = 1.3db
+shortblocks: sfb=5           -9db              0db
+
+Input:  1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated)
+longblocks:  amp=1      sfb=12   en0/bw=-103 db      max_en0 = -92db
+            amp=32767   sfb=12           -12 db                 -1.4db 
+
+Input:  1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated)
+shortblocks: amp=1      sfb=5   en0/bw= -99                    -86 
+            amp=32767   sfb=5           -9  db                  4db 
+
+
+MAX energy of largest wave at 3.3kHz = 1db
+AVE energy of largest wave at 3.3kHz = -11db
+Let's take AVE:  -11db = maximum signal in sfb=12.  
+Dynamic range of CD: 96db.  Therefor energy of smallest audible wave 
+in sfb=12  = -11  - 96 = -107db = ATH at 3.3kHz.  
+
+ATH formula for this wave: -5db.  To adjust to LAME scaling, we need
+ATH = ATH_formula  - 103  (db)
+ATH = ATH * 2.5e-10      (ener)
+
+*/
+
+FLOAT8 ATHmdct( lame_global_flags *gfp, FLOAT8 f )
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    FLOAT8 ath;
+  
+    ath = ATHformula( f , gfp );
+         
+    if (gfc->nsPsy.use) {
+        ath -= NSATHSCALE;
+    } else {
+        ath -= 114;
+    }
+    
+    /*  modify the MDCT scaling for the ATH  */
+    ath -= gfp->ATHlower;
+
+    /* convert to energy */
+    ath = pow( 10.0, ath/10.0 );
+    return ath;
+}
+
+void compute_ath( lame_global_flags *gfp, FLOAT8 ATH_l[], FLOAT8 ATH_s[] )
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    int sfb, i, start, end;
+    FLOAT8 ATH_f;
+    FLOAT8 samp_freq = gfp->out_samplerate;
+
+    for (sfb = 0; sfb < SBMAX_l; sfb++) {
+        start = gfc->scalefac_band.l[ sfb ];
+        end   = gfc->scalefac_band.l[ sfb+1 ];
+        ATH_l[sfb]=FLOAT8_MAX;
+        for (i = start ; i < end; i++) {
+            FLOAT8 freq = i*samp_freq/(2*576);
+            ATH_f = ATHmdct( gfp, freq );  /* freq in kHz */
+            ATH_l[sfb] = Min( ATH_l[sfb], ATH_f );
+        }
+    }
+
+    for (sfb = 0; sfb < SBMAX_s; sfb++){
+        start = gfc->scalefac_band.s[ sfb ];
+        end   = gfc->scalefac_band.s[ sfb+1 ];
+        ATH_s[sfb] = FLOAT8_MAX;
+        for (i = start ; i < end; i++) {
+            FLOAT8 freq = i*samp_freq/(2*192);
+            ATH_f = ATHmdct( gfp, freq );    /* freq in kHz */
+            ATH_s[sfb] = Min( ATH_s[sfb], ATH_f );
+        }
+    }
+
+    /*  no-ATH mode:
+     *  reduce ATH to -200 dB
+     */
+    
+    if (gfp->noATH) {
+        for (sfb = 0; sfb < SBMAX_l; sfb++) {
+            ATH_l[sfb] = 1E-37;
+        }
+        for (sfb = 0; sfb < SBMAX_s; sfb++) {
+            ATH_s[sfb] = 1E-37;
+        }
+    }
+    
+    /*  work in progress, don't rely on it too much
+     */
+    gfc->ATH-> floor = 10. * log10( ATHmdct( gfp, -1. ) );
+    
+    /*
+    {   FLOAT8 g=10000, t=1e30, x;
+        for ( f = 100; f < 10000; f++ ) {
+            x = ATHmdct( gfp, f );
+            if ( t > x ) t = x, g = f;
+        }
+        printf("min=%g\n", g);
+    }*/
+}
+
+
+
+
+
+/* convert from L/R <-> Mid/Side, src == dst allowed */
+void ms_convert(FLOAT8 dst[2][576], FLOAT8 src[2][576])
+{
+    FLOAT8 l;
+    FLOAT8 r;
+    int i;
+    for (i = 0; i < 576; ++i) {
+        l = src[0][i];
+        r = src[1][i];
+        dst[0][i] = (l+r) * (FLOAT8)(SQRT2*0.5);
+        dst[1][i] = (l-r) * (FLOAT8)(SQRT2*0.5);
+    }
+}
+
+
+
+/************************************************************************
+ * allocate bits among 2 channels based on PE
+ * mt 6/99
+ * bugfixes rh 8/01: often allocated more than the allowed 4095 bits
+ ************************************************************************/
+int on_pe( lame_global_flags *gfp, FLOAT8 pe[][2], III_side_info_t *l3_side,
+           int targ_bits[2], int mean_bits, int gr )
+{
+    lame_internal_flags * gfc = gfp->internal_flags;
+    gr_info *   cod_info;
+    int     extra_bits, tbits, bits;
+    int     add_bits[2]; 
+    int     max_bits;  /* maximum allowed bits for this granule */
+    int     ch;
+
+    /* allocate targ_bits for granule */
+    ResvMaxBits( gfp, mean_bits, &tbits, &extra_bits );
+    max_bits = tbits + extra_bits;
+    if (max_bits > MAX_BITS) /* hard limit per granule */
+        max_bits = MAX_BITS;
+    
+    for ( bits = 0, ch = 0; ch < gfc->channels_out; ++ch ) {
+        /******************************************************************
+         * allocate bits for each channel 
+         ******************************************************************/
+        cod_info = &l3_side->gr[gr].ch[ch].tt;
+    
+        targ_bits[ch] = Min( MAX_BITS, tbits/gfc->channels_out );
+    
+        if (gfc->nsPsy.use) {
+            add_bits[ch] = targ_bits[ch] * pe[gr][ch] / 700.0 - targ_bits[ch];
+        } 
+        else {
+            add_bits[ch] = (pe[gr][ch]-750) / 1.4;
+            /* short blocks us a little extra, no matter what the pe */
+            if ( cod_info->block_type == SHORT_TYPE ) {
+               if (add_bits[ch] < mean_bits/4) 
+                    add_bits[ch] = mean_bits/4;
+            }
+        }
+
+        /* at most increase bits by 1.5*average */
+        if (add_bits[ch] > mean_bits*3/4) 
+            add_bits[ch] = mean_bits*3/4;
+        if (add_bits[ch] < 0) 
+            add_bits[ch] = 0;
+
+        if (add_bits[ch]+targ_bits[ch] > MAX_BITS) 
+           add_bits[ch] = Max( 0, MAX_BITS-targ_bits[ch] );
+
+        bits += add_bits[ch];
+    }
+    if (bits > extra_bits) {
+        for ( ch = 0; ch < gfc->channels_out; ++ch ) {
+            add_bits[ch] = extra_bits * add_bits[ch] / bits;
+        }
+    }
+
+    for ( ch = 0; ch < gfc->channels_out; ++ch ) {
+        targ_bits[ch] += add_bits[ch];
+        extra_bits    -= add_bits[ch];
+        assert( targ_bits[ch] <= MAX_BITS );
+    }
+    assert( max_bits <= MAX_BITS );
+    return max_bits;
+}
+
+
+
+
+void reduce_side(int targ_bits[2],FLOAT8 ms_ener_ratio,int mean_bits,int max_bits)
+{
+  int move_bits;
+  FLOAT fac;
+
+
+  /*  ms_ener_ratio = 0:  allocate 66/33  mid/side  fac=.33  
+   *  ms_ener_ratio =.5:  allocate 50/50 mid/side   fac= 0 */
+  /* 75/25 split is fac=.5 */
+  /* float fac = .50*(.5-ms_ener_ratio[gr])/.5;*/
+  fac = .33*(.5-ms_ener_ratio)/.5;
+  if (fac<0) fac=0;
+  if (fac>.5) fac=.5;
+  
+    /* number of bits to move from side channel to mid channel */
+    /*    move_bits = fac*targ_bits[1];  */
+    move_bits = fac*.5*(targ_bits[0]+targ_bits[1]);  
+
+    if (move_bits > MAX_BITS - targ_bits[0]) {
+        move_bits = MAX_BITS - targ_bits[0];
+    }
+    if (move_bits<0) move_bits=0;
+    
+    if (targ_bits[1] >= 125) {
+      /* dont reduce side channel below 125 bits */
+      if (targ_bits[1]-move_bits > 125) {
+
+       /* if mid channel already has 2x more than average, dont bother */
+       /* mean_bits = bits per granule (for both channels) */
+       if (targ_bits[0] < mean_bits)
+         targ_bits[0] += move_bits;
+       targ_bits[1] -= move_bits;
+      } else {
+       targ_bits[0] += targ_bits[1] - 125;
+       targ_bits[1] = 125;
+      }
+    }
+    
+    move_bits=targ_bits[0]+targ_bits[1];
+    if (move_bits > max_bits) {
+      targ_bits[0]=(max_bits*targ_bits[0])/move_bits;
+      targ_bits[1]=(max_bits*targ_bits[1])/move_bits;
+    }
+    assert (targ_bits[0] <= MAX_BITS);
+    assert (targ_bits[1] <= MAX_BITS);
+}
+
+
+/**
+ *  Robert Hegemann 2001-04-27:
+ *  this adjusts the ATH, keeping the original noise floor
+ *  affects the higher frequencies more than the lower ones
+ */
+
+FLOAT8 athAdjust( FLOAT8 a, FLOAT8 x, FLOAT8 athFloor )
+{
+    /*  work in progress
+     */
+    FLOAT8 const o = 90.30873362;
+    FLOAT8 const p = 94.82444863;
+    FLOAT8 u = 10. * log10(x); 
+    FLOAT8 v = a*a;
+    FLOAT8 w = 0.0;   
+    u -= athFloor;                                  // undo scaling
+    if ( v > 1E-20 ) w = 1. + 10. * log10(v) / o;
+    if ( w < 0  )    w = 0.; 
+    u *= w; 
+    u += athFloor + o-p;                            // redo scaling
+
+    return pow( 10., 0.1*u );
+}
+
+
+/*************************************************************************/
+/*            calc_xmin                                                  */
+/*************************************************************************/
+
+/*
+  Calculate the allowed distortion for each scalefactor band,
+  as determined by the psychoacoustic model.
+  xmin(sb) = ratio(sb) * en(sb) / bw(sb)
+
+  returns number of sfb's with energy > ATH
+*/
+int calc_xmin( 
+        lame_global_flags *gfp,
+        const FLOAT8                xr [576],
+        const III_psy_ratio * const ratio,
+       const gr_info       * const cod_info, 
+              III_psy_xmin  * const l3_xmin ) 
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    int sfb,j,start, end, bw,l, b, ath_over=0;
+    FLOAT8 en0, xmin, ener, tmpATH;
+    ATH_t * ATH = gfc->ATH;
+
+    if (cod_info->block_type == SHORT_TYPE) {
+
+        for ( j = 0, sfb = 0; sfb < SBMAX_s; sfb++ ) {
+            if ( gfp->VBR == vbr_rh || gfp->VBR == vbr_mtrh )
+                tmpATH = athAdjust( ATH->adjust, ATH->s[sfb], ATH->floor );
+            else
+                tmpATH = ATH->adjust * ATH->s[sfb];
+            start = gfc->scalefac_band.s[ sfb ];
+            end   = gfc->scalefac_band.s[ sfb + 1 ];
+            bw = end - start;
+
+            for ( b = 0; b < 3; b++ ) {
+                for (en0 = 0.0, l = start; l < end; l++) {
+                    ener = xr[j++];
+                    ener = ener * ener;
+                    en0 += ener;
+                }
+                en0 /= bw;
+      
+                if (gfp->ATHonly || gfp->ATHshort) {
+                    xmin = tmpATH;
+                } 
+                else {
+                    xmin = ratio->en.s[sfb][b];
+                    if (xmin > 0.0)
+                        xmin = en0 * ratio->thm.s[sfb][b] * gfc->masking_lower / xmin;
+                    if (xmin < tmpATH) 
+                        xmin = tmpATH;
+                }
+                xmin *= bw;
+
+                if (gfc->nsPsy.use) {
+                    if      (sfb <=  5) xmin *= gfc->nsPsy.bass;
+                    else if (sfb <= 10) xmin *= gfc->nsPsy.alto;
+                    else                xmin *= gfc->nsPsy.treble;
+                    if ((gfp->VBR == vbr_off || gfp->VBR == vbr_abr) && gfp->quality <= 1)
+                        xmin *= 0.001;
+                }
+                l3_xmin->s[sfb][b] = xmin;
+                if (en0 > tmpATH) ath_over++;
+            }   /* b */
+        }   /* sfb */
+
+        if (gfp->useTemporal) {
+            for (sfb = 0; sfb < SBMAX_s; sfb++ ) {
+                for ( b = 1; b < 3; b++ ) {
+                    xmin = l3_xmin->s[sfb][b] * (1.0 - gfc->decay)
+                         + l3_xmin->s[sfb][b-1] * gfc->decay;
+                    if (l3_xmin->s[sfb][b] < xmin)
+                        l3_xmin->s[sfb][b] = xmin;
+                }
+            }
+        }
+
+    }   /* end of short block case */
+    else {
+        
+        for ( sfb = 0; sfb < SBMAX_l; sfb++ ){
+            if ( gfp->VBR == vbr_rh || gfp->VBR == vbr_mtrh )
+                tmpATH = athAdjust( ATH->adjust, ATH->l[sfb], ATH->floor );
+            else
+                tmpATH = ATH->adjust * ATH->l[sfb];
+            start = gfc->scalefac_band.l[ sfb ];
+            end   = gfc->scalefac_band.l[ sfb+1 ];
+            bw = end - start;
+    
+            for (en0 = 0.0, l = start; l < end; l++ ) {
+                ener = xr[l] * xr[l];
+                en0 += ener;
+            }
+            /* why is it different from short blocks <?> */
+            if ( !gfc->nsPsy.use ) en0 /= bw;   
+    
+            if (gfp->ATHonly) {
+                xmin = tmpATH;
+            }
+            else {
+                xmin = ratio->en.l[sfb];
+                if (xmin > 0.0)
+                    xmin = en0 * ratio->thm.l[sfb] * gfc->masking_lower / xmin;
+                if (xmin < tmpATH) 
+                    xmin = tmpATH;
+            }
+            /* why is it different from short blocks <?> */
+            if ( !gfc->nsPsy.use ) {
+                xmin *= bw;
+            }
+            else {
+                if      (sfb <=  6) xmin *= gfc->nsPsy.bass;
+                else if (sfb <= 13) xmin *= gfc->nsPsy.alto;
+                else if (sfb <= 20) xmin *= gfc->nsPsy.treble;
+                else                xmin *= gfc->nsPsy.sfb21;
+                if ((gfp->VBR == vbr_off || gfp->VBR == vbr_abr) && gfp->quality <= 1)
+                    xmin *= 0.001;
+            }
+            l3_xmin->l[sfb] = xmin;
+            if (en0 > tmpATH) ath_over++;
+        }   /* sfb */
+       
+    }   /* end of long block case */
+
+    return ath_over;
+}
+
+
+
+
+
+
+
+/*************************************************************************/
+/*            calc_noise                                                 */
+/*************************************************************************/
+
+// -oo dB  =>  -1.00
+// - 6 dB  =>  -0.97
+// - 3 dB  =>  -0.80
+// - 2 dB  =>  -0.64
+// - 1 dB  =>  -0.38
+//   0 dB  =>   0.00
+// + 1 dB  =>  +0.49
+// + 2 dB  =>  +1.06
+// + 3 dB  =>  +1.68
+// + 6 dB  =>  +3.69
+// +10 dB  =>  +6.45
+
+double penalties ( double noise )
+{
+    return log ( 0.368 + 0.632 * noise * noise * noise );
+}
+
+/*  mt 5/99:  Function: Improved calc_noise for a single channel   */
+
+int  calc_noise( 
+        const lame_internal_flags           * const gfc,
+        const FLOAT8                    xr [576],
+        const int                       ix [576],
+        const gr_info           * const cod_info,
+        const III_psy_xmin      * const l3_xmin, 
+        const III_scalefac_t    * const scalefac,
+              III_psy_xmin      * xfsf,
+              calc_noise_result * const res )
+{
+  int sfb,start, end, j,l, i, over=0;
+  FLOAT8 sum;
+  
+  int count=0;
+  FLOAT8 noise,noise_db;
+  FLOAT8 over_noise_db = 0;
+  FLOAT8 tot_noise_db  = 0;     /*    0 dB relative to masking */
+  FLOAT8 max_noise  = 1E-20; /* -200 dB relative to masking */
+  double klemm_noise = 1E-37;
+
+  if (cod_info->block_type == SHORT_TYPE) {
+    int max_index = gfc->sfb21_extra ? SBMAX_s : SBPSY_s;
+
+    for ( j=0, sfb = 0; sfb < max_index; sfb++ ) {
+         start = gfc->scalefac_band.s[ sfb ];
+         end   = gfc->scalefac_band.s[ sfb+1 ];
+         for ( i = 0; i < 3; i++ ) {
+           FLOAT8 step;
+           int s;
+
+           s = (scalefac->s[sfb][i] << (cod_info->scalefac_scale + 1))
+               + cod_info->subblock_gain[i] * 8;
+           s = cod_info->global_gain - s;
+
+           assert(s<Q_MAX);
+           assert(s>=0);
+           step = POW20(s);
+           sum = 0.0;
+           l = start;
+           do {
+             FLOAT8 temp;
+             temp = pow43[ix[j]];
+             temp *= step;
+             temp -= fabs(xr[j]);
+             ++j;
+             sum += temp * temp;
+             l++;
+           } while (l < end);
+            noise = xfsf->s[sfb][i]  = sum / l3_xmin->s[sfb][i];
+
+           max_noise    = Max(max_noise,noise);
+           klemm_noise += penalties (noise);
+
+           noise_db=10*log10(Max(noise,1E-20));
+           tot_noise_db += noise_db;
+
+            if (noise > 1) {
+               over++;
+               over_noise_db += noise_db;
+           }
+           count++;        
+        }
+    }
+  }else{ /* cod_info->block_type == SHORT_TYPE */
+    int max_index = gfc->sfb21_extra ? SBMAX_l : SBPSY_l;
+    
+    for ( sfb = 0; sfb < max_index; sfb++ ) {
+       FLOAT8 step;
+       int s = scalefac->l[sfb];
+
+       if (cod_info->preflag)
+           s += pretab[sfb];
+
+       s = cod_info->global_gain - (s << (cod_info->scalefac_scale + 1));
+       assert(s<Q_MAX);
+       assert(s>=0);
+       step = POW20(s);
+
+       start = gfc->scalefac_band.l[ sfb ];
+        end   = gfc->scalefac_band.l[ sfb+1 ];
+
+       for ( sum = 0.0, l = start; l < end; l++ ) {
+         FLOAT8 temp;
+         temp = fabs(xr[l]) - pow43[ix[l]] * step;
+         sum += temp * temp;
+       }
+       noise = xfsf->l[sfb] = sum / l3_xmin->l[sfb];
+       max_noise=Max(max_noise,noise);
+       klemm_noise += penalties (noise);
+
+       noise_db=10*log10(Max(noise,1E-20));
+       /* multiplying here is adding in dB, but can overflow */
+       //tot_noise *= Max(noise, 1E-20);
+       tot_noise_db += noise_db;
+
+       if (noise > 1) {
+         over++;
+         /* multiplying here is adding in dB -but can overflow */
+         //over_noise *= noise;
+         over_noise_db += noise_db;
+       }
+
+       count++;
+    }
+  } /* cod_info->block_type == SHORT_TYPE */
+
+  /* normalization at this point by "count" is not necessary, since
+   * the values are only used to compare with previous values */
+  res->over_count = over;
+
+  /* convert to db. DO NOT CHANGE THESE */
+  /* tot_noise = is really the average over each sfb of: 
+     [noise(db) - allowed_noise(db)]
+
+     and over_noise is the same average, only over only the
+     bands with noise > allowed_noise.  
+
+  */
+
+  //res->tot_noise   = 10.*log10(Max(1e-20,tot_noise )); 
+  //res->over_noise  = 10.*log10(Max(1e+00,over_noise)); 
+  res->tot_noise   = tot_noise_db;
+  res->over_noise  = over_noise_db;
+  res->max_noise   = 10.*log10(Max(1e-20,max_noise ));
+  res->klemm_noise = 10.*log10(Max(1e-20,klemm_noise));
+
+  return over;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/************************************************************************
+ *
+ *  set_pinfo()
+ *
+ *  updates plotting data    
+ *
+ *  Mark Taylor 2000-??-??                
+ *
+ *  Robert Hegemann: moved noise/distortion calc into it                          
+ *
+ ************************************************************************/
+
+static
+void set_pinfo (
+        lame_global_flags *gfp,
+        const gr_info        * const cod_info,
+        const III_psy_ratio  * const ratio, 
+        const III_scalefac_t * const scalefac,
+        const FLOAT8                 xr[576],
+        const int                    l3_enc[576],        
+        const int                    gr,
+        const int                    ch )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    int sfb;
+    int j,i,l,start,end,bw;
+    FLOAT8 en0,en1;
+    FLOAT ifqstep = ( cod_info->scalefac_scale == 0 ) ? .5 : 1.0;
+
+
+    III_psy_xmin l3_xmin;
+    calc_noise_result noise;
+    III_psy_xmin xfsf;
+
+    calc_xmin (gfp,xr, ratio, cod_info, &l3_xmin);
+
+    calc_noise (gfc, xr, l3_enc, cod_info, &l3_xmin, scalefac, &xfsf, &noise);
+
+    if (cod_info->block_type == SHORT_TYPE) {
+        for (j=0, sfb = 0; sfb < SBMAX_s; sfb++ )  {
+            start = gfc->scalefac_band.s[ sfb ];
+            end   = gfc->scalefac_band.s[ sfb + 1 ];
+            bw = end - start;
+            for ( i = 0; i < 3; i++ ) {
+                for ( en0 = 0.0, l = start; l < end; l++ ) {
+                    en0 += xr[j] * xr[j];
+                    ++j;
+                }
+                en0=Max(en0/bw,1e-20);
+
+
+#if 0
+{
+    double tot1,tot2;
+    if (sfb<SBMAX_s-1) {
+        if (sfb==0) {
+            tot1=0;
+            tot2=0;
+        }
+        tot1 += en0;
+        tot2 += ratio->en.s[sfb][i];
+
+        DEBUGF("%i %i sfb=%i mdct=%f fft=%f  fft-mdct=%f db \n",
+                gr,ch,sfb,
+                10*log10(Max(1e-25,ratio->en.s[sfb][i])),
+                10*log10(Max(1e-25,en0)),
+                10*log10((Max(1e-25,en0)/Max(1e-25,ratio->en.s[sfb][i]))));
+
+        if (sfb==SBMAX_s-2) {
+            DEBUGF("%i %i toti %f %f ratio=%f db \n",gr,ch,
+                    10*log10(Max(1e-25,tot2)),
+                    10*log(Max(1e-25,tot1)),
+                    10*log10(Max(1e-25,tot1)/(Max(1e-25,tot2))));
+
+        }
+    }
+    /*
+        masking: multiplied by en0/fft_energy
+        average seems to be about -135db.
+     */
+}
+#endif
+
+
+                /* convert to MDCT units */
+                en1=1e15;  /* scaling so it shows up on FFT plot */
+                gfc->pinfo->xfsf_s[gr][ch][3*sfb+i] 
+                    = en1*xfsf.s[sfb][i]*l3_xmin.s[sfb][i]/bw;
+                gfc->pinfo->en_s[gr][ch][3*sfb+i] = en1*en0;
+
+                if (ratio->en.s[sfb][i]>0)
+                    en0 = en0/ratio->en.s[sfb][i];
+                else
+                    en0=0;
+                if (gfp->ATHonly || gfp->ATHshort)
+                    en0=0;
+
+                gfc->pinfo->thr_s[gr][ch][3*sfb+i] = 
+                        en1*Max(en0*ratio->thm.s[sfb][i],gfc->ATH->s[sfb]);
+
+                /* there is no scalefactor bands >= SBPSY_s */
+                if (sfb < SBPSY_s) {
+                    gfc->pinfo->LAMEsfb_s[gr][ch][3*sfb+i]=
+                                            -ifqstep*scalefac->s[sfb][i];
+                } else {
+                    gfc->pinfo->LAMEsfb_s[gr][ch][3*sfb+i]=0;
+                }
+                gfc->pinfo->LAMEsfb_s[gr][ch][3*sfb+i] -=
+                                             2*cod_info->subblock_gain[i];
+            }
+        }
+    } else {
+        for ( sfb = 0; sfb < SBMAX_l; sfb++ )   {
+            start = gfc->scalefac_band.l[ sfb ];
+            end   = gfc->scalefac_band.l[ sfb+1 ];
+            bw = end - start;
+            for ( en0 = 0.0, l = start; l < end; l++ ) 
+                en0 += xr[l] * xr[l];
+            if (!gfc->nsPsy.use) en0/=bw;
+      /*
+    DEBUGF("diff  = %f \n",10*log10(Max(ratio[gr][ch].en.l[sfb],1e-20))
+                            -(10*log10(en0)+150));
+       */
+
+#if 0
+ {
+    double tot1,tot2;
+    if (sfb==0) {
+        tot1=0;
+        tot2=0;
+    }
+    tot1 += en0;
+    tot2 += ratio->en.l[sfb];
+
+
+    DEBUGF("%i %i sfb=%i mdct=%f fft=%f  fft-mdct=%f db \n",
+            gr,ch,sfb,
+            10*log10(Max(1e-25,ratio->en.l[sfb])),
+            10*log10(Max(1e-25,en0)),
+            10*log10((Max(1e-25,en0)/Max(1e-25,ratio->en.l[sfb]))));
+
+    if (sfb==SBMAX_l-1) {
+        DEBUGF("%i %i toti %f %f ratio=%f db \n",
+            gr,ch,
+            10*log10(Max(1e-25,tot2)),
+            10*log(Max(1e-25,tot1)),
+            10*log10(Max(1e-25,tot1)/(Max(1e-25,tot2))));
+    }
+    /*
+        masking: multiplied by en0/fft_energy
+        average seems to be about -147db.
+     */
+}
+#endif
+
+
+            /* convert to MDCT units */
+            en1=1e15;  /* scaling so it shows up on FFT plot */
+            gfc->pinfo->xfsf[gr][ch][sfb] =  en1*xfsf.l[sfb]*l3_xmin.l[sfb]/bw;
+            gfc->pinfo->en[gr][ch][sfb] = en1*en0;
+            if (ratio->en.l[sfb]>0)
+                en0 = en0/ratio->en.l[sfb];
+            else
+                en0=0;
+            if (gfp->ATHonly)
+                en0=0;
+            gfc->pinfo->thr[gr][ch][sfb] =
+                             en1*Max(en0*ratio->thm.l[sfb],gfc->ATH->l[sfb]);
+
+            /* there is no scalefactor bands >= SBPSY_l */
+            if (sfb<SBPSY_l) {
+                if (scalefac->l[sfb]<0)  /* scfsi! */
+                    gfc->pinfo->LAMEsfb[gr][ch][sfb] =
+                                            gfc->pinfo->LAMEsfb[0][ch][sfb];
+                else
+                    gfc->pinfo->LAMEsfb[gr][ch][sfb] = -ifqstep*scalefac->l[sfb];
+            }else{
+                gfc->pinfo->LAMEsfb[gr][ch][sfb] = 0;
+            }
+
+            if (cod_info->preflag && sfb>=11) 
+                gfc->pinfo->LAMEsfb[gr][ch][sfb] -= ifqstep*pretab[sfb];
+        } /* for sfb */
+    } /* block type long */
+    gfc->pinfo->LAMEqss     [gr][ch] = cod_info->global_gain;
+    gfc->pinfo->LAMEmainbits[gr][ch] = cod_info->part2_3_length;
+    gfc->pinfo->LAMEsfbits  [gr][ch] = cod_info->part2_length;
+
+    gfc->pinfo->over      [gr][ch] = noise.over_count;
+    gfc->pinfo->max_noise [gr][ch] = noise.max_noise;
+    gfc->pinfo->over_noise[gr][ch] = noise.over_noise;
+    gfc->pinfo->tot_noise [gr][ch] = noise.tot_noise;
+}
+
+
+/************************************************************************
+ *
+ *  set_frame_pinfo()
+ *
+ *  updates plotting data for a whole frame  
+ *
+ *  Robert Hegemann 2000-10-21                          
+ *
+ ************************************************************************/
+
+void set_frame_pinfo( 
+        lame_global_flags *gfp,
+        FLOAT8          xr       [2][2][576],
+        III_psy_ratio   ratio    [2][2],  
+        int             l3_enc   [2][2][576],
+        III_scalefac_t  scalefac [2][2] )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    unsigned int          sfb;
+       int                   ch;
+       int                   gr;
+    int                   act_l3enc[576];
+    III_scalefac_t        act_scalefac [2];
+    int scsfi[2] = {0,0};
+    
+    
+    gfc->masking_lower = 1.0;
+    
+    /* reconstruct the scalefactors in case SCSFI was used 
+     */
+    for (ch = 0; ch < gfc->channels_out; ch ++) {
+        for (sfb = 0; sfb < SBMAX_l; sfb ++) {
+            if (scalefac[1][ch].l[sfb] == -1) {/* scfsi */
+                act_scalefac[ch].l[sfb] = scalefac[0][ch].l[sfb];
+                scsfi[ch] = 1;
+            } else {
+                act_scalefac[ch].l[sfb] = scalefac[1][ch].l[sfb];
+            }
+        }
+    }
+    
+    /* for every granule and channel patch l3_enc and set info
+     */
+    for (gr = 0; gr < gfc->mode_gr; gr ++) {
+        for (ch = 0; ch < gfc->channels_out; ch ++) {
+            int i;
+            gr_info *cod_info = &gfc->l3_side.gr[gr].ch[ch].tt;
+            
+            /* revert back the sign of l3enc */
+            for ( i = 0; i < 576; i++) {
+                if (xr[gr][ch][i] < 0) 
+                    act_l3enc[i] = -l3_enc[gr][ch][i];
+                else
+                    act_l3enc[i] = +l3_enc[gr][ch][i];
+            }
+            if (gr == 1 && scsfi[ch]) 
+                set_pinfo (gfp, cod_info, &ratio[gr][ch], &act_scalefac[ch],
+                        xr[gr][ch], act_l3enc, gr, ch);                    
+            else
+                set_pinfo (gfp, cod_info, &ratio[gr][ch], &scalefac[gr][ch],
+                        xr[gr][ch], act_l3enc, gr, ch);                    
+        } /* for ch */
+    }    /* for gr */
+}
+        
+
+
+
+/*********************************************************************
+ * nonlinear quantization of xr 
+ * More accurate formula than the ISO formula.  Takes into account
+ * the fact that we are quantizing xr -> ix, but we want ix^4/3 to be 
+ * as close as possible to x^4/3.  (taking the nearest int would mean
+ * ix is as close as possible to xr, which is different.)
+ * From Segher Boessenkool <segher@eastsite.nl>  11/1999
+ * ASM optimization from 
+ *    Mathew Hendry <scampi@dial.pipex.com> 11/1999
+ *    Acy Stapp <AStapp@austin.rr.com> 11/1999
+ *    Takehiro Tominaga <tominaga@isoternet.org> 11/1999
+ * 9/00: ASM code removed in favor of IEEE754 hack.  If you need
+ * the ASM code, check CVS circa Aug 2000.  
+ *********************************************************************/
+
+
+#ifdef TAKEHIRO_IEEE754_HACK
+
+typedef union {
+    float f;
+    int i;
+} fi_union;
+
+#define MAGIC_FLOAT (65536*(128))
+#define MAGIC_INT 0x4b000000
+
+void quantize_xrpow(const FLOAT8 *xp, int *pi, FLOAT8 istep)
+{
+    /* quantize on xr^(3/4) instead of xr */
+    int j;
+    fi_union *fi;
+
+    fi = (fi_union *)pi;
+    for (j = 576 / 4 - 1; j >= 0; --j) {
+       double x0 = istep * xp[0];
+       double x1 = istep * xp[1];
+       double x2 = istep * xp[2];
+       double x3 = istep * xp[3];
+
+       x0 += MAGIC_FLOAT; fi[0].f = x0;
+       x1 += MAGIC_FLOAT; fi[1].f = x1;
+       x2 += MAGIC_FLOAT; fi[2].f = x2;
+       x3 += MAGIC_FLOAT; fi[3].f = x3;
+
+       fi[0].f = x0 + (adj43asm - MAGIC_INT)[fi[0].i];
+       fi[1].f = x1 + (adj43asm - MAGIC_INT)[fi[1].i];
+       fi[2].f = x2 + (adj43asm - MAGIC_INT)[fi[2].i];
+       fi[3].f = x3 + (adj43asm - MAGIC_INT)[fi[3].i];
+
+       fi[0].i -= MAGIC_INT;
+       fi[1].i -= MAGIC_INT;
+       fi[2].i -= MAGIC_INT;
+       fi[3].i -= MAGIC_INT;
+       fi += 4;
+       xp += 4;
+    }
+}
+
+#  define ROUNDFAC -0.0946
+void quantize_xrpow_ISO(const FLOAT8 *xp, int *pi, FLOAT8 istep)
+{
+    /* quantize on xr^(3/4) instead of xr */
+    int j;
+    fi_union *fi;
+
+    fi = (fi_union *)pi;
+    for (j=576/4 - 1;j>=0;j--) {
+       fi[0].f = istep * xp[0] + (ROUNDFAC + MAGIC_FLOAT);
+       fi[1].f = istep * xp[1] + (ROUNDFAC + MAGIC_FLOAT);
+       fi[2].f = istep * xp[2] + (ROUNDFAC + MAGIC_FLOAT);
+       fi[3].f = istep * xp[3] + (ROUNDFAC + MAGIC_FLOAT);
+
+       fi[0].i -= MAGIC_INT;
+       fi[1].i -= MAGIC_INT;
+       fi[2].i -= MAGIC_INT;
+       fi[3].i -= MAGIC_INT;
+       fi+=4;
+       xp+=4;
+    }
+}
+
+#else
+
+/*********************************************************************
+ * XRPOW_FTOI is a macro to convert floats to ints.  
+ * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]
+ *                                         ROUNDFAC= -0.0946
+ *
+ * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]   
+ *                                   ROUNDFAC=0.4054
+ *
+ * Note: using floor() or (int) is extermely slow. On machines where
+ * the TAKEHIRO_IEEE754_HACK code above does not work, it is worthwile
+ * to write some ASM for XRPOW_FTOI().  
+ *********************************************************************/
+#define XRPOW_FTOI(src,dest) ((dest) = (int)(src))
+#define QUANTFAC(rx)  adj43[rx]
+#define ROUNDFAC 0.4054
+
+
+void quantize_xrpow(const FLOAT8 *xr, int *ix, FLOAT8 istep) {
+    /* quantize on xr^(3/4) instead of xr */
+    /* from Wilfried.Behne@t-online.de.  Reported to be 2x faster than 
+       the above code (when not using ASM) on PowerPC */
+    int j;
+
+    for ( j = 576/8; j > 0; --j) {
+       FLOAT8  x1, x2, x3, x4, x5, x6, x7, x8;
+       int     rx1, rx2, rx3, rx4, rx5, rx6, rx7, rx8;
+       x1 = *xr++ * istep;
+       x2 = *xr++ * istep;
+       XRPOW_FTOI(x1, rx1);
+       x3 = *xr++ * istep;
+       XRPOW_FTOI(x2, rx2);
+       x4 = *xr++ * istep;
+       XRPOW_FTOI(x3, rx3);
+       x5 = *xr++ * istep;
+       XRPOW_FTOI(x4, rx4);
+       x6 = *xr++ * istep;
+       XRPOW_FTOI(x5, rx5);
+       x7 = *xr++ * istep;
+       XRPOW_FTOI(x6, rx6);
+       x8 = *xr++ * istep;
+       XRPOW_FTOI(x7, rx7);
+       x1 += QUANTFAC(rx1);
+       XRPOW_FTOI(x8, rx8);
+       x2 += QUANTFAC(rx2);
+       XRPOW_FTOI(x1,*ix++);
+       x3 += QUANTFAC(rx3);
+       XRPOW_FTOI(x2,*ix++);
+       x4 += QUANTFAC(rx4);
+       XRPOW_FTOI(x3,*ix++);
+       x5 += QUANTFAC(rx5);
+       XRPOW_FTOI(x4,*ix++);
+       x6 += QUANTFAC(rx6);
+       XRPOW_FTOI(x5,*ix++);
+       x7 += QUANTFAC(rx7);
+       XRPOW_FTOI(x6,*ix++);
+       x8 += QUANTFAC(rx8);
+       XRPOW_FTOI(x7,*ix++);
+       XRPOW_FTOI(x8,*ix++);
+    }
+}
+
+
+
+
+
+
+void quantize_xrpow_ISO( const FLOAT8 *xr, int *ix, FLOAT8 istep )
+{
+    /* quantize on xr^(3/4) instead of xr */
+    const FLOAT8 compareval0 = (1.0 - 0.4054)/istep;
+    int j;
+    /* depending on architecture, it may be worth calculating a few more
+       compareval's.
+
+       eg.  compareval1 = (2.0 - 0.4054/istep);
+       .. and then after the first compare do this ...
+       if compareval1>*xr then ix = 1;
+
+       On a pentium166, it's only worth doing the one compare (as done here),
+       as the second compare becomes more expensive than just calculating
+       the value. Architectures with slow FP operations may want to add some
+       more comparevals. try it and send your diffs statistically speaking
+
+       73% of all xr*istep values give ix=0
+       16% will give 1
+       4%  will give 2
+    */
+    for (j=576;j>0;j--) {
+       if (compareval0 > *xr) {
+           *(ix++) = 0;
+           xr++;
+       } else {
+           /*    *(ix++) = (int)( istep*(*(xr++))  + 0.4054); */
+           XRPOW_FTOI(  istep*(*(xr++))  + ROUNDFAC , *(ix++) );
+       }
+    }
+}
+
+#endif
diff --git a/lib/lame/quantize_pvt.h b/lib/lame/quantize_pvt.h
new file mode 100644 (file)
index 0000000..79e7a5a
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ *     quantize_pvt include file
+ *
+ *     Copyright (c) 1999 Takehiro TOMINAGA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_QUANTIZE_PVT_H
+#define LAME_QUANTIZE_PVT_H
+
+#include "l3side.h"
+#define IXMAX_VAL 8206  /* ix always <= 8191+15.    see count_bits() */
+
+/* buggy Winamp decoder cannot handle values > 8191 */
+/* #define IXMAX_VAL 8191 */
+
+#define PRECALC_SIZE (IXMAX_VAL+2)
+
+
+extern const int nr_of_sfb_block[6][3][4];
+extern const char pretab[SBMAX_l];
+extern const char slen1_tab[16];
+extern const char slen2_tab[16];
+
+extern const scalefac_struct sfBandIndex[9];
+
+extern FLOAT8 pow43[PRECALC_SIZE];
+extern FLOAT8 adj43[PRECALC_SIZE];
+extern FLOAT8 adj43asm[PRECALC_SIZE];
+
+#define Q_MAX 330
+
+extern FLOAT8 pow20[Q_MAX];
+extern FLOAT8 ipow20[Q_MAX];
+extern FLOAT8 *iipow20_;
+
+typedef struct calc_noise_result_t {
+    int     over_count;      /* number of quantization noise > masking */
+    FLOAT8  over_noise;      /* sum of quantization noise > masking */
+    FLOAT8  tot_noise;       /* sum of all quantization noise */
+    FLOAT8  max_noise;       /* max quantization noise */
+    float   klemm_noise;
+} calc_noise_result;
+
+void    compute_ath (lame_global_flags * gfp, FLOAT8 ATH_l[SBPSY_l],
+                     FLOAT8 ATH_s[SBPSY_l]);
+
+void    ms_convert (FLOAT8 xr[2][576], FLOAT8 xr_org[2][576]);
+
+int     on_pe (lame_global_flags *gfp, FLOAT8 pe[2][2], III_side_info_t * l3_side,
+               int targ_bits[2], int mean_bits, int gr);
+
+void    reduce_side (int targ_bits[2], FLOAT8 ms_ener_ratio, int mean_bits,
+                     int max_bits);
+
+
+int     bin_search_StepSize (lame_internal_flags * const gfc, gr_info * const cod_info,
+                             const int desired_rate, const int start,
+                             const FLOAT8 xrpow[576], int l3enc[576]);
+
+int     inner_loop (lame_internal_flags * const gfc, gr_info * const cod_info, const int max_bits,
+                    const FLOAT8 xrpow[576], int l3enc[576]);
+
+void    iteration_init (lame_global_flags *gfp);
+
+
+int     calc_xmin (lame_global_flags *gfp, const FLOAT8 xr[576],
+                   const III_psy_ratio * const ratio, const gr_info * const cod_info,
+                   III_psy_xmin * const l3_xmin);
+
+int     calc_noise (const lame_internal_flags * const gfc, const FLOAT8 xr[576],
+                    const int ix[576], const gr_info * const cod_info,
+                    const III_psy_xmin * const l3_xmin,
+                    const III_scalefac_t * const scalefac,
+                    III_psy_xmin * distort, calc_noise_result * const res);
+
+void    set_frame_pinfo (lame_global_flags *gfp, FLOAT8 xr[2][2][576],
+                         III_psy_ratio ratio[2][2], int l3_enc[2][2][576],
+                         III_scalefac_t scalefac[2][2]);
+
+
+void    quantize_xrpow (const FLOAT8 *xr, int *ix, FLOAT8 istep);
+
+void    quantize_xrpow_ISO (const FLOAT8 *xr, int *ix, FLOAT8 istep);
+
+
+
+/* takehiro.c */
+
+int     count_bits (lame_internal_flags * const gfc, int * const ix, const FLOAT8 * const xr,
+                    gr_info * const cod_info);
+
+
+void    best_huffman_divide (const lame_internal_flags * const gfc, 
+                             gr_info * const cod_info, int * const ix);
+
+void    best_scalefac_store (const lame_internal_flags * gfc, const int gr, const int ch,
+                             int l3_enc[2][2][576], III_side_info_t * const l3_side,
+                             III_scalefac_t scalefac[2][2]);
+
+int     scale_bitcount (III_scalefac_t * const scalefac, gr_info * const cod_info);
+
+int     scale_bitcount_lsf (const lame_internal_flags *gfp, const III_scalefac_t * const scalefac,
+                            gr_info * const cod_info);
+
+void    huffman_init (lame_internal_flags * const gfc);
+
+#define LARGE_BITS 100000
+
+#endif /* LAME_QUANTIZE_PVT_H */
diff --git a/lib/lame/reservoir.c b/lib/lame/reservoir.c
new file mode 100644 (file)
index 0000000..38d3849
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ *     bit reservoir source file
+ *
+ *     Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: reservoir.c,v 1.1 2002/04/28 17:30:27 kramm Exp $ */
+
+#include "config_static.h"
+
+#include <assert.h>
+#include "util.h"
+#include "reservoir.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+/*
+  ResvFrameBegin:
+  Called (repeatedly) at the beginning of a frame. Updates the maximum
+  size of the reservoir, and checks to make sure main_data_begin
+  was set properly by the formatter
+*/
+
+/*
+ *  Background information:
+ *
+ *  This is the original text from the ISO standard. Because of 
+ *  sooo many bugs and irritations correcting comments are added 
+ *  in brackets []. A '^W' means you should remove the last word.
+ *
+ *  1) The following rule can be used to calculate the maximum 
+ *     number of bits used for one granule [^W frame]: 
+ *     At the highest possible bitrate of Layer III (320 kbps 
+ *     per stereo signal [^W^W^W], 48 kHz) the frames must be of
+ *     [^W^W^W are designed to have] constant length, i.e. 
+ *     one buffer [^W^W the frame] length is:
+ *
+ *         320 kbps * 1152/48 kHz = 7680 bit = 960 byte
+ *
+ *     This value is used as the maximum buffer per channel [^W^W] at 
+ *     lower bitrates [than 320 kbps]. At 64 kbps mono or 128 kbps 
+ *     stereo the main granule length is 64 kbps * 576/48 kHz = 768 bit
+ *     [per granule and channel] at 48 kHz sampling frequency. 
+ *     This means that there is a maximum deviation (short time buffer 
+ *     [= reservoir]) of 7680 - 2*2*768 = 4608 bits is allowed at 64 kbps. 
+ *     The actual deviation is equal to the number of bytes [with the 
+ *     meaning of octets] denoted by the main_data_end offset pointer. 
+ *     The actual maximum deviation is (2^9-1)*8 bit = 4088 bits 
+ *     [for MPEG-1 and (2^8-1)*8 bit for MPEG-2, both are hard limits].
+ *     ... The xchange of buffer bits between the left and right channel
+ *     is allowed without restrictions [exception: dual channel].
+ *     Because of the [constructed] constraint on the buffer size
+ *     main_data_end is always set to 0 in the case of bit_rate_index==14, 
+ *     i.e. data rate 320 kbps per stereo signal [^W^W^W]. In this case 
+ *     all data are allocated between adjacent header [^W sync] words 
+ *     [, i.e. there is no buffering at all].
+ */
+
+int
+ResvFrameBegin(lame_global_flags *gfp,III_side_info_t *l3_side, int mean_bits, int frameLength )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    int fullFrameBits;
+    int resvLimit;
+    int maxmp3buf;
+
+/*
+ *  Meaning of the variables:
+ *      resvLimit: (0, 8, ..., 8*255 (MPEG-2), 8*511 (MPEG-1))
+ *          Number of bits can be stored in previous frame(s) due to 
+ *          counter size constaints
+ *      maxmp3buf: ( ??? ... 8*1951 (MPEG-1 and 2), 8*2047 (MPEG-2.5))
+ *          Number of bits allowed to encode one frame (you can take 8*511 bit 
+ *          from the bit reservoir and at most 8*1440 bit from the current 
+ *          frame (320 kbps, 32 kHz), so 8*1951 bit is the largest possible 
+ *          value for MPEG-1 and -2)
+ *       
+ *          maximum allowed granule/channel size times 4 = 8*2047 bits.,
+ *          so this is the absolute maximum supported by the format.
+ *
+ *          
+ *      fullFrameBits:  maximum number of bits available for encoding
+ *                      the current frame.
+ *
+ *      mean_bits:      target number of bits per granule.  
+ *
+ *      frameLength:
+ *
+ *      gfc->ResvMax:   maximum allowed reservoir 
+ *
+ *      gfc->ResvSize:  current reservoir size
+ *
+ *      l3_side->resvDrain_pre:
+ *         ancillary data to be added to previous frame:
+ *         (only usefull in VBR modes if it is possible to have
+ *         maxmp3buf < fullFrameBits)).  Currently disabled, 
+ *         see #define NEW_DRAIN
+ *
+ *      l3_side->resvDrain_post:
+ *         ancillary data to be added to this frame:
+ *
+ */
+
+    /* main_data_begin has 9 bits in MPEG-1, 8 bits MPEG-2 */
+    resvLimit = (gfp->version==1) ? 8*511 : 8*255 ;
+
+
+    /* maximum allowed frame size.  dont use more than this number of
+       bits, even if the frame has the space for them: */
+    /* Bouvigne suggests this more lax interpretation of the ISO doc 
+       instead of using 8*960. */
+    if (gfp->strict_ISO) {
+        if (gfp->version==1)
+            maxmp3buf=8*((int)(320000/(gfp->out_samplerate / (FLOAT8)1152)/8 +.5));
+        else
+            maxmp3buf=8*((int)(160000/(gfp->out_samplerate / (FLOAT8)576)/8 +.5));
+    } else
+        /*all mp3 decoders should have enough buffer to handle this value: size of a 320kbps 32kHz frame*/
+        maxmp3buf = 8*1440;
+
+
+    if ( frameLength > maxmp3buf ||  gfp->disable_reservoir ) {
+       gfc->ResvMax = 0;
+    } else {
+       gfc->ResvMax = maxmp3buf - frameLength;
+       if ( gfc->ResvMax > resvLimit )
+         gfc->ResvMax = resvLimit;
+    }
+
+    fullFrameBits = mean_bits * gfc->mode_gr + Min ( gfc->ResvSize, gfc->ResvMax );
+    
+    if ( fullFrameBits > maxmp3buf )
+        fullFrameBits = maxmp3buf;
+
+    assert ( 0 == gfc->ResvMax % 8 );
+    assert ( gfc->ResvMax >= 0 );
+
+    l3_side->resvDrain_pre = 0;
+
+    if ( gfc->pinfo != NULL ) {
+        gfc->pinfo->mean_bits = mean_bits / 2;  /* expected bits per channel per granule [is this also right for mono/stereo, MPEG-1/2 ?] */
+        gfc->pinfo->resvsize  = gfc->ResvSize;
+    }
+
+    return fullFrameBits;
+}
+
+
+/*
+  ResvMaxBits
+  returns targ_bits:  target number of bits to use for 1 granule
+         extra_bits:  amount extra available from reservoir
+  Mark Taylor 4/99
+*/
+void ResvMaxBits(lame_global_flags *gfp, int mean_bits, int *targ_bits, int *extra_bits)
+{
+  lame_internal_flags *gfc=gfp->internal_flags;
+  int add_bits;
+  int full_fac;
+  
+  *targ_bits = mean_bits ;
+
+  /* extra bits if the reservoir is almost full */
+  full_fac=9;
+  if (gfc->ResvSize > ((gfc->ResvMax * full_fac) / 10)) {
+    add_bits= gfc->ResvSize-((gfc->ResvMax * full_fac) / 10);
+    *targ_bits += add_bits;
+  }else {
+    add_bits =0 ;
+    /* build up reservoir.  this builds the reservoir a little slower
+     * than FhG.  It could simple be mean_bits/15, but this was rigged
+     * to always produce 100 (the old value) at 128kbs */
+    /*    *targ_bits -= (int) (mean_bits/15.2);*/
+    if (!gfp->disable_reservoir) 
+      *targ_bits -= .1*mean_bits;
+  }
+
+
+  /* amount from the reservoir we are allowed to use. ISO says 6/10 */
+  *extra_bits =
+    (gfc->ResvSize  < (gfc->ResvMax*6)/10  ? gfc->ResvSize : (gfc->ResvMax*6)/10);
+  *extra_bits -= add_bits;
+
+  if (*extra_bits < 0) *extra_bits=0;
+
+
+}
+
+/*
+  ResvAdjust:
+  Called after a granule's bit allocation. Readjusts the size of
+  the reservoir to reflect the granule's usage.
+*/
+void
+ResvAdjust(lame_internal_flags *gfc,gr_info *gi, III_side_info_t *l3_side, int mean_bits )
+{
+  gfc->ResvSize += (mean_bits / gfc->channels_out) - gi->part2_3_length;
+#if 0
+  printf("part2_3_length:  %i  avg=%i  incres: %i  resvsize=%i\n",gi->part2_3_length,
+        mean_bits/gfc->channels_out,
+mean_bits/gfc->channels_out-gi->part2_3_length,gfc->ResvSize);
+#endif
+}
+
+
+/*
+  ResvFrameEnd:
+  Called after all granules in a frame have been allocated. Makes sure
+  that the reservoir size is within limits, possibly by adding stuffing
+  bits.
+*/
+void
+ResvFrameEnd(lame_internal_flags *gfc, III_side_info_t *l3_side, int mean_bits)
+{
+    int stuffingBits;
+    int over_bits;
+
+
+    /* just in case mean_bits is odd, this is necessary... */
+    if ( gfc->channels_out == 2  &&  (mean_bits & 1) )
+       gfc->ResvSize += 1;
+
+    stuffingBits=0;
+    l3_side->resvDrain_post = 0;
+    l3_side->resvDrain_pre = 0;
+
+    /* we must be byte aligned */
+    if ( (over_bits = gfc->ResvSize % 8) != 0 )
+       stuffingBits += over_bits;
+
+
+    over_bits = (gfc->ResvSize - stuffingBits) - gfc->ResvMax;
+    if (over_bits > 0) {
+      assert ( 0 == over_bits % 8 );
+      assert ( over_bits >= 0 );
+      stuffingBits += over_bits;
+    }
+
+
+#undef NEW_DRAIN
+#ifdef NEW_DRAIN
+    /* drain as many bits as possible into previous frame ancillary data
+     * In particular, in VBR mode ResvMax may have changed, and we have
+     * to make sure main_data_begin does not create a reservoir bigger
+     * than ResvMax  mt 4/00*/
+  {
+    int mdb_bytes = Min(l3_side->main_data_begin*8,stuffingBits)/8;
+    l3_side->resvDrain_pre += 8*mdb_bytes;
+    stuffingBits -= 8*mdb_bytes;
+    gfc->ResvSize -= 8*mdb_bytes;
+    l3_side->main_data_begin -= mdb_bytes;
+
+
+    /* drain just enough to be byte aligned.  The remaining bits will
+     * be added to the reservoir, and we will deal with them next frame.
+     * If the next frame is at a lower bitrate, it may have a larger ResvMax,
+     * and we will not have to waste these bits!  mt 4/00 */
+    assert ( stuffingBits >= 0 );
+    l3_side->resvDrain_post += (stuffingBits % 8);
+    gfc->ResvSize -= stuffingBits % 8;
+  }
+#else
+    /* drain the rest into this frames ancillary data*/
+    l3_side->resvDrain_post += stuffingBits;
+    gfc->ResvSize -= stuffingBits;
+#endif
+
+    return;
+}
+
+
diff --git a/lib/lame/reservoir.h b/lib/lame/reservoir.h
new file mode 100644 (file)
index 0000000..aeed917
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *     bit reservoir include file
+ *
+ *     Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_RESERVOIR_H
+#define LAME_RESERVOIR_H
+
+int ResvFrameBegin(lame_global_flags *gfp,III_side_info_t *l3_side, int mean_bits, int frameLength );
+void ResvMaxBits(lame_global_flags *gfp, int mean_bits, int *targ_bits, int *max_bits);
+void ResvAdjust(lame_internal_flags *gfc,gr_info *gi, III_side_info_t *l3_side, int mean_bits );
+void ResvFrameEnd(lame_internal_flags *gfc,III_side_info_t *l3_side, int mean_bits );
+
+#endif /* LAME_RESERVOIR_H */
diff --git a/lib/lame/set_get.c b/lib/lame/set_get.c
new file mode 100644 (file)
index 0000000..5c04ca3
--- /dev/null
@@ -0,0 +1,1550 @@
+/* -*- mode: C; mode: fold -*- */
+/*
+ * set/get functions for lame_global_flags
+ *
+ * Copyright (c) 2001 Alexander Leidinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: set_get.c,v 1.1 2002/04/28 17:30:28 kramm Exp $ */
+
+#include "config_static.h"
+
+#include <assert.h>
+#include "util.h"
+#include "bitstream.h"  /* because of compute_flushbits */
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+
+/*
+ * input stream description
+ */
+
+/* number of samples */
+/* it's unlikely for this function to return an error */
+int
+lame_set_num_samples( lame_global_flags*  gfp,
+                      unsigned long       num_samples)
+{
+    /* default = 2^32-1 */
+
+    gfp->num_samples = num_samples;
+
+    return 0;
+}
+
+unsigned long
+lame_get_num_samples( const lame_global_flags* gfp )
+{
+    return gfp->num_samples;
+}
+
+
+/* input samplerate */
+int
+lame_set_in_samplerate( lame_global_flags*  gfp,
+                        int                 in_samplerate )
+{
+    /* input sample rate in Hz,  default = 44100 Hz */
+    gfp->in_samplerate = in_samplerate;
+
+    return 0;
+}
+
+int
+lame_get_in_samplerate( const lame_global_flags*  gfp )
+{
+    return gfp->in_samplerate;
+}
+
+
+/* number of channels in input stream */
+int
+lame_set_num_channels( lame_global_flags*  gfp,
+                       int                 num_channels )
+{
+    /* default = 2 */
+
+    if ( 2 < num_channels || 0 == num_channels )
+        return -1;    /* we don't support more than 2 channels */
+
+    gfp->num_channels = num_channels;
+
+    return 0;
+}
+
+int
+lame_get_num_channels( const lame_global_flags*  gfp )
+{
+    return gfp->num_channels;
+}
+
+
+/* scale the input by this amount before encoding (not used for decoding) */
+int
+lame_set_scale( lame_global_flags*  gfp,
+                float               scale )
+{
+    /* default = 0 */
+    gfp->scale = scale;
+
+    return 0;
+}
+
+float
+lame_get_scale( const lame_global_flags*  gfp )
+{
+    return gfp->scale;
+}
+
+
+/* scale the channel 0 (left) input by this amount before 
+   encoding (not used for decoding) */
+int
+lame_set_scale_left( lame_global_flags*  gfp,
+                     float               scale )
+{
+    /* default = 0 */
+    gfp->scale_left = scale;
+
+    return 0;
+}
+
+float
+lame_get_scale_left( const lame_global_flags*  gfp )
+{
+    return gfp->scale_left;
+}
+
+
+/* scale the channel 1 (right) input by this amount before 
+   encoding (not used for decoding) */
+int
+lame_set_scale_right( lame_global_flags*  gfp,
+                      float               scale )
+{
+    /* default = 0 */
+    gfp->scale_right = scale;
+
+    return 0;
+}
+
+float
+lame_get_scale_right( const lame_global_flags*  gfp )
+{
+    return gfp->scale_right;
+}
+
+
+/* output sample rate in Hz */
+int
+lame_set_out_samplerate( lame_global_flags*  gfp,
+                         int                 out_samplerate )
+{
+    /*
+     * default = 0: LAME picks best value based on the amount
+     *              of compression
+     * MPEG only allows:
+     *  MPEG1    32, 44.1,   48khz
+     *  MPEG2    16, 22.05,  24
+     *  MPEG2.5   8, 11.025, 12
+     *
+     * (not used by decoding routines)
+     */
+    gfp->out_samplerate = out_samplerate;
+
+    return 0;
+}
+
+int
+lame_get_out_samplerate( const lame_global_flags*  gfp )
+{
+    return gfp->out_samplerate;
+}
+
+
+
+
+/*
+ * general control parameters
+ */
+
+/* collect data for an MP3 frame analzyer */
+int
+lame_set_analysis( lame_global_flags*  gfp,
+                   int                 analysis )
+{
+    /* default = 0 */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > analysis || 1 < analysis )
+        return -1;
+
+    gfp->analysis = analysis;
+
+    return 0;
+}
+
+int
+lame_get_analysis( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->analysis && 1 >= gfp->analysis );
+
+    return gfp->analysis;
+}
+
+
+/* write a Xing VBR header frame */
+int
+lame_set_bWriteVbrTag( lame_global_flags*  gfp,
+                       int bWriteVbrTag )
+{
+    /* default = 1 (on) for VBR/ABR modes, 0 (off) for CBR mode */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > bWriteVbrTag || 1 < bWriteVbrTag )
+        return -1;
+
+    gfp->bWriteVbrTag = bWriteVbrTag;
+
+    return 0;
+}
+
+int
+lame_get_bWriteVbrTag( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->bWriteVbrTag && 1 >= gfp->bWriteVbrTag );
+
+    return gfp->bWriteVbrTag;
+}
+
+
+
+/* decode only, use lame/mpglib to convert mp3/ogg to wav */
+int
+lame_set_decode_only( lame_global_flags*  gfp,
+                      int                 decode_only )
+{
+    /* default = 0 (disabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > decode_only || 1 < decode_only )
+        return -1;
+
+    gfp->decode_only = decode_only;
+
+    return 0;
+}
+
+int
+lame_get_decode_only( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->decode_only && 1 >= gfp->decode_only );
+
+    return gfp->decode_only;
+}
+
+
+/* encode a Vorbis .ogg file */
+int
+lame_set_ogg( lame_global_flags*  gfp,
+              int                 ogg )
+{
+    /* default = 0 (disabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > ogg || 1 < ogg )
+        return -1;
+
+    gfp->ogg = ogg;
+
+    return 0;
+}
+
+int
+lame_get_ogg( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->ogg && 1 >= gfp->ogg );
+
+    return gfp->ogg;
+}
+
+
+/*
+ * Internal algorithm selection.
+ * True quality is determined by the bitrate but this variable will effect
+ * quality by selecting expensive or cheap algorithms.
+ * quality=0..9.  0=best (very slow).  9=worst.  
+ * recommended:  2     near-best quality, not too slow
+ *               5     good quality, fast
+ *               7     ok quality, really fast
+ */
+int
+lame_set_quality( lame_global_flags*  gfp,
+                  int                 quality )
+{
+    gfp->quality = quality;
+
+    return 0;
+}
+
+int
+lame_get_quality( const lame_global_flags*  gfp )
+{
+    return gfp->quality;
+}
+
+
+/* mode = STEREO, JOINT_STEREO, DUAL_CHANNEL (not supported), MONO */
+int
+lame_set_mode( lame_global_flags*  gfp,
+               MPEG_mode           mode )
+{
+    /* default: lame chooses based on compression ratio and input channels */
+
+    if( 0 > mode || MAX_INDICATOR <= mode )
+        return -1;  /* Unknown MPEG mode! */
+
+    gfp->mode = mode;
+
+    return 0;
+}
+
+MPEG_mode
+lame_get_mode( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->mode && MAX_INDICATOR > gfp->mode );
+
+    return gfp->mode;
+}
+
+
+/* Us a M/S mode with a switching threshold based on compression ratio */
+int
+lame_set_mode_automs( lame_global_flags*  gfp,
+                      int                 mode_automs )
+{
+    /* default = 0 (disabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > mode_automs || 1 < mode_automs )
+        return -1;
+
+    gfp->mode_automs = mode_automs;
+
+    return 0;
+}
+
+int
+lame_get_mode_automs( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->mode_automs && 1 >= gfp->mode_automs );
+
+    return gfp->mode_automs;
+}
+
+
+/*
+ * Force M/S for all frames.  For testing only.
+ * Requires mode = 1.
+ */
+int
+lame_set_force_ms( lame_global_flags*  gfp,
+                   int                 force_ms )
+{
+    /* default = 0 (disabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > force_ms || 1 < force_ms )
+        return -1;
+
+    gfp->force_ms = force_ms;
+
+    return 0;
+}
+
+int
+lame_get_force_ms( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->force_ms && 1 >= gfp->force_ms );
+
+    return gfp->force_ms;
+}
+
+
+/* Use free_format. */
+int
+lame_set_free_format( lame_global_flags*  gfp,
+                      int                 free_format )
+{
+    /* default = 0 (disabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > free_format || 1 < free_format )
+        return -1;
+
+    gfp->free_format = free_format;
+
+    return 0;
+}
+
+int
+lame_get_free_format( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->free_format && 1 >= gfp->free_format );
+
+    return gfp->free_format;
+}
+
+
+/* message handlers */
+int
+lame_set_errorf( lame_global_flags*  gfp,
+                 void                (*func)( const char*, va_list ) )
+{
+    gfp->report.errorf = func;
+
+    return 0;
+}
+
+int
+lame_set_debugf( lame_global_flags*  gfp,
+                 void                (*func)( const char*, va_list ) )
+{
+    gfp->report.debugf = func;
+
+    return 0;
+}
+
+int
+lame_set_msgf( lame_global_flags*  gfp,
+               void                (*func)( const char *, va_list ) )
+{
+    gfp->report.msgf = func;
+
+    return 0;
+}
+
+
+/*
+ * Set one of
+ *  - brate
+ *  - compression ratio.
+ *
+ * Default is compression ratio of 11.
+ */
+int
+lame_set_brate( lame_global_flags*  gfp,
+                int                 brate )
+{
+    gfp->brate = brate;
+
+    return 0;
+}
+
+int
+lame_get_brate( const lame_global_flags*  gfp )
+{
+    return gfp->brate;
+}
+
+int
+lame_set_compression_ratio( lame_global_flags*  gfp,
+                            float               compression_ratio )
+{
+    gfp->compression_ratio = compression_ratio;
+
+    return 0;
+}
+
+float
+lame_get_compression_ratio( const lame_global_flags*  gfp )
+{
+    return gfp->compression_ratio;
+}
+
+
+
+
+/*
+ * frame parameters
+ */
+
+/* Mark as copyright protected. */
+int
+lame_set_copyright( lame_global_flags*  gfp,
+                    int                 copyright )
+{
+    /* default = 0 (disabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > copyright || 1 < copyright )
+        return -1;
+
+    gfp->copyright = copyright;
+
+    return 0;
+}
+
+int
+lame_get_copyright( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->copyright && 1 >= gfp->copyright );
+
+    return gfp->copyright;
+}
+
+
+/* Mark as original. */
+int
+lame_set_original( lame_global_flags*  gfp,
+                   int                 original )
+{
+    /* default = 1 (enabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > original || 1 < original )
+        return -1;
+
+    gfp->original = original;
+
+    return 0;
+}
+
+int
+lame_get_original( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->original && 1 >= gfp->original );
+
+    return gfp->original;
+}
+
+
+/*
+ * error_protection.
+ * Use 2 bytes from each frame for CRC checksum.
+ */
+int
+lame_set_error_protection( lame_global_flags*  gfp,
+                           int                 error_protection )
+{
+    /* default = 0 (disabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > error_protection || 1 < error_protection )
+        return -1;
+
+    gfp->error_protection = error_protection;
+
+    return 0;
+}
+
+int
+lame_get_error_protection( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->error_protection && 1 >= gfp->error_protection );
+
+    return gfp->error_protection;
+}
+
+
+/*
+ * padding_type.
+ *  PAD_NO     = pad no frames
+ *  PAD_ALL    = pad all frames
+ *  PAD_ADJUST = adjust padding
+ */
+int
+lame_set_padding_type( lame_global_flags*  gfp,
+                       Padding_type        padding_type )
+{
+    /* default = 2 */
+
+    if ( 0 > padding_type || PAD_MAX_INDICATOR < padding_type )
+        return -1;  /* Unknown padding type */
+
+    gfp->padding_type = padding_type;
+
+    return 0;
+}
+
+Padding_type
+lame_get_padding_type( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->padding_type && PAD_MAX_INDICATOR > gfp->padding_type );
+
+    return gfp->padding_type;
+}
+
+
+/* MP3 'private extension' bit. Meaningless. */
+int
+lame_set_extension( lame_global_flags*  gfp,
+                    int                 extension )
+{
+    /* default = 0 (disabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > extension || 1 < extension )
+        return -1;
+
+    gfp->extension = extension;
+
+    return 0;
+}
+
+int
+lame_get_extension( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->extension && 1 >= gfp->extension );
+
+    return gfp->extension;
+}
+
+
+/* Enforce strict ISO compliance. */
+int
+lame_set_strict_ISO( lame_global_flags*  gfp,
+                     int                 strict_ISO )
+{
+    /* default = 0 (disabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > strict_ISO || 1 < strict_ISO )
+        return -1;
+
+    gfp->strict_ISO = strict_ISO;
+
+    return 0;
+}
+
+int
+lame_get_strict_ISO( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->strict_ISO && 1 >= gfp->strict_ISO );
+
+    return gfp->strict_ISO;
+}
+
+
+
+/********************************************************************
+ * quantization/noise shaping 
+ ***********************************************************************/
+
+/* Disable the bit reservoir. For testing only. */
+int
+lame_set_disable_reservoir( lame_global_flags*  gfp,
+                            int                 disable_reservoir )
+{
+    /* default = 0 (disabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > disable_reservoir || 1 < disable_reservoir )
+        return -1;
+
+    gfp->disable_reservoir = disable_reservoir;
+
+    return 0;
+}
+
+int
+lame_get_disable_reservoir( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->disable_reservoir && 1 >= gfp->disable_reservoir );
+
+    return gfp->disable_reservoir;
+}
+
+
+
+
+/* Select a different "best quantization" function. default = 0 */
+int
+lame_set_experimentalX( lame_global_flags*  gfp,
+                        int                 experimentalX )
+{
+    gfp->experimentalX = experimentalX;
+
+    return 0;
+}
+
+int
+lame_get_experimentalX( const lame_global_flags*  gfp )
+{
+    return gfp->experimentalX;
+}
+
+
+/* Another experimental option. For testing only. */
+int
+lame_set_experimentalY( lame_global_flags*  gfp,
+                        int                 experimentalY )
+{
+    gfp->experimentalY = experimentalY;
+
+    return 0;
+}
+
+int
+lame_get_experimentalY( const lame_global_flags*  gfp )
+{
+    return gfp->experimentalY;
+}
+
+
+/* Another experimental option. For testing only. */
+int
+lame_set_experimentalZ( lame_global_flags*  gfp,
+                        int                 experimentalZ )
+{
+    gfp->experimentalZ += experimentalZ;
+
+    return 0;
+}
+
+int
+lame_get_experimentalZ( const lame_global_flags*  gfp )
+{
+    return gfp->experimentalZ;
+}
+
+
+/* Naoki's psycho acoustic model. */
+int
+lame_set_exp_nspsytune( lame_global_flags*  gfp,
+                        int                 exp_nspsytune )
+{
+    /* default = 0 (disabled) */
+
+    gfp->exp_nspsytune = exp_nspsytune;
+
+    return 0;
+}
+
+int
+lame_get_exp_nspsytune( const lame_global_flags*  gfp )
+{
+    return gfp->exp_nspsytune;
+}
+
+
+
+
+/********************************************************************
+ * VBR control
+ ***********************************************************************/
+
+// Types of VBR.  default = vbr_off = CBR
+int
+lame_set_VBR( lame_global_flags*  gfp,
+              vbr_mode            VBR )
+{
+    if( 0 > VBR || vbr_max_indicator <= VBR )
+        return -1;  /* Unknown VBR mode! */
+
+    gfp->VBR = VBR;
+
+    return 0;
+}
+
+vbr_mode
+lame_get_VBR( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->VBR && vbr_max_indicator > gfp->VBR );
+
+    return gfp->VBR;
+}
+
+
+/*
+ * VBR quality level.
+ *  0 = highest
+ *  9 = lowest 
+ */
+int
+lame_set_VBR_q( lame_global_flags*  gfp,
+                int                 VBR_q )
+{
+    /* XXX: This should be an enum */
+    /*  to whoever added this note: why should it be an enum?
+        do you want to call a specific setting by name? 
+        say VBR quality level red? */
+    /* No, but VBR_Q_HIGHEST, VBR_Q_HIGH, ..., VBR_Q_MID, ...
+       VBR_Q_LOW, VBR_Q_LOWEST (or something like that )and a
+       VBR_Q_DEFAULT, which aliases the default setting of
+       e.g. VBR_Q_MID. */
+
+
+    if( 0 > VBR_q || 10 <= VBR_q )
+        return -1;  /* Unknown VBR quality level! */
+
+    gfp->VBR_q = VBR_q;
+
+    return 0;
+}
+
+int
+lame_get_VBR_q( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->VBR_q && 10 > gfp->VBR_q );
+
+    return gfp->VBR_q;
+}
+
+
+/* Ignored except for VBR = vbr_abr (ABR mode) */
+int
+lame_set_VBR_mean_bitrate_kbps( lame_global_flags*  gfp,
+                                int                 VBR_mean_bitrate_kbps )
+{
+    gfp->VBR_mean_bitrate_kbps = VBR_mean_bitrate_kbps;
+
+    return 0;
+}
+
+int
+lame_get_VBR_mean_bitrate_kbps( const lame_global_flags*  gfp )
+{
+    return gfp->VBR_mean_bitrate_kbps;
+}
+
+int
+lame_set_VBR_min_bitrate_kbps( lame_global_flags*  gfp,
+                               int                 VBR_min_bitrate_kbps )
+{
+    gfp->VBR_min_bitrate_kbps = VBR_min_bitrate_kbps;
+
+    return 0;
+}
+
+int
+lame_get_VBR_min_bitrate_kbps( const lame_global_flags*  gfp )
+{
+    return gfp->VBR_min_bitrate_kbps;
+}
+
+int
+lame_set_VBR_max_bitrate_kbps( lame_global_flags*  gfp,
+                               int                 VBR_max_bitrate_kbps )
+{
+    gfp->VBR_max_bitrate_kbps = VBR_max_bitrate_kbps;
+
+    return 0;
+}
+
+int
+lame_get_VBR_max_bitrate_kbps( const lame_global_flags*  gfp )
+{
+    return gfp->VBR_max_bitrate_kbps;
+}
+
+
+/*
+ * Strictly enforce VBR_min_bitrate.
+ * Normally it will be violated for analog silence.
+ */
+int
+lame_set_VBR_hard_min( lame_global_flags*  gfp,
+                       int                 VBR_hard_min )
+{
+    /* default = 0 (disabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > VBR_hard_min || 1 < VBR_hard_min )
+        return -1;
+
+    gfp->VBR_hard_min = VBR_hard_min;
+
+    return 0;
+}
+
+int
+lame_get_VBR_hard_min( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->VBR_hard_min && 1 >= gfp->VBR_hard_min );
+
+    return gfp->VBR_hard_min;
+}
+
+
+/********************************************************************
+ * Filtering control
+ ***********************************************************************/
+
+/*
+ * Freqency in Hz to apply lowpass.
+ *   0 = default = lame chooses
+ *  -1 = disabled
+ */
+int
+lame_set_lowpassfreq( lame_global_flags*  gfp,
+                      int                 lowpassfreq )
+{
+    gfp->lowpassfreq = lowpassfreq;
+
+    return 0;
+}
+
+int
+lame_get_lowpassfreq( const lame_global_flags*  gfp )
+{
+    return gfp->lowpassfreq;
+}
+
+
+/*
+ * Width of transition band (in Hz).
+ *  default = one polyphase filter band
+ */
+int
+lame_set_lowpasswidth( lame_global_flags*  gfp,
+                       int                 lowpasswidth )
+{
+    gfp->lowpasswidth = lowpasswidth;
+
+    return 0;
+}
+
+int
+lame_get_lowpasswidth( const lame_global_flags*  gfp )
+{
+    return gfp->lowpasswidth;
+}
+
+
+/*
+ * Frequency in Hz to apply highpass.
+ *   0 = default = lame chooses
+ *  -1 = disabled
+ */
+int
+lame_set_highpassfreq( lame_global_flags*  gfp,
+                       int                 highpassfreq )
+{
+    gfp->highpassfreq = highpassfreq;
+
+    return 0;
+}
+
+int
+lame_get_highpassfreq( const lame_global_flags*  gfp )
+{
+    return gfp->highpassfreq;
+}
+
+
+/*
+ * Width of transition band (in Hz).
+ *  default = one polyphase filter band
+ */
+int
+lame_set_highpasswidth( lame_global_flags*  gfp,
+                        int                 highpasswidth )
+{
+    gfp->highpasswidth = highpasswidth;
+
+    return 0;
+}
+
+int
+lame_get_highpasswidth( const lame_global_flags*  gfp )
+{
+    return gfp->highpasswidth;
+}
+
+
+
+
+/*
+ * psycho acoustics and other arguments which you should not change 
+ * unless you know what you are doing
+ */
+
+/* Only use ATH for masking. */
+int
+lame_set_ATHonly( lame_global_flags*  gfp,
+                  int                 ATHonly )
+{
+    gfp->ATHonly = ATHonly;
+
+    return 0;
+}
+
+int
+lame_get_ATHonly( const lame_global_flags*  gfp )
+{
+    return gfp->ATHonly;
+}
+
+
+/* Only use ATH for short blocks. */
+int
+lame_set_ATHshort( lame_global_flags*  gfp,
+                   int                 ATHshort )
+{
+    gfp->ATHshort = ATHshort;
+
+    return 0;
+}
+
+int
+lame_get_ATHshort( const lame_global_flags*  gfp )
+{
+    return gfp->ATHshort;
+}
+
+
+/* Disable ATH. */
+int
+lame_set_noATH( lame_global_flags*  gfp,
+                int                 noATH )
+{
+    gfp->noATH = noATH;
+
+    return 0;
+}
+
+int
+lame_get_noATH( const lame_global_flags*  gfp )
+{
+    return gfp->noATH;
+}
+
+
+/* Select ATH formula. */
+int
+lame_set_ATHtype( lame_global_flags*  gfp,
+                  int                 ATHtype )
+{
+    /* XXX: ATHtype should be converted to an enum. */
+    gfp->ATHtype = ATHtype;
+
+    return 0;
+}
+
+int
+lame_get_ATHtype( const lame_global_flags*  gfp )
+{
+    return gfp->ATHtype;
+}
+
+
+/* Lower ATH by this many db. */
+int
+lame_set_ATHlower( lame_global_flags*  gfp,
+                   float               ATHlower )
+{
+    gfp->ATHlower = ATHlower;
+    return 0;
+}
+
+float
+lame_get_ATHlower( const lame_global_flags*  gfp )
+{
+    return gfp->ATHlower;
+}
+
+
+/* Select ATH adaptive adjustment scheme. */
+int
+lame_set_athaa_type( lame_global_flags*  gfp,
+                      int                athaa_type )
+{
+    gfp->athaa_type = athaa_type;
+
+    return 0;
+}
+
+int
+lame_get_athaa_type( const lame_global_flags*  gfp )
+{
+    return gfp->athaa_type;
+}
+
+
+/* Select the loudness approximation used by the ATH adaptive auto-leveling. */
+int
+lame_set_athaa_loudapprox( lame_global_flags*  gfp,
+                           int                 athaa_loudapprox )
+{
+    gfp->athaa_loudapprox = athaa_loudapprox;
+
+    return 0;
+}
+
+int
+lame_get_athaa_loudapprox( const lame_global_flags*  gfp )
+{
+    return gfp->athaa_loudapprox;
+}
+
+
+/* Adjust (in dB) the point below which adaptive ATH level adjustment occurs. */
+int
+lame_set_athaa_sensitivity( lame_global_flags*  gfp,
+                            float               athaa_sensitivity )
+{
+    gfp->athaa_sensitivity = athaa_sensitivity;
+
+    return 0;
+}
+
+float
+lame_get_athaa_sensitivity( const lame_global_flags*  gfp )
+{
+    return gfp->athaa_sensitivity;
+}
+
+
+/* Predictability limit (ISO tonality formula) */
+int
+lame_set_cwlimit( lame_global_flags*  gfp,
+                  int                 cwlimit )
+{
+    gfp->cwlimit = cwlimit;
+
+    return 0;
+}
+
+int
+lame_get_cwlimit( const lame_global_flags*  gfp )
+{
+    return gfp->cwlimit;
+}
+
+
+
+/*
+ * Allow blocktypes to differ between channels.
+ * default:
+ *  0 for jstereo => block types coupled
+ *  1 for stereo  => block types may differ
+ */
+int
+lame_set_allow_diff_short( lame_global_flags*  gfp,
+                           int                 allow_diff_short )
+{
+    gfp->short_blocks = 
+        allow_diff_short ? short_block_allowed : short_block_coupled;
+
+    return 0;
+}
+
+int
+lame_get_allow_diff_short( const lame_global_flags*  gfp )
+{
+    if ( gfp->short_blocks == short_block_allowed ) 
+        return 1; /* short blocks allowed to differ */
+    else 
+        return 0; /* not set, dispensed, forced or coupled */
+}
+
+
+/* Use temporal masking effect */
+int
+lame_set_useTemporal( lame_global_flags*  gfp,
+                      int                 useTemporal )
+{
+    /* default = 1 (enabled) */
+
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > useTemporal || 1 < useTemporal )
+        return -1;
+
+    gfp->useTemporal = useTemporal;
+
+    return 0;
+}
+
+int
+lame_get_useTemporal( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->useTemporal && 1 >= gfp->useTemporal );
+
+    return gfp->useTemporal;
+}
+
+
+/* Disable short blocks. */
+int
+lame_set_no_short_blocks( lame_global_flags*  gfp,
+                          int                 no_short_blocks )
+{
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > no_short_blocks || 1 < no_short_blocks )
+        return -1;
+
+    gfp->short_blocks = 
+        no_short_blocks ? short_block_dispensed : short_block_allowed;
+
+    return 0;
+}
+int
+lame_get_no_short_blocks( const lame_global_flags*  gfp )
+{
+    switch ( gfp->short_blocks ) {
+    default:
+    case short_block_not_set:   return -1;
+    case short_block_dispensed: return 1;
+    case short_block_allowed:
+    case short_block_coupled:
+    case short_block_forced:    return 0;
+    }
+}
+
+
+/* Force short blocks. */
+int
+lame_set_force_short_blocks( lame_global_flags*  gfp,
+                          int                 short_blocks )
+{
+    /* enforce disable/enable meaning, if we need more than two values
+       we need to switch to an enum to have an apropriate representation
+       of the possible meanings of the value */
+    if ( 0 > short_blocks || 1 < short_blocks )
+        return -1;
+
+    if (short_blocks == 1)
+        gfp->short_blocks = short_block_forced;
+    else if (gfp->short_blocks == short_block_forced) 
+        gfp->short_blocks = short_block_allowed;
+
+    return 0;
+}
+int
+lame_get_force_short_blocks( const lame_global_flags*  gfp )
+{
+    switch ( gfp->short_blocks ) {
+    default:
+    case short_block_not_set:   return -1;
+    case short_block_dispensed: 
+    case short_block_allowed:
+    case short_block_coupled:   return 0;
+    case short_block_forced:    return 1;
+    }
+}
+
+
+/*
+ * Input PCM is emphased PCM
+ * (for instance from one of the rarely emphased CDs).
+ *
+ * It is STRONGLY not recommended to use this, because psycho does not
+ * take it into account, and last but not least many decoders
+ * ignore these bits
+ */
+int
+lame_set_emphasis( lame_global_flags*  gfp,
+                   int                 emphasis )
+{
+    /* XXX: emphasis should be converted to an enum */
+    if ( 0 > emphasis || 4 <= emphasis )
+        return -1;
+
+    gfp->emphasis = emphasis;
+
+    return 0;
+}
+
+int
+lame_get_emphasis( const lame_global_flags*  gfp )
+{
+    assert( 0 <= gfp->emphasis && 4 > gfp->emphasis );
+
+    return gfp->emphasis;
+}
+
+
+
+
+/***************************************************************/
+/* internal variables, cannot be set...                        */
+/* provided because they may be of use to calling application  */
+/***************************************************************/
+
+/* MPEG version.
+ *  0 = MPEG-2
+ *  1 = MPEG-1
+ * (2 = MPEG-2.5)    
+ */
+int
+lame_get_version( const lame_global_flags* gfp )
+{
+    return gfp->version;
+}
+
+
+/* Encoder delay. */
+int
+lame_get_encoder_delay( const lame_global_flags*  gfp )
+{
+    return gfp->encoder_delay;
+}
+
+/* padding added to the end of the input */
+int
+lame_get_encoder_padding( const lame_global_flags*  gfp )
+{
+    return gfp->encoder_padding;
+}
+
+
+/* Size of MPEG frame. */
+int
+lame_get_framesize( const lame_global_flags*  gfp )
+{
+    return gfp->framesize;
+}
+
+
+/* Number of frames encoded so far. */
+int
+lame_get_frameNum( const lame_global_flags*  gfp )
+{
+    return gfp->frameNum;
+}
+
+int
+lame_get_mf_samples_to_encode( const lame_global_flags*  gfp )
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    return gfc->mf_samples_to_encode;
+}
+
+
+int CDECL lame_get_size_mp3buffer( const lame_global_flags*  gfp )
+{
+    int size;
+    compute_flushbits(gfp,&size);
+    return size;
+}
+
+
+
+/*
+ * LAME's estimate of the total number of frames to be encoded.
+ * Only valid if calling program set num_samples.
+ */
+int
+lame_get_totalframes( const lame_global_flags*  gfp )
+{
+    int totalframes;
+    /* estimate based on user set num_samples: */
+    totalframes =
+        2 + ((double)gfp->num_samples * gfp->out_samplerate) / 
+              ((double)gfp->in_samplerate * gfp->framesize);
+
+    /* check to see if we underestimated totalframes */
+    //    if (totalframes < gfp->frameNum)
+    //        totalframes = gfp->frameNum;
+
+    return totalframes;
+}
+
+
+/*
+
+UNDOCUMENTED, experimental settings.  These routines are not prototyped
+in lame.h.  You should not use them, they are experimental and may
+change.  
+
+*/
+
+
+/*
+ *  just another daily changing developer switch  
+ */
+void lame_set_tune( lame_global_flags* gfp, float val ) 
+{
+    gfp->tune_value_a = val;
+    gfp->tune = 1;
+}
+
+/* Custom msfix hack */
+void
+lame_set_msfix( lame_global_flags*  gfp, double msfix )
+{
+    /* default = 0 */
+    gfp->msfix = msfix;
+
+}
+
+int
+lame_set_preset_expopts( lame_global_flags*  gfp, int preset_expopts )
+{
+
+    lame_internal_flags *gfc = gfp->internal_flags;
+
+    gfc->presetTune.use = 1;
+
+    /* default = 0 (disabled) */
+    gfp->preset_expopts = preset_expopts;
+
+    switch (preset_expopts)
+    {
+        case 1:
+
+          lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 1);
+          lame_set_experimentalX(gfp, 3);
+          lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); // safejoint
+          lame_set_ATHtype(gfp, 2);
+
+          gfc->presetTune.attackthre   = 35;
+          gfc->presetTune.attackthre_s = 150;
+          gfc->presetTune.ms_maskadjust = .5;
+                 gfc->presetTune.quantcomp_type_s = 3;
+          gfc->presetTune.quantcomp_alt_type = 3;
+          gfc->presetTune.athadjust_switch_level = 2; // Always switch
+
+          break;
+
+        case 2:
+
+          if (gfp->VBR == vbr_mtrh) {
+             lame_set_experimentalX(gfp, 2);
+             gfc->presetTune.quantcomp_adjust_mtrh = 9;
+             gfc->presetTune.quantcomp_type_s = 4;
+             gfc->presetTune.quantcomp_alt_type = 0;
+             gfc->presetTune.athadjust_safe_noiseshaping_thre = 0.0;
+                        gfc->presetTune.athadjust_safe_athaasensitivity = 8.0;
+          }
+          else {
+             lame_set_experimentalX(gfp, 3);
+             gfc->presetTune.quantcomp_adjust_rh_tot = 600;
+                        gfc->presetTune.quantcomp_adjust_rh_max = 60;
+             gfc->presetTune.quantcomp_type_s = 3;
+             gfc->presetTune.quantcomp_alt_type = 1;
+          }
+
+          lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 1);
+          lame_set_experimentalZ(gfp, 1);
+          lame_set_VBR_q(gfp, 2);
+          lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); // safejoint
+          lame_set_ATHtype(gfp, 2);                            
+          // modify sfb21 by 3 dB plus ns-treble=0                 
+          lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (12 << 20));
+
+          gfc->presetTune.attackthre   = 35;
+          gfc->presetTune.attackthre_s = 150;
+          gfc->presetTune.ms_maskadjust = .5;
+          gfc->presetTune.athadjust_switch_level = 1;
+          gfc->presetTune.athadjust_msfix = 2.13;
+
+          break;
+
+        case 3:
+
+          if (gfp->VBR == vbr_mtrh) {
+             gfc->presetTune.quantcomp_type_s = 4;
+             gfc->presetTune.quantcomp_adjust_mtrh = 9;
+                        gfc->presetTune.quantcomp_alt_type = 0;
+             (void) lame_set_ATHlower( gfp, -2 );
+             gfc->presetTune.athadjust_safe_noiseshaping_thre = 0.0;
+                        gfc->presetTune.athadjust_safe_athaasensitivity = 8.0;
+          }
+          else {
+             gfc->presetTune.quantcomp_type_s = 3;
+             gfc->presetTune.quantcomp_adjust_rh_tot = 600;
+                        gfc->presetTune.quantcomp_adjust_rh_max = 60;
+             (void) lame_set_ATHlower( gfp, -1 );
+          }
+
+          lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 1);
+          lame_set_experimentalZ(gfp, 1);
+          lame_set_experimentalX(gfp, 1);
+          lame_set_VBR_q(gfp, 2);
+          lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); // safejoint
+   (void) lame_set_msfix( gfp, 2.13 );
+          lame_set_ATHtype(gfp, 4);
+          // modify sfb21 by 3.75 dB plus ns-treble=0                 
+          lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (15 << 20));
+
+          gfc->presetTune.attackthre   = 35;
+          gfc->presetTune.attackthre_s = 150;
+          gfc->presetTune.ms_maskadjust = .5;
+          gfc->presetTune.athadjust_switch_level = 1;
+
+          break;
+    }
+    return 0;
+}
+
+int
+lame_set_preset_notune( lame_global_flags*  gfp, int preset_notune )
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+
+    gfc->presetTune.use = 0;  // Turn off specialized preset tunings
+
+    return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/lame/tables.c b/lib/lame/tables.c
new file mode 100644 (file)
index 0000000..bb27a68
--- /dev/null
@@ -0,0 +1,507 @@
+/*
+ *     MPEG layer 3 tables source file
+ *
+ *     Copyright (c) 1999 Albert L Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: tables.c,v 1.1 2002/04/28 17:30:29 kramm Exp $ */
+
+#include "config_static.h"
+
+#include "util.h"
+#include "tables.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+static const short      t1HB[]   = {
+  1, 1, 
+  1, 0};
+
+static const short      t2HB[]   = {
+  1, 2, 1,
+  3, 1, 1,
+  3, 2, 0};
+
+static const short      t3HB[]   = {
+  3, 2, 1,
+  1, 1, 1,
+  3, 2, 0};
+
+static const short      t5HB[]   = {
+  1, 2, 6, 5,
+  3, 1, 4, 4,
+  7, 5, 7, 1,
+  6, 1, 1, 0};
+
+static const short      t6HB[]   = {
+  7, 3, 5, 1,
+  6, 2, 3, 2,
+  5, 4, 4, 1,
+  3, 3, 2, 0};
+
+static const short      t7HB[]   = {
+   1, 2,10,19,16,10,
+   3, 3, 7,10, 5, 3,
+  11, 4,13,17, 8, 4,
+  12,11,18,15,11, 2,
+   7, 6, 9,14, 3, 1,
+   6, 4, 5, 3, 2, 0};
+
+static const short      t8HB[]   = {
+  3, 4, 6, 18,12, 5,
+  5, 1, 2, 16, 9, 3,
+  7, 3, 5, 14, 7, 3,
+ 19,17,15, 13,10, 4,
+ 13, 5, 8, 11, 5, 1,
+ 12, 4, 4,  1, 1, 0};
+
+static const short      t9HB[]   = {
+  7, 5, 9, 14, 15, 7,
+  6, 4, 5,  5,  6, 7,
+  7, 6, 8,  8,  8, 5,
+ 15, 6, 9, 10,  5, 1,
+ 11, 7, 9,  6,  4, 1,
+ 14, 4, 6,  2,  6, 0};
+
+static const short      t10HB[]   = {
+  1, 2, 10, 23, 35, 30, 12, 17,
+  3, 3,  8, 12, 18, 21, 12,  7,
+ 11, 9, 15, 21, 32, 40, 19,  6,
+ 14,13, 22, 34, 46, 23, 18,  7,
+ 20,19, 33, 47, 27, 22,  9,  3,
+ 31,22, 41, 26, 21, 20,  5,  3,
+ 14,13, 10, 11, 16,  6,  5,  1,
+  9, 8,  7,  8,  4,  4,  2,  0};
+
+static const short      t11HB[]   = {
+  3, 4, 10, 24, 34, 33, 21, 15,
+  5, 3,  4, 10, 32, 17, 11, 10,
+ 11, 7, 13, 18, 30, 31, 20,  5,
+ 25,11, 19, 59, 27, 18, 12,  5,
+ 35,33, 31, 58, 30, 16,  7,  5,
+ 28,26, 32, 19, 17, 15,  8, 14,
+ 14,12,  9, 13, 14,  9,  4,  1,
+ 11, 4,  6,  6,  6,  3,  2,  0};
+
+static const short      t12HB[]   = {
+  9,  6, 16, 33, 41, 39, 38,26,
+  7,  5,  6,  9, 23, 16, 26,11,
+ 17,  7, 11, 14, 21, 30, 10, 7,
+ 17, 10, 15, 12, 18, 28, 14, 5,
+ 32, 13, 22, 19, 18, 16,  9, 5,
+ 40, 17, 31, 29, 17, 13,  4, 2,
+ 27, 12, 11, 15, 10,  7,  4, 1,
+ 27, 12,  8, 12,  6,  3,  1, 0};
+
+static const short      t13HB[]   = {
+  1,  5, 14, 21, 34, 51, 46, 71, 42, 52, 68, 52, 67, 44, 43, 19,
+  3,  4, 12, 19, 31, 26, 44, 33, 31, 24, 32, 24, 31, 35, 22, 14,
+ 15, 13, 23, 36, 59, 49, 77, 65, 29, 40, 30, 40, 27, 33, 42, 16,
+ 22, 20, 37, 61, 56, 79, 73, 64, 43, 76, 56, 37, 26, 31, 25, 14,
+ 35, 16, 60, 57, 97, 75,114, 91, 54, 73, 55, 41, 48, 53, 23, 24,
+ 58, 27, 50, 96, 76, 70, 93, 84, 77, 58, 79, 29, 74, 49, 41, 17,
+ 47, 45, 78, 74,115, 94, 90, 79, 69, 83, 71, 50, 59, 38, 36, 15,
+ 72, 34, 56, 95, 92, 85, 91, 90, 86, 73, 77, 65, 51, 44, 43, 42,
+ 43, 20, 30, 44, 55, 78, 72, 87, 78, 61, 46, 54, 37, 30, 20, 16,
+ 53, 25, 41, 37, 44, 59, 54, 81, 66, 76, 57, 54, 37, 18, 39, 11,
+ 35, 33, 31, 57, 42, 82, 72, 80, 47, 58, 55, 21, 22, 26, 38, 22,
+ 53, 25, 23, 38, 70, 60, 51, 36, 55, 26, 34, 23, 27, 14,  9,  7,
+ 34, 32, 28, 39, 49, 75, 30, 52, 48, 40, 52, 28, 18, 17,  9,  5,
+ 45, 21, 34, 64, 56, 50, 49, 45, 31, 19, 12, 15, 10,  7,  6,  3,
+ 48, 23, 20, 39, 36, 35, 53, 21, 16, 23, 13, 10,  6,  1,  4,  2,
+ 16, 15, 17, 27, 25, 20, 29, 11, 17, 12, 16,  8,  1,  1,  0,  1};
+
+static const short      t15HB[]   = {
+   7, 12, 18, 53, 47, 76,124,108, 89,123,108,119,107, 81,122, 63,
+  13,  5, 16, 27, 46, 36, 61, 51, 42, 70, 52, 83, 65, 41, 59, 36,
+  19, 17, 15, 24, 41, 34, 59, 48, 40, 64, 50, 78, 62, 80, 56, 33,
+  29, 28, 25, 43, 39, 63, 55, 93, 76, 59, 93, 72, 54, 75, 50, 29,
+  52, 22, 42, 40, 67, 57, 95, 79, 72, 57, 89, 69, 49, 66, 46, 27,
+  77, 37, 35, 66, 58, 52, 91, 74, 62, 48, 79, 63, 90, 62, 40, 38,
+ 125, 32, 60, 56, 50, 92, 78, 65, 55, 87, 71, 51, 73, 51, 70, 30,
+ 109, 53, 49, 94, 88, 75, 66,122, 91, 73, 56, 42, 64, 44, 21, 25,
+  90, 43, 41, 77, 73, 63, 56, 92, 77, 66, 47, 67, 48, 53, 36, 20,
+  71, 34, 67, 60, 58, 49, 88, 76, 67,106, 71, 54, 38, 39, 23, 15,
+ 109, 53, 51, 47, 90, 82, 58, 57, 48, 72, 57, 41, 23, 27, 62,  9,
+  86, 42, 40, 37, 70, 64, 52, 43, 70, 55, 42, 25, 29, 18, 11, 11, 
+ 118, 68, 30, 55, 50, 46, 74, 65, 49, 39, 24, 16, 22, 13, 14,  7,
+  91, 44, 39, 38, 34, 63, 52, 45, 31, 52, 28, 19, 14,  8,  9,  3,
+ 123, 60, 58, 53, 47, 43, 32, 22, 37, 24, 17, 12, 15, 10,  2,  1,
+  71, 37, 34, 30, 28, 20, 17, 26, 21, 16, 10,  6,  8,  6,  2,  0};
+
+static const short      t16HB[]   = {
+   1,   5, 14, 44, 74, 63, 110, 93, 172, 149, 138, 242, 225, 195, 376, 17,
+   3,   4, 12, 20, 35, 62,  53, 47,  83,  75,  68, 119, 201, 107, 207,  9,
+  15,  13, 23, 38, 67, 58, 103, 90, 161,  72, 127, 117, 110, 209, 206, 16,
+  45,  21, 39, 69, 64,114,  99, 87, 158, 140, 252, 212, 199, 387, 365, 26,
+  75,  36, 68, 65,115,101, 179,164, 155, 264, 246, 226, 395, 382, 362,  9,
+  66,  30, 59, 56,102,185, 173,265, 142, 253, 232, 400, 388, 378, 445, 16,
+ 111,  54, 52,100,184,178, 160,133, 257, 244, 228, 217, 385, 366, 715, 10,
+  98,  48, 91, 88,165,157, 148,261, 248, 407, 397, 372, 380, 889, 884,  8,
+  85,  84, 81,159,156,143, 260,249, 427, 401, 392, 383, 727, 713, 708,  7,
+ 154,  76, 73,141,131,256, 245,426, 406, 394, 384, 735, 359, 710, 352, 11,
+ 139, 129, 67,125,247,233, 229,219, 393, 743, 737, 720, 885, 882, 439,  4,
+ 243, 120,118,115,227,223, 396,746, 742, 736, 721, 712, 706, 223, 436,  6,
+ 202, 224,222,218,216,389, 386,381, 364, 888, 443, 707, 440, 437,1728,  4,
+ 747, 211,210,208,370,379, 734,723, 714,1735, 883, 877, 876,3459, 865,  2,
+ 377, 369,102,187,726,722, 358,711, 709, 866,1734, 871,3458, 870, 434,  0,
+  12,  10,  7, 11, 10, 17,  11,  9,  13,  12,  10,   7,   5,   3,   1,  3};
+
+static const short      t24HB[]   = {
+   15, 13, 46, 80, 146, 262, 248, 434, 426, 669, 653, 649, 621, 517, 1032, 88,
+   14, 12, 21, 38,  71, 130, 122, 216, 209, 198, 327, 345, 319, 297,  279, 42,
+   47, 22, 41, 74,  68, 128, 120, 221, 207, 194, 182, 340, 315, 295,  541, 18,
+   81, 39, 75, 70, 134, 125, 116, 220, 204, 190, 178, 325, 311, 293,  271, 16,
+  147, 72, 69,135, 127, 118, 112, 210, 200, 188, 352, 323, 306, 285,  540, 14,
+  263, 66,129,126, 119, 114, 214, 202, 192, 180, 341, 317, 301, 281,  262, 12,
+  249,123,121,117, 113, 215, 206, 195, 185, 347, 330, 308, 291, 272,  520, 10,
+  435,115,111,109, 211, 203, 196, 187, 353, 332, 313, 298, 283, 531,  381, 17,
+  427,212,208,205, 201, 193, 186, 177, 169, 320, 303, 286, 268, 514,  377, 16,
+  335,199,197,191, 189, 181, 174, 333, 321, 305, 289, 275, 521, 379,  371, 11,
+  668,184,183,179, 175, 344, 331, 314, 304, 290, 277, 530, 383, 373,  366, 10,
+  652,346,171,168, 164, 318, 309, 299, 287, 276, 263, 513, 375, 368,  362,  6,
+  648,322,316,312, 307, 302, 292, 284, 269, 261, 512, 376, 370, 364,  359,  4,
+  620,300,296,294, 288, 282, 273, 266, 515, 380, 374, 369, 365, 361,  357,  2,
+ 1033,280,278,274, 267, 264, 259, 382, 378, 372, 367, 363, 360, 358,  356,  0,
+   43, 20, 19, 17,  15,  13,  11,   9,   7,   6,   4,   7,   5,   3,    1,  3};
+
+static const short      t32HB[]   = {
+  1 << 0,  5 << 1,  4 << 1,  5 << 2,  6 << 1,  5 << 2,  4 << 2,  4 << 3,
+  7 << 1,  3 << 2,  6 << 2,  0 << 3,  7 << 2,  2 << 3,  3 << 3,  1 << 4};
+
+static const short      t33HB[]   = {
+ 15 << 0, 14 << 1, 13 << 1, 12 << 2, 11 << 1, 10 << 2,  9 << 2,  8 << 3,
+  7 << 1,  6 << 2,  5 << 2,  4 << 3,  3 << 2,  2 << 3,  1 << 3,  0 << 4};
+
+
+const  char t1l[] = {
+ 1,  4, 
+ 3,  5};
+
+const  char t2l[] = {
+ 1,  4,  7, 
+ 4,  5,  7, 
+ 6,  7,  8};
+
+const  char t3l[] = {
+ 2,  3,  7, 
+ 4,  4,  7, 
+ 6,  7,  8};
+
+const  char t5l[] = {
+ 1,  4,  7,  8, 
+ 4,  5,  8,  9, 
+ 7,  8,  9, 10, 
+ 8,  8,  9, 10};
+
+const  char t6l[] = {
+ 3,  4,  6,  8, 
+ 4,  4,  6,  7, 
+ 5,  6,  7,  8, 
+ 7,  7,  8,  9};
+
+const  char t7l[] = {
+ 1,  4,  7,  9,  9, 10, 
+ 4,  6,  8,  9,  9, 10, 
+ 7,  7,  9, 10, 10, 11, 
+ 8,  9, 10, 11, 11, 11, 
+ 8,  9, 10, 11, 11, 12, 
+ 9, 10, 11, 12, 12, 12};
+
+const  char t8l[] = {
+ 2,  4,  7,  9,  9, 10, 
+ 4,  4,  6, 10, 10, 10, 
+ 7,  6,  8, 10, 10, 11, 
+ 9, 10, 10, 11, 11, 12, 
+ 9,  9, 10, 11, 12, 12, 
+10, 10, 11, 11, 13, 13};
+
+const  char t9l[] = {
+ 3,  4,  6,  7,  9, 10, 
+ 4,  5,  6,  7,  8, 10, 
+ 5,  6,  7,  8,  9, 10, 
+ 7,  7,  8,  9,  9, 10, 
+ 8,  8,  9,  9, 10, 11, 
+ 9,  9, 10, 10, 11, 11};
+
+const  char t10l[] = {
+ 1,  4,  7,  9, 10, 10, 10, 11, 
+ 4,  6,  8,  9, 10, 11, 10, 10, 
+ 7,  8,  9, 10, 11, 12, 11, 11, 
+ 8,  9, 10, 11, 12, 12, 11, 12, 
+ 9, 10, 11, 12, 12, 12, 12, 12, 
+10, 11, 12, 12, 13, 13, 12, 13, 
+ 9, 10, 11, 12, 12, 12, 13, 13, 
+10, 10, 11, 12, 12, 13, 13, 13};
+
+const  char t11l[] = {
+ 2,  4,  6,  8,  9, 10,  9, 10, 
+ 4,  5,  6,  8, 10, 10,  9, 10, 
+ 6,  7,  8,  9, 10, 11, 10, 10, 
+ 8,  8,  9, 11, 10, 12, 10, 11, 
+ 9, 10, 10, 11, 11, 12, 11, 12, 
+ 9, 10, 11, 12, 12, 13, 12, 13, 
+ 9,  9,  9, 10, 11, 12, 12, 12, 
+ 9,  9, 10, 11, 12, 12, 12, 12};
+
+const  char t12l[] = {
+ 4,  4,  6,  8,  9, 10, 10, 10, 
+ 4,  5,  6,  7,  9,  9, 10, 10, 
+ 6,  6,  7,  8,  9, 10,  9, 10, 
+ 7,  7,  8,  8,  9, 10, 10, 10, 
+ 8,  8,  9,  9, 10, 10, 10, 11, 
+ 9,  9, 10, 10, 10, 11, 10, 11, 
+ 9,  9,  9, 10, 10, 11, 11, 12, 
+10, 10, 10, 11, 11, 11, 11, 12};
+
+const  char t13l[] = {
+ 1,  5,  7,  8,  9, 10, 10, 11, 10, 11, 12, 12, 13, 13, 14, 14, 
+ 4,  6,  8,  9, 10, 10, 11, 11, 11, 11, 12, 12, 13, 14, 14, 14, 
+ 7,  8,  9, 10, 11, 11, 12, 12, 11, 12, 12, 13, 13, 14, 15, 15, 
+ 8,  9, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 15, 
+ 9,  9, 11, 11, 12, 12, 13, 13, 12, 13, 13, 14, 14, 15, 15, 16, 
+10, 10, 11, 12, 12, 12, 13, 13, 13, 13, 14, 13, 15, 15, 16, 16, 
+10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 
+11, 11, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 18, 18, 
+10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 16, 17, 17, 
+11, 11, 12, 12, 13, 13, 13, 15, 14, 15, 15, 16, 16, 16, 18, 17, 
+11, 12, 12, 13, 13, 14, 14, 15, 14, 15, 16, 15, 16, 17, 18, 19, 
+12, 12, 12, 13, 14, 14, 14, 14, 15, 15, 15, 16, 17, 17, 17, 18, 
+12, 13, 13, 14, 14, 15, 14, 15, 16, 16, 17, 17, 17, 18, 18, 18, 
+13, 13, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 18, 17, 18, 18, 
+14, 14, 14, 15, 15, 15, 17, 16, 16, 19, 17, 17, 17, 19, 18, 18, 
+13, 14, 15, 16, 16, 16, 17, 16, 17, 17, 18, 18, 21, 20, 21, 18};
+
+const  char t15l[] = {
+ 3,  5,  6,  8,  8,  9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 14, 
+ 5,  5,  7,  8,  9,  9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 
+ 6,  7,  7,  8,  9,  9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13, 
+ 7,  8,  8,  9,  9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 
+ 8,  8,  9,  9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 
+ 9,  9,  9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 14, 
+10,  9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 
+10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 14, 
+10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14, 
+10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 
+11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 14, 
+11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 
+12, 12, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 15, 15, 
+12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 14, 15, 
+13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15};
+
+const  char t16_5l[] = {
+ 1,  5,  7,  9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 11, 
+ 4,  6,  8,  9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 11, 
+ 7,  8,  9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 12, 
+ 9,  9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 13, 
+10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 12, 
+10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 13, 
+11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 13, 
+11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 13, 
+11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 13, 
+12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 14, 
+12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 13, 
+13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 14, 
+13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 14, 
+15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 14, 
+14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 14, 
+11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 12};
+
+const  char t16l[] = {
+ 1,  5,  7,  9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 10, 
+ 4,  6,  8,  9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 10, 
+ 7,  8,  9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 11, 
+ 9,  9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 12, 
+10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 11, 
+10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 12, 
+11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 12, 
+11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 12, 
+11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 12, 
+12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 13, 
+12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 12, 
+13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 13, 
+13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 13, 
+15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 13, 
+14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 13, 
+10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10};
+
+const  char t24l[] = {
+ 4,  5,  7,  8,  9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 13, 10, 
+ 5,  6,  7,  8,  9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 10, 
+ 7,  7,  8,  9,  9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13,  9, 
+ 8,  8,  9,  9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12,  9, 
+ 9,  9,  9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13,  9, 
+10,  9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12,  9, 
+10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13,  9, 
+11, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 10, 
+11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 10, 
+11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 10, 
+12, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10, 
+12, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10, 
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 10, 
+12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10, 
+13, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 10, 
+ 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10,  6};
+
+const  char t32l[]  = {
+  1+0,  4+1,  4+1,  5+2,  4+1,  6+2,  5+2,  6+3,
+  4+1,  5+2,  5+2,  6+3,  5+2,  6+3,  6+3,  6+4};
+
+const  char t33l[]  = {
+  4+0,  4+1,  4+1,  4+2,  4+1,  4+2,  4+2,  4+3,
+  4+1,  4+2,  4+2,  4+3,  4+2,  4+3,  4+3,  4+4};
+
+
+const struct huffcodetab ht[HTN] =
+{
+  /* xlen, linmax, table, hlen */
+  { 0,   0,NULL,NULL},
+  { 2,   0,t1HB, t1l},
+  { 3,   0,t2HB, t2l},
+  { 3,   0,t3HB, t3l},
+  { 0,   0,NULL,NULL},/* Apparently not used */
+  { 4,   0,t5HB, t5l},
+  { 4,   0,t6HB, t6l},
+  { 6,   0,t7HB, t7l},
+  { 6,   0,t8HB, t8l},
+  { 6,   0,t9HB, t9l},
+  { 8,   0,t10HB, t10l},
+  { 8,   0,t11HB, t11l},
+  { 8,   0,t12HB, t12l},
+  {16,   0,t13HB, t13l},
+  { 0,   0,NULL,  t16_5l},/* Apparently not used */
+  {16,   0,t15HB, t15l},
+
+  { 1,   1,t16HB, t16l},
+  { 2,   3,t16HB, t16l},
+  { 3,   7,t16HB, t16l},
+  { 4,  15,t16HB, t16l},
+  { 6,  63,t16HB, t16l},
+  { 8, 255,t16HB, t16l},
+  {10,1023,t16HB, t16l},
+  {13,8191,t16HB, t16l},
+
+  { 4,  15,t24HB, t24l},
+  { 5,  31,t24HB, t24l},
+  { 6,  63,t24HB, t24l},
+  { 7, 127,t24HB, t24l},
+  { 8, 255,t24HB, t24l},
+  { 9, 511,t24HB, t24l},
+  {11,2047,t24HB, t24l},
+  {13,8191,t24HB, t24l},
+
+  { 0,   0,t32HB, t32l},
+  { 0,   0,t33HB, t33l},
+};
+
+
+
+
+
+/*  for (i = 0; i < 16*16; i++) {
+ *      largetbl[i] = ((ht[16].hlen[i]) << 16) + ht[24].hlen[i];
+ *  }
+ */
+const unsigned int largetbl[16*16] = {
+0x010004, 0x050005, 0x070007, 0x090008, 0x0a0009, 0x0a000a, 0x0b000a, 0x0b000b,
+0x0c000b, 0x0c000c, 0x0c000c, 0x0d000c, 0x0d000c, 0x0d000c, 0x0e000d, 0x0a000a,
+0x040005, 0x060006, 0x080007, 0x090008, 0x0a0009, 0x0b000a, 0x0b000a, 0x0b000b,
+0x0c000b, 0x0c000b, 0x0c000c, 0x0d000c, 0x0e000c, 0x0d000c, 0x0e000c, 0x0a000a,
+0x070007, 0x080007, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000b,
+0x0d000b, 0x0c000b, 0x0d000b, 0x0d000c, 0x0d000c, 0x0e000c, 0x0e000d, 0x0b0009,
+0x090008, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0c000b,
+0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0c0009,
+0x0a0009, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000a, 0x0d000b,
+0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000d, 0x0b0009,
+0x0a000a, 0x0a0009, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0e000b,
+0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0c0009,
+0x0b000a, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0d000b, 0x0d000b,
+0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000d, 0x0c0009,
+0x0b000b, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b,
+0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x11000d, 0x11000d, 0x0c000a,
+0x0b000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b,
+0x0f000b, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000d, 0x10000d, 0x0c000a,
+0x0c000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, 0x0f000c,
+0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0f000d, 0x10000d, 0x0f000d, 0x0d000a,
+0x0c000c, 0x0d000b, 0x0c000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c,
+0x0f000c, 0x10000c, 0x10000c, 0x10000d, 0x11000d, 0x11000d, 0x10000d, 0x0c000a,
+0x0d000c, 0x0d000c, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x10000c,
+0x10000c, 0x10000c, 0x10000c, 0x10000d, 0x10000d, 0x0f000d, 0x10000d, 0x0d000a,
+0x0d000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c,
+0x0f000c, 0x11000c, 0x10000d, 0x10000d, 0x10000d, 0x10000d, 0x12000d, 0x0d000a,
+0x0f000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000c,
+0x10000d, 0x12000d, 0x11000d, 0x11000d, 0x11000d, 0x13000d, 0x11000d, 0x0d000a,
+0x0e000d, 0x0f000c, 0x0d000c, 0x0e000c, 0x10000c, 0x10000c, 0x0f000c, 0x10000d,
+0x10000d, 0x11000d, 0x12000d, 0x11000d, 0x13000d, 0x11000d, 0x10000d, 0x0d000a,
+0x0a0009, 0x0a0009, 0x0a0009, 0x0b0009, 0x0b0009, 0x0c0009, 0x0c0009, 0x0c0009,
+0x0d0009, 0x0d0009, 0x0d0009, 0x0d000a, 0x0d000a, 0x0d000a, 0x0d000a, 0x0a0006
+};
+
+/*  for (i = 0; i < 3*3; i++) {
+ *      table23[i] = ((ht[2].hlen[i]) << 16) + ht[3].hlen[i];
+ *  }
+ */
+const unsigned int table23[3*3] = {
+0x010002, 0x040003, 0x070007,
+0x040004, 0x050004, 0x070007, 
+0x060006, 0x070007, 0x080008
+};
+
+/*   for (i = 0; i < 4*4; i++) {
+ *       table56[i] = ((ht[5].hlen[i]) << 16) + ht[6].hlen[i];
+ *   }
+ */
+const unsigned int table56[4*4] = {
+0x010003, 0x040004, 0x070006, 0x080008, 0x040004, 0x050004, 0x080006, 0x090007,
+0x070005, 0x080006, 0x090007, 0x0a0008, 0x080007, 0x080007, 0x090008, 0x0a0009
+};
+
+
+
+/* 
+ * 0: MPEG-2 LSF
+ * 1: MPEG-1
+ * 2: MPEG-2.5 LSF FhG extention                  (1995-07-11 shn)
+ */
+
+typedef enum {
+    MPEG_2  = 0,
+    MPEG_1  = 1,
+    MPEG_25 = 2
+} MPEG_t;
+const int  bitrate_table    [3] [16] = {
+    { 0,  8, 16, 24, 32, 40, 48, 56,  64,  80,  96, 112, 128, 144, 160, -1 },
+    { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1 },
+    { 0,  8, 16, 24, 32, 40, 48, 56,  64,  80,  96, 112, 128, 144, 160, -1 },
+};
+
+const int  samplerate_table [3]  [4] = { 
+    { 22050, 24000, 16000, -1 },      /* MPEG 2 */
+    { 44100, 48000, 32000, -1 },      /* MPEG 1 */  
+    { 11025, 12000,  8000, -1 },      /* MPEG 2.5 */
+};
+
+const char* version_string  [3] = { "2", "1", "2.5" };
+
+const unsigned  header_word [3] = { 0xFFF00000, 0xFFF80000, 0xFFE00000 };
+
+/* end of tables.h */
diff --git a/lib/lame/tables.h b/lib/lame/tables.h
new file mode 100644 (file)
index 0000000..486f2b1
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *     MPEG layer 3 tables include file
+ *
+ *     Copyright (c) 1999 Albert L Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_TABLES_H
+#define LAME_TABLES_H
+
+#include "machine.h"
+
+typedef struct {
+    unsigned char  no;
+    unsigned char  width;
+    unsigned char  minval_2;
+    float          quiet_thr;
+    float          norm;
+    float          bark;
+} type1_t;
+
+typedef struct {
+    unsigned char  no;
+    unsigned char  width;
+    float          quiet_thr;
+    float          norm;
+    float          SNR;
+    float          bark;
+} type2_t;
+
+typedef struct {
+    unsigned int  no     :  5;
+    unsigned int  cbw    :  3;
+    unsigned int  bu     :  6;
+    unsigned int  bo     :  6;
+    unsigned int  w1_576 : 10;
+    unsigned int  w2_576 : 10;
+} type34_t;
+
+typedef struct {
+    size_t                 len1;
+    const type1_t*  const  tab1;
+    size_t                 len2;
+    const type2_t*  const  tab2;
+    size_t                 len3;
+    const type34_t* const  tab3;
+    size_t                 len4;
+    const type34_t* const  tab4;
+} type5_t;
+
+extern const type5_t  table5 [6];
+
+
+
+#define HTN    34
+struct huffcodetab {
+    const int    xlen;                 /* max. x-index+                        */ 
+    const int    linmax;       /* max number to be stored in linbits   */
+    const short*   table;              /* pointer to array[xlen][ylen]         */
+    const char*  hlen;         /* pointer to array[xlen][ylen]         */
+};
+
+extern const struct huffcodetab ht [HTN];
+    /* global memory block                     */
+    /* array of all huffcodtable headers       */
+    /* 0..31 Huffman code table 0..31          */
+    /* 32,33 count1-tables                     */
+
+extern const char t32l [];
+extern const char t33l [];
+
+extern const unsigned int   largetbl    [16*16];
+extern const unsigned int   table23       [3*3];
+extern const unsigned int   table56       [4*4];
+#endif /* LAME_TABLES_H */
diff --git a/lib/lame/takehiro.c b/lib/lame/takehiro.c
new file mode 100644 (file)
index 0000000..13507ba
--- /dev/null
@@ -0,0 +1,1030 @@
+/*
+ *     MP3 huffman table selecting and bit counting
+ *
+ *     Copyright (c) 1999 Takehiro TOMINAGA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: takehiro.c,v 1.1 2002/04/28 17:30:29 kramm Exp $ */
+
+#include "config_static.h"
+
+#include <assert.h>
+#include "util.h"
+#include "l3side.h"
+#include "tables.h"
+#include "quantize_pvt.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+static const struct
+{
+    const int region0_count;
+    const int region1_count;
+} subdv_table[ 23 ] =
+{
+{0, 0}, /* 0 bands */
+{0, 0}, /* 1 bands */
+{0, 0}, /* 2 bands */
+{0, 0}, /* 3 bands */
+{0, 0}, /* 4 bands */
+{0, 1}, /* 5 bands */
+{1, 1}, /* 6 bands */
+{1, 1}, /* 7 bands */
+{1, 2}, /* 8 bands */
+{2, 2}, /* 9 bands */
+{2, 3}, /* 10 bands */
+{2, 3}, /* 11 bands */
+{3, 4}, /* 12 bands */
+{3, 4}, /* 13 bands */
+{3, 4}, /* 14 bands */
+{4, 5}, /* 15 bands */
+{4, 5}, /* 16 bands */
+{4, 6}, /* 17 bands */
+{5, 6}, /* 18 bands */
+{5, 6}, /* 19 bands */
+{5, 7}, /* 20 bands */
+{6, 7}, /* 21 bands */
+{6, 7}, /* 22 bands */
+};
+
+
+
+
+/*************************************************************************/
+/*           ix_max                                                     */
+/*************************************************************************/
+
+int 
+ix_max(const int *ix, const int *end)
+{
+    int max1 = 0, max2 = 0;
+
+    do {
+       int x1 = *ix++;
+       int x2 = *ix++;
+       if (max1 < x1) 
+           max1 = x1;
+
+       if (max2 < x2) 
+           max2 = x2;
+    } while (ix < end);
+    if (max1 < max2) 
+       max1 = max2;
+    return max1;
+}
+
+
+
+
+
+
+
+
+int
+count_bit_ESC( 
+    const int *       ix, 
+    const int * const end, 
+          int         t1,
+    const int         t2,
+          int * const s )
+{
+    /* ESC-table is used */
+    int linbits = ht[t1].xlen * 65536 + ht[t2].xlen;
+    int sum = 0, sum2;
+
+    do {
+       int x = *ix++;
+       int y = *ix++;
+
+       if (x != 0) {
+           if (x > 14) {
+               x = 15;
+               sum += linbits;
+           }
+           x *= 16;
+       }
+
+       if (y != 0) {
+           if (y > 14) {
+               y = 15;
+               sum += linbits;
+           }
+           x += y;
+       }
+
+       sum += largetbl[x];
+    } while (ix < end);
+
+    sum2 = sum & 0xffff;
+    sum >>= 16;
+
+    if (sum > sum2) {
+       sum = sum2;
+       t1 = t2;
+    }
+
+    *s += sum;
+    return t1;
+}
+
+
+inline static int
+count_bit_noESC(const int * ix, const int * const end, int * const s)
+{
+    /* No ESC-words */
+    int        sum1 = 0;
+    const char *hlen1 = ht[1].hlen;
+
+    do {
+       int x = ix[0] * 2 + ix[1];
+       ix += 2;
+       sum1 += hlen1[x];
+    } while (ix < end);
+
+    *s += sum1;
+    return 1;
+}
+
+
+
+inline static int
+count_bit_noESC_from2(
+    const int *       ix, 
+    const int * const end,
+          int         t1,
+          int * const s )
+{
+    /* No ESC-words */
+    unsigned int sum = 0, sum2;
+    const int xlen = ht[t1].xlen;
+    const unsigned int *hlen;
+    if (t1 == 2)
+       hlen = table23;
+    else
+       hlen = table56;
+
+    do {
+       int x = ix[0] * xlen + ix[1];
+       ix += 2;
+       sum += hlen[x];
+    } while (ix < end);
+
+    sum2 = sum & 0xffff;
+    sum >>= 16;
+
+    if (sum > sum2) {
+       sum = sum2;
+       t1++;
+    }
+
+    *s += sum;
+    return t1;
+}
+
+
+inline static int
+count_bit_noESC_from3(
+    const int *       ix, 
+    const int * const end,
+          int         t1,
+          int * const s )
+{
+    /* No ESC-words */
+    int        sum1 = 0;
+    int        sum2 = 0;
+    int        sum3 = 0;
+    const int xlen = ht[t1].xlen;
+    const char *hlen1 = ht[t1].hlen;
+    const char *hlen2 = ht[t1+1].hlen;
+    const char *hlen3 = ht[t1+2].hlen;
+    int t;
+
+    do {
+       int x = ix[0] * xlen + ix[1];
+       ix += 2;
+       sum1 += hlen1[x];
+       sum2 += hlen2[x];
+       sum3 += hlen3[x];
+    } while (ix < end);
+
+    t = t1;
+    if (sum1 > sum2) {
+       sum1 = sum2;
+       t++;
+    }
+    if (sum1 > sum3) {
+       sum1 = sum3;
+       t = t1+2;
+    }
+    *s += sum1;
+
+    return t;
+}
+
+
+/*************************************************************************/
+/*           choose table                                               */
+/*************************************************************************/
+
+/*
+  Choose the Huffman table that will encode ix[begin..end] with
+  the fewest bits.
+
+  Note: This code contains knowledge about the sizes and characteristics
+  of the Huffman tables as defined in the IS (Table B.7), and will not work
+  with any arbitrary tables.
+*/
+
+static int choose_table_nonMMX(
+    const int *       ix, 
+    const int * const end,
+          int * const s )
+{
+    int max;
+    int choice, choice2;
+    static const int huf_tbl_noESC[] = {
+       1, 2, 5, 7, 7,10,10,13,13,13,13,13,13,13,13 /* char not enough ? */
+    };
+
+    max = ix_max(ix, end);
+
+    switch (max) {
+    case 0:
+       return max;
+
+    case 1:
+       return count_bit_noESC(ix, end, s);
+
+    case 2:
+    case 3:
+       return count_bit_noESC_from2(ix, end, huf_tbl_noESC[max - 1], s);
+
+    case 4: case 5: case 6:
+    case 7: case 8: case 9:
+    case 10: case 11: case 12:
+    case 13: case 14: case 15:
+       return count_bit_noESC_from3(ix, end, huf_tbl_noESC[max - 1], s);
+
+    default:
+       /* try tables with linbits */
+       if (max > IXMAX_VAL) {
+           *s = LARGE_BITS;
+           return -1;
+       }
+       max -= 15;
+       for (choice2 = 24; choice2 < 32; choice2++) {
+           if (ht[choice2].linmax >= max) {
+               break;
+           }
+       }
+
+       for (choice = choice2 - 8; choice < 24; choice++) {
+           if (ht[choice].linmax >= max) {
+               break;
+           }
+       }
+       return count_bit_ESC(ix, end, choice, choice2, s);
+    }
+}
+
+
+
+/*************************************************************************/
+/*           count_bit                                                  */
+/*************************************************************************/
+
+int count_bits(
+          lame_internal_flags * const gfc, 
+          int     * const ix,
+    const FLOAT8  * const xr,
+          gr_info * const gi)  
+{
+    int bits = 0;
+    int i, a1, a2;
+    /* since quantize_xrpow uses table lookup, we need to check this first: */
+    FLOAT8 w = (IXMAX_VAL) / IPOW20(gi->global_gain);
+    for ( i = 0; i < 576; i++ )  {
+       if (xr[i] > w)
+           return LARGE_BITS;
+    }
+
+    if (gfc->quantization) 
+       quantize_xrpow(xr, ix, IPOW20(gi->global_gain));
+    else
+       quantize_xrpow_ISO(xr, ix, IPOW20(gi->global_gain));
+
+    if (gfc->noise_shaping_amp==3) {
+      int sfb;
+      // 0.634521682242439 = 0.5946*2**(.5*0.1875)
+      FLOAT8 roundfac = 0.634521682242439 / IPOW20(gi->global_gain+gi->scalefac_scale);
+      i = 0;
+      for (sfb = 0; sfb < gi->sfb_lmax; sfb++) {
+       int end;
+       if (!gfc->pseudohalf.l[sfb])
+         continue;
+
+       end   = gfc->scalefac_band.l[sfb+1];
+       for (; i < end; i++)
+         if (xr[i] < roundfac)
+           ix[i] = 0;
+      }
+
+      for (sfb = gi->sfb_smin; sfb < SBPSY_s; sfb++) {
+       int start, end, win;
+       start = gfc->scalefac_band.s[sfb];
+       end   = gfc->scalefac_band.s[sfb+1];
+       for (win = 0; win < 3; win++) {
+         int j;
+         if (!gfc->pseudohalf.s[sfb][win])
+           continue;
+         for (j = start; j < end; j++, i++)
+           if (xr[i] < roundfac)
+             ix[i] = 0;
+       }
+      }
+    }
+
+
+
+
+
+
+    i=576;
+    /* Determine count1 region */
+    for (; i > 1; i -= 2) 
+       if (ix[i - 1] | ix[i - 2])
+           break;
+    gi->count1 = i;
+
+    /* Determines the number of bits to encode the quadruples. */
+    a1 = a2 = 0;
+    for (; i > 3; i -= 4) {
+       int p;
+       /* hack to check if all values <= 1 */
+       if ((unsigned int)(ix[i-1] | ix[i-2] | ix[i-3] | ix[i-4]) > 1)
+           break;
+
+       p = ((ix[i-4] * 2 + ix[i-3]) * 2 + ix[i-2]) * 2 + ix[i-1];
+       a1 += t32l[p];
+       a2 += t33l[p];
+    }
+
+    bits = a1;
+    gi->count1table_select = 0;
+    if (a1 > a2) {
+       bits = a2;
+       gi->count1table_select = 1;
+    }
+
+    gi->count1bits = bits;
+    gi->big_values = i;
+    if (i == 0)
+       return bits;
+
+    if (gi->block_type == SHORT_TYPE) {
+      a1=3*gfc->scalefac_band.s[3];
+      if (a1 > gi->big_values) a1 = gi->big_values;
+      a2 = gi->big_values;
+
+    }else if (gi->block_type == NORM_TYPE) {
+       assert(i <= 576); /* bv_scf has 576 entries (0..575) */
+        a1 = gi->region0_count = gfc->bv_scf[i-2];
+       a2 = gi->region1_count = gfc->bv_scf[i-1];
+
+       assert(a1+a2+2 < SBPSY_l);
+        a2 = gfc->scalefac_band.l[a1 + a2 + 2];
+       a1 = gfc->scalefac_band.l[a1 + 1];
+       if (a2 < i)
+         gi->table_select[2] = gfc->choose_table(ix + a2, ix + i, &bits);
+
+    } else {
+       gi->region0_count = 7;
+       /*gi->region1_count = SBPSY_l - 7 - 1;*/
+       gi->region1_count = SBMAX_l -1 - 7 - 1;
+       a1 = gfc->scalefac_band.l[7 + 1];
+       a2 = i;
+       if (a1 > a2) {
+           a1 = a2;
+       }
+    }
+
+
+    /* have to allow for the case when bigvalues < region0 < region1 */
+    /* (and region0, region1 are ignored) */
+    a1 = Min(a1,i);
+    a2 = Min(a2,i);
+    
+    assert( a1 >= 0 );
+    assert( a2 >= 0 );
+
+    /* Count the number of bits necessary to code the bigvalues region. */
+    if (0 < a1)
+      gi->table_select[0] = gfc->choose_table(ix, ix + a1, &bits);
+    if (a1 < a2)
+      gi->table_select[1] = gfc->choose_table(ix + a1, ix + a2, &bits);
+    return bits;
+}
+
+/***********************************************************************
+  re-calculate the best scalefac_compress using scfsi
+  the saved bits are kept in the bit reservoir.
+ **********************************************************************/
+
+
+inline static void
+recalc_divide_init(
+    const lame_internal_flags * const gfc,
+          gr_info         cod_info,
+          int     * const ix,
+          int             r01_bits[],
+          int             r01_div [],
+          int             r0_tbl  [],
+          int             r1_tbl  [] )
+{
+    int r0, r1, bigv, r0t, r1t, bits;
+
+    bigv = cod_info.big_values;
+
+    for (r0 = 0; r0 <= 7 + 15; r0++) {
+       r01_bits[r0] = LARGE_BITS;
+    }
+
+    for (r0 = 0; r0 < 16; r0++) {
+       int a1 = gfc->scalefac_band.l[r0 + 1], r0bits;
+       if (a1 >= bigv)
+           break;
+       r0bits = cod_info.part2_length;
+       r0t = gfc->choose_table(ix, ix + a1, &r0bits);
+
+       for (r1 = 0; r1 < 8; r1++) {
+           int a2 = gfc->scalefac_band.l[r0 + r1 + 2];
+           if (a2 >= bigv)
+               break;
+
+           bits = r0bits;
+           r1t = gfc->choose_table(ix + a1, ix + a2, &bits);
+           if (r01_bits[r0 + r1] > bits) {
+               r01_bits[r0 + r1] = bits;
+               r01_div[r0 + r1] = r0;
+               r0_tbl[r0 + r1] = r0t;
+               r1_tbl[r0 + r1] = r1t;
+           }
+       }
+    }
+}
+
+inline static void
+recalc_divide_sub(
+    const lame_internal_flags * const gfc,
+    const gr_info         cod_info2,
+          gr_info * const gi,
+    const int     * const ix,
+    const int             r01_bits[],
+    const int             r01_div [],
+    const int             r0_tbl  [],
+    const int             r1_tbl  [] )
+{
+    int bits, r2, a2, bigv, r2t;
+
+    bigv = cod_info2.big_values;
+
+    for (r2 = 2; r2 < SBMAX_l + 1; r2++) {
+       a2 = gfc->scalefac_band.l[r2];
+       if (a2 >= bigv) 
+           break;
+
+       bits = r01_bits[r2 - 2] + cod_info2.count1bits;
+       if (gi->part2_3_length <= bits)
+           break;
+
+       r2t = gfc->choose_table(ix + a2, ix + bigv, &bits);
+       if (gi->part2_3_length <= bits)
+           continue;
+
+       memcpy(gi, &cod_info2, sizeof(gr_info));
+       gi->part2_3_length = bits;
+       gi->region0_count = r01_div[r2 - 2];
+       gi->region1_count = r2 - 2 - r01_div[r2 - 2];
+       gi->table_select[0] = r0_tbl[r2 - 2];
+       gi->table_select[1] = r1_tbl[r2 - 2];
+       gi->table_select[2] = r2t;
+    }
+}
+
+
+
+
+void best_huffman_divide(
+    const lame_internal_flags * const gfc,
+          gr_info * const gi,
+          int     * const ix )
+{
+    int i, a1, a2;
+    gr_info cod_info2;
+
+    int r01_bits[7 + 15 + 1];
+    int r01_div[7 + 15 + 1];
+    int r0_tbl[7 + 15 + 1];
+    int r1_tbl[7 + 15 + 1];
+
+
+    /* SHORT BLOCK stuff fails for MPEG2 */ 
+    if (gi->block_type == SHORT_TYPE && gfc->mode_gr==1) 
+          return;
+
+
+    memcpy(&cod_info2, gi, sizeof(gr_info));
+    if (gi->block_type == NORM_TYPE) {
+       recalc_divide_init(gfc, cod_info2, ix, r01_bits,r01_div,r0_tbl,r1_tbl);
+       recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits,r01_div,r0_tbl,r1_tbl);
+    }
+
+    i = cod_info2.big_values;
+    if (i == 0 || (unsigned int)(ix[i-2] | ix[i-1]) > 1)
+       return;
+
+    i = gi->count1 + 2;
+    if (i > 576)
+       return;
+
+    /* Determines the number of bits to encode the quadruples. */
+    memcpy(&cod_info2, gi, sizeof(gr_info));
+    cod_info2.count1 = i;
+    a1 = a2 = 0;
+
+    assert(i <= 576);
+    
+    for (; i > cod_info2.big_values; i -= 4) {
+       int p = ((ix[i-4] * 2 + ix[i-3]) * 2 + ix[i-2]) * 2 + ix[i-1];
+       a1 += t32l[p];
+       a2 += t33l[p];
+    }
+    cod_info2.big_values = i;
+
+    cod_info2.count1table_select = 0;
+    if (a1 > a2) {
+       a1 = a2;
+       cod_info2.count1table_select = 1;
+    }
+
+    cod_info2.count1bits = a1;
+    cod_info2.part2_3_length = a1 + cod_info2.part2_length;
+
+    if (cod_info2.block_type == NORM_TYPE)
+       recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits,r01_div,r0_tbl,r1_tbl);
+    else {
+       /* Count the number of bits necessary to code the bigvalues region. */
+       a1 = gfc->scalefac_band.l[7 + 1];
+       if (a1 > i) {
+           a1 = i;
+       }
+       if (a1 > 0)
+         cod_info2.table_select[0] =
+           gfc->choose_table(ix, ix + a1, (int *)&cod_info2.part2_3_length);
+       if (i > a1)
+         cod_info2.table_select[1] =
+           gfc->choose_table(ix + a1, ix + i, (int *)&cod_info2.part2_3_length);
+       if (gi->part2_3_length > cod_info2.part2_3_length)
+           memcpy(gi, &cod_info2, sizeof(gr_info));
+    }
+}
+
+static const int slen1_n[16] = { 1, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, 8, 8,16,16 };
+static const int slen2_n[16] = { 1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, 4, 8, 4, 8 };
+
+void
+scfsi_calc(int ch,
+          III_side_info_t *l3_side,
+          III_scalefac_t scalefac[2][2])
+{
+    int i, s1, s2, c1, c2;
+    int sfb;
+    gr_info *gi = &l3_side->gr[1].ch[ch].tt;
+
+    static const int scfsi_band[5] = { 0, 6, 11, 16, 21 };
+#if 0
+    static const int slen1_n[16] = { 0, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, 8, 8,16,16 };
+    static const int slen2_n[16] = { 0, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, 4, 8, 4, 8 };
+#endif
+
+    for (i = 0; i < 4; i++) 
+       l3_side->scfsi[ch][i] = 0;
+
+    for (i = 0; i < (sizeof(scfsi_band) / sizeof(int)) - 1; i++) {
+       for (sfb = scfsi_band[i]; sfb < scfsi_band[i + 1]; sfb++) {
+           if (scalefac[0][ch].l[sfb] != scalefac[1][ch].l[sfb])
+               break;
+       }
+       if (sfb == scfsi_band[i + 1]) {
+           for (sfb = scfsi_band[i]; sfb < scfsi_band[i + 1]; sfb++) {
+               scalefac[1][ch].l[sfb] = -1;
+           }
+           l3_side->scfsi[ch][i] = 1;
+       }
+    }
+
+    s1 = c1 = 0;
+    for (sfb = 0; sfb < 11; sfb++) {
+       if (scalefac[1][ch].l[sfb] < 0)
+           continue;
+       c1++;
+       if (s1 < scalefac[1][ch].l[sfb])
+           s1 = scalefac[1][ch].l[sfb];
+    }
+
+    s2 = c2 = 0;
+    for (; sfb < SBPSY_l; sfb++) {
+       if (scalefac[1][ch].l[sfb] < 0)
+           continue;
+       c2++;
+       if (s2 < scalefac[1][ch].l[sfb])
+           s2 = scalefac[1][ch].l[sfb];
+    }
+
+    for (i = 0; i < 16; i++) {
+       if (s1 < slen1_n[i] && s2 < slen2_n[i]) {
+           int c = slen1_tab[i] * c1 + slen2_tab[i] * c2;
+           if (gi->part2_length > c) {
+               gi->part2_length = c;
+               gi->scalefac_compress = i;
+           }
+       }
+    }
+}
+
+/*
+Find the optimal way to store the scalefactors.
+Only call this routine after final scalefactors have been
+chosen and the channel/granule will not be re-encoded.
+ */
+void best_scalefac_store(
+    const lame_internal_flags *gfc,
+    const int             gr,
+    const int             ch,
+          int             l3_enc[2][2][576],
+          III_side_info_t * const l3_side,
+          III_scalefac_t          scalefac[2][2] )
+{
+
+    /* use scalefac_scale if we can */
+    gr_info *gi = &l3_side->gr[gr].ch[ch].tt;
+    int sfb,i,j,j2,l,start,end;
+
+    /* remove scalefacs from bands with ix=0.  This idea comes
+     * from the AAC ISO docs.  added mt 3/00 */
+    /* check if l3_enc=0 */
+    for ( sfb = 0; sfb < gi->sfb_lmax; sfb++ ) {
+      if (scalefac[gr][ch].l[sfb]>0) { 
+       start = gfc->scalefac_band.l[ sfb ];
+       end   = gfc->scalefac_band.l[ sfb+1 ];
+       for ( l = start; l < end; l++ ) if (l3_enc[gr][ch][l]!=0) break;
+       if (l==end) scalefac[gr][ch].l[sfb]=0;
+      }
+    }
+    for ( j=0, sfb = gi->sfb_smin; sfb < SBPSY_s; sfb++ ) {
+       start = gfc->scalefac_band.s[ sfb ];
+       end   = gfc->scalefac_band.s[ sfb+1 ];
+       for ( i = 0; i < 3; i++ ) {
+         if (scalefac[gr][ch].s[sfb][i]>0) {
+           j2 = j;
+           for ( l = start; l < end; l++ ) 
+             if (l3_enc[gr][ch][j2++ /*3*l+i*/]!=0) break;
+           if (l==end) scalefac[gr][ch].s[sfb][i]=0;
+         }
+         j += end-start;
+       }
+    }
+
+
+    gi->part2_3_length -= gi->part2_length;
+    if (!gi->scalefac_scale && !gi->preflag) {
+       int b, s = 0;
+       for (sfb = 0; sfb < gi->sfb_lmax; sfb++) {
+           s |= scalefac[gr][ch].l[sfb];
+       }
+
+       for (sfb = gi->sfb_smin; sfb < SBPSY_s; sfb++) {
+           for (b = 0; b < 3; b++) {
+               s |= scalefac[gr][ch].s[sfb][b];
+           }
+       }
+
+       if (!(s & 1) && s != 0) {
+           for (sfb = 0; sfb < gi->sfb_lmax; sfb++) {
+               scalefac[gr][ch].l[sfb] /= 2;
+           }
+           for (sfb = gi->sfb_smin; sfb < SBPSY_s; sfb++) {
+               for (b = 0; b < 3; b++) {
+                   scalefac[gr][ch].s[sfb][b] /= 2;
+               }
+           }
+
+           gi->scalefac_scale = 1;
+           gi->part2_length = 99999999;
+           if (gfc->mode_gr == 2) {
+               scale_bitcount(&scalefac[gr][ch], gi);
+           } else {
+               scale_bitcount_lsf(gfc,&scalefac[gr][ch], gi);
+           }
+       }
+    }
+
+
+    for ( i = 0; i < 4; i++ )
+      l3_side->scfsi[ch][i] = 0;
+
+    if (gfc->mode_gr==2 && gr == 1
+       && l3_side->gr[0].ch[ch].tt.block_type != SHORT_TYPE
+       && l3_side->gr[1].ch[ch].tt.block_type != SHORT_TYPE) {
+       scfsi_calc(ch, l3_side, scalefac);
+    }
+    gi->part2_3_length += gi->part2_length;
+}
+
+
+/* number of bits used to encode scalefacs */
+
+/* 18*slen1_tab[i] + 18*slen2_tab[i] */
+static const int scale_short[16] = {
+    0, 18, 36, 54, 54, 36, 54, 72, 54, 72, 90, 72, 90, 108, 108, 126 };
+
+/* 17*slen1_tab[i] + 18*slen2_tab[i] */
+static const int scale_mixed[16] = {
+    0, 18, 36, 54, 51, 35, 53, 71, 52, 70, 88, 69, 87, 105, 104, 122 };
+
+/* 11*slen1_tab[i] + 10*slen2_tab[i] */
+static const int scale_long[16] = {
+    0, 10, 20, 30, 33, 21, 31, 41, 32, 42, 52, 43, 53, 63, 64, 74 };
+
+
+/*************************************************************************/
+/*            scale_bitcount                                             */
+/*************************************************************************/
+
+/* Also calculates the number of bits necessary to code the scalefactors. */
+
+int scale_bitcount( 
+    III_scalefac_t * const scalefac, gr_info * const cod_info)
+{
+    int i, k, sfb, max_slen1 = 0, max_slen2 = 0, ep = 2;
+
+    /* maximum values */
+    const int *tab;
+
+
+    if ( cod_info->block_type == SHORT_TYPE ) {
+       tab = scale_short;
+       if (cod_info->mixed_block_flag) {
+           tab = scale_mixed;
+           for ( sfb = 0 ; sfb < cod_info->sfb_lmax; sfb++ )
+               if (max_slen1 < scalefac->l[sfb])
+                   max_slen1 = scalefac->l[sfb];
+       }
+
+       for ( i = 0; i < 3; i++ ) {
+           for ( sfb = cod_info->sfb_smin; sfb < 6; sfb++ )
+               if (max_slen1 < scalefac->s[sfb][i])
+                   max_slen1 = scalefac->s[sfb][i];
+           for (sfb = 6; sfb < SBPSY_s; sfb++ )
+               if (max_slen2 < scalefac->s[sfb][i])
+                   max_slen2 = scalefac->s[sfb][i];
+       }
+    }
+    else
+    { /* block_type == 1,2,or 3 */
+        tab = scale_long;
+        for ( sfb = 0; sfb < 11; sfb++ )
+            if ( scalefac->l[sfb] > max_slen1 )
+                max_slen1 = scalefac->l[sfb];
+
+       if (!cod_info->preflag) {
+           for ( sfb = 11; sfb < SBPSY_l; sfb++ )
+               if (scalefac->l[sfb] < pretab[sfb])
+                   break;
+
+           if (sfb == SBPSY_l) {
+               cod_info->preflag = 1;
+               for ( sfb = 11; sfb < SBPSY_l; sfb++ )
+                   scalefac->l[sfb] -= pretab[sfb];
+           }
+       }
+
+        for ( sfb = 11; sfb < SBPSY_l; sfb++ )
+            if ( scalefac->l[sfb] > max_slen2 )
+                max_slen2 = scalefac->l[sfb];
+    }
+
+
+    /* from Takehiro TOMINAGA <tominaga@isoternet.org> 10/99
+     * loop over *all* posible values of scalefac_compress to find the
+     * one which uses the smallest number of bits.  ISO would stop
+     * at first valid index */
+    cod_info->part2_length = LARGE_BITS;
+    for ( k = 0; k < 16; k++ )
+    {
+        if ( (max_slen1 < slen1_n[k]) && (max_slen2 < slen2_n[k]) &&
+             (cod_info->part2_length > tab[k])) {
+         cod_info->part2_length=tab[k];
+         cod_info->scalefac_compress=k;
+         ep=0;  /* we found a suitable scalefac_compress */
+       }
+    }
+    return ep;
+}
+
+
+
+/*
+  table of largest scalefactor values for MPEG2
+*/
+static const int max_range_sfac_tab[6][4] =
+{
+ { 15, 15, 7,  7},
+ { 15, 15, 7,  0},
+ { 7,  3,  0,  0},
+ { 15, 31, 31, 0},
+ { 7,  7,  7,  0},
+ { 3,  3,  0,  0}
+};
+
+
+
+
+/*************************************************************************/
+/*            scale_bitcount_lsf                                         */
+/*************************************************************************/
+
+/* Also counts the number of bits to encode the scalefacs but for MPEG 2 */ 
+/* Lower sampling frequencies  (24, 22.05 and 16 kHz.)                   */
+/*  This is reverse-engineered from section 2.4.3.2 of the MPEG2 IS,     */
+/* "Audio Decoding Layer III"                                            */
+
+int scale_bitcount_lsf(const lame_internal_flags *gfc,
+    const III_scalefac_t * const scalefac, gr_info * const cod_info)
+{
+    int table_number, row_in_table, partition, nr_sfb, window, over;
+    int i, sfb, max_sfac[ 4 ];
+    const int *partition_table;
+
+    /*
+      Set partition table. Note that should try to use table one,
+      but do not yet...
+    */
+    if ( cod_info->preflag )
+       table_number = 2;
+    else
+       table_number = 0;
+
+    for ( i = 0; i < 4; i++ )
+       max_sfac[i] = 0;
+
+    if ( cod_info->block_type == SHORT_TYPE )
+    {
+           row_in_table = 1;
+           partition_table = &nr_of_sfb_block[table_number][row_in_table][0];
+           for ( sfb = 0, partition = 0; partition < 4; partition++ )
+           {
+               nr_sfb = partition_table[ partition ] / 3;
+               for ( i = 0; i < nr_sfb; i++, sfb++ )
+                   for ( window = 0; window < 3; window++ )
+                       if ( scalefac->s[sfb][window] > max_sfac[partition] )
+                           max_sfac[partition] = scalefac->s[sfb][window];
+           }
+    }
+    else
+    {
+       row_in_table = 0;
+       partition_table = &nr_of_sfb_block[table_number][row_in_table][0];
+       for ( sfb = 0, partition = 0; partition < 4; partition++ )
+       {
+           nr_sfb = partition_table[ partition ];
+           for ( i = 0; i < nr_sfb; i++, sfb++ )
+               if ( scalefac->l[sfb] > max_sfac[partition] )
+                   max_sfac[partition] = scalefac->l[sfb];
+       }
+    }
+
+    for ( over = 0, partition = 0; partition < 4; partition++ )
+    {
+       if ( max_sfac[partition] > max_range_sfac_tab[table_number][partition] )
+           over++;
+    }
+    if ( !over )
+    {
+       /*
+         Since no bands have been over-amplified, we can set scalefac_compress
+         and slen[] for the formatter
+       */
+       static const int log2tab[] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
+
+       int slen1, slen2, slen3, slen4;
+
+        cod_info->sfb_partition_table = nr_of_sfb_block[table_number][row_in_table];
+       for ( partition = 0; partition < 4; partition++ )
+           cod_info->slen[partition] = log2tab[max_sfac[partition]];
+
+       /* set scalefac_compress */
+       slen1 = cod_info->slen[ 0 ];
+       slen2 = cod_info->slen[ 1 ];
+       slen3 = cod_info->slen[ 2 ];
+       slen4 = cod_info->slen[ 3 ];
+
+       switch ( table_number )
+       {
+         case 0:
+           cod_info->scalefac_compress = (((slen1 * 5) + slen2) << 4)
+               + (slen3 << 2)
+               + slen4;
+           break;
+
+         case 1:
+           cod_info->scalefac_compress = 400
+               + (((slen1 * 5) + slen2) << 2)
+               + slen3;
+           break;
+
+         case 2:
+           cod_info->scalefac_compress = 500 + (slen1 * 3) + slen2;
+           break;
+
+         default:
+           ERRORF(gfc,"intensity stereo not implemented yet\n" );
+           break;
+       }
+    }
+#ifdef DEBUG
+    if ( over ) 
+        ERRORF(gfc, "---WARNING !! Amplification of some bands over limits\n" );
+#endif
+    if (!over) {
+      assert( cod_info->sfb_partition_table );     
+      cod_info->part2_length=0;
+      for ( partition = 0; partition < 4; partition++ )
+       cod_info->part2_length += cod_info->slen[partition] * cod_info->sfb_partition_table[partition];
+    }
+    return over;
+}
+
+
+
+void huffman_init(lame_internal_flags * const gfc)
+{
+    int i;
+
+    gfc->choose_table = choose_table_nonMMX;
+    
+#ifdef MMX_choose_table
+    if (gfc->CPU_features.MMX) {
+        extern int choose_table_MMX(const int *ix, const int *end, int *s);
+        gfc->choose_table = choose_table_MMX;
+    }
+#endif
+
+    for (i = 2; i <= 576; i += 2) {
+       int scfb_anz = 0, index;
+       while (gfc->scalefac_band.l[++scfb_anz] < i)
+           ;
+
+       index = subdv_table[scfb_anz].region0_count;
+       while (gfc->scalefac_band.l[index + 1] > i)
+           index--;
+
+       if (index < 0) {
+         /* this is an indication that everything is going to
+            be encoded as region0:  bigvalues < region0 < region1
+            so lets set region0, region1 to some value larger
+            than bigvalues */
+         index = subdv_table[scfb_anz].region0_count;
+       }
+
+       gfc->bv_scf[i-2] = index;
+
+       index = subdv_table[scfb_anz].region1_count;
+       while (gfc->scalefac_band.l[index + gfc->bv_scf[i-2] + 2] > i)
+           index--;
+
+       if (index < 0) {
+         index = subdv_table[scfb_anz].region1_count;
+       }
+
+       gfc->bv_scf[i-1] = index;
+    }
+}
diff --git a/lib/lame/tools.h b/lib/lame/tools.h
new file mode 100644 (file)
index 0000000..e8c6de3
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *    LAME tools library include file
+ *    Simple context free functions
+ *      - no references to gfc, to gfp, or to any other function not defined
+ *        in this module
+ * 
+ *    Copyright (c) 2000 Frank Klemm
+ *    Copyright (c) 2001 John Dahlstrom
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: tools.h,v 1.1 2002/04/28 17:30:30 kramm Exp $ */
+
+#ifndef LAME_TOOLS_H
+#define LAME_TOOLS_H
+
+#include "machine.h"
+
+
+
+/***********************************************************************
+*  Function Prototype Declarations
+***********************************************************************/
+
+static inline void qinterp_cf_42( const FLOAT y[4], FLOAT c[3] );
+static inline void qinterp_cf_3( const FLOAT y[3], FLOAT c[3] );
+static inline FLOAT qinterp_eval( const FLOAT c[3], FLOAT x, 
+                                  FLOAT xtrans, FLOAT xratio );
+
+
+
+/***********************************************************************
+*  Macros and Static Inline Function Definitions
+***********************************************************************/
+
+/* qinterp_cf_42 - Given 4 points, find the coefficients for a quadratic
+                   that connects the 2 center points.  -jd
+  in: y    coordinate values, paired with constant x coordinates, -1, 0, 1, 2
+ out: c    coefficients ordered for quadratic, (c[2] * x*x + c[1] * x + c[0])
+design note:
+  Utilize the inverse of two constant 3x3 matrices to compute two quadratics,
+  one from the points at (-1,0,1), and the other from the points at (0,1,2).
+  The mean of the two yields a quadratic between the points at 0 and 1.
+*/
+static inline void
+qinterp_cf_42( const FLOAT y[4], FLOAT c[3] )
+{
+  c[2] = ( y[0] - y[1] - y[2] + y[3]) * 0.25; /* ([1 -1 -1 1] .* Y) * 0.25 */
+  c[1] = y[2] - y[1] - c[2];    /* ([-1 -3 5 -1] .* Y) * 0.25 */
+  c[0] = y[1];
+}
+
+/* qinterp_cf_3 - Given 3 points, find the coefficients for a quadratic
+                  that connects the 3 points.  -jd
+  in: y    coordinate values, paired with constant x coordinates, 0, 1, 2
+ out: c    coefficients ordered for quadratic, (c[2] * x*x + c[1] * x + c[0])
+*/
+static inline void
+qinterp_cf_3( const FLOAT y[3], FLOAT c[3] )
+{
+  c[2] = ( y[0] + y[2]) * 0.5 - y[1]; /* ([1 -2 1] .* Y) * 0.5 */
+  c[1] = y[1] - y[0] - c[2];    /* ([-3 4 -1] .* Y) * 0.5 */
+  c[0] = y[0];
+}
+
+
+
+/* qinterp_eval - Evaluate a quadratic at a point, given polynomial 
+                  coefficients, and an x coordinate with translation and scale
+                  ratio values.  This function evaluates the quadratic at the
+                  transformed x coordinate ((x - xtrans) * xratio)).  -jd
+ in: c       quadratic coefficients, for (c[2] * x * x + c[1] * x + c[0])
+     x
+     xtrans
+     xratio
+returns: y coordinate (the quadratic evaluated)
+*/
+static inline FLOAT
+qinterp_eval( const FLOAT c[3], FLOAT x, FLOAT xtrans, FLOAT xratio )
+{
+  x = (x - xtrans) * xratio;
+  return( (c[2] * x + c[1]) * x + c[0] );
+}
+
+
+
+#endif /* LAME_TOOLS_H */
diff --git a/lib/lame/util.c b/lib/lame/util.c
new file mode 100644 (file)
index 0000000..1df7de1
--- /dev/null
@@ -0,0 +1,989 @@
+/*
+ *     lame utility library source file
+ *
+ *     Copyright (c) 1999 Albert L Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: util.c,v 1.1 2002/04/28 17:30:30 kramm Exp $ */
+
+#include "config_static.h"
+
+#define PRECOMPUTE
+
+#include "util.h"
+#include "tools.h"
+#include <ctype.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#if defined(__FreeBSD__) && !defined(__alpha__)
+# include <machine/floatingpoint.h>
+#endif
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+/***********************************************************************
+*
+*  Global Function Definitions
+*
+***********************************************************************/
+/*empty and close mallocs in gfc */
+
+void  freegfc ( lame_internal_flags* const gfc )   /* bit stream structure */
+{
+    int  i;
+
+#ifdef KLEMM_44
+    if (gfc->resample_in != NULL) {
+        resample_close(gfc->resample_in);
+        gfc->resample_in = NULL;
+    }
+    free(gfc->mfbuf[0]);
+    free(gfc->mfbuf[1]);
+#endif
+
+    for ( i = 0 ; i <= 2*BPC; i++ )
+        if ( gfc->blackfilt[i] != NULL ) {
+            free ( gfc->blackfilt[i] );
+           gfc->blackfilt[i] = NULL;
+       }
+    if ( gfc->inbuf_old[0] ) { 
+        free ( gfc->inbuf_old[0] );
+       gfc->inbuf_old[0] = NULL;
+    }
+    if ( gfc->inbuf_old[1] ) { 
+        free ( gfc->inbuf_old[1] );
+       gfc->inbuf_old[1] = NULL;
+    }
+
+    if ( gfc->bs.buf != NULL ) {
+        free ( gfc->bs.buf );
+        gfc->bs.buf = NULL;
+    }
+
+    if ( gfc->VBR_seek_table.bag ) {
+        free ( gfc->VBR_seek_table.bag );
+    }
+    if ( gfc->ATH ) {
+        free ( gfc->ATH );
+    }
+    if ( gfc->VBR ) {
+        free ( gfc->VBR );
+    }
+    if ( gfc->PSY ) {
+        free ( gfc->PSY );
+    }
+    if ( gfc->s3_ll ) {
+        /* XXX allocated in psymodel_init() */
+        free ( gfc->s3_ll );
+    }
+    if ( gfc->s3_ss ) {
+        /* XXX allocated in psymodel_init() */
+        free ( gfc->s3_ss );
+    }
+    free ( gfc );
+}
+
+
+
+/*those ATH formulas are returning
+their minimum value for input = -1*/
+
+FLOAT8 ATHformula_GB(FLOAT8 f, FLOAT8 value)
+{
+  /* from Painter & Spanias
+    modified by Gabriel Bouvigne to better fit the reality
+  ath =    3.640 * pow(f,-0.8)
+         - 6.800 * exp(-0.6*pow(f-3.4,2.0))
+         + 6.000 * exp(-0.15*pow(f-8.7,2.0))
+         + 0.6* 0.001 * pow(f,4.0);
+
+
+  In the past LAME was using the Painter &Spanias formula.
+  But we had some recurrent problems with HF content.
+  We measured real ATH values, and found the older formula
+  to be inacurate in the higher part. So we made this new
+  formula and this solved most of HF problematic testcases.
+  The tradeoff is that in VBR mode it increases a lot the
+  bitrate.*/
+
+
+/*this curve can be udjusted according to the VBR scale:
+it adjusts from something close to Painter & Spanias
+on V9 up to Bouvigne's formula for V0. This way the VBR
+bitrate is more balanced according to the -V value.*/
+
+  FLOAT8 ath;
+
+  if (f < -.3)
+      f=3410;
+
+  f /= 1000;  // convert to khz
+  f  = Max(0.01, f);
+  f  = Min(18.0, f);
+
+  ath =    3.640 * pow(f,-0.8)
+         - 6.800 * exp(-0.6*pow(f-3.4,2.0))
+         + 6.000 * exp(-0.15*pow(f-8.7,2.0))
+         + (0.6+0.04*value)* 0.001 * pow(f,4.0);
+  return ath;
+}
+
+
+/* 
+ *  Klemm 1994 and 1997. Experimental data. Sorry, data looks a little bit
+ *  dodderly. Data below 30 Hz is extrapolated from other material, above 18
+ *  kHz the ATH is limited due to the original purpose (too much noise at
+ *  ATH is not good even if it's theoretically inaudible).
+ */
+
+FLOAT8  ATHformula_Frank( FLOAT8 freq )
+{
+    /*
+     * one value per 100 cent = 1
+     * semitone = 1/4
+     * third = 1/12
+     * octave = 1/40 decade
+     * rest is linear interpolated, values are currently in decibel rel. 20 ÂµPa
+     */
+    static FLOAT tab [] = {
+        /*    10.0 */  96.69, 96.69, 96.26, 95.12,
+        /*    12.6 */  93.53, 91.13, 88.82, 86.76,
+        /*    15.8 */  84.69, 82.43, 79.97, 77.48,
+        /*    20.0 */  74.92, 72.39, 70.00, 67.62,
+        /*    25.1 */  65.29, 63.02, 60.84, 59.00,
+        /*    31.6 */  57.17, 55.34, 53.51, 51.67,
+        /*    39.8 */  50.04, 48.12, 46.38, 44.66,
+        /*    50.1 */  43.10, 41.73, 40.50, 39.22,
+        /*    63.1 */  37.23, 35.77, 34.51, 32.81,
+        /*    79.4 */  31.32, 30.36, 29.02, 27.60,
+        /*   100.0 */  26.58, 25.91, 24.41, 23.01,
+        /*   125.9 */  22.12, 21.25, 20.18, 19.00,
+        /*   158.5 */  17.70, 16.82, 15.94, 15.12,
+        /*   199.5 */  14.30, 13.41, 12.60, 11.98,
+        /*   251.2 */  11.36, 10.57,  9.98,  9.43,
+        /*   316.2 */   8.87,  8.46,  7.44,  7.12,
+        /*   398.1 */   6.93,  6.68,  6.37,  6.06,
+        /*   501.2 */   5.80,  5.55,  5.29,  5.02,
+        /*   631.0 */   4.75,  4.48,  4.22,  3.98,
+        /*   794.3 */   3.75,  3.51,  3.27,  3.22,
+        /*  1000.0 */   3.12,  3.01,  2.91,  2.68,
+        /*  1258.9 */   2.46,  2.15,  1.82,  1.46,
+        /*  1584.9 */   1.07,  0.61,  0.13, -0.35,
+        /*  1995.3 */  -0.96, -1.56, -1.79, -2.35,
+        /*  2511.9 */  -2.95, -3.50, -4.01, -4.21,
+        /*  3162.3 */  -4.46, -4.99, -5.32, -5.35,
+        /*  3981.1 */  -5.13, -4.76, -4.31, -3.13,
+        /*  5011.9 */  -1.79,  0.08,  2.03,  4.03,
+        /*  6309.6 */   5.80,  7.36,  8.81, 10.22,
+        /*  7943.3 */  11.54, 12.51, 13.48, 14.21,
+        /* 10000.0 */  14.79, 13.99, 12.85, 11.93,
+        /* 12589.3 */  12.87, 15.19, 19.14, 23.69,
+        /* 15848.9 */  33.52, 48.65, 59.42, 61.77,
+        /* 19952.6 */  63.85, 66.04, 68.33, 70.09,
+        /* 25118.9 */  70.66, 71.27, 71.91, 72.60,
+    };
+    FLOAT8    freq_log;
+    unsigned  index;
+    
+    if (freq < -.3)
+        freq=3758;
+
+    if ( freq <    10. ) freq =    10.;
+    if ( freq > 29853. ) freq = 29853.;
+    
+    freq_log = 40. * log10 (0.1 * freq);   /* 4 steps per third, starting at 10 Hz */
+    index    = (unsigned) freq_log;
+    assert ( index < sizeof(tab)/sizeof(*tab) );
+    return tab [index] * (1 + index - freq_log) + tab [index+1] * (freq_log - index);
+}
+
+
+
+/* ATHformula_jd - Compute ATH at a given frequency from experimental data.
+                   Below 15000 Hz, this ATH curve is based on data merged from
+                   various existing sources.  New experimental data covers
+                   frequencies above 15000 Hz.  -jd
+     in: freq    (Hz)
+returns: ATH value at freq in dB, or minimum ATH value if input freq is -1
+design notes:
+   Above 15000 Hz, my data indicates roughly 10 dB between the edge of
+   ready detection, and statistical indistinguishability.  To provide a
+   balance between my data, and ATH data from other sources, roughly 5 dB
+   is added above 15000 Hz, except at frequencies above 20500 Hz.  The ATH
+   of 21000+ Hz frequencies is decreased by 5 dB, to reduce the possibility
+   of extra distortion that some output systems exhibit when given a contrived
+   sample with an intense, but hardly audible frequency.
+*/
+FLOAT8
+ATHformula_jd( FLOAT8 freq )
+{
+  int i;
+  int ifreq;
+  int at_i;
+  int tstep;
+  int xtrans;
+  FLOAT coeff[3];
+  FLOAT8 rval;
+
+  const FLOAT ath_lt100[]       /* 20 - 120 Hz (for computing 0 - 100 Hz) */
+    = { 74.0, 47.9, 35.2, 28.1, 23.5,    20.4 };
+
+  const FLOAT ath_lt500[]       /* 100 - 600 Hz (for 100 - 500 Hz) */
+    = { 23.5, 13.4, 9.4, 6.9, 5.9,    5.0 };
+
+  const FLOAT ath_gt500[]       /* 500 Hz and above */
+    = { /*   500 */        5.9,  3.2,  1.6, -0.7,
+        /*  2500 */ -2.7, -4.5, -5.2, -4.8, -3.7,
+        /*  5000 */ -1.6,  1.5,  3.8,  5.3,  6.8,
+        /*  7500 */  8.2,  9.5, 10.5, 11.3, 11.8,
+        /* 10000 */ 12.1, 12.2, 12.4, 12.4, 12.4,
+        /* 12500 */ 12.8, 13.5, 14.9, 16.8, 19.0,
+        /* 15000 */ 23.0, 27.0, 33.0, 36.5, 39.5,
+        /* 17500 */ 43.5, 51.5, 58.5, 65.0, 71.5,
+        /* 20000 */ 78.0, 79.5, 80.0, 80.5, 80.5,    80.5 };
+
+  const FLOAT *ath_table[4];
+  const int ath_table_step[4] =     {   20,  100,   500,   500 };
+  const FLOAT ath_table_xratio[4] = { 0.05, 0.01, 0.002, 0.002 };
+
+  ath_table[0] = ath_lt100;
+  ath_table[1] = ath_lt500;
+  ath_table[3] = ath_gt500;
+
+  if( freq >= -0.5 && freq < 22000 ) {
+      ifreq = (int) freq;
+      at_i = ( (((99 - ifreq) >> (sizeof(int) * 8 - 1)) & 0x1)
+               | (((499 - ifreq) >> (sizeof(int) * 8 - 2)) & 0x3) );
+      tstep = ath_table_step[at_i];
+      
+      i = (ifreq / tstep);
+      i -= 2;
+      if( i >= 0 ) {
+          qinterp_cf_42( ath_table[at_i] + i, coeff );
+          xtrans = (i + 2) * tstep;
+      } else {                  /* leading edge */
+          qinterp_cf_3( ath_table[at_i], coeff );
+          xtrans = tstep;
+      }
+      rval = qinterp_eval( coeff, freq, (FLOAT)xtrans, ath_table_xratio[at_i]);
+      return(rval);
+  } else if( freq < 0 ) {
+      return(-5.2);             /* minimum value from table */
+  } else {
+      return( ath_gt500[ 22000 / 500 - 1 ] ); /* 22kHz ATH used for 22kHz+ */
+  }
+}
+
+
+
+FLOAT8 ATHformula(FLOAT8 f,lame_global_flags *gfp)
+{
+  switch(gfp->ATHtype)
+    {
+    case 0:
+      return ATHformula_GB(f, 9);
+    case 1:
+      return ATHformula_Frank(f);
+    case 2:
+      return ATHformula_GB(f, 0);
+    case 3:
+      return ATHformula_GB(f, 1) +6;     /*modification of GB formula by Roel*/
+    case 4:
+      if (!(gfp->VBR == vbr_off || gfp->VBR == vbr_abr)) /*this case should be used with true vbr only*/
+        return ATHformula_GB(f,gfp->VBR_q);
+    case 5:
+      return ATHformula_jd(f);
+    }
+
+  return ATHformula_GB(f, 0);
+}
+
+/* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */
+FLOAT8 freq2bark(FLOAT8 freq)
+{
+  /* input: freq in hz  output: barks */
+    if (freq<0) freq=0;
+    freq = freq * 0.001;
+    return 13.0*atan(.76*freq) + 3.5*atan(freq*freq/(7.5*7.5));
+}
+
+/* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */
+FLOAT8 freq2cbw(FLOAT8 freq)
+{
+  /* input: freq in hz  output: critical band width */
+    freq = freq * 0.001;
+    return 25+75*pow(1+1.4*(freq*freq),0.69);
+}
+
+
+
+
+
+
+/***********************************************************************
+ * compute bitsperframe and mean_bits for a layer III frame 
+ **********************************************************************/
+void getframebits(const lame_global_flags * gfp, int *bitsPerFrame, int *mean_bits) 
+{
+  lame_internal_flags *gfc=gfp->internal_flags;
+  int  whole_SpF;  /* integral number of Slots per Frame without padding */
+  int  bit_rate;
+  
+  /* get bitrate in kbps [?] */
+  if (gfc->bitrate_index) 
+    bit_rate = bitrate_table[gfp->version][gfc->bitrate_index];
+  else
+    bit_rate = gfp->brate;
+  assert ( bit_rate <= 550 );
+  
+  // bytes_per_frame = bitrate * 1000 / ( gfp->out_samplerate / (gfp->version == 1  ?  1152  :  576 )) / 8;
+  // bytes_per_frame = bitrate * 1000 / gfp->out_samplerate * (gfp->version == 1  ?  1152  :  576 ) / 8;
+  // bytes_per_frame = bitrate * ( gfp->version == 1  ?  1152/8*1000  :  576/8*1000 ) / gfp->out_samplerate;
+  
+  whole_SpF = (gfp->version+1)*72000*bit_rate / gfp->out_samplerate;
+  
+  /* main encoding routine toggles padding on and off */
+  /* one Layer3 Slot consists of 8 bits */
+  *bitsPerFrame = 8 * (whole_SpF + gfc->padding);
+  
+  // sideinfo_len
+  *mean_bits = (*bitsPerFrame - 8*gfc->sideinfo_len) / gfc->mode_gr;
+}
+
+
+
+
+#define ABS(A) (((A)>0) ? (A) : -(A))
+
+int FindNearestBitrate(
+int bRate,        /* legal rates from 32 to 448 */
+int version,      /* MPEG-1 or MPEG-2 LSF */
+int samplerate)   /* convert bitrate in kbps to index */
+{
+    int  bitrate = 0;
+    int  i;
+  
+    for ( i = 1; i <= 14; i++ )
+        if ( ABS (bitrate_table[version][i] - bRate) < ABS (bitrate - bRate) )
+            bitrate = bitrate_table [version] [i];
+           
+    return bitrate;
+}
+
+
+/* map frequency to a valid MP3 sample frequency
+ *
+ * Robert.Hegemann@gmx.de 2000-07-01
+ */
+int map2MP3Frequency(int freq)
+{
+    if (freq <=  8000) return  8000;
+    if (freq <= 11025) return 11025;
+    if (freq <= 12000) return 12000;
+    if (freq <= 16000) return 16000;
+    if (freq <= 22050) return 22050;
+    if (freq <= 24000) return 24000;
+    if (freq <= 32000) return 32000;
+    if (freq <= 44100) return 44100;
+    
+    return 48000;
+}
+
+int BitrateIndex(
+int bRate,        /* legal rates from 32 to 448 kbps */
+int version,      /* MPEG-1 or MPEG-2/2.5 LSF */
+int samplerate)   /* convert bitrate in kbps to index */
+{
+    int  i;
+
+    for ( i = 0; i <= 14; i++)
+        if ( bitrate_table [version] [i] == bRate )
+            return i;
+           
+    return -1;
+}
+
+/* convert samp freq in Hz to index */
+
+int SmpFrqIndex ( int sample_freq, int* const version )
+{
+    switch ( sample_freq ) {
+    case 44100: *version = 1; return  0;
+    case 48000: *version = 1; return  1;
+    case 32000: *version = 1; return  2;
+    case 22050: *version = 0; return  0;
+    case 24000: *version = 0; return  1;
+    case 16000: *version = 0; return  2;
+    case 11025: *version = 0; return  0;
+    case 12000: *version = 0; return  1;
+    case  8000: *version = 0; return  2;
+    default:    *version = 0; return -1;
+    }
+}
+
+
+/*****************************************************************************
+*
+*  End of bit_stream.c package
+*
+*****************************************************************************/
+
+/* reorder the three short blocks By Takehiro TOMINAGA */
+/*
+  Within each scalefactor band, data is given for successive
+  time windows, beginning with window 0 and ending with window 2.
+  Within each window, the quantized values are then arranged in
+  order of increasing frequency...
+*/
+void freorder(int scalefac_band[],FLOAT8 ix_orig[576]) {
+  int i,sfb, window, j=0;
+  FLOAT8 ix[576];
+  for (sfb = 0; sfb < SBMAX_s; sfb++) {
+    int start = scalefac_band[sfb];
+    int end   = scalefac_band[sfb + 1];
+    for (window = 0; window < 3; window++) {
+      for (i = start; i < end; ++i) {
+       ix[j++] = ix_orig[3*i+window];
+      }
+    }
+  }
+  memcpy(ix_orig,ix,576*sizeof(FLOAT8));
+}
+
+
+
+
+
+
+
+#ifndef KLEMM_44
+
+
+/* resampling via FIR filter, blackman window */
+inline static FLOAT8 blackman(FLOAT8 x,FLOAT8 fcn,int l)
+{
+  /* This algorithm from:
+SIGNAL PROCESSING ALGORITHMS IN FORTRAN AND C
+S.D. Stearns and R.A. David, Prentice-Hall, 1992
+  */
+  FLOAT8 bkwn,x2;
+  FLOAT8 wcn = (PI * fcn);
+  
+  x /= l;
+  if (x<0) x=0;
+  if (x>1) x=1;
+  x2 = x - .5;
+
+  bkwn = 0.42 - 0.5*cos(2*x*PI)  + 0.08*cos(4*x*PI);
+  if (fabs(x2)<1e-9) return wcn/PI;
+  else 
+    return  (  bkwn*sin(l*wcn*x2)  / (PI*l*x2)  );
+
+
+}
+
+/* gcd - greatest common divisor */
+/* Joint work of Euclid and M. Hendry */
+
+int gcd ( int i, int j )
+{
+//    assert ( i > 0  &&  j > 0 );
+    return j ? gcd(j, i % j) : i;
+}
+
+
+
+/* copy in new samples from in_buffer into mfbuf, with resampling & scaling 
+   if necessary.  n_in = number of samples from the input buffer that
+   were used.  n_out = number of samples copied into mfbuf  */
+
+void fill_buffer(lame_global_flags *gfp,
+                sample_t *mfbuf[2],
+                sample_t *in_buffer[2],
+                int nsamples, int *n_in, int *n_out)
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    int ch,i;
+
+    /* copy in new samples into mfbuf, with resampling if necessary */
+    if (gfc->resample_ratio != 1.0) {
+       for (ch = 0; ch < gfc->channels_out; ch++) {
+           *n_out =
+               fill_buffer_resample(gfp, &mfbuf[ch][gfc->mf_size],
+                                    gfp->framesize, in_buffer[ch],
+                                    nsamples, n_in, ch);
+       }
+    }
+    else {
+       *n_out = Min(gfp->framesize, nsamples);
+       *n_in = *n_out;
+       for (i = 0; i < *n_out; ++i) {
+           mfbuf[0][gfc->mf_size + i] = in_buffer[0][i];
+           if (gfc->channels_out == 2)
+               mfbuf[1][gfc->mf_size + i] = in_buffer[1][i];
+       }
+    }
+
+    /* user selected scaling of the samples */
+    if (gfp->scale != 0 && gfp->scale != 1.0) {
+       for (i=0 ; i<*n_out; ++i) {
+           mfbuf[0][gfc->mf_size+i] *= gfp->scale;
+           if (gfc->channels_out == 2)
+               mfbuf[1][gfc->mf_size + i] *= gfp->scale;
+       }
+    }
+
+    /* user selected scaling of the channel 0 (left) samples */
+    if (gfp->scale_left != 0 && gfp->scale_left != 1.0) {
+       for (i=0 ; i<*n_out; ++i) {
+           mfbuf[0][gfc->mf_size+i] *= gfp->scale_left;
+       }
+    }
+
+    /* user selected scaling of the channel 1 (right) samples */
+    if (gfc->channels_out == 2) {
+       if (gfp->scale_right != 0 && gfp->scale_right != 1.0) {
+           for (i=0 ; i<*n_out; ++i) {
+               mfbuf[1][gfc->mf_size + i] *= gfp->scale_right;
+           }
+       }
+    }
+}
+    
+
+
+
+int fill_buffer_resample(
+       lame_global_flags *gfp,
+       sample_t *outbuf,
+       int desired_len,
+       sample_t *inbuf,
+       int len,
+       int *num_used,
+       int ch) 
+{
+
+  
+  lame_internal_flags *gfc=gfp->internal_flags;
+  int BLACKSIZE;
+  FLOAT8 offset,xvalue;
+  int i,j=0,k;
+  int filter_l;
+  FLOAT8 fcn,intratio;
+  FLOAT *inbuf_old;
+  int bpc;   /* number of convolution functions to pre-compute */
+  bpc = gfp->out_samplerate/gcd(gfp->out_samplerate,gfp->in_samplerate);
+  if (bpc>BPC) bpc = BPC;
+
+  intratio=( fabs(gfc->resample_ratio - floor(.5+gfc->resample_ratio)) < .0001 );
+  fcn = 1.00/gfc->resample_ratio;
+  if (fcn>1.00) fcn=1.00;
+  filter_l = gfp->quality < 7 ? 31 : 7;
+  filter_l = 31;
+  if (0==filter_l % 2 ) --filter_l;/* must be odd */
+  filter_l += intratio;            /* unless resample_ratio=int, it must be even */
+
+
+  BLACKSIZE = filter_l+1;  /* size of data needed for FIR */
+  
+  if ( gfc->fill_buffer_resample_init == 0 ) {
+    gfc->inbuf_old[0]=calloc(BLACKSIZE,sizeof(gfc->inbuf_old[0][0]));
+    gfc->inbuf_old[1]=calloc(BLACKSIZE,sizeof(gfc->inbuf_old[0][0]));
+    for (i=0; i<=2*bpc; ++i)
+      gfc->blackfilt[i]=calloc(BLACKSIZE,sizeof(gfc->blackfilt[0][0]));
+
+    gfc->itime[0]=0;
+    gfc->itime[1]=0;
+
+    /* precompute blackman filter coefficients */
+    for ( j = 0; j <= 2*bpc; j++ ) {
+        FLOAT8 sum = 0.; 
+        offset = (j-bpc) / (2.*bpc);
+        for ( i = 0; i <= filter_l; i++ ) 
+            sum += 
+           gfc->blackfilt[j][i]  = blackman(i-offset,fcn,filter_l);
+       for ( i = 0; i <= filter_l; i++ ) 
+         gfc->blackfilt[j][i] /= sum;
+    }
+    gfc->fill_buffer_resample_init = 1;
+  }
+  
+  inbuf_old=gfc->inbuf_old[ch];
+
+  /* time of j'th element in inbuf = itime + j/ifreq; */
+  /* time of k'th element in outbuf   =  j/ofreq */
+  for (k=0;k<desired_len;k++) {
+    FLOAT8 time0;
+    int joff;
+
+    time0 = k*gfc->resample_ratio;       /* time of k'th output sample */
+    j = floor( time0 -gfc->itime[ch]  );
+
+    /* check if we need more input data */
+    if ((filter_l + j - filter_l/2) >= len) break;
+
+    /* blackman filter.  by default, window centered at j+.5(filter_l%2) */
+    /* but we want a window centered at time0.   */
+    offset = ( time0 -gfc->itime[ch] - (j + .5*(filter_l%2)));
+    assert(fabs(offset)<=.501);
+
+    /* find the closest precomputed window for this offset: */
+    joff = floor((offset*2*bpc) + bpc +.5);
+
+    xvalue = 0.;
+    for (i=0 ; i<=filter_l ; ++i) {
+      int j2 = i+j-filter_l/2;
+      int y;
+      assert(j2<len);
+      assert(j2+BLACKSIZE >= 0);
+      y = (j2<0) ? inbuf_old[BLACKSIZE+j2] : inbuf[j2];
+#define PRECOMPUTE
+#ifdef PRECOMPUTE
+      xvalue += y*gfc->blackfilt[joff][i];
+#else
+      xvalue += y*blackman(i-offset,fcn,filter_l);  /* very slow! */
+#endif
+    }
+    outbuf[k]=xvalue;
+  }
+
+  
+  /* k = number of samples added to outbuf */
+  /* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2]  */
+
+  /* how many samples of input data were used:  */
+  *num_used = Min(len,filter_l+j-filter_l/2);
+
+  /* adjust our input time counter.  Incriment by the number of samples used,
+   * then normalize so that next output sample is at time 0, next
+   * input buffer is at time itime[ch] */
+  gfc->itime[ch] += *num_used - k*gfc->resample_ratio;
+
+  /* save the last BLACKSIZE samples into the inbuf_old buffer */
+  if (*num_used >= BLACKSIZE) {
+      for (i=0;i<BLACKSIZE;i++)
+         inbuf_old[i]=inbuf[*num_used + i -BLACKSIZE];
+  }else{
+      /* shift in *num_used samples into inbuf_old  */
+       int n_shift = BLACKSIZE-*num_used;  /* number of samples to shift */
+
+       /* shift n_shift samples by *num_used, to make room for the
+       * num_used new samples */
+       for (i=0; i<n_shift; ++i ) 
+          inbuf_old[i] = inbuf_old[i+ *num_used];
+
+       /* shift in the *num_used samples */
+       for (j=0; i<BLACKSIZE; ++i, ++j ) 
+          inbuf_old[i] = inbuf[j];
+
+       assert(j==*num_used);
+  }
+  return k;  /* return the number samples created at the new samplerate */
+}
+
+
+#endif /* ndef KLEMM_44 */
+
+
+
+/***********************************************************************
+*
+*  Message Output
+*
+***********************************************************************/
+void  lame_debugf (const lame_internal_flags *gfc, const char* format, ... )
+{
+    va_list  args;
+
+    va_start ( args, format );
+
+    if ( gfc->report.debugf != NULL ) {
+        gfc->report.debugf( format, args );
+    } else {
+        (void) vfprintf ( stderr, format, args );
+        fflush ( stderr );      /* an debug function should flush immediately */
+    }
+
+    va_end   ( args );
+}
+
+
+void  lame_msgf (const lame_internal_flags *gfc, const char* format, ... )
+{
+    va_list  args;
+
+    va_start ( args, format );
+   
+    if ( gfc->report.msgf != NULL ) {
+        gfc->report.msgf( format, args );
+    } else {
+        (void) vfprintf ( stderr, format, args );
+        fflush ( stderr );     /* we print to stderr, so me may want to flush */
+    }
+
+    va_end   ( args );
+}
+
+
+void  lame_errorf (const lame_internal_flags *gfc, const char* format, ... )
+{
+    va_list  args;
+
+    va_start ( args, format );
+    
+    if ( gfc->report.errorf != NULL ) {
+        gfc->report.errorf( format, args );
+    } else {
+        (void) vfprintf ( stderr, format, args );
+        fflush   ( stderr );    /* an error function should flush immediately */
+    }
+
+    va_end   ( args );
+}
+
+
+
+/***********************************************************************
+ *
+ *      routines to detect CPU specific features like 3DNow, MMX, SIMD
+ *
+ *  donated by Frank Klemm
+ *  added Robert Hegemann 2000-10-10
+ *
+ ***********************************************************************/
+
+int  has_i387 ( void )
+{
+#ifdef HAVE_NASM 
+    return 1;
+#else
+    return 0;   /* don't know, assume not */
+#endif
+}    
+
+int  has_MMX ( void )
+{
+#ifdef HAVE_NASM 
+    extern int has_MMX_nasm ( void );
+    return has_MMX_nasm ();
+#else
+    return 0;   /* don't know, assume not */
+#endif
+}    
+
+int  has_3DNow ( void )
+{
+#ifdef HAVE_NASM 
+    extern int has_3DNow_nasm ( void );
+    return has_3DNow_nasm ();
+#else
+    return 0;   /* don't know, assume not */
+#endif
+}    
+
+int  has_SIMD ( void )
+{
+#ifdef HAVE_NASM 
+    extern int has_SIMD_nasm ( void );
+    return has_SIMD_nasm ();
+#else
+    return 0;   /* don't know, assume not */
+#endif
+}    
+
+int  has_SIMD2 ( void )
+{
+#ifdef HAVE_NASM 
+    extern int has_SIMD2_nasm ( void );
+    return has_SIMD2_nasm ();
+#else
+    return 0;   /* don't know, assume not */
+#endif
+}    
+
+/***********************************************************************
+ *
+ *  some simple statistics
+ *
+ *  bitrate index 0: free bitrate -> not allowed in VBR mode
+ *  : bitrates, kbps depending on MPEG version
+ *  bitrate index 15: forbidden
+ *
+ *  mode_ext:
+ *  0:  LR
+ *  1:  LR-i
+ *  2:  MS
+ *  3:  MS-i
+ *
+ ***********************************************************************/
+void updateStats( lame_internal_flags * const gfc )
+{
+    assert ( gfc->bitrate_index < 16u );
+    assert ( gfc->mode_ext      <  4u );
+    
+    /* count bitrate indices */
+    gfc->bitrate_stereoMode_Hist [gfc->bitrate_index] [4] ++;
+    
+    /* count 'em for every mode extension in case of 2 channel encoding */
+    if (gfc->channels_out == 2)
+        gfc->bitrate_stereoMode_Hist [gfc->bitrate_index] [gfc->mode_ext]++;
+}
+
+
+
+/*  caution: a[] will be resorted!!
+ */
+int select_kth_int(int a[], int N, int k)
+{
+    int i, j, l, r, v, w;
+    
+    l = 0;
+    r = N-1;
+    while (r > l) {
+        v = a[r];
+        i = l-1;
+        j = r;
+        for (;;) {
+            while (a[++i] < v) /*empty*/;
+            while (a[--j] > v) /*empty*/;
+            if (i >= j) 
+                break;
+            /* swap i and j */
+            w = a[i];
+            a[i] = a[j];
+            a[j] = w;
+        }
+        /* swap i and r */
+        w = a[i];
+        a[i] = a[r];
+        a[r] = w;
+        if (i >= k) 
+            r = i-1;
+        if (i <= k) 
+            l = i+1;
+    }
+    return a[k];
+}
+
+
+
+void disable_FPE(void) {
+/* extremly system dependent stuff, move to a lib to make the code readable */
+/*==========================================================================*/
+
+
+
+    /*
+     *  Disable floating point exceptions
+     */
+
+
+
+
+#if defined(__FreeBSD__) && !defined(__alpha__)
+    {
+        /* seet floating point mask to the Linux default */
+        fp_except_t mask;
+        mask = fpgetmask();
+        /* if bit is set, we get SIGFPE on that error! */
+        fpsetmask(mask & ~(FP_X_INV | FP_X_DZ));
+        /*  DEBUGF("FreeBSD mask is 0x%x\n",mask); */
+    }
+#endif
+
+#if defined(__riscos__) && !defined(ABORTFP)
+    /* Disable FPE's under RISC OS */
+    /* if bit is set, we disable trapping that error! */
+    /*   _FPE_IVO : invalid operation */
+    /*   _FPE_DVZ : divide by zero */
+    /*   _FPE_OFL : overflow */
+    /*   _FPE_UFL : underflow */
+    /*   _FPE_INX : inexact */
+    DisableFPETraps(_FPE_IVO | _FPE_DVZ | _FPE_OFL);
+#endif
+
+    /*
+     *  Debugging stuff
+     *  The default is to ignore FPE's, unless compiled with -DABORTFP
+     *  so add code below to ENABLE FPE's.
+     */
+
+#if defined(ABORTFP)
+#if defined(_MSC_VER)
+    {
+
+   /* set affinity to a single CPU.  Fix for EAC/lame on SMP systems from
+     "Todd Richmond" <todd.richmond@openwave.com> */
+    SYSTEM_INFO si;
+    GetSystemInfo(&si);
+    SetProcessAffinityMask(GetCurrentProcess(), si.dwActiveProcessorMask);
+
+#include <float.h>
+        unsigned int mask;
+        mask = _controlfp(0, 0);
+        mask &= ~(_EM_OVERFLOW | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_INVALID);
+        mask = _controlfp(mask, _MCW_EM);
+    }
+#elif defined(__CYGWIN__)
+#  define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
+#  define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
+
+#  define _EM_INEXACT     0x00000020 /* inexact (precision) */
+#  define _EM_UNDERFLOW   0x00000010 /* underflow */
+#  define _EM_OVERFLOW    0x00000008 /* overflow */
+#  define _EM_ZERODIVIDE  0x00000004 /* zero divide */
+#  define _EM_INVALID     0x00000001 /* invalid */
+    {
+        unsigned int mask;
+        _FPU_GETCW(mask);
+        /* Set the FPU control word to abort on most FPEs */
+        mask &= ~(_EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID);
+        _FPU_SETCW(mask);
+    }
+# elif defined(__linux__)
+    {
+
+#  include <fpu_control.h>
+#  ifndef _FPU_GETCW
+#  define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
+#  endif
+#  ifndef _FPU_SETCW
+#  define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
+#  endif
+
+        /* 
+         * Set the Linux mask to abort on most FPE's
+         * if bit is set, we _mask_ SIGFPE on that error!
+         *  mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM );
+         */
+
+        unsigned int mask;
+        _FPU_GETCW(mask);
+        mask &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
+        _FPU_SETCW(mask);
+    }
+#endif
+#endif /* ABORTFP */
+}
+
+
+/* end of util.c */
diff --git a/lib/lame/util.h b/lib/lame/util.h
new file mode 100644 (file)
index 0000000..a042409
--- /dev/null
@@ -0,0 +1,615 @@
+/*
+ *     lame utility library include file
+ *
+ *     Copyright (c) 1999 Albert L Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_UTIL_H
+#define LAME_UTIL_H
+
+/***********************************************************************
+*
+*  Global Include Files
+*
+***********************************************************************/
+#include "machine.h"
+#include "encoder.h"
+#include "lame.h"
+#include "lame_global_flags.h"
+#include "lame-analysis.h"
+#include "id3tag.h"
+
+/***********************************************************************
+*
+*  Global Definitions
+*
+***********************************************************************/
+
+#ifndef FALSE
+#define         FALSE                   0
+#endif
+
+#ifndef TRUE
+#define         TRUE                    (!FALSE)
+#endif
+
+#ifdef UINT_MAX
+# define         MAX_U_32_NUM            UINT_MAX
+#else
+# define         MAX_U_32_NUM            0xFFFFFFFF
+#endif
+
+#ifndef PI
+# ifdef M_PI
+#  define       PI                      M_PI
+# else
+#  define       PI                      3.14159265358979323846
+# endif
+#endif
+
+
+#ifdef M_LN2
+# define        LOG2                    M_LN2
+#else
+# define        LOG2                    0.69314718055994530942
+#endif
+
+#ifdef M_LN10
+# define        LOG10                   M_LN10
+#else
+# define        LOG10                   2.30258509299404568402
+#endif
+
+
+#ifdef M_SQRT2
+# define        SQRT2                   M_SQRT2
+#else
+# define        SQRT2                   1.41421356237309504880
+#endif
+
+
+#define         HAN_SIZE                512
+#define         CRC16_POLYNOMIAL        0x8005
+#define MAX_BITS 4095
+
+/* "bit_stream.h" Definitions */
+#define         BUFFER_SIZE     LAME_MAXMP3BUFFER 
+
+#define         Min(A, B)       ((A) < (B) ? (A) : (B))
+#define         Max(A, B)       ((A) > (B) ? (A) : (B))
+
+
+
+
+
+/***********************************************************************
+*
+*  Global Type Definitions
+*
+***********************************************************************/
+
+
+
+/* "bit_stream.h" Type Definitions */
+
+typedef struct  bit_stream_struc {
+    unsigned char *buf;         /* bit stream buffer */
+    int         buf_size;       /* size of buffer (in number of bytes) */
+    int         totbit;         /* bit counter of bit stream */
+    int         buf_byte_idx;   /* pointer to top byte in buffer */
+    int         buf_bit_idx;    /* pointer to top bit of top byte in buffer */
+    
+    /* format of file in rd mode (BINARY/ASCII) */
+} Bit_stream_struc;
+
+#include "l3side.h"
+
+
+/* variables used for --nspsytune */
+typedef struct {
+  int   use; /* indicates the use of exp_nspsytune */
+  int   safejoint; /* safe joint stereo mode */
+  FLOAT last_en_subshort[4][9];
+  FLOAT last_attack_intensity[4][9];
+  FLOAT        last_thm[4][SBMAX_s][3];
+  int   last_attacks[4][3];
+  FLOAT pe_l[4],pe_s[4];
+  FLOAT pefirbuf[19];
+  FLOAT bass,alto,treble,sfb21;
+} nsPsy_t;
+
+/* variables used for --alt-preset */
+typedef struct {
+
+  // indicates the use of alt-preset
+  int     use;
+
+  // short block tuning
+  int     attackthre;
+  int     attackthre_s;
+
+  // adjustment to joint stereo
+  FLOAT8  ms_maskadjust;
+
+  // adjustments to quantization selection
+  int     quantcomp_current;          // current quant_compare mode we are using
+  FLOAT8  quantcomp_adjust_rh_tot;    // adjustments for tot_noise with vbr-old
+  FLOAT8  quantcomp_adjust_rh_max;    // adjustments for max_noise with vbr-old
+  FLOAT8  quantcomp_adjust_mtrh;      // adjustments for calc_scalefac "c" with vbr-mtrh
+  int     quantcomp_type_s;           // quantization comparison to switch to on non-normal blocks
+  int     quantcomp_alt_type;          // third quantization comparison to use for special cases
+                                       // such as high athadjust values, or long blocks, etc
+
+  // tunings reliant upon athadjust
+  FLOAT8  athadjust_max_val;           // maximum value of athadjust before limit is applied
+  FLOAT8  athadjust_switch_level;      // level of athadjust at which to apply tunings at
+                                       // x <= 0 == never switch, x >= 1 == always switch
+  FLOAT8  athadjust_msfix;             // msfix adjustment based on athadjust
+  int     athadjust_safe_noiseshaping; // if 0, noise shaping 2 will not be used no matter what
+                                       // the noise shaping type would normally be set to
+  FLOAT8  athadjust_safe_noiseshaping_thre; // value which max_pow_alt must be greater than
+                                            // for noise shaping 2 to be used "safely"                                                     
+  FLOAT8  athadjust_safe_athaasensitivity; // used for second determination if it is safe to switch
+                                             // to noise shaping 2
+} presetTune_t;
+
+typedef struct 
+{
+    int sum;    // what we have seen so far
+    int seen;   // how many frames we have seen in this chunk
+    int want;   // how many frames we want to collect into one chunk
+    int pos;    // actual position in our bag
+    int size;   // size of our bag
+    int *bag;   // pointer to our bag
+} VBR_seek_info_t;
+
+
+/**
+ *  ATH related stuff, if something new ATH related has to be added,
+ *  please plugg it here into the ATH_t struct
+ */
+typedef struct
+{
+    int     use_adjust;     // method for the auto adjustment 
+    FLOAT8  adjust;         // lowering based on peak volume, 1 = no lowering
+    FLOAT8  adjust_limit;   // limit for dynamic ATH adjust
+    FLOAT8  decay;          // determined to lower x dB each second
+    FLOAT8  floor;          // lowest ATH value
+    FLOAT8  l[SBMAX_l];     // ATH for sfbs in long blocks
+    FLOAT8  s[SBMAX_s];     // ATH for sfbs in short blocks
+    FLOAT8  cb[CBANDS];     // ATH for convolution bands
+} ATH_t;
+
+/**
+ *  VBR related stuff
+ */
+typedef struct
+{
+    int     quality;
+    FLOAT8  mask_adjust;    // the dbQ stuff
+    int     smooth;         // 0=no, 1=peaks, 2=+-4
+    int     bitpressure;    // strategy for bitpressure situations
+    FLOAT8  scratch[192];
+} VBR_t;
+
+/**
+ *  PSY Model related stuff
+ */
+typedef struct
+{
+    int     tonalityPatch;      // temporaly needed by VBR
+    FLOAT   cwlimit;
+    FLOAT8  prvTonRed[CBANDS];
+} PSY_t; 
+
+
+/* Guest structure, only temporarly here */
+
+typedef enum {
+    coding_MPEG_Layer_1 = 1,
+    coding_MPEG_Layer_2 = 2,
+    coding_MPEG_Layer_3 = 3,
+    coding_MPEG_AAC     = 4,
+    coding_Ogg_Vorbis   = 5,
+    coding_MPEG_plus    = 6
+} coding_t;
+
+#define MAX_CHANNELS  2
+
+typedef struct {
+    unsigned long  Class_ID;        /* Class ID to recognize a resample_t
+                                       object */
+    FLOAT8   sample_freq_in;  /* Input sample frequency in Hz */
+    FLOAT8   sample_freq_out; /* requested Output sample frequency in Hz */
+    FLOAT8   lowpass_freq;    /* lowpass frequency, this is the -6 dB
+                                       point */
+    int            scale_in;        /* the resampling is actually done by
+                                       scale_out: */
+    int            scale_out;       /* frequency is
+                                         samplefreq_in * scale_out / scal */
+    int            taps;            /* number of taps for every FIR resample
+                                       filter */
+
+    sample_t**     fir;             /* the FIR resample filters:
+                                         fir [scale_out] [taps */
+    void*          firfree;         /* start address of the alloced memory for
+                                       fir, */
+    unsigned char* src_step;
+    sample_t*      in_old       [MAX_CHANNELS];
+    //    uint64_t       sample_count [MAX_CHANNELS];
+    unsigned       fir_stepper  [MAX_CHANNELS];
+    int            inp_stepper  [MAX_CHANNELS];
+
+} resample_t;
+
+
+struct lame_internal_flags {
+
+  /********************************************************************
+   * internal variables NOT set by calling program, and should not be *
+   * modified by the calling program                                  *
+   ********************************************************************/
+  
+  /*  
+   * Some remarks to the Class_ID field:
+   * The Class ID is an Identifier for a pointer to this struct.
+   * It is very unlikely that a pointer to lame_global_flags has the same 32 bits 
+   * in it's structure (large and other special properties, for instance prime).
+   *
+   * To test that the structure is right and initialized, use:
+   *     if ( gfc -> Class_ID == LAME_ID ) ...
+   * Other remark:
+   *     If you set a flag to 0 for uninit data and 1 for init data, the right test
+   *     should be "if (flag == 1)" and NOT "if (flag)". Unintended modification
+   *     of this element will be otherwise misinterpreted as an init.
+   */
+  
+  #define  LAME_ID   0xFFF88E3B
+  unsigned long Class_ID;
+
+  struct {
+    void (*msgf)  (const char *format, va_list ap);
+    void (*debugf)(const char *format, va_list ap);
+    void (*errorf)(const char *format, va_list ap);
+  } report;
+  
+  int lame_encode_frame_init;     
+  int iteration_init_init;
+  int fill_buffer_resample_init;
+  int psymodel_init;
+
+  int padding;                  /* padding for the current frame? */
+  int mode_gr;                    /* granules per frame */
+  int          channels_in;    /* number of channels in the input data stream (PCM or decoded PCM) */
+  int          channels_out;  /* number of channels in the output data stream (not used for decoding) */
+  resample_t*  resample_in;   /* context for coding (PCM=>MP3) resampling */
+  resample_t*  resample_out;   /* context for decoding (MP3=>PCM) resampling */
+  FLOAT8  samplefreq_in;
+  FLOAT8  samplefreq_out;
+  uint16_t nMusicCRC;
+
+#ifndef  MFSIZE
+# define MFSIZE  ( 3*1152 + ENCDELAY - MDCTDELAY )
+#endif
+#ifdef  KLEMM_44
+  sample_t*    mfbuf [MAX_CHANNELS];
+#else
+  sample_t     mfbuf [2] [MFSIZE];
+#endif
+  size_t       frame_size;    /* size of one frame in samples per channel */
+  lame_global_flags* gfp;     /* needed as long as the frame encoding functions must access gfp (all needed information can be added to gfc) */
+  coding_t     coding;        /* MPEG Layer 1/2/3, Ogg Vorbis, MPEG AAC, ... */
+  unsigned long frame_count;  /* Number of frames coded, 2^32 > 3 years */
+  int          mf_samples_to_encode;
+  int          mf_size;
+  FLOAT8       ampl;     /* amplification at the end of the current chunk (1. = 0 dB) */
+  FLOAT8       last_ampl;        /* amplification at the end of the last chunk    (1. = 0 dB) */
+  int VBR_min_bitrate;            /* min bitrate index */
+  int VBR_max_bitrate;            /* max bitrate index */
+  FLOAT resample_ratio;           /* input_samp_rate/output_samp_rate */
+  int bitrate_index;
+  int samplerate_index;
+  int mode_ext;
+
+
+  /* lowpass and highpass filter control */
+  FLOAT8 lowpass1,lowpass2;        /* normalized frequency bounds of passband */
+  FLOAT8 highpass1,highpass2;      /* normalized frequency bounds of passband */
+                                  
+  /* polyphase filter (filter_type=0)  */
+  int lowpass_band;          /* zero bands >= lowpass_band in the polyphase filterbank */
+  int highpass_band;         /* zero bands <= highpass_band */
+  int lowpass_start_band;    /* amplify bands between start */
+  int lowpass_end_band;      /* and end for lowpass */
+  int highpass_start_band;   /* amplify bands between start */
+  int highpass_end_band;     /* and end for highpass */
+
+
+  int filter_type;          /* 0=polyphase filter, 1= FIR filter 2=MDCT filter(bad)*/
+  int quantization;         /* 0 = ISO formual,  1=best amplitude */
+  int noise_shaping;        /* 0 = none 
+                               1 = ISO AAC model
+                               2 = allow scalefac_select=1  
+                             */
+
+  int noise_shaping_amp;    /*  0 = ISO model: amplify all distorted bands
+                                1 = amplify within 50% of max (on db scale)
+                                2 = amplify only most distorted band
+                                3 = amplify only most distorted band and
+                                   use pseudo half step
+                            */
+
+  int psymodel;             /* 1 = gpsycho. 0 = none */
+  int noise_shaping_stop;   /* 0 = stop at over=0, all scalefacs amplified or
+                                   a scalefac has reached max value
+                               1 = stop when all scalefacs amplified or        
+                                   a scalefac has reached max value
+                               2 = stop when all scalefacs amplified 
+                           */
+
+  int use_best_huffman;     /* 0 = no.  1=outside loop  2=inside loop(slow) */
+
+
+
+
+  /* variables used by lame.c */
+  Bit_stream_struc   bs;
+  III_side_info_t l3_side;
+  FLOAT8 ms_ratio[2];
+  /* used for padding */
+  int frac_SpF;
+  int slot_lag;
+
+
+  /* optional ID3 tags, used in id3tag.c  */
+  struct id3tag_spec tag_spec;
+
+
+  /* variables used by quantize.c */
+  int OldValue[2];
+  int CurrentStep;
+  FLOAT8 decay;
+  FLOAT8 masking_lower;
+
+  char bv_scf[576];
+  
+  int sfb21_extra; /* will be set in lame_init_params */
+  
+  int is_mpeg1; /* 1 for MPEG-1, 0 for MPEG-2(.5) */
+
+#ifndef KLEMM_44
+  /* variables used by util.c */
+  /* BPC = maximum number of filter convolution windows to precompute */
+#define BPC 320
+  sample_t *inbuf_old [2];
+  sample_t *blackfilt [2*BPC+1];
+  FLOAT8 itime[2];
+#endif
+  int sideinfo_len;
+
+  /* variables for newmdct.c */
+  FLOAT8 sb_sample[2][2][18][SBLIMIT];
+  FLOAT8 amp_lowpass[32];
+  FLOAT8 amp_highpass[32];
+
+  /* variables for bitstream.c */
+  /* mpeg1: buffer=511 bytes  smallest frame: 96-38(sideinfo)=58
+   * max number of frames in reservoir:  8 
+   * mpeg2: buffer=255 bytes.  smallest frame: 24-23bytes=1
+   * with VBR, if you are encoding all silence, it is possible to
+   * have 8kbs/24khz frames with 1byte of data each, which means we need
+   * to buffer up to 255 headers! */
+  /* also, max_header_buf has to be a power of two */
+#define MAX_HEADER_BUF 256
+#define MAX_HEADER_LEN 40 /* max size of header is 38 */
+  struct {
+    int write_timing;
+    int ptr;
+    char buf[MAX_HEADER_LEN];
+  } header[MAX_HEADER_BUF];
+
+  int h_ptr;
+  int w_ptr;
+  int ancillary_flag;
+  
+
+  /* variables for reservoir.c */
+  int ResvSize; /* in bits */
+  int ResvMax;  /* in bits */
+
+  
+  scalefac_struct scalefac_band;
+
+  /* DATA FROM PSYMODEL.C */
+/* The static variables "r", "phi_sav", "new", "old" and "oldest" have    */
+/* to be remembered for the unpredictability measure.  For "r" and        */
+/* "phi_sav", the first index from the left is the channel select and     */
+/* the second index is the "age" of the data.                             */
+  FLOAT8       minval[CBANDS];
+  FLOAT8       nb_1[4][CBANDS], nb_2[4][CBANDS];
+  FLOAT8       nb_s1[4][CBANDS], nb_s2[4][CBANDS];
+  FLOAT8  *s3_ss;
+  FLOAT8  *s3_ll;
+
+  III_psy_xmin thm[4];
+  III_psy_xmin en[4];
+  
+  /* unpredictability calculation
+   */
+  int cw_upper_index;
+  int cw_lower_index;
+  FLOAT ax_sav[4][2][HBLKSIZE];
+  FLOAT bx_sav[4][2][HBLKSIZE];
+  FLOAT rx_sav[4][2][HBLKSIZE];
+  FLOAT cw[HBLKSIZE];
+
+  /* fft and energy calculation    */
+  FLOAT wsamp_L[2][BLKSIZE];
+  FLOAT energy[HBLKSIZE];
+  FLOAT wsamp_S[2][3][BLKSIZE_s];
+  FLOAT energy_s[3][HBLKSIZE_s];
+  FLOAT tot_ener[4];
+
+
+  /* loudness calculation (for adaptive threshold of hearing) */
+  FLOAT loudness_sq[2][2];  /* loudness^2 approx. per granule and channel */
+  FLOAT loudness_sq_save[2];/* account for granule delay of L3psycho_anal */
+
+  /* factor for tuning the (sample power) point below which adaptive threshold
+     of hearing adjustment occurs 
+   */
+  FLOAT athaa_sensitivity_p;
+
+  /* fft.c    */
+  FLOAT window[BLKSIZE], window_s[BLKSIZE_s/2];
+  
+  
+  /* Scale Factor Bands    */
+  III_scalefac_t pseudohalf;
+  FLOAT8       w1_l[SBMAX_l], w2_l[SBMAX_l];
+  FLOAT8       w1_s[SBMAX_s], w2_s[SBMAX_s];
+  FLOAT8 mld_l[SBMAX_l],mld_s[SBMAX_s];
+  int  bu_l[SBMAX_l],bo_l[SBMAX_l] ;
+  int  bu_s[SBMAX_s],bo_s[SBMAX_s] ;
+  int  npart_l,npart_s;
+  int  npart_l_orig,npart_s_orig;
+  
+  int  s3ind[CBANDS][2];
+  int  s3ind_s[CBANDS][2];
+  FLOAT8 SNR_s[CBANDS];
+
+  int  numlines_s[CBANDS];
+  int  numlines_l[CBANDS];
+  
+  
+  /* frame analyzer    */
+  FLOAT energy_save[4][HBLKSIZE];
+  FLOAT8 pe_save[4];
+  FLOAT8 ers_save[4];
+  
+  /* simple statistics */
+  int   bitrate_stereoMode_Hist [16] [4+1];
+
+  /* ratios  */
+  FLOAT8 pe[4];
+  FLOAT8 ms_ratio_s_old,ms_ratio_l_old;
+  FLOAT8 ms_ener_ratio_old;
+
+  /* block type */
+  int  blocktype_old[2];
+
+  /* used by the frame analyzer */
+  plotting_data *pinfo;
+
+  /* CPU features */
+  struct {
+    unsigned int  i387      : 1; /* FPU is a normal Intel CPU */
+    unsigned int  MMX       : 1; /* Pentium MMX, Pentium II...IV, K6, K6-2,
+                                    K6-III, Athlon */
+    unsigned int  AMD_3DNow : 1; /* K6-2, K6-III, Athlon      */
+    unsigned int  SIMD      : 1; /* Pentium III, Pentium 4    */
+    unsigned int  SIMD2     : 1; /* Pentium 4, K8             */
+  } CPU_features;
+   
+  /* functions to replace with CPU feature optimized versions in takehiro.c */
+  int (*choose_table)(const int *ix, const int *end, int *s);
+  
+  void (*fft_fht)(FLOAT *, int);
+
+  nsPsy_t nsPsy;  /* variables used for --nspsytune */
+  presetTune_t presetTune;  /* variables used for --alt-preset */
+  
+  unsigned crcvalue;
+  
+  VBR_seek_info_t VBR_seek_table; // used for Xing VBR header
+  
+  ATH_t *ATH;   // all ATH related stuff
+  VBR_t *VBR;
+  PSY_t *PSY;
+
+  int nogap_total;
+  int nogap_current;  
+};
+
+
+
+
+/***********************************************************************
+*
+*  Global Function Prototype Declarations
+*
+***********************************************************************/
+void                  freegfc(lame_internal_flags * const gfc);
+extern int            BitrateIndex(int, int,int);
+extern int            FindNearestBitrate(int,int,int);
+extern int            map2MP3Frequency(int freq);
+extern int            SmpFrqIndex(int, int* const);
+extern FLOAT8         ATHformula(FLOAT8 f,lame_global_flags *gfp);
+extern FLOAT8         freq2bark(FLOAT8 freq);
+extern FLOAT8         freq2cbw(FLOAT8 freq);
+extern void freorder(int scalefac_band[],FLOAT8 ix_orig[576]);
+void disable_FPE(void);
+
+extern void 
+getframebits( const lame_global_flags *gfp, int *bitsPerFrame, int *mean_bits);
+
+void fill_buffer(lame_global_flags *gfp,
+                sample_t *mfbuf[2],
+                sample_t *in_buffer[2],
+                int nsamples, int *n_in, int *n_out);
+
+int  fill_buffer_resample (
+        lame_global_flags *gfp,
+        sample_t*  outbuf,
+        int        desired_len,
+        sample_t*  inbuf,
+        int        len,
+        int*       num_used,
+        int        channels );
+
+
+extern int  has_i387  ( void );
+extern int  has_MMX   ( void );
+extern int  has_3DNow ( void );
+extern int  has_SIMD  ( void );
+extern int  has_SIMD2 ( void );
+
+extern void updateStats (lame_internal_flags * const gfc);
+
+
+
+/***********************************************************************
+*
+*  Macros about Message Printing and Exit
+*
+***********************************************************************/
+extern void lame_errorf(const lame_internal_flags *gfc, const char *, ...);
+extern void lame_debugf(const lame_internal_flags *gfc, const char *, ...);
+extern void lame_msgf  (const lame_internal_flags *gfc, const char *, ...);
+#define DEBUGF  lame_debugf
+#define ERRORF lame_errorf
+#define MSGF   lame_msgf
+
+
+int select_kth_int(int b[], int N, int k);
+
+
+
+#endif /* LAME_UTIL_H */
diff --git a/lib/lame/vbrquantize.c b/lib/lame/vbrquantize.c
new file mode 100644 (file)
index 0000000..8d96ab8
--- /dev/null
@@ -0,0 +1,1769 @@
+/*
+ *     MP3 quantization
+ *
+ *     Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: vbrquantize.c,v 1.1 2002/04/28 17:30:30 kramm Exp $ */
+
+#include "config_static.h"
+
+#include <assert.h>
+#include "util.h"
+#include "l3side.h"
+#include "reservoir.h"
+#include "quantize_pvt.h"
+#include "vbrquantize.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+
+
+typedef union {
+    float f;
+    int   i;
+} fi_union;
+
+#define MAGIC_FLOAT (65536*(128))
+#define MAGIC_INT    0x4b000000
+
+#ifdef TAKEHIRO_IEEE754_HACK
+
+#define DUFFBLOCKMQ() do { \
+        xp = xr34[0] * sfpow34_p1; \
+        xe = xr34[0] * sfpow34_eq; \
+        xm = xr34[0] * sfpow34_m1; \
+        if (xm > IXMAX_VAL)  \
+            return -1; \
+        xp += MAGIC_FLOAT; \
+        xe += MAGIC_FLOAT; \
+        xm += MAGIC_FLOAT; \
+        fi[0].f = xp; \
+        fi[1].f = xe; \
+        fi[2].f = xm; \
+        fi[0].f = xp + (adj43asm - MAGIC_INT)[fi[0].i]; \
+        fi[1].f = xe + (adj43asm - MAGIC_INT)[fi[1].i]; \
+        fi[2].f = xm + (adj43asm - MAGIC_INT)[fi[2].i]; \
+        fi[0].i -= MAGIC_INT; \
+        fi[1].i -= MAGIC_INT; \
+        fi[2].i -= MAGIC_INT; \
+        x0 = fabs(xr[0]); \
+        xp = x0 - pow43[fi[0].i] * sfpow_p1; \
+        xe = x0 - pow43[fi[1].i] * sfpow_eq; \
+        xm = x0 - pow43[fi[2].i] * sfpow_m1; \
+        xp *= xp; \
+        xe *= xe; \
+        xm *= xm; \
+        xfsf_eq = Max(xfsf_eq, xe); \
+        xfsf_p1 = Max(xfsf_p1, xp); \
+        xfsf_m1 = Max(xfsf_m1, xm); \
+        ++xr; \
+        ++xr34; \
+    } while(0)  
+
+#define DUFFBLOCK() do { \
+        xp = xr34[0] * sfpow34_p1; \
+        xe = xr34[0] * sfpow34_eq; \
+        xm = xr34[0] * sfpow34_m1; \
+        if (xm > IXMAX_VAL)  \
+            return -1; \
+        xp += MAGIC_FLOAT; \
+        xe += MAGIC_FLOAT; \
+        xm += MAGIC_FLOAT; \
+        fi[0].f = xp; \
+        fi[1].f = xe; \
+        fi[2].f = xm; \
+        fi[0].f = xp + (adj43asm - MAGIC_INT)[fi[0].i]; \
+        fi[1].f = xe + (adj43asm - MAGIC_INT)[fi[1].i]; \
+        fi[2].f = xm + (adj43asm - MAGIC_INT)[fi[2].i]; \
+        fi[0].i -= MAGIC_INT; \
+        fi[1].i -= MAGIC_INT; \
+        fi[2].i -= MAGIC_INT; \
+        x0 = fabs(xr[0]); \
+        xp = x0 - pow43[fi[0].i] * sfpow_p1; \
+        xe = x0 - pow43[fi[1].i] * sfpow_eq; \
+        xm = x0 - pow43[fi[2].i] * sfpow_m1; \
+        xfsf_p1 += xp * xp; \
+        xfsf_eq += xe * xe; \
+        xfsf_m1 += xm * xm; \
+        ++xr; \
+        ++xr34; \
+    } while(0)  
+
+#else
+
+/*********************************************************************
+ * XRPOW_FTOI is a macro to convert floats to ints.  
+ * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]
+ *                                         ROUNDFAC= -0.0946
+ *
+ * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]   
+ *                                   ROUNDFAC=0.4054
+ *********************************************************************/
+#  define QUANTFAC(rx)  adj43[rx]
+#  define ROUNDFAC 0.4054
+#  define XRPOW_FTOI(src,dest) ((dest) = (int)(src))
+
+
+#endif
+
+/*  caution: a[] will be resorted!!
+ */
+FLOAT8 select_kth(FLOAT8 a[], int N, int k)
+{
+    int i, j, l, r;
+    FLOAT8 v, w;
+    
+    l = 0;
+    r = N-1;
+    while (r > l) {
+        v = a[r];
+        i = l-1;
+        j = r;
+        for (;;) {
+            while (a[++i] < v) /*empty*/;
+            while (a[--j] > v) /*empty*/;
+            if (i >= j) 
+                break;
+            /* swap i and j */
+            w = a[i];
+            a[i] = a[j];
+            a[j] = w;
+        }
+        /* swap i and r */
+        w = a[i];
+        a[i] = a[r];
+        a[r] = w;
+        if (i >= k) 
+            r = i-1;
+        if (i <= k) 
+            l = i+1;
+    }
+    return a[k];
+}
+
+
+
+
+static FLOAT8
+calc_sfb_noise(const FLOAT8 *xr, const FLOAT8 *xr34, int bw, int sf)
+{
+    int j;
+    fi_union fi; 
+    FLOAT8 temp;
+    FLOAT8 xfsf = 0;
+    FLOAT8 sfpow, sfpow34;
+
+    sfpow   =  POW20(sf+210); /*pow(2.0,sf/4.0); */
+    sfpow34 = IPOW20(sf+210); /*pow(sfpow,-3.0/4.0);*/
+
+    for ( j = 0; j < bw ; ++j ) {
+        if ( xr34[j]*sfpow34 > IXMAX_VAL ) return -1;
+
+#ifdef TAKEHIRO_IEEE754_HACK
+        temp   = sfpow34*xr34[j];
+        temp  += MAGIC_FLOAT; 
+        fi.f  = temp;
+        fi.f  = temp + (adj43asm - MAGIC_INT)[fi.i];
+        fi.i -= MAGIC_INT;
+#else
+        temp = xr34[j]*sfpow34;
+        XRPOW_FTOI(temp, fi.i);
+        XRPOW_FTOI(temp + QUANTFAC(fi.i), fi.i);
+#endif
+
+        temp = fabs(xr[j])- pow43[fi.i]*sfpow;
+        xfsf += temp*temp;
+    }
+    return xfsf;
+}
+
+
+
+
+static FLOAT8
+calc_sfb_noise_mq( const FLOAT8 *xr, const FLOAT8 *xr34, int bw, int sf, 
+                   int mq, FLOAT8 *scratch )
+{
+    int j, k;
+    fi_union fi; 
+    FLOAT8 temp;
+    FLOAT8 sfpow, sfpow34, xfsfm = 0, xfsf = 0;
+
+    sfpow   =  POW20(sf+210); /*pow(2.0,sf/4.0); */
+    sfpow34 = IPOW20(sf+210); /*pow(sfpow,-3.0/4.0);*/
+
+    for ( j = 0; j < bw; ++j ) {
+        if ( xr34[j]*sfpow34 > IXMAX_VAL ) return -1;
+
+#ifdef TAKEHIRO_IEEE754_HACK
+        temp  = sfpow34*xr34[j];
+        temp += MAGIC_FLOAT; 
+        fi.f  = temp;
+        fi.f  = temp + (adj43asm - MAGIC_INT)[fi.i];
+        fi.i -= MAGIC_INT;
+#else
+        temp = xr34[j]*sfpow34;
+        XRPOW_FTOI(temp, fi.i);
+        XRPOW_FTOI(temp + QUANTFAC(fi.i), fi.i);
+#endif
+
+        temp = fabs(xr[j])- pow43[fi.i]*sfpow;
+        temp *= temp;
+  
+        scratch[j] = temp;  
+        if ( xfsfm < temp ) xfsfm = temp;
+        xfsf += temp;
+    }
+    if ( mq == 1 ) return bw*select_kth(scratch,bw,bw*13/16);
+    
+    xfsf /= bw;
+    for ( k = 1, j = 0; j < bw; ++j ) {
+        if ( scratch[j] > xfsf ) { 
+            xfsfm += scratch[j];
+            ++k; 
+        }
+    }
+    return xfsfm/k * bw;
+}
+
+
+
+
+static FLOAT8
+calc_sfb_noise_ave(const FLOAT8 *xr, const FLOAT8 *xr34, int bw, int sf)
+{
+    double xp;
+    double xe;
+    double xm;
+#ifdef TAKEHIRO_IEEE754_HACK
+    double x0;
+#endif
+    int xx[3], j;
+    fi_union *fi = (fi_union *)xx; 
+    FLOAT8 sfpow34_eq, sfpow34_p1, sfpow34_m1;
+    FLOAT8 sfpow_eq, sfpow_p1, sfpow_m1;
+    FLOAT8 xfsf_eq = 0, xfsf_p1 = 0, xfsf_m1 = 0;
+
+    sfpow_eq = POW20(sf + 210); /*pow(2.0,sf/4.0); */
+    sfpow_m1 = sfpow_eq * .8408964153;  /* pow(2,(sf-1)/4.0) */
+    sfpow_p1 = sfpow_eq * 1.189207115;  
+    
+    sfpow34_eq = IPOW20(sf + 210); /*pow(sfpow,-3.0/4.0);*/
+    sfpow34_m1 = sfpow34_eq * 1.13878863476;       /* .84089 ^ -3/4 */
+    sfpow34_p1 = sfpow34_eq * 0.878126080187;
+
+#ifdef TAKEHIRO_IEEE754_HACK
+    /*
+     *  loop unrolled into "Duff's Device".   Robert Hegemann
+     */    
+    j = (bw+3) / 4;
+    switch (bw % 4) {
+        default:
+        case 0: do{ DUFFBLOCK();
+        case 3:     DUFFBLOCK();
+        case 2:     DUFFBLOCK();
+        case 1:     DUFFBLOCK(); } while (--j);
+    }
+#else
+    for (j = 0; j < bw; ++j) {
+
+        if (xr34[j]*sfpow34_m1 > IXMAX_VAL) return -1;
+
+        xe = xr34[j]*sfpow34_eq;
+        XRPOW_FTOI(xe, fi[0].i);
+        XRPOW_FTOI(xe + QUANTFAC(fi[0].i), fi[0].i);
+        xe = fabs(xr[j])- pow43[fi[0].i]*sfpow_eq;
+        xe *= xe;
+
+        xp = xr34[j]*sfpow34_p1;
+        XRPOW_FTOI(xp, fi[0].i);
+        XRPOW_FTOI(xp + QUANTFAC(fi[0].i), fi[0].i);
+        xp = fabs(xr[j])- pow43[fi[0].i]*sfpow_p1;
+        xp *= xp;
+
+        xm = xr34[j]*sfpow34_m1;
+        XRPOW_FTOI(xm, fi[0].i);
+        XRPOW_FTOI(xm + QUANTFAC(fi[0].i), fi[0].i);
+        xm = fabs(xr[j])- pow43[fi[0].i]*sfpow_m1;
+        xm *= xm;
+
+        xfsf_eq += xe;
+        xfsf_p1 += xp;
+        xfsf_m1 += xm;
+    }
+#endif
+
+    if ( xfsf_eq < xfsf_p1 ) xfsf_eq = xfsf_p1;
+    if ( xfsf_eq < xfsf_m1 ) xfsf_eq = xfsf_m1;
+    return xfsf_eq;
+}
+
+
+
+INLINE int
+find_scalefac( const FLOAT8 *xr, const FLOAT8 *xr34, FLOAT8 l3_xmin, int bw )
+{
+    FLOAT8 xfsf;
+    int i, sf, sf_ok, delsf;
+
+    /* search will range from sf:  -209 -> 45  */
+    sf = -82;
+    delsf = 128;
+
+    sf_ok = 10000;
+    for (i = 0; i < 7; ++i) {
+        delsf /= 2;
+        xfsf = calc_sfb_noise( xr, xr34, bw, sf );
+
+        if (xfsf < 0) {
+            /* scalefactors too small */
+            sf += delsf;
+        }
+        else {
+            if (xfsf > l3_xmin) {
+                /* distortion.  try a smaller scalefactor */
+                sf -= delsf;
+            }
+            else {
+                sf_ok = sf;
+                sf += delsf;
+            }
+        }
+    } 
+
+    /*  returning a scalefac without distortion, if possible
+     */
+    return sf_ok > 45 ? sf : sf_ok;
+}
+
+INLINE int
+find_scalefac_mq( const FLOAT8 *xr, const FLOAT8 *xr34, FLOAT8 l3_xmin, 
+                  int bw, int mq, FLOAT8 *scratch )
+{
+    FLOAT8 xfsf;
+    int i, sf, sf_ok, delsf;
+
+    /* search will range from sf:  -209 -> 45  */
+    sf = -82;
+    delsf = 128;
+
+    sf_ok = 10000;
+    for (i = 0; i < 7; ++i) {
+        delsf /= 2;
+        xfsf = calc_sfb_noise_mq( xr, xr34, bw, sf, mq, scratch );
+
+        if (xfsf < 0) {
+            /* scalefactors too small */
+            sf += delsf;
+        }
+        else {
+            if (xfsf > l3_xmin) {
+                /* distortion.  try a smaller scalefactor */
+                sf -= delsf;
+            }
+            else {
+                sf_ok = sf;
+                sf += delsf;
+            }
+        }
+    } 
+
+    /*  returning a scalefac without distortion, if possible
+     */
+    return sf_ok > 45 ? sf : sf_ok;
+}
+
+INLINE int
+find_scalefac_ave( const FLOAT8 *xr, const FLOAT8 *xr34, FLOAT8 l3_xmin, int bw )
+{
+    FLOAT8 xfsf; 
+    int i, sf, sf_ok, delsf;
+
+    /* search will range from sf:  -209 -> 45  */
+    sf = -82;
+    delsf = 128;
+
+    sf_ok = 10000;
+    for (i = 0; i < 7; ++i) {
+        delsf /= 2;
+        xfsf = calc_sfb_noise_ave( xr, xr34, bw, sf );
+
+        if (xfsf < 0) {
+            /* scalefactors too small */
+            sf += delsf;
+        }
+        else{
+            if (xfsf > l3_xmin) {
+                /* distortion.  try a smaller scalefactor */
+                sf -= delsf;
+            }
+            else {
+                sf_ok = sf;
+                sf += delsf;
+            }
+        }
+    } 
+
+    /*  returning a scalefac without distortion, if possible
+     */
+    return sf_ok > 45 ? sf : sf_ok;
+}
+
+
+/**
+ *  Robert Hegemann 2001-05-01
+ *  calculates quantization step size determined by allowed masking
+ */
+INLINE int 
+calc_scalefac( FLOAT8 l3_xmin, int bw, FLOAT8 preset_tune )
+{
+    FLOAT8 const c = (preset_tune > 0 ? preset_tune
+                                             : 5.799142446);   // 10 * 10^(2/3) * log10(4/3)
+    return (int)(c*log10(l3_xmin/bw)-.5);
+}
+
+
+
+static const int max_range_short[SBMAX_s] =
+{15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 0 };
+
+static const int max_range_long[SBMAX_l] =
+{15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0};
+
+static const int max_range_long_lsf_pretab[SBMAX_l] =
+{ 7,7,7,7,7,7, 3,3,3,3,3, 0,0,0,0, 0,0,0, 0,0,0, 0 };
+    
+
+
+/*
+    sfb=0..5  scalefac < 16 
+    sfb>5     scalefac < 8
+
+    ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
+    ol_sf =  (cod_info->global_gain-210.0);
+    ol_sf -= 8*cod_info->subblock_gain[i];
+    ol_sf -= ifqstep*scalefac[gr][ch].s[sfb][i];
+
+*/
+INLINE int 
+compute_scalefacs_short(
+    int sf[][3], const gr_info *cod_info, int scalefac[][3], int *sbg )
+{
+    const int maxrange1 = 15, maxrange2 = 7;
+    int maxrange, maxover = 0;
+    int sfb, i;
+    int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
+
+    for (i = 0; i < 3; ++i) {
+        int maxsf1 = 0, maxsf2 = 0, minsf = 1000;
+        /* see if we should use subblock gain */
+        for (sfb = 0; sfb < 6; ++sfb) {         /* part 1 */
+            if (maxsf1 < -sf[sfb][i]) maxsf1 = -sf[sfb][i];
+            if (minsf  > -sf[sfb][i]) minsf  = -sf[sfb][i];
+        }
+        for (; sfb < SBPSY_s; ++sfb) {          /* part 2 */
+            if (maxsf2 < -sf[sfb][i]) maxsf2 = -sf[sfb][i];
+            if (minsf  > -sf[sfb][i]) minsf  = -sf[sfb][i];
+        }
+
+        /* boost subblock gain as little as possible so we can
+         * reach maxsf1 with scalefactors 
+         * 8*sbg >= maxsf1   
+         */
+        maxsf1 = Max (maxsf1-maxrange1*ifqstep, maxsf2-maxrange2*ifqstep);
+        sbg[i] = 0;
+        if (minsf  > 0) sbg[i] = floor (.125*minsf + .001);
+        if (maxsf1 > 0) sbg[i] = Max (sbg[i], (maxsf1/8 + (maxsf1 % 8 != 0)));
+        if (sbg[i] > 7) sbg[i] = 7;
+
+        for (sfb = 0; sfb < SBPSY_s; ++sfb) {
+            sf[sfb][i] += 8*sbg[i];
+
+            if (sf[sfb][i] < 0) {
+                maxrange = sfb < 6 ? maxrange1 : maxrange2;
+                
+                scalefac[sfb][i]
+                     = -sf[sfb][i]/ifqstep + (-sf[sfb][i]%ifqstep != 0);
+                
+                if (scalefac[sfb][i] > maxrange)
+                    scalefac[sfb][i] = maxrange;
+
+                if (maxover < -(sf[sfb][i] + scalefac[sfb][i]*ifqstep)) 
+                    maxover = -(sf[sfb][i] + scalefac[sfb][i]*ifqstep);
+            }
+        }
+        scalefac[sfb][i] = 0;
+    }
+
+    return maxover;
+}
+
+
+
+/*
+         ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
+         ol_sf =  (cod_info->global_gain-210.0);
+         ol_sf -= ifqstep*scalefac[gr][ch].l[sfb];
+         if (cod_info->preflag && sfb>=11) 
+         ol_sf -= ifqstep*pretab[sfb];
+*/
+INLINE int
+compute_scalefacs_long_lsf( int *sf, const gr_info * cod_info, int *scalefac )
+{
+    const int * max_range = max_range_long;
+    int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
+    int sfb;
+    int maxover;
+
+    if (cod_info->preflag) {
+        max_range = max_range_long_lsf_pretab;
+        for (sfb = 11; sfb < SBPSY_l; ++sfb) 
+            sf[sfb] += pretab[sfb] * ifqstep;
+    }
+
+    maxover = 0;
+    for (sfb = 0; sfb < SBPSY_l; ++sfb) {
+
+        if (sf[sfb] < 0) {
+            /* ifqstep*scalefac >= -sf[sfb], so round UP */
+            scalefac[sfb] = -sf[sfb]/ifqstep  + (-sf[sfb] % ifqstep != 0);
+            if (scalefac[sfb] > max_range[sfb]) 
+                scalefac[sfb] = max_range[sfb];
+      
+            /* sf[sfb] should now be positive: */
+            if (-(sf[sfb] + scalefac[sfb]*ifqstep) > maxover) {
+                maxover = -(sf[sfb] + scalefac[sfb]*ifqstep);
+            }
+        }
+    }
+    scalefac[sfb] = 0;  /* sfb21 */
+
+    return maxover;
+}
+
+
+
+
+
+/*
+         ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
+         ol_sf =  (cod_info->global_gain-210.0);
+         ol_sf -= ifqstep*scalefac[gr][ch].l[sfb];
+         if (cod_info->preflag && sfb>=11) 
+         ol_sf -= ifqstep*pretab[sfb];
+*/
+INLINE int
+compute_scalefacs_long( int *sf, const gr_info * cod_info, int *scalefac )
+{
+    int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
+    int sfb;
+    int maxover;  
+
+    if (cod_info->preflag) {
+        for (sfb = 11; sfb < SBPSY_l; ++sfb) 
+            sf[sfb] += pretab[sfb] * ifqstep;
+    }
+
+    maxover = 0;
+    for (sfb = 0; sfb < SBPSY_l; ++sfb) {
+
+        if (sf[sfb] < 0) {
+            /* ifqstep*scalefac >= -sf[sfb], so round UP */
+            scalefac[sfb] = -sf[sfb]/ifqstep  + (-sf[sfb] % ifqstep != 0);
+            if (scalefac[sfb] > max_range_long[sfb]) 
+                scalefac[sfb] = max_range_long[sfb];
+      
+            /* sf[sfb] should now be positive: */
+            if (-(sf[sfb] + scalefac[sfb]*ifqstep) > maxover) {
+                maxover = -(sf[sfb] + scalefac[sfb]*ifqstep);
+            }
+        }
+    }
+    scalefac[sfb] = 0;  /* sfb21 */
+
+    return maxover;
+}
+  
+  
+
+
+
+
+
+
+/************************************************************************
+ *
+ * quantize and encode with the given scalefacs and global gain
+ *
+ * compute scalefactors, l3_enc, and return number of bits needed to encode
+ *
+ *
+ ************************************************************************/
+
+static int
+VBR_quantize_granule( 
+          lame_internal_flags * gfc,
+          FLOAT8              * xr34, 
+          int                 * l3_enc,
+          III_scalefac_t      * scalefac, 
+          int gr, int ch )
+{
+    int status;
+    III_side_info_t * l3_side  = & gfc->l3_side;
+    gr_info         * cod_info = & l3_side->gr[gr].ch[ch].tt;  
+
+    /* encode scalefacs */
+    if ( gfc->is_mpeg1 ) 
+        status = scale_bitcount( scalefac, cod_info );
+    else
+        status = scale_bitcount_lsf( gfc, scalefac, cod_info );
+
+    if (status != 0) {
+        return -1;
+    }
+  
+    /* quantize xr34 */
+    cod_info->part2_3_length = count_bits(gfc,l3_enc,xr34,cod_info);
+    if (cod_info->part2_3_length >= LARGE_BITS) return -2;
+    cod_info->part2_3_length += cod_info->part2_length;
+
+
+    if (gfc->use_best_huffman == 1) {
+        best_huffman_divide(gfc, cod_info, l3_enc);
+    }
+    return 0;
+}
+
+
+  
+/***********************************************************************
+ *
+ *      calc_short_block_vbr_sf()
+ *      calc_long_block_vbr_sf()
+ *
+ *  Mark Taylor 2000-??-??
+ *  Robert Hegemann 2000-10-25 made functions of it
+ *
+ ***********************************************************************/
+static const int MAX_SF_DELTA = 4;    
+
+static void
+short_block_sf (
+    const lame_internal_flags * gfc,
+    const III_psy_xmin   * l3_xmin,
+    const FLOAT8         * xr34_orig,
+    const FLOAT8         * xr34,
+          III_scalefac_t * vbrsf,
+          int            * vbrmin,
+          int            * vbrmax )
+{
+    int j, sfb, b;
+    int vbrmean, vbrmn;
+    int sf_cache[SBMAX_s];
+    int scalefac_criteria;
+
+    if (gfc->presetTune.use) {
+           /* map experimentalX settings to internal selections */
+        static char const map[] = {2,1,0,3,6};
+        scalefac_criteria = map[gfc->presetTune.quantcomp_current];
+    }
+       else {
+        scalefac_criteria = gfc->VBR->quality;
+    }
+  
+    for (j = 0, sfb = 0; sfb < SBMAX_s; ++sfb) {
+        for (b = 0; b < 3; ++b) {
+            const  int start = gfc->scalefac_band.s[ sfb ];
+            const  int end   = gfc->scalefac_band.s[ sfb+1 ];
+            const  int width = end - start;
+           
+            switch( scalefac_criteria ) {
+            default:
+                /*  the fastest
+                 */
+                vbrsf->s[sfb][b] = calc_scalefac( l3_xmin->s[sfb][b], width,
+                                                                     gfc->presetTune.quantcomp_adjust_mtrh );
+                break;
+            case 5:
+            case 4:
+            case 3:
+                /*  the faster and sloppier mode to use at lower quality
+                 */
+                vbrsf->s[sfb][b] = find_scalefac (&xr34[j], &xr34_orig[j], 
+                                              l3_xmin->s[sfb][b], width);
+                break;
+            case 2:
+                /*  the slower and better mode to use at higher quality
+                 */
+                vbrsf->s[sfb][b] = find_scalefac_ave (&xr34[j], &xr34_orig[j],
+                                                    l3_xmin->s[sfb][b], width);
+                break;
+            case 1:
+                /*  maxnoise mode to use at higher quality
+                 */
+                vbrsf->s[sfb][b] = find_scalefac_mq (&xr34[j], &xr34_orig[j], 
+                                              l3_xmin->s[sfb][b], width,
+                                              1, gfc->VBR->scratch);
+                break;
+            case 0:
+                /*  maxnoise mode to use at higher quality
+                 */
+                vbrsf->s[sfb][b] = find_scalefac_mq (&xr34[j], &xr34_orig[j], 
+                                              l3_xmin->s[sfb][b], width,
+                                              0, gfc->VBR->scratch);
+                break;
+            }
+            j += width;
+        }
+    }
+    
+    *vbrmax = -10000;
+    *vbrmin = +10000;
+    
+    for (b = 0; b < 3; ++b) { 
+
+        /*  smoothing
+         */
+        switch( gfc->VBR->smooth ) {
+        default:
+        case  0: 
+            break;
+            
+        case  1:
+            /*  make working copy, get min value, select_kth_int will reorder!
+             */
+            for (vbrmn = +10000, sfb = 0; sfb < SBMAX_s; ++sfb) {
+                sf_cache[sfb] = vbrsf->s[sfb][b];
+                if (vbrmn > vbrsf->s[sfb][b])
+                    vbrmn = vbrsf->s[sfb][b];
+            }
+
+            /*  find median value, take it as mean 
+             */
+            vbrmean = select_kth_int (sf_cache, SBMAX_s, (SBMAX_s+1)/2);
+
+            /*  cut peaks
+             */
+            for (sfb = 0; sfb < SBMAX_s; ++sfb) {
+                if (vbrsf->s[sfb][b] > vbrmean+(vbrmean-vbrmn))
+                    vbrsf->s[sfb][b] = vbrmean+(vbrmean-vbrmn);
+            }
+            break;
+            
+        case  2:
+            for (sfb = 0; sfb < SBMAX_s; ++sfb) {
+               if (sfb > 0) 
+                   if (vbrsf->s[sfb][b] > vbrsf->s[sfb-1][b]+MAX_SF_DELTA)
+                        vbrsf->s[sfb][b] = vbrsf->s[sfb-1][b]+MAX_SF_DELTA;
+               if (sfb < SBMAX_s-1) 
+                   if (vbrsf->s[sfb][b] > vbrsf->s[sfb+1][b]+MAX_SF_DELTA)
+                        vbrsf->s[sfb][b] = vbrsf->s[sfb+1][b]+MAX_SF_DELTA;
+            }
+            break;
+        }
+        
+        /*  get max value
+         */
+        for (sfb = 0; sfb < SBMAX_s; ++sfb) { 
+            if (*vbrmax < vbrsf->s[sfb][b])
+                *vbrmax = vbrsf->s[sfb][b];
+            if (*vbrmin > vbrsf->s[sfb][b])
+                *vbrmin = vbrsf->s[sfb][b];
+        }
+    }
+}
+
+
+    /* a variation for vbr-mtrh */
+static void
+long_block_sf (
+    const lame_internal_flags * gfc,
+    const III_psy_xmin   * l3_xmin,
+    const FLOAT8         * xr34_orig,
+    const FLOAT8         * xr34,
+          III_scalefac_t * vbrsf,
+          int            * vbrmin,
+          int            * vbrmax )
+{
+    int sfb;
+    int vbrmean, vbrmn;
+    int sf_cache[SBMAX_l];
+    int scalefac_criteria;
+
+    if (gfc->presetTune.use) {
+           /* map experimentalX settings to internal selections */
+        static char const map[] = {2,1,0,3,6};
+        scalefac_criteria = map[gfc->presetTune.quantcomp_current];
+    }
+       else {
+        scalefac_criteria = gfc->VBR->quality;
+    }
+    
+    for (sfb = 0; sfb < SBMAX_l; ++sfb) {
+        const  int start = gfc->scalefac_band.l[ sfb ];
+        const  int end   = gfc->scalefac_band.l[ sfb+1 ];
+        const  int width = end - start;
+        
+        switch( scalefac_criteria ) {
+        default:
+            /*  the fastest
+             */
+            vbrsf->l[sfb] = calc_scalefac( l3_xmin->l[sfb], width,
+                                                          gfc->presetTune.quantcomp_adjust_mtrh );
+            break;
+        case 5:
+        case 4:
+        case 3:
+            /*  the faster and sloppier mode to use at lower quality
+             */
+            vbrsf->l[sfb] = find_scalefac (&xr34[start], &xr34_orig[start], 
+                                           l3_xmin->l[sfb], width);
+            break;
+        case 2:
+            /*  the slower and better mode to use at higher quality
+             */
+            vbrsf->l[sfb] = find_scalefac_ave (&xr34[start], &xr34_orig[start],
+                                               l3_xmin->l[sfb], width);
+            break;
+        case 1:
+            /*  maxnoise mode to use at higher quality
+             */
+            vbrsf->l[sfb] = find_scalefac_mq (&xr34[start], &xr34_orig[start], 
+                                           l3_xmin->l[sfb], width, 
+                                           1, gfc->VBR->scratch);
+            break;
+        case 0:
+            /*  maxnoise mode to use at higher quality
+             */
+            vbrsf->l[sfb] = find_scalefac_mq (&xr34[start], &xr34_orig[start], 
+                                           l3_xmin->l[sfb], width, 
+                                           0, gfc->VBR->scratch);
+            break;
+        }
+    }
+
+    switch( gfc->VBR->smooth ) {
+    default:
+    case  0:
+        break;
+        
+    case  1:
+        /*  make working copy, get min value, select_kth_int will reorder!
+         */
+        for (vbrmn = +10000, sfb = 0; sfb < SBMAX_l; ++sfb) {
+            sf_cache[sfb] = vbrsf->l[sfb];
+            if (vbrmn > vbrsf->l[sfb])
+                vbrmn = vbrsf->l[sfb];
+        }    
+        /*  find median value, take it as mean 
+         */
+        vbrmean = select_kth_int (sf_cache, SBMAX_l, (SBMAX_l+1)/2);
+
+        /*  cut peaks
+         */
+        for (sfb = 0; sfb < SBMAX_l; ++sfb) {
+            if (vbrsf->l[sfb] > vbrmean+(vbrmean-vbrmn))
+                vbrsf->l[sfb] = vbrmean+(vbrmean-vbrmn);
+        }
+        break;
+        
+    case  2:
+        for (sfb = 0; sfb < SBMAX_l; ++sfb) {
+            if (sfb > 0) 
+               if (vbrsf->l[sfb] > vbrsf->l[sfb-1]+MAX_SF_DELTA)
+                    vbrsf->l[sfb] = vbrsf->l[sfb-1]+MAX_SF_DELTA;
+            if (sfb < SBMAX_l-1) 
+               if (vbrsf->l[sfb] > vbrsf->l[sfb+1]+MAX_SF_DELTA)
+                    vbrsf->l[sfb] = vbrsf->l[sfb+1]+MAX_SF_DELTA;
+        }
+        break;
+    }
+    
+    /*  get max value
+     */
+    for (*vbrmin = +10000, *vbrmax = -10000, sfb = 0; sfb < SBMAX_l; ++sfb) {
+        if (*vbrmax < vbrsf->l[sfb]) 
+            *vbrmax = vbrsf->l[sfb];
+        if (*vbrmin > vbrsf->l[sfb])
+            *vbrmin = vbrsf->l[sfb];
+    }
+}
+
+
+
+/******************************************************************
+ *
+ *  short block scalefacs
+ *
+ ******************************************************************/
+
+static void 
+short_block_scalefacs (
+    const lame_internal_flags * gfc,
+          gr_info             * cod_info,
+          III_scalefac_t      * scalefac,
+          III_scalefac_t      * vbrsf,
+          int                 * VBRmax )
+{
+    int sfb, maxsfb, b;
+    int maxover, maxover0, maxover1, mover;
+    int v0, v1;
+    int minsfb;
+    int vbrmax = *VBRmax;
+    
+    maxover0 = 0;
+    maxover1 = 0;
+    maxsfb = gfc->sfb21_extra ? SBMAX_s : SBPSY_s;
+    for (sfb = 0; sfb < maxsfb; ++sfb) {
+        for (b = 0; b < 3; ++b) {
+            v0 = (vbrmax - vbrsf->s[sfb][b]) - (4*14 + 2*max_range_short[sfb]);
+            v1 = (vbrmax - vbrsf->s[sfb][b]) - (4*14 + 4*max_range_short[sfb]);
+            if (maxover0 < v0)
+                maxover0 = v0;
+            if (maxover1 < v1)
+                maxover1 = v1;
+        }
+    }
+
+    if ((gfc->noise_shaping == 2) && (gfc->presetTune.use && !(gfc->presetTune.athadjust_safe_noiseshaping || gfc->ATH->adjust < 1.0)))
+        /* allow scalefac_scale=1 */
+        mover = Min (maxover0, maxover1);
+    else
+        mover = maxover0; 
+
+    vbrmax   -= mover;
+    maxover0 -= mover;
+    maxover1 -= mover;
+
+    if (maxover0 == 0) 
+        cod_info->scalefac_scale = 0;
+    else if (maxover1 == 0)
+        cod_info->scalefac_scale = 1;
+
+    /* sf =  (cod_info->global_gain-210.0) */
+    cod_info->global_gain = vbrmax + 210;
+    assert(cod_info->global_gain < 256);
+    
+    if (cod_info->global_gain < 0) {
+        cod_info->global_gain = 0; 
+    }
+    else
+    if (cod_info->global_gain > 255) {
+        cod_info->global_gain = 255;
+    }
+    for (sfb = 0; sfb < SBMAX_s; ++sfb) {
+        for (b = 0; b < 3; ++b) {
+            vbrsf->s[sfb][b] -= vbrmax;
+        }
+    }
+    maxover = compute_scalefacs_short (vbrsf->s, cod_info, scalefac->s,
+                                           cod_info->subblock_gain);
+                                           
+    assert (maxover <= 0);
+
+    /* adjust global_gain so at least 1 subblock gain = 0 */
+    minsfb = 999; /* prepare for minimum search */
+    for (b = 0; b < 3; ++b) 
+        if (minsfb > cod_info->subblock_gain[b])
+            minsfb = cod_info->subblock_gain[b];
+    
+    if (minsfb > cod_info->global_gain/8)
+        minsfb = cod_info->global_gain/8;
+    
+    vbrmax                -= 8*minsfb; 
+    cod_info->global_gain -= 8*minsfb;
+    
+    for (b = 0; b < 3; ++b)
+        cod_info->subblock_gain[b] -= minsfb;
+        
+    *VBRmax = vbrmax;
+}
+
+
+
+/******************************************************************
+ *
+ *  long block scalefacs
+ *
+ ******************************************************************/
+
+static void 
+long_block_scalefacs (
+    const lame_internal_flags * gfc,
+          gr_info             * cod_info,
+          III_scalefac_t      * scalefac,
+          III_scalefac_t      * vbrsf,
+          int                 * VBRmax )
+{
+    const int * max_rangep;
+    int sfb, maxsfb;
+    int maxover, maxover0, maxover1, maxover0p, maxover1p, mover;
+    int v0, v1, v0p, v1p;
+    int vbrmax = *VBRmax;
+
+    max_rangep = gfc->is_mpeg1 ? max_range_long : max_range_long_lsf_pretab;
+    
+    maxover0  = 0;
+    maxover1  = 0;
+    maxover0p = 0; /* pretab */
+    maxover1p = 0; /* pretab */
+       
+    maxsfb = gfc->sfb21_extra ? SBMAX_l : SBPSY_l;
+    for ( sfb = 0; sfb < maxsfb; ++sfb ) {
+        v0  = (vbrmax - vbrsf->l[sfb]) - 2*max_range_long[sfb];
+        v1  = (vbrmax - vbrsf->l[sfb]) - 4*max_range_long[sfb];
+        v0p = (vbrmax - vbrsf->l[sfb]) - 2*(max_rangep[sfb]+pretab[sfb]);
+        v1p = (vbrmax - vbrsf->l[sfb]) - 4*(max_rangep[sfb]+pretab[sfb]);
+        if (maxover0 < v0)
+            maxover0 = v0;
+        if (maxover1 < v1)
+            maxover1 = v1;
+        if (maxover0p < v0p)
+            maxover0p = v0p;
+        if (maxover1p < v1p)
+            maxover1p = v1p;
+    }
+
+    mover = Min (maxover0, maxover0p);
+    if ((gfc->noise_shaping == 2) && (gfc->presetTune.use && !(gfc->presetTune.athadjust_safe_noiseshaping || gfc->ATH->adjust < 1.0))) {
+        /* allow scalefac_scale=1 */
+        mover = Min (mover, maxover1);
+        mover = Min (mover, maxover1p);
+    }
+
+    vbrmax    -= mover;
+    maxover0  -= mover;
+    maxover0p -= mover;
+    maxover1  -= mover;
+    maxover1p -= mover;
+
+    if (maxover0 <= 0) {
+        cod_info->scalefac_scale = 0;
+        cod_info->preflag = 0;
+        vbrmax -= maxover0;
+    } else if (maxover0p <= 0) {
+        cod_info->scalefac_scale = 0;
+        cod_info->preflag = 1;
+        vbrmax -= maxover0p;
+    } else if (maxover1 == 0) {
+        cod_info->scalefac_scale = 1;
+        cod_info->preflag = 0;
+    } else if (maxover1p == 0) {
+        cod_info->scalefac_scale = 1;
+        cod_info->preflag = 1;
+    } else {
+        assert(0); /* this should not happen */
+    }
+
+    /* sf =  (cod_info->global_gain-210.0) */
+    cod_info->global_gain = vbrmax + 210;
+    assert (cod_info->global_gain < 256);
+
+    if (cod_info->global_gain < 0) {
+        cod_info->global_gain = 0; 
+    }
+    else
+    if (cod_info->global_gain > 255) 
+        cod_info->global_gain = 255;
+    
+    for (sfb = 0; sfb < SBMAX_l; ++sfb)   
+        vbrsf->l[sfb] -= vbrmax;
+
+    if ( gfc->is_mpeg1 == 1 ) 
+        maxover = compute_scalefacs_long (vbrsf->l, cod_info, scalefac->l);
+    else
+        maxover = compute_scalefacs_long_lsf (vbrsf->l, cod_info, scalefac->l);
+
+    assert (maxover <= 0);
+    
+    *VBRmax = vbrmax;
+}
+
+
+
+/***********************************************************************
+ *
+ *  quantize xr34 based on scalefactors
+ *
+ *  calc_short_block_xr34      
+ *  calc_long_block_xr34
+ *
+ *  Mark Taylor 2000-??-??
+ *  Robert Hegemann 2000-10-20 made functions of them
+ *
+ ***********************************************************************/
+
+static void
+short_block_xr34 ( 
+    const lame_internal_flags * gfc,
+    const gr_info             * cod_info,
+    const III_scalefac_t      * scalefac, 
+    const FLOAT8              * xr34_orig,
+          FLOAT8              * xr34 )
+{
+    int    sfb, l, j, b;
+    int    ifac, ifqstep, start, end;
+    FLOAT8 fac;
+
+    /* even though there is no scalefactor for sfb12
+     * subblock gain affects upper frequencies too, that's why
+     * we have to go up to SBMAX_s
+     */
+    ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
+    for ( j = 0, sfb = 0; sfb < SBMAX_s; ++sfb ) {
+        start = gfc->scalefac_band.s[ sfb ];
+        end   = gfc->scalefac_band.s[ sfb+1 ];
+        for (b = 0; b < 3; ++b) {
+            ifac = 8*cod_info->subblock_gain[b]+ifqstep*scalefac->s[sfb][b];
+            
+            if ( ifac == 0 ) {  /* just copy */
+                l = (end-start+7) / 8;
+                switch ((end-start) % 8) {
+                    default:
+                    case 0: do{ xr34[j] = xr34_orig[j]; ++j;
+                    case 7:     xr34[j] = xr34_orig[j]; ++j;
+                    case 6:     xr34[j] = xr34_orig[j]; ++j;
+                    case 5:     xr34[j] = xr34_orig[j]; ++j;
+                    case 4:     xr34[j] = xr34_orig[j]; ++j;
+                    case 3:     xr34[j] = xr34_orig[j]; ++j;
+                    case 2:     xr34[j] = xr34_orig[j]; ++j;
+                    case 1:     xr34[j] = xr34_orig[j]; ++j; } while (--l);
+                }
+                continue;
+            }
+            if (ifac < Q_MAX-210)
+                fac = IIPOW20_(ifac);    
+            else
+                fac = pow (2.0, 0.1875*ifac);
+            
+            /*
+             *  loop unrolled into "Duff's Device".  Robert Hegemann
+             */
+            l = (end-start+7) / 8;
+            switch ((end-start) % 8) {
+                default:
+                case 0: do{ xr34[j] = xr34_orig[j]*fac; ++j;
+                case 7:     xr34[j] = xr34_orig[j]*fac; ++j;
+                case 6:     xr34[j] = xr34_orig[j]*fac; ++j;
+                case 5:     xr34[j] = xr34_orig[j]*fac; ++j;
+                case 4:     xr34[j] = xr34_orig[j]*fac; ++j;
+                case 3:     xr34[j] = xr34_orig[j]*fac; ++j;
+                case 2:     xr34[j] = xr34_orig[j]*fac; ++j;
+                case 1:     xr34[j] = xr34_orig[j]*fac; ++j; } while (--l);
+            }
+        }
+    }
+}
+
+
+
+static void 
+long_block_xr34 ( 
+    const lame_internal_flags * gfc,
+    const gr_info             * cod_info,
+    const III_scalefac_t      * scalefac, 
+    const FLOAT8              * xr34_orig,
+          FLOAT8              * xr34 )
+{ 
+    int    sfb, l, j;
+    int    ifac, ifqstep, start, end;
+    FLOAT8 fac;
+        
+    ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
+    for ( sfb = 0; sfb < SBMAX_l; ++sfb ) {
+
+        ifac = ifqstep*scalefac->l[sfb];
+        if (cod_info->preflag)
+            ifac += ifqstep*pretab[sfb];
+
+        start = gfc->scalefac_band.l[ sfb ];
+        end   = gfc->scalefac_band.l[ sfb+1 ];
+        
+        if ( ifac == 0 ) {  /* just copy */
+            j = start;
+            l = (end-start+7) / 8;
+            switch ((end-start) % 8) {
+                default:
+                case 0: do{ xr34[j] = xr34_orig[j]; ++j;
+                case 7:     xr34[j] = xr34_orig[j]; ++j;
+                case 6:     xr34[j] = xr34_orig[j]; ++j;
+                case 5:     xr34[j] = xr34_orig[j]; ++j;
+                case 4:     xr34[j] = xr34_orig[j]; ++j;
+                case 3:     xr34[j] = xr34_orig[j]; ++j;
+                case 2:     xr34[j] = xr34_orig[j]; ++j;
+                case 1:     xr34[j] = xr34_orig[j]; ++j; } while (--l);
+            }
+            continue;
+        }
+        if (ifac < Q_MAX-210)
+            fac = IIPOW20_(ifac);    
+        else
+            fac = pow (2.0, 0.1875*ifac);
+        
+        /*
+         *  loop unrolled into "Duff's Device".  Robert Hegemann
+         */
+        j = start;
+        l = (end-start+7) / 8;
+        switch ((end-start) % 8) {
+            default:
+            case 0: do{ xr34[j] = xr34_orig[j]*fac; ++j;
+            case 7:     xr34[j] = xr34_orig[j]*fac; ++j;
+            case 6:     xr34[j] = xr34_orig[j]*fac; ++j;
+            case 5:     xr34[j] = xr34_orig[j]*fac; ++j;
+            case 4:     xr34[j] = xr34_orig[j]*fac; ++j;
+            case 3:     xr34[j] = xr34_orig[j]*fac; ++j;
+            case 2:     xr34[j] = xr34_orig[j]*fac; ++j;
+            case 1:     xr34[j] = xr34_orig[j]*fac; ++j; } while (--l);
+        }
+    }
+}
+
+
+
+
+
+
+
+/************************************************************************
+ *
+ *  VBR_noise_shaping2()
+ *
+ *  may result in a need of too many bits, then do it CBR like
+ *
+ *  Robert Hegemann 2000-10-25
+ *
+ ***********************************************************************/
+int
+VBR_noise_shaping2 (
+    lame_global_flags * gfp,
+    FLOAT8            * xr, 
+    FLOAT8            * xr34orig,
+    int               * l3_enc, 
+    int                 minbits,
+    int                 maxbits,
+    III_scalefac_t    * scalefac,
+    III_psy_xmin      * l3_xmin,
+    int                 gr,
+    int                 ch )
+{
+    lame_internal_flags *gfc = gfp->internal_flags;
+    III_scalefac_t vbrsf;
+    III_scalefac_t vbrsf2;
+    gr_info *cod_info;  
+    FLOAT8 xr34[576];
+    int shortblock, ret, bits, huffbits;
+    int vbrmin, vbrmax, vbrmin2, vbrmax2;
+    int best_huffman = gfc->use_best_huffman;
+    int count=6;
+    
+    gfc->use_best_huffman = 0; /* we will do it later */
+    cod_info   = &gfc->l3_side.gr[gr].ch[ch].tt;
+    shortblock = (cod_info->block_type == SHORT_TYPE);
+      
+    if (shortblock) {
+        short_block_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf2, &vbrmin2, &vbrmax2);
+    } else {
+        long_block_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf2, &vbrmin2, &vbrmax2);  
+    } 
+    vbrsf = vbrsf2;  
+    vbrmin = vbrmin2;
+    vbrmax = vbrmax2;
+
+do {
+--count;    
+
+    if (shortblock) {
+        short_block_scalefacs (gfc, cod_info, scalefac, &vbrsf, &vbrmax);
+        short_block_xr34      (gfc, cod_info, scalefac, xr34orig, xr34);
+    } else {
+        long_block_scalefacs (gfc, cod_info, scalefac, &vbrsf, &vbrmax);
+        long_block_xr34      (gfc, cod_info, scalefac, xr34orig, xr34);
+    } 
+    
+    ret = VBR_quantize_granule (gfc, xr34, l3_enc, scalefac, gr, ch);
+    
+    if (vbrmin == vbrmax) break;
+    else if (cod_info->part2_3_length < minbits) {
+        int i;
+        vbrmax = vbrmin2 + (vbrmax2-vbrmin2) * count/6;
+        vbrmin = vbrmin2;
+        if (shortblock) {
+            for (i = 0; i < SBMAX_s; ++i) {
+                //vbrsf.s[i][0] = vbrmin2 + (vbrsf2.s[i][0]-vbrmin2) * count/6;
+                //vbrsf.s[i][1] = vbrmin2 + (vbrsf2.s[i][1]-vbrmin2) * count/6;
+                //vbrsf.s[i][2] = vbrmin2 + (vbrsf2.s[i][2]-vbrmin2) * count/6;
+                vbrsf.s[i][0] = Min(vbrsf2.s[i][0], vbrmax);
+                vbrsf.s[i][1] = Min(vbrsf2.s[i][1], vbrmax);
+                vbrsf.s[i][2] = Min(vbrsf2.s[i][2], vbrmax);
+            }
+        }
+        else {
+            for (i = 0; i < SBMAX_l; ++i) {
+                //vbrsf.l[i] = vbrmin2 + (vbrsf2.l[i]-vbrmin2) * count/6;
+                vbrsf.l[i] = Min(vbrsf2.l[i], vbrmax);
+            }
+        }
+    }
+    else if (cod_info->part2_3_length > maxbits) {
+        int i;
+        vbrmax = vbrmax2;
+        vbrmin = vbrmax2 + (vbrmin2-vbrmax2) * count/6;
+        if (shortblock) {
+            for (i = 0; i < SBMAX_s; ++i) {
+                //vbrsf.s[i][0] = vbrmax2 + (vbrsf2.s[i][0]-vbrmax2) * count/6;
+                //vbrsf.s[i][1] = vbrmax2 + (vbrsf2.s[i][1]-vbrmax2) * count/6;
+                //vbrsf.s[i][2] = vbrmax2 + (vbrsf2.s[i][2]-vbrmax2) * count/6;
+                vbrsf.s[i][0] = Max(vbrsf2.s[i][0], vbrmin);
+                vbrsf.s[i][1] = Max(vbrsf2.s[i][1], vbrmin);
+                vbrsf.s[i][2] = Max(vbrsf2.s[i][2], vbrmin);
+            }
+        }
+        else {
+            for (i = 0; i < SBMAX_l; ++i) {
+                //vbrsf.l[i] = vbrmax2 + (vbrsf2.l[i]-vbrmax2) * count/6;
+                vbrsf.l[i] = Max(vbrsf2.l[i], vbrmin);
+            }
+        }
+    }
+    else break;
+} while(1 && ret != -1);
+
+
+    gfc->use_best_huffman = best_huffman;
+
+    if (ret == -1) /* Houston, we have a problem */
+        return -1;
+
+    if (cod_info->part2_3_length < minbits) {
+        huffbits = minbits - cod_info->part2_length;
+        bits = bin_search_StepSize (gfc, cod_info, huffbits, 
+                                    gfc->OldValue[ch], xr34, l3_enc);
+        gfc->OldValue[ch] = cod_info->global_gain;
+        cod_info->part2_3_length  = bits + cod_info->part2_length;
+    }
+    if (cod_info->part2_3_length > maxbits) {
+        huffbits = maxbits - cod_info->part2_length;
+        if (huffbits < 0) huffbits = 0;
+        bits = bin_search_StepSize (gfc, cod_info, huffbits, 
+                                    gfc->OldValue[ch], xr34, l3_enc);
+        gfc->OldValue[ch] = cod_info->global_gain;
+        cod_info->part2_3_length = bits;
+        if (bits > huffbits) {
+            bits = inner_loop (gfc, cod_info, huffbits, xr34, l3_enc);
+            cod_info->part2_3_length  = bits;
+        }
+        if (bits >= LARGE_BITS) /* Houston, we have a problem */
+            return -2;
+        cod_info->part2_3_length += cod_info->part2_length;
+    }
+
+    if (cod_info->part2_length >= LARGE_BITS) /* Houston, we have a problem */
+        return -2;
+        
+    assert (cod_info->global_gain < 256);
+    
+    return 0;
+}
+
+
+
+
+
+
+/************************************************************************
+ *
+ * VBR_noise_shaping()
+ *
+ * compute scalefactors, l3_enc, and return number of bits needed to encode
+ *
+ * return code:    0   scalefactors were found with all noise < masking
+ *
+ *               n>0   scalefactors required too many bits.  global gain
+ *                     was decreased by n
+ *                     If n is large, we should probably recompute scalefacs
+ *                     with a lower quality.
+ *
+ *               n<0   scalefactors used less than minbits.
+ *                     global gain was increased by n.  
+ *                     If n is large, might want to recompute scalefacs
+ *                     with a higher quality setting?
+ *
+ ************************************************************************/
+static int
+VBR_noise_shaping (
+    lame_global_flags *gfp,
+    FLOAT8             xr       [576], 
+    FLOAT8             xr34orig [576],
+    int                l3_enc   [576], 
+    int                digital_silence, 
+    int                minbits,
+    int                maxbits,
+    III_scalefac_t    *scalefac,
+    III_psy_xmin      *l3_xmin,
+    int                gr,
+    int                ch )
+{
+    lame_internal_flags *gfc=gfp->internal_flags;
+    III_scalefac_t save_sf;
+    III_scalefac_t vbrsf;
+    gr_info *cod_info;  
+    FLOAT8 xr34[576];
+    int shortblock;
+    int vbrmax, vbrmin;
+    int global_gain_adjust = 0;
+
+    cod_info   = &gfc->l3_side.gr[gr].ch[ch].tt;
+    shortblock = (cod_info->block_type == SHORT_TYPE);
+  
+    if (shortblock)
+        short_block_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf, &vbrmin, &vbrmax);  
+    else
+        long_block_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf, &vbrmin, &vbrmax);  
+
+    /* save a copy of vbrsf, incase we have to recomptue scalefacs */
+    memcpy (&save_sf, &vbrsf, sizeof(III_scalefac_t));
+
+    do { 
+        memset (scalefac, 0, sizeof(III_scalefac_t));
+        
+        if (shortblock) {
+            short_block_scalefacs (gfc, cod_info, scalefac, &vbrsf, &vbrmax);
+            short_block_xr34      (gfc, cod_info, scalefac, xr34orig, xr34);
+        } else {
+            long_block_scalefacs (gfc, cod_info, scalefac, &vbrsf, &vbrmax);
+            long_block_xr34      (gfc, cod_info, scalefac, xr34orig, xr34);
+        } 
+        VBR_quantize_granule (gfc, xr34, l3_enc, scalefac, gr, ch);
+
+        
+        /* decrease noise until we use at least minbits
+         */
+        if (cod_info->part2_3_length < minbits) {
+            if (digital_silence) break;  
+            //if (cod_info->part2_3_length == cod_info->part2_length) break;
+            if (vbrmax+210 == 0) break;
+            
+            /* decrease global gain, recompute scale factors */
+            --vbrmax;
+            --global_gain_adjust;
+            memcpy (&vbrsf, &save_sf, sizeof(III_scalefac_t));
+        }
+
+    } while (cod_info->part2_3_length < minbits);
+
+    /* inject noise until we meet our bit limit
+     */
+    while (cod_info->part2_3_length > Min (maxbits, MAX_BITS)) {
+        /* increase global gain, keep existing scale factors */
+        ++cod_info->global_gain;
+        if (cod_info->global_gain > 255) 
+            ERRORF (gfc,"%ld impossible to encode ??? frame! bits=%d\n",
+                    //  gfp->frameNum, cod_info->part2_3_length);
+                             -1,       cod_info->part2_3_length);
+        VBR_quantize_granule (gfc, xr34, l3_enc, scalefac, gr, ch);
+
+        ++global_gain_adjust;
+    }
+
+    return global_gain_adjust;
+}
+
+
+
+void
+VBR_quantize(lame_global_flags *gfp,
+                FLOAT8 pe[2][2], FLOAT8 ms_ener_ratio[2],
+                FLOAT8 xr[2][2][576], III_psy_ratio ratio[2][2],
+                int l3_enc[2][2][576],
+                III_scalefac_t scalefac[2][2])
+{
+  lame_internal_flags *gfc=gfp->internal_flags;
+  III_psy_xmin l3_xmin[2][2];
+  int minbits,maxbits,max_frame_bits,totbits,gr,ch,i,bits_ok;
+  int bitsPerFrame,mean_bits;
+  int analog_silence;
+  FLOAT8 qadjust;
+  III_side_info_t * l3_side;
+  gr_info *cod_info;  
+  int digital_silence[2][2];
+  FLOAT8 masking_lower_db=0;
+  FLOAT8 xr34[2][2][576];
+  
+  qadjust=0;   /* start with -1 db quality improvement over quantize.c VBR */
+
+  l3_side = &gfc->l3_side;
+
+  /* now find out: if the frame can be considered analog silent
+   *               if each granule can be considered digital silent
+   * and calculate l3_xmin and the fresh xr34 array
+   */
+
+  assert( gfp->VBR_q <= 9 );
+  assert( gfp->VBR_q >= 0 );
+  analog_silence=1;
+  for (gr = 0; gr < gfc->mode_gr; ++gr) {
+    /* copy data to be quantized into xr */
+    if (gfc->mode_ext==MPG_MD_MS_LR) {
+      ms_convert(xr[gr],xr[gr]);
+    }
+    for (ch = 0; ch < gfc->channels_out; ++ch) {
+      /* if in the following sections the quality would not be adjusted
+       * then we would only have to call calc_xmin once here and
+       * could drop subsequently calls (rh 2000/07/17)
+       */
+      int over_ath;
+      cod_info = &l3_side->gr[gr].ch[ch].tt;
+      cod_info->part2_3_length=LARGE_BITS;
+      
+      if (cod_info->block_type == SHORT_TYPE) {
+          cod_info->sfb_lmax = 0; /* No sb*/
+          cod_info->sfb_smin = 0;
+      } else {
+          /* MPEG 1 doesnt use last scalefactor band */
+          cod_info->sfb_lmax = SBPSY_l;
+          cod_info->sfb_smin = SBPSY_s;    /* No sb */
+         if (cod_info->mixed_block_flag) {
+           cod_info->sfb_lmax        = gfc->is_mpeg1 ? 8 : 6;
+           cod_info->sfb_smin        = 3;
+         }
+      }
+      
+      /* quality setting */
+      masking_lower_db = gfc->VBR->mask_adjust;
+      if (pe[gr][ch]>750) {
+        masking_lower_db -= Min(10,4*(pe[gr][ch]-750.)/750.);
+      }
+      gfc->masking_lower = pow(10.0,masking_lower_db/10);
+      
+      /* masking thresholds */
+      over_ath = calc_xmin(gfp,xr[gr][ch],&ratio[gr][ch],cod_info,&l3_xmin[gr][ch]);
+      
+      /* if there are bands with more energy than the ATH 
+       * then we say the frame is not analog silent */
+      if (over_ath) {
+        analog_silence = 0;
+      }
+      
+      /* if there is no line with more energy than 1e-20
+       * then this granule is considered to be digital silent
+       * plus calculation of xr34 */
+      digital_silence[gr][ch] = 1;
+      for(i=0;i<576;++i) {
+        FLOAT8 temp=fabs(xr[gr][ch][i]);
+        xr34[gr][ch][i]=sqrt(sqrt(temp)*temp);
+        digital_silence[gr][ch] &= temp < 1E-20;
+      }
+    } /* ch */
+  }  /* gr */
+
+  
+  /* compute minimum allowed bits from minimum allowed bitrate */
+  if (analog_silence) {
+    gfc->bitrate_index=1;
+  } else {
+    gfc->bitrate_index=gfc->VBR_min_bitrate;
+  }
+  getframebits(gfp, &bitsPerFrame, &mean_bits);
+  minbits = (mean_bits/gfc->channels_out);
+
+  /* compute maximum allowed bits from max allowed bitrate */
+  gfc->bitrate_index=gfc->VBR_max_bitrate;
+  getframebits(gfp, &bitsPerFrame, &mean_bits);
+  max_frame_bits = ResvFrameBegin(gfp, l3_side, mean_bits, bitsPerFrame);
+  maxbits=2.5*(mean_bits/gfc->channels_out);
+
+  {
+  /* compute a target  mean_bits based on compression ratio 
+   * which was set based on VBR_q  
+   */
+  int bit_rate = gfp->out_samplerate*16*gfc->channels_out/(1000.0*gfp->compression_ratio);
+  bitsPerFrame = (bit_rate*gfp->framesize*1000)/gfp->out_samplerate;
+  mean_bits = (bitsPerFrame - 8*gfc->sideinfo_len) / gfc->mode_gr;
+  }
+
+
+  minbits = Max(minbits,125);
+  minbits=Max(minbits,.40*(mean_bits/gfc->channels_out));
+  maxbits=Min(maxbits,2.5*(mean_bits/gfc->channels_out));
+
+
+
+
+
+
+
+  /* 
+   * loop over all ch,gr, encoding anything with bits > .5*(max_frame_bits/4)
+   *
+   * If a particular granule uses way too many bits, it will be re-encoded
+   * on the next iteration of the loop (with a lower quality setting).  
+   * But granules which dont use
+   * use too many bits will not be re-encoded.
+   *
+   * minbits:  minimum allowed bits for 1 granule 1 channel
+   * maxbits:  maximum allowwed bits for 1 granule 1 channel
+   * max_frame_bits:  maximum allowed bits for entire frame
+   * (max_frame_bits/4)   estimate of average bits per granule per channel
+   * 
+   */
+
+  do {
+  
+    totbits=0;
+    for (gr = 0; gr < gfc->mode_gr; ++gr) {
+      int minbits_lr[2];
+      minbits_lr[0]=minbits;
+      minbits_lr[1]=minbits;
+
+#if 0
+      if (gfc->mode_ext==MPG_MD_MS_LR) {
+        FLOAT8 fac;
+        fac = .33*(.5-ms_ener_ratio[gr])/.5;
+        if (fac<0) fac=0;
+        if (fac>.5) fac=.5;
+        minbits_lr[0] = (1+fac)*minbits;
+        minbits_lr[1] = Max(125,(1-fac)*minbits);
+      }
+#endif
+
+
+      for (ch = 0; ch < gfc->channels_out; ++ch) { 
+        int adjusted,shortblock;
+        cod_info = &l3_side->gr[gr].ch[ch].tt;
+        
+        /* ENCODE this data first pass, and on future passes unless it uses
+         * a very small percentage of the max_frame_bits  */
+        if (cod_info->part2_3_length > (max_frame_bits/(2*gfc->channels_out*gfc->mode_gr))) {
+  
+          shortblock = (cod_info->block_type == SHORT_TYPE);
+  
+          /* Adjust allowed masking based on quality setting */
+          if (qadjust!=0 /*|| shortblock*/) {
+            masking_lower_db = gfc->VBR->mask_adjust + qadjust;
+
+            /*
+            if (shortblock) masking_lower_db -= 4;
+            */
+     
+            if (pe[gr][ch]>750)
+              masking_lower_db -= Min(10,4*(pe[gr][ch]-750.)/750.);
+            gfc->masking_lower = pow(10.0,masking_lower_db/10);
+            calc_xmin( gfp, xr[gr][ch], ratio[gr]+ch, cod_info, l3_xmin[gr]+ch);
+          }
+          
+          /* digital silent granules do not need the full round trip,
+           * but this can be optimized later on
+           */
+          adjusted = VBR_noise_shaping (gfp,xr[gr][ch],xr34[gr][ch],
+                                        l3_enc[gr][ch],
+                                        digital_silence[gr][ch],
+                                        minbits_lr[ch],
+                                        maxbits,scalefac[gr]+ch,
+                                        l3_xmin[gr]+ch,gr,ch);
+          if (adjusted>10) {
+            /* global_gain was changed by a large amount to get bits < maxbits */
+            /* quality is set to high.  we could set bits = LARGE_BITS
+             * to force re-encoding.  But most likely the other channels/granules
+             * will also use too many bits, and the entire frame will
+             * be > max_frame_bits, forcing re-encoding below.
+             */
+            // cod_info->part2_3_bits = LARGE_BITS;
+          }
+        }
+        totbits += cod_info->part2_3_length;
+      }
+    }
+    bits_ok=1;
+    if (totbits>max_frame_bits) {
+      /* lower quality */
+      qadjust += Max(.125,Min(1,(totbits-max_frame_bits)/300.0));
+      /* adjusting minbits and maxbits is necessary too
+       * cos lowering quality is not enough in rare cases
+       * when each granule still needs almost maxbits, it wont fit */ 
+      minbits = Max(125,minbits*0.975);
+      maxbits = Max(minbits,maxbits*0.975);
+      //      DEBUGF("%i totbits>max_frame_bits   totbits=%i  maxbits=%i \n",gfp->frameNum,totbits,max_frame_bits);
+      //      DEBUGF("next masking_lower_db = %f \n",masking_lower_db + qadjust);
+      bits_ok=0;
+    }
+    
+  } while (!bits_ok);
+  
+
+
+  /* find optimal scalefac storage.  Cant be done above because
+   * might enable scfsi which breaks the interation loops */
+  totbits=0;
+  for (gr = 0; gr < gfc->mode_gr; ++gr) {
+    for (ch = 0; ch < gfc->channels_out; ++ch) {
+      best_scalefac_store(gfc, gr, ch, l3_enc, l3_side, scalefac);
+      totbits += l3_side->gr[gr].ch[ch].tt.part2_3_length;
+    }
+  }
+
+
+  
+
+  if (analog_silence && !gfp->VBR_hard_min) {
+    gfc->bitrate_index = 1;
+  } else {
+    gfc->bitrate_index = gfc->VBR_min_bitrate;
+  }
+  for( ; gfc->bitrate_index < gfc->VBR_max_bitrate; ++gfc->bitrate_index ) {
+
+    getframebits (gfp, &bitsPerFrame, &mean_bits);
+    maxbits = ResvFrameBegin(gfp, l3_side, mean_bits, bitsPerFrame);
+    if (totbits <= maxbits) break;
+  }
+  if (gfc->bitrate_index == gfc->VBR_max_bitrate) {
+    getframebits (gfp, &bitsPerFrame, &mean_bits);
+    maxbits = ResvFrameBegin(gfp, l3_side, mean_bits, bitsPerFrame);
+  }
+
+  //  DEBUGF("%i total_bits=%i max_frame_bits=%i index=%i  \n",gfp->frameNum,totbits,max_frame_bits,gfc->bitrate_index);
+
+  for (gr = 0; gr < gfc->mode_gr; ++gr) {
+    for (ch = 0; ch < gfc->channels_out; ++ch) {
+      cod_info = &l3_side->gr[gr].ch[ch].tt;
+
+
+      ResvAdjust (gfc, cod_info, l3_side, mean_bits);
+      
+      /*******************************************************************
+       * set the sign of l3_enc from the sign of xr
+       *******************************************************************/
+      for ( i = 0; i < 576; ++i) {
+        if (xr[gr][ch][i] < 0) l3_enc[gr][ch][i] *= -1;
+      }
+    }
+  }
+  ResvFrameEnd (gfc, l3_side, mean_bits);
+
+
+
+}
+
+
+
+
diff --git a/lib/lame/vbrquantize.h b/lib/lame/vbrquantize.h
new file mode 100644 (file)
index 0000000..9eff403
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * MP3 VBR quantization
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_VBRQUANTIZE_H
+#define LAME_VBRQUANTIZE_H
+
+void VBR_quantize( 
+                    lame_global_flags      *gfp,
+                   FLOAT8         pe[2][2], 
+                    FLOAT8         ms_ener_ratio[2],
+                   FLOAT8         xr[2][2][576], 
+                    III_psy_ratio  ratio[2][2],
+                   int            l3_enc[2][2][576],
+                   III_scalefac_t scalefac[2][2]);
+
+
+int VBR_noise_shaping2(
+                    lame_global_flags * gfp,
+                    FLOAT8            * xr, 
+                    FLOAT8            * xr34orig, 
+                    int               * l3_enc, 
+                    int                 minbits, 
+                    int                 maxbits,
+                    III_scalefac_t    * scalefac, 
+                    III_psy_xmin      * l3_xmin,
+                    int                 gr,
+                    int                 ch );
+
+#endif /* LAME_VBRQUANTIZE_H */
diff --git a/lib/lame/version.c b/lib/lame/version.c
new file mode 100644 (file)
index 0000000..f5e45e9
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ *      Version numbering for LAME.
+ *
+ *      Copyright (c) 1999 A.L. Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*!
+  \file   version.c
+  \brief  Version numbering for LAME.
+
+  Contains functions which describe the version of LAME.
+
+  \author A.L. Faber
+  \version \$Id: version.c,v 1.1 2002/04/28 17:30:31 kramm Exp $
+  \ingroup libmp3lame
+*/
+
+
+#include "config_static.h"
+
+
+#include <stdio.h>
+#include "version.h"    /* macros of version numbers */
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+//! Stringify \a x.
+#define STR(x)   #x
+//! Stringify \a x, perform macro expansion.
+#define XSTR(x)  STR(x)
+
+#if defined(MMX_choose_table)
+# define V1  "MMX "
+#else
+# define V1  ""
+#endif
+
+#if defined(KLEMM)
+# define V2  "KLM "
+#else
+# define V2  ""
+#endif
+
+#if defined(RH)
+# define V3  "RH "
+#else
+# define V3  ""
+#endif
+
+//! Compile time features.
+#define V   V1 V2 V3
+
+//! Get the LAME version string.
+/*!
+  \param void
+  \return a pointer to a string which describes the version of LAME.
+*/
+const char*  get_lame_version ( void )         /* primary to write screen reports */
+{
+    /* Here we can also add informations about compile time configurations */
+
+#if   LAME_ALPHA_VERSION > 0
+    static /*@observer@*/ const char *const str =
+        XSTR(LAME_MAJOR_VERSION) "." XSTR(LAME_MINOR_VERSION) " " V
+        "(alpha " XSTR(LAME_ALPHA_VERSION) ", " __DATE__ " " __TIME__ ")";
+#elif LAME_BETA_VERSION > 0
+    static /*@observer@*/ const char *const str =
+        XSTR(LAME_MAJOR_VERSION) "." XSTR(LAME_MINOR_VERSION) " " V
+        "(beta " XSTR(LAME_BETA_VERSION) ", " __DATE__ ")";
+#else
+    static /*@observer@*/ const char *const str =
+        XSTR(LAME_MAJOR_VERSION) "." XSTR(LAME_MINOR_VERSION) " " V;
+#endif
+
+    return str;
+}
+
+
+//! Get the short LAME version string.
+/*!
+  It's mainly for inclusion into the MP3 stream.
+
+  \param void   
+  \return a pointer to the short version of the LAME version string.
+*/
+const char*  get_lame_short_version ( void )
+{
+    /* adding date and time to version string makes it harder for output
+       validation */
+
+#if   LAME_ALPHA_VERSION > 0
+    static /*@observer@*/ const char *const str =
+        XSTR(LAME_MAJOR_VERSION) "." XSTR(LAME_MINOR_VERSION) " (alpha)";
+#elif LAME_BETA_VERSION > 0
+    static /*@observer@*/ const char *const str =
+        XSTR(LAME_MAJOR_VERSION) "." XSTR(LAME_MINOR_VERSION) " (beta)";
+#else
+    static /*@observer@*/ const char *const str =
+        XSTR(LAME_MAJOR_VERSION) "." XSTR(LAME_MINOR_VERSION);
+#endif
+
+    return str;
+}
+
+//! Get the _very_ short LAME version string.
+/*!
+  It's used in the LAME VBR tag only.
+
+  \param void   
+  \return a pointer to the short version of the LAME version string.
+*/
+const char*  get_lame_very_short_version ( void )
+{
+    /* adding date and time to version string makes it harder for output
+       validation */
+
+#if   LAME_ALPHA_VERSION > 0
+    static /*@observer@*/ const char *const str =
+       "LAME" XSTR(LAME_MAJOR_VERSION) "." XSTR(LAME_MINOR_VERSION) "a";
+#elif LAME_BETA_VERSION > 0
+    static /*@observer@*/ const char *const str =
+       "LAME" XSTR(LAME_MAJOR_VERSION) "." XSTR(LAME_MINOR_VERSION) "b";
+#else
+    static /*@observer@*/ const char *const str =
+       "LAME" XSTR(LAME_MAJOR_VERSION) "." XSTR(LAME_MINOR_VERSION) " ";
+#endif
+
+    return str;
+}
+
+//! Get the version string for GPSYCHO.
+/*!
+  \param void
+  \return a pointer to a string which describes the version of GPSYCHO.
+*/
+const char*  get_psy_version ( void )
+{
+#if   PSY_ALPHA_VERSION > 0
+    static /*@observer@*/ const char *const str =
+        XSTR(PSY_MAJOR_VERSION) "." XSTR(PSY_MINOR_VERSION)
+        " (alpha " XSTR(PSY_ALPHA_VERSION) ", " __DATE__ " " __TIME__ ")";
+#elif PSY_BETA_VERSION > 0
+    static /*@observer@*/ const char *const str =
+        XSTR(PSY_MAJOR_VERSION) "." XSTR(PSY_MINOR_VERSION)
+        " (beta " XSTR(PSY_BETA_VERSION) ", " __DATE__ ")";
+#else
+    static /*@observer@*/ const char *const str =
+        XSTR(PSY_MAJOR_VERSION) "." XSTR(PSY_MINOR_VERSION);
+#endif
+
+    return str;
+}
+
+
+//! Get the URL for the LAME website.
+/*!
+  \param void
+  \return a pointer to a string which is a URL for the LAME website.
+*/
+const char*  get_lame_url ( void )
+{
+    static /*@observer@*/ const char *const str = LAME_URL;
+
+    return str;
+}    
+
+
+//! Get the numerical representation of the version.
+/*!
+  Writes the numerical representation of the version of LAME and
+  GPSYCHO into lvp.
+
+  \param lvp    
+*/
+void get_lame_version_numerical ( lame_version_t *const lvp )
+{
+    static /*@observer@*/ const char *const features = V;
+
+    /* generic version */
+    lvp->major = LAME_MAJOR_VERSION;
+    lvp->minor = LAME_MINOR_VERSION;
+    lvp->alpha = LAME_ALPHA_VERSION;
+    lvp->beta  = LAME_BETA_VERSION;
+
+    /* psy version */
+    lvp->psy_major = PSY_MAJOR_VERSION;
+    lvp->psy_minor = PSY_MINOR_VERSION;
+    lvp->psy_alpha = PSY_ALPHA_VERSION;
+    lvp->psy_beta  = PSY_BETA_VERSION;
+
+    /* compile time features */
+    /*@-mustfree@*/
+    lvp->features = features;
+    /*@=mustfree@*/
+}
+
+/* end of version.c */
diff --git a/lib/lame/version.h b/lib/lame/version.h
new file mode 100644 (file)
index 0000000..2b8a9e5
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *      Version numbering for LAME.
+ *
+ *      Copyright (c) 1999 A.L. Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_VERSION_H
+#define LAME_VERSION_H
+
+# include "lame.h"
+
+/* 
+ * To make a string from a token, use the # operator:
+ *
+ * #define __STR(x)  #x
+ * #define STR(x)    __STR(x)
+ */
+
+# define LAME_URL              "http://www.mp3dev.org/"
+
+# define LAME_MAJOR_VERSION      3      /* Major version number */
+# define LAME_MINOR_VERSION     91      /* Minor version number */
+# define LAME_ALPHA_VERSION      0      /* Patch level of alpha version, otherwise zero */
+# define LAME_BETA_VERSION       0      /* Patch level of beta  version, otherwise zero */
+
+# define PSY_MAJOR_VERSION       0      /* Major version number */
+# define PSY_MINOR_VERSION      89      /* Minor version number */
+# define PSY_ALPHA_VERSION       0      /* Set number if this is an alpha version, otherwise zero */
+# define PSY_BETA_VERSION        0      /* Set number if this is a beta version, otherwise zero */
+
+
+const char*  get_lame_version       ( void );
+const char*  get_lame_short_version ( void );
+const char*  get_psy_version        ( void );
+const char*  get_lame_url           ( void );
+void         get_lame_version_numerical ( lame_version_t *const lvp );
+
+#endif  /* LAME_VERSION_H */
+
+/* End of version.h */