--- /dev/null
+/*
+ * 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 */
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/* 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
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+** 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;
+}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+
+#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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/* -*- 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+
+#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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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));
+ }
+ }
+}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 );
+}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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);
+}
+
+
+
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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;
+}
+
+
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/* -*- 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;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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);
+
+
+
+}
+
+
+
+
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */