/* * 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. */ #include #ifdef HAVEGTK #include "gtkanal.h" #include #endif #include "lame.h" #include "util.h" #include "timestatus.h" #include "psymodel.h" #include "newmdct.h" #include "quantize.h" #include "quantize-pvt.h" #include "l3bitstream.h" #include "formatBitstream.h" #include "version.h" #include "VbrTag.h" #include "id3tag.h" #include "tables.h" #include "brhist.h" #include "get_audio.h" #ifdef __riscos__ #include "asmstuff.h" #endif /* Global variable definitions for lame.c */ static Bit_stream_struc bs; static III_side_info_t l3_side; #define MFSIZE (1152+1152+ENCDELAY-MDCTDELAY) static short int mfbuf[2][MFSIZE]; static int mf_size; static int mf_samples_to_encode; /******************************************************************** * initialize internal params based on data in gf * (globalflags struct filled in by calling program) * ********************************************************************/ void lame_init_params(lame_global_flags *gfp) { int i; FLOAT compression_ratio; memset(&bs, 0, sizeof(Bit_stream_struc)); memset(&l3_side,0x00,sizeof(III_side_info_t)); gfp->frameNum=0; InitFormatBitStream(); if (gfp->num_channels==1) { gfp->mode = MPG_MD_MONO; } gfp->stereo=2; if (gfp->mode == MPG_MD_MONO) gfp->stereo=1; #ifdef BRHIST if (gfp->silent) { disp_brhist=0; /* turn of VBR historgram */ } if (!gfp->VBR) { disp_brhist=0; /* turn of VBR historgram */ } #endif /* set the output sampling rate, and resample options if necessary samplerate = input sample rate resamplerate = ouput sample rate */ if (gfp->out_samplerate==0) { /* user did not specify output sample rate */ gfp->out_samplerate=gfp->in_samplerate; /* default */ /* if resamplerate is not valid, find a valid value */ if (gfp->out_samplerate>=48000) gfp->out_samplerate=48000; else if (gfp->out_samplerate>=44100) gfp->out_samplerate=44100; else if (gfp->out_samplerate>=32000) gfp->out_samplerate=32000; else if (gfp->out_samplerate>=24000) gfp->out_samplerate=24000; else if (gfp->out_samplerate>=22050) gfp->out_samplerate=22050; else gfp->out_samplerate=16000; if (gfp->brate>0) { /* check if user specified bitrate requires downsampling */ compression_ratio = gfp->out_samplerate*16*gfp->stereo/(1000.0*gfp->brate); if (!gfp->VBR && compression_ratio > 13 ) { /* automatic downsample, if possible */ gfp->out_samplerate = (10*1000.0*gfp->brate)/(16*gfp->stereo); if (gfp->out_samplerate<=16000) gfp->out_samplerate=16000; else if (gfp->out_samplerate<=22050) gfp->out_samplerate=22050; else if (gfp->out_samplerate<=24000) gfp->out_samplerate=24000; else if (gfp->out_samplerate<=32000) gfp->out_samplerate=32000; else if (gfp->out_samplerate<=44100) gfp->out_samplerate=44100; else gfp->out_samplerate=48000; } } } gfp->mode_gr = (gfp->out_samplerate <= 24000) ? 1 : 2; /* mode_gr = 2 */ gfp->encoder_delay = ENCDELAY; gfp->framesize = gfp->mode_gr*576; if (gfp->brate==0) { /* user didn't specify a bitrate, use default */ gfp->brate=128; if (gfp->mode_gr==1) gfp->brate=64; } gfp->resample_ratio=1; if (gfp->out_samplerate != gfp->in_samplerate) gfp->resample_ratio = (FLOAT)gfp->in_samplerate/(FLOAT)gfp->out_samplerate; /* estimate total frames. must be done after setting sampling rate so * we know the framesize. */ gfp->totalframes=0; gfp->totalframes = 2+ gfp->num_samples/(gfp->resample_ratio*gfp->framesize); /* 44.1kHz at 56kbs/channel: compression factor of 12.6 44.1kHz at 64kbs/channel: compression factor of 11.025 44.1kHz at 80kbs/channel: compression factor of 8.82 22.05kHz at 24kbs: 14.7 22.05kHz at 32kbs: 11.025 22.05kHz at 40kbs: 8.82 16kHz at 16kbs: 16.0 16kHz at 24kbs: 10.7 compression_ratio 11 .70? 12 sox resample .66 14.7 sox resample .45 */ if (gfp->brate >= 320) gfp->VBR=0; /* dont bother with VBR at 320kbs */ compression_ratio = gfp->out_samplerate*16*gfp->stereo/(1000.0*gfp->brate); /* for VBR, take a guess at the compression_ratio */ /* VBR_q compression like 0 4.4 320kbs 1 5.4 256kbs 3 7.4 192kbs 4 8.8 160kbs 6 10.4 128kbs */ if (gfp->VBR && compression_ratio>11) { compression_ratio = 4.4 + gfp->VBR_q; } /* At higher quality (lower compression) use STEREO instead of JSTEREO. * (unless the user explicitly specified a mode ) */ if ( (!gfp->mode_fixed) && (gfp->mode !=MPG_MD_MONO)) { if (compression_ratio < 9 ) { gfp->mode = MPG_MD_STEREO; } } /****************************************************************/ /* if a filter has not been enabled, see if we should add one: */ /****************************************************************/ if (gfp->lowpassfreq == 0) { /* If the user has not selected their own filter, add a lowpass * filter based on the compression ratio. Formula based on 44.1 /160 4.4x 44.1 /128 5.5x keep all bands 44.1 /96kbs 7.3x keep band 28 44.1 /80kbs 8.8x keep band 25 44.1khz/64kbs 11x keep band 21 22? 16khz/24kbs 10.7x keep band 21 22kHz/32kbs 11x keep band ? 22kHz/24kbs 14.7x keep band 16 16 16 16x keep band 14 */ /* Should we use some lowpass filters? */ int band = 1+floor(.5 + 14-18*log(compression_ratio/16.0)); if (band < 31) { gfp->lowpass1 = band/31.0; gfp->lowpass2 = band/31.0; } } /****************************************************************/ /* apply user driven filters*/ /****************************************************************/ if ( gfp->highpassfreq > 0 ) { gfp->highpass1 = 2.0*gfp->highpassfreq/gfp->out_samplerate; /* will always be >=0 */ if ( gfp->highpasswidth >= 0 ) { gfp->highpass2 = 2.0*(gfp->highpassfreq+gfp->highpasswidth)/gfp->out_samplerate; } else { /* 15% above on default */ /* gfp->highpass2 = 1.15*2.0*gfp->highpassfreq/gfp->out_samplerate; */ gfp->highpass2 = 1.00*2.0*gfp->highpassfreq/gfp->out_samplerate; } gfp->highpass1 = Min( 1, gfp->highpass1 ); gfp->highpass2 = Min( 1, gfp->highpass2 ); } if ( gfp->lowpassfreq > 0 ) { gfp->lowpass2 = 2.0*gfp->lowpassfreq/gfp->out_samplerate; /* will always be >=0 */ if ( gfp->lowpasswidth >= 0 ) { gfp->lowpass1 = 2.0*(gfp->lowpassfreq-gfp->lowpasswidth)/gfp->out_samplerate; if ( gfp->lowpass1 < 0 ) { /* has to be >= 0 */ gfp->lowpass1 = 0; } } else { /* 15% below on default */ /* gfp->lowpass1 = 0.85*2.0*gfp->lowpassfreq/gfp->out_samplerate; */ gfp->lowpass1 = 1.00*2.0*gfp->lowpassfreq/gfp->out_samplerate; } gfp->lowpass1 = Min( 1, gfp->lowpass1 ); gfp->lowpass2 = Min( 1, gfp->lowpass2 ); } /***************************************************************/ /* compute info needed for polyphase filter */ /***************************************************************/ if (gfp->filter_type==0) { int band,maxband,minband; FLOAT8 amp,freq; if (gfp->lowpass1 > 0) { minband=999; maxband=-1; for (band=0; band <=31 ; ++band) { freq = band/31.0; amp = 1; /* this band and above will be zeroed: */ if (freq >= gfp->lowpass2) { gfp->lowpass_band= Min(gfp->lowpass_band,band); amp=0; } if (gfp->lowpass1 < freq && freq < gfp->lowpass2) { minband = Min(minband,band); maxband = Max(maxband,band); amp = cos((PI/2)*(gfp->lowpass1-freq)/(gfp->lowpass2-gfp->lowpass1)); } /* printf("lowpass band=%i amp=%f \n",band,amp);*/ } /* compute the *actual* transition band implemented by the polyphase filter */ if (minband==999) gfp->lowpass1 = (gfp->lowpass_band-.75)/31.0; else gfp->lowpass1 = (minband-.75)/31.0; gfp->lowpass2 = gfp->lowpass_band/31.0; } /* make sure highpass filter is within 90% of whan the effective highpass * frequency will be */ if (gfp->highpass2 > 0) if (gfp->highpass2 < .9*(.75/31.0) ) { gfp->highpass1=0; gfp->highpass2=0; fprintf(stderr,"Warning: highpass filter disabled. highpass frequency to small\n"); } if (gfp->highpass2 > 0) { minband=999; maxband=-1; for (band=0; band <=31; ++band) { freq = band/31.0; amp = 1; /* this band and below will be zereod */ if (freq <= gfp->highpass1) { gfp->highpass_band = Max(gfp->highpass_band,band); amp=0; } if (gfp->highpass1 < freq && freq < gfp->highpass2) { minband = Min(minband,band); maxband = Max(maxband,band); amp = cos((PI/2)*(gfp->highpass2-freq)/(gfp->highpass2-gfp->highpass1)); } /* printf("highpass band=%i amp=%f \n",band,amp);*/ } /* compute the *actual* transition band implemented by the polyphase filter */ gfp->highpass1 = gfp->highpass_band/31.0; if (maxband==-1) gfp->highpass2 = (gfp->highpass_band+.75)/31.0; else gfp->highpass2 = (maxband+.75)/31.0; } /* printf("lowpass band with amp=0: %i \n",gfp->lowpass_band); printf("highpass band with amp=0: %i \n",gfp->highpass_band); */ } /***************************************************************/ /* compute info needed for FIR filter */ /***************************************************************/ if (gfp->filter_type==1) { } gfp->mode_ext=MPG_MD_LR_LR; gfp->stereo = (gfp->mode == MPG_MD_MONO) ? 1 : 2; gfp->samplerate_index = SmpFrqIndex((long)gfp->out_samplerate, &gfp->version); if( gfp->samplerate_index < 0) { display_bitrates(stderr); exit(1); } if( (gfp->bitrate_index = BitrateIndex(gfp->brate, gfp->version,gfp->out_samplerate)) < 0) { display_bitrates(stderr); exit(1); } /* choose a min/max bitrate for VBR */ if (gfp->VBR) { /* if the user didn't specify VBR_max_bitrate: */ if (0==gfp->VBR_max_bitrate_kbps) { /* default max bitrate is 256kbs */ /* we do not normally allow 320bps frams with VBR, unless: */ gfp->VBR_max_bitrate=13; /* default: allow 256kbs */ if (gfp->VBR_min_bitrate_kbps>=256) gfp->VBR_max_bitrate=14; if (gfp->VBR_q == 0) gfp->VBR_max_bitrate=14; /* allow 320kbs */ if (gfp->VBR_q >= 4) gfp->VBR_max_bitrate=12; /* max = 224kbs */ if (gfp->VBR_q >= 8) gfp->VBR_max_bitrate=9; /* low quality, max = 128kbs */ }else{ if( (gfp->VBR_max_bitrate = BitrateIndex(gfp->VBR_max_bitrate_kbps, gfp->version,gfp->out_samplerate)) < 0) { display_bitrates(stderr); exit(1); } } if (0==gfp->VBR_min_bitrate_kbps) { gfp->VBR_min_bitrate=1; /* 32 kbps */ }else{ if( (gfp->VBR_min_bitrate = BitrateIndex(gfp->VBR_min_bitrate_kbps, gfp->version,gfp->out_samplerate)) < 0) { display_bitrates(stderr); exit(1); } } } if (gfp->VBR) gfp->quality=Min(gfp->quality,2); /* always use quality <=2 with VBR */ /* dont allow forced mid/side stereo for mono output */ if (gfp->mode == MPG_MD_MONO) gfp->force_ms=0; /* Do not write VBR tag if VBR flag is not specified */ if (gfp->VBR==0) gfp->bWriteVbrTag=0; /* some file options not allowed if output is: not specified or stdout */ if (gfp->outPath!=NULL && gfp->outPath[0]=='-' ) { gfp->bWriteVbrTag=0; /* turn off VBR tag */ } if (gfp->outPath==NULL || gfp->outPath[0]=='-' ) { id3tag.used=0; /* turn of id3 tagging */ } if (gfp->gtkflag) { gfp->bWriteVbrTag=0; /* disable Xing VBR tag */ } init_bit_stream_w(&bs); /* set internal feature flags. USER should not access these since * some combinations will produce strange results */ /* no psymodel, no noise shaping */ if (gfp->quality==9) { gfp->filter_type=0; gfp->psymodel=0; gfp->quantization=0; gfp->noise_shaping=0; gfp->noise_shaping_stop=0; gfp->use_best_huffman=0; } if (gfp->quality==8) gfp->quality=7; /* use psymodel (for short block and m/s switching), but no noise shapping */ if (gfp->quality==7) { gfp->filter_type=0; gfp->psymodel=1; gfp->quantization=0; gfp->noise_shaping=0; gfp->noise_shaping_stop=0; gfp->use_best_huffman=0; } if (gfp->quality==6) gfp->quality=5; if (gfp->quality==5) { /* the default */ gfp->filter_type=0; gfp->psymodel=1; gfp->quantization=0; gfp->noise_shaping=1; gfp->noise_shaping_stop=0; gfp->use_best_huffman=0; } if (gfp->quality==4) gfp->quality=2; if (gfp->quality==3) gfp->quality=2; if (gfp->quality==2) { gfp->filter_type=0; gfp->psymodel=1; gfp->quantization=1; gfp->noise_shaping=1; gfp->noise_shaping_stop=0; gfp->use_best_huffman=1; } if (gfp->quality==1) { gfp->filter_type=0; gfp->psymodel=1; gfp->quantization=1; gfp->noise_shaping=1; gfp->noise_shaping_stop=1; gfp->use_best_huffman=1; } if (gfp->quality==0) { /* 0..1 quality */ gfp->filter_type=1; /* not yet coded */ gfp->psymodel=1; gfp->quantization=1; gfp->noise_shaping=3; /* not yet coded */ gfp->noise_shaping_stop=2; /* not yet coded */ gfp->use_best_huffman=2; /* not yet coded */ exit(-99); } for (i = 0; i < SBMAX_l + 1; i++) { scalefac_band.l[i] = sfBandIndex[gfp->samplerate_index + (gfp->version * 3)].l[i]; } for (i = 0; i < SBMAX_s + 1; i++) { scalefac_band.s[i] = sfBandIndex[gfp->samplerate_index + (gfp->version * 3)].s[i]; } if (gfp->bWriteVbrTag) { /* Write initial VBR Header to bitstream */ InitVbrTag(&bs,1-gfp->version,gfp->mode,gfp->samplerate_index); } #ifdef HAVEGTK gtkflag=gfp->gtkflag; #endif #ifdef BRHIST if (gfp->VBR) { if (disp_brhist) brhist_init(gfp,1, 14); } else disp_brhist = 0; #endif return; } /************************************************************************ * * print_config * * PURPOSE: Prints the encoding parameters used * ************************************************************************/ void lame_print_config(lame_global_flags *gfp) { static const char *mode_names[4] = { "stereo", "j-stereo", "dual-ch", "single-ch" }; FLOAT out_samplerate=gfp->out_samplerate/1000.0; FLOAT in_samplerate = gfp->resample_ratio*out_samplerate; FLOAT compression= (FLOAT)(gfp->stereo*16*out_samplerate)/(FLOAT)(gfp->brate); // lame_print_version(stderr); /* if (gfp->num_channels==2 && gfp->stereo==1) { fprintf(stderr, "Autoconverting from stereo to mono. Setting encoding to mono mode.\n"); } if (gfp->resample_ratio!=1) { fprintf(stderr,"Resampling: input=%ikHz output=%ikHz\n", (int)in_samplerate,(int)out_samplerate); } if (gfp->highpass2>0.0) fprintf(stderr, "Using polyphase highpass filter, transition band: %.0f Hz - %.0f Hz\n", gfp->highpass1*out_samplerate*500, gfp->highpass2*out_samplerate*500); if (gfp->lowpass1>0.0) fprintf(stderr, "Using polyphase lowpass filter, transition band: %.0f Hz - %.0f Hz\n", gfp->lowpass1*out_samplerate*500, gfp->lowpass2*out_samplerate*500); */ if (gfp->gtkflag) { fprintf(stderr, "Analyzing %s \n",gfp->inPath); } else { /* fprintf(stderr, "Encoding %s to %s\n", (strcmp(gfp->inPath, "-")? gfp->inPath : "stdin"), (strcmp(gfp->outPath, "-")? gfp->outPath : "stdout")); */ if (gfp->VBR) fprintf(stderr, "Encoding as %.1fkHz VBR(q=%i) %s MPEG%i LayerIII qval=%i\n", gfp->out_samplerate/1000.0, gfp->VBR_q,mode_names[gfp->mode],2-gfp->version,gfp->quality); else fprintf(stderr, "Encoding as %.1f kHz %d kbps %s MPEG%i LayerIII (%4.1fx) qval=%i\n", gfp->out_samplerate/1000.0,gfp->brate, mode_names[gfp->mode],2-gfp->version,compression,gfp->quality); } fflush(stderr); } /************************************************************************ * * 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 day, 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 */ int lame_encode_frame(lame_global_flags *gfp, short int inbuf_l[],short int inbuf_r[], int mf_size,char *mp3buf, int mp3buf_size) { static unsigned long frameBits; static unsigned long bitsPerSlot; static FLOAT8 frac_SpF; static FLOAT8 slot_lag; static unsigned long sentBits = 0; FLOAT8 xr[2][2][576]; int l3_enc[2][2][576]; int mp3count; III_psy_ratio masking_ratio[2][2]; /*LR ratios */ III_psy_ratio masking_MS_ratio[2][2]; /*MS ratios */ III_psy_ratio (*masking)[2][2]; /*LR ratios and MS ratios*/ III_scalefac_t scalefac[2][2]; short int *inbuf[2]; typedef FLOAT8 pedata[2][2]; pedata pe,pe_MS; pedata *pe_use; int ch,gr,mean_bits; int bitsPerFrame; int check_ms_stereo; static FLOAT8 ms_ratio[2]={0,0}; FLOAT8 ms_ratio_next=0; FLOAT8 ms_ratio_prev=0; static FLOAT8 ms_ener_ratio[2]={0,0}; memset((char *) masking_ratio, 0, sizeof(masking_ratio)); memset((char *) masking_MS_ratio, 0, sizeof(masking_MS_ratio)); memset((char *) scalefac, 0, sizeof(scalefac)); inbuf[0]=inbuf_l; inbuf[1]=inbuf_r; gfp->mode_ext = MPG_MD_LR_LR; if (gfp->frameNum==0 ) { /* Figure average number of 'slots' per frame. */ FLOAT8 avg_slots_per_frame; FLOAT8 sampfreq = gfp->out_samplerate/1000.0; int bit_rate = gfp->brate; sentBits = 0; bitsPerSlot = 8; avg_slots_per_frame = (bit_rate*gfp->framesize) / (sampfreq* bitsPerSlot); /* -f fast-math option causes some strange rounding here, be carefull: */ frac_SpF = avg_slots_per_frame - floor(avg_slots_per_frame + 1e-9); if (fabs(frac_SpF) < 1e-9) frac_SpF = 0; slot_lag = -frac_SpF; gfp->padding = 1; if (frac_SpF==0) gfp->padding = 0; /* check FFT will not use a negative starting offset */ assert(576>=FFTOFFSET); /* check if we have enough data for FFT */ assert(mf_size>=(BLKSIZE+gfp->framesize-FFTOFFSET)); } /********************** padding *****************************/ switch (gfp->padding_type) { case 0: gfp->padding=0; break; case 1: gfp->padding=1; break; case 2: default: if (gfp->VBR) { gfp->padding=0; } else { if (gfp->disable_reservoir) { gfp->padding = 0; /* if the user specified --nores, dont very gfp->padding either */ /* tiny changes in frac_SpF rounding will cause file differences */ }else{ if (frac_SpF != 0) { if (slot_lag > (frac_SpF-1.0) ) { slot_lag -= frac_SpF; gfp->padding = 0; } else { gfp->padding = 1; slot_lag += (1-frac_SpF); } } } } } /********************** status display *****************************/ if (!gfp->gtkflag && !gfp->silent) { int mod = gfp->version == 0 ? 200 : 50; if (gfp->frameNum%mod==0) { timestatus(gfp->out_samplerate,gfp->frameNum,gfp->totalframes,gfp->framesize); #ifdef BRHIST if (disp_brhist) { brhist_add_count(); brhist_disp(); } #endif } } if (gfp->psymodel) { /* psychoacoustic model * psy model has a 1 granule (576) delay that we must compensate for * (mt 6/99). */ short int *bufp[2]; /* address of beginning of left & right granule */ int blocktype[2]; ms_ratio_prev=ms_ratio[gfp->mode_gr-1]; for (gr=0; gr < gfp->mode_gr ; gr++) { for ( ch = 0; ch < gfp->stereo; ch++ ) bufp[ch] = &inbuf[ch][576 + gr*576-FFTOFFSET]; L3psycho_anal( gfp,bufp, gr, &ms_ratio[gr],&ms_ratio_next,&ms_ener_ratio[gr], masking_ratio, masking_MS_ratio, pe[gr],pe_MS[gr],blocktype); for ( ch = 0; ch < gfp->stereo; ch++ ) l3_side.gr[gr].ch[ch].tt.block_type=blocktype[ch]; } }else{ for (gr=0; gr < gfp->mode_gr ; gr++) for ( ch = 0; ch < gfp->stereo; ch++ ) { l3_side.gr[gr].ch[ch].tt.block_type=NORM_TYPE; pe[gr][ch]=700; } } /* block type flags */ for( gr = 0; gr < gfp->mode_gr; gr++ ) { for ( ch = 0; ch < gfp->stereo; ch++ ) { gr_info *cod_info = &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(gfp,inbuf[0], inbuf[1], xr, &l3_side); /* use m/s gfp->stereo? */ check_ms_stereo = (gfp->mode == MPG_MD_JOINT_STEREO); if (check_ms_stereo) { /* make sure block type is the same in each channel */ check_ms_stereo = (l3_side.gr[0].ch[0].tt.block_type==l3_side.gr[0].ch[1].tt.block_type) && (l3_side.gr[1].ch[0].tt.block_type==l3_side.gr[1].ch[1].tt.block_type); } if (check_ms_stereo) { /* ms_ratio = is like the ratio of side_energy/total_energy */ FLOAT8 ms_ratio_ave,ms_ener_ratio_ave; /* ms_ratio_ave = .5*(ms_ratio[0] + ms_ratio[1]);*/ ms_ratio_ave = .25*(ms_ratio[0] + ms_ratio[1]+ ms_ratio_prev + ms_ratio_next); ms_ener_ratio_ave = .5*(ms_ener_ratio[0]+ms_ener_ratio[1]); if ( ms_ratio_ave <.35 /*&& ms_ener_ratio_ave<.75*/ ) gfp->mode_ext = MPG_MD_MS_LR; } if (gfp->force_ms) gfp->mode_ext = MPG_MD_MS_LR; #ifdef HAVEGTK if (gfp->gtkflag) { int j; for ( gr = 0; gr < gfp->mode_gr; gr++ ) { for ( ch = 0; ch < gfp->stereo; ch++ ) { pinfo->ms_ratio[gr]=ms_ratio[gr]; pinfo->ms_ener_ratio[gr]=ms_ener_ratio[gr]; pinfo->blocktype[gr][ch]= l3_side.gr[gr].ch[ch].tt.block_type; for ( j = 0; j < 576; j++ ) pinfo->xr[gr][ch][j]=xr[gr][ch][j]; /* if MS stereo, switch to MS psy data */ if (gfp->mode_ext==MPG_MD_MS_LR) { pinfo->pe[gr][ch]=pinfo->pe[gr][ch+2]; pinfo->ers[gr][ch]=pinfo->ers[gr][ch+2]; memcpy(pinfo->energy[gr][ch],pinfo->energy[gr][ch+2], sizeof(pinfo->energy[gr][ch])); } } } } #endif /* bit and noise allocation */ if (MPG_MD_MS_LR == gfp->mode_ext) { masking = &masking_MS_ratio; /* use MS masking */ pe_use=&pe_MS; } else { masking = &masking_ratio; /* use LR masking */ pe_use=&pe; } /* VBR_iteration_loop_new( gfp,*pe_use, ms_ratio, xr, masking, &l3_side, l3_enc, &scalefac); */ if (gfp->VBR) { VBR_iteration_loop( gfp,*pe_use, ms_ratio, xr, *masking, &l3_side, l3_enc, scalefac); }else{ iteration_loop( gfp,*pe_use, ms_ratio, xr, *masking, &l3_side, l3_enc, scalefac); } #ifdef BRHIST brhist_temp[gfp->bitrate_index]++; #endif /* write the frame to the bitstream */ getframebits(gfp,&bitsPerFrame,&mean_bits); III_format_bitstream( gfp,bitsPerFrame, l3_enc, &l3_side, scalefac, &bs); frameBits = bs.totbit - sentBits; if ( frameBits % bitsPerSlot ) /* a program failure */ fprintf( stderr, "Sent %ld bits = %ld slots plus %ld\n", frameBits, frameBits/bitsPerSlot, frameBits%bitsPerSlot ); sentBits += frameBits; /* copy mp3 bit buffer into array */ mp3count = copy_buffer(mp3buf,mp3buf_size,&bs); if (gfp->bWriteVbrTag) AddVbrFrame((int)(sentBits/8)); #ifdef HAVEGTK if (gfp->gtkflag) { int j; for ( ch = 0; ch < gfp->stereo; ch++ ) { for ( j = 0; j < FFTOFFSET; j++ ) pinfo->pcmdata[ch][j] = pinfo->pcmdata[ch][j+gfp->framesize]; for ( j = FFTOFFSET; j < 1600; j++ ) { pinfo->pcmdata[ch][j] = inbuf[ch][j-FFTOFFSET]; } } } #endif gfp->frameNum++; return mp3count; } int fill_buffer_resample(lame_global_flags *gfp,short int *outbuf,int desired_len, short int *inbuf,int len,int *num_used,int ch) { static FLOAT8 itime[2]; #define OLDBUFSIZE 5 static short int inbuf_old[2][OLDBUFSIZE]; static int init[2]={0,0}; int i,j=0,k,linear,value; if (gfp->frameNum==0 && !init[ch]) { init[ch]=1; itime[ch]=0; memset((char *) inbuf_old[ch], 0, sizeof(short int)*OLDBUFSIZE); } if (gfp->frameNum!=0) init[ch]=0; /* reset, for next time framenum=0 */ /* if downsampling by an integer multiple, use linear resampling, * otherwise use quadratic */ linear = ( fabs(gfp->resample_ratio - floor(.5+gfp->resample_ratio)) < .0001 ); /* time of j'th element in inbuf = itime + j/ifreq; */ /* time of k'th element in outbuf = j/ofreq */ for (k=0;kresample_ratio; /* time of k'th output sample */ j = floor( time0 -itime[ch] ); /* itime[ch] + j; */ /* time of j'th input sample */ if (j+2 >= len) break; /* not enough data in input buffer */ x1 = time0-(itime[ch]+j); x2 = x1-1; y1 = (j<0) ? inbuf_old[ch][OLDBUFSIZE+j] : inbuf[j]; y2 = ((1+j)<0) ? inbuf_old[ch][OLDBUFSIZE+1+j] : inbuf[1+j]; /* linear resample */ if (linear) { outbuf[k] = floor(.5 + (y2*x1-y1*x2) ); } else { /* quadratic */ x0 = x1+1; x3 = x1-2; y0 = ((j-1)<0) ? inbuf_old[ch][OLDBUFSIZE+(j-1)] : inbuf[j-1]; y3 = ((j+2)<0) ? inbuf_old[ch][OLDBUFSIZE+(j+2)] : inbuf[j+2]; value = floor(.5 + -y0*x1*x2*x3/6 + y1*x0*x2*x3/2 - y2*x0*x1*x3/2 +y3*x0*x1*x2/6 ); if (value > 32767) outbuf[k]=32767; else if (value < -32767) outbuf[k]=-32767; else outbuf[k]=value; /* printf("k=%i new=%i [ %i %i %i %i ]\n",k,outbuf[k], y0,y1,y2,y3); */ } } /* k = number of samples added to outbuf */ /* last k sample used data from j,j+1, or j+1 overflowed buffer */ /* remove num_used samples from inbuf: */ *num_used = Min(len,j+2); itime[ch] += *num_used - k*gfp->resample_ratio; for (i=0;i=MDCTDELAY); assert(BLKSIZE-FFTOFFSET >= 0); mf_needed = BLKSIZE+gfp->framesize-FFTOFFSET; assert(MFSIZE>=mf_needed); /* The reason for * int mf_samples_to_encode = ENCDELAY + 288; * ENCDELAY = internal encoder delay. And then we have to add 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. */ if (gfp->frameNum==0 && !frame_buffered) { memset((char *) mfbuf, 0, sizeof(mfbuf)); frame_buffered=1; mf_samples_to_encode = ENCDELAY+288; mf_size=ENCDELAY-MDCTDELAY; /* we pad input with this many 0's */ } if (gfp->frameNum==1) { /* reset, for the next time frameNum==0 */ frame_buffered=0; } if (gfp->num_channels==2 && gfp->stereo==1) { /* downsample to mono */ for (i=0; i 0) { int n_in=0; int n_out=0; /* copy in new samples */ for (ch=0; chstereo; ch++) { if (gfp->resample_ratio!=1) { n_out=fill_buffer_resample(gfp,&mfbuf[ch][mf_size],gfp->framesize, in_buffer[ch],nsamples,&n_in,ch); } else { n_out=fill_buffer(gfp,&mfbuf[ch][mf_size],gfp->framesize,in_buffer[ch],nsamples); n_in = n_out; } in_buffer[ch] += n_in; } nsamples -= n_in; mf_size += n_out; assert(mf_size<=MFSIZE); mf_samples_to_encode += n_out; if (mf_size >= mf_needed) { /* encode the frame */ ret = lame_encode_frame(gfp,mfbuf[0],mfbuf[1],mf_size,mp3buf,mp3buf_size); if (ret == -1) { /* fatel error: mp3buffer was too small */ return -1; } mp3buf += ret; mp3size += ret; /* shift out old samples */ mf_size -= gfp->framesize; mf_samples_to_encode -= gfp->framesize; for (ch=0; chstereo; ch++) for (i=0; iframesize]; } } assert(nsamples==0); return mp3size; } int lame_encode_buffer_interleaved(lame_global_flags *gfp, short int buffer[], int nsamples, char *mp3buf, int mp3buf_size) { static int frame_buffered=0; int mp3size=0,ret,i,ch,mf_needed; /* some sanity checks */ assert(ENCDELAY>=MDCTDELAY); assert(BLKSIZE-FFTOFFSET >= 0); mf_needed = BLKSIZE+gfp->framesize-FFTOFFSET; assert(MFSIZE>=mf_needed); if (gfp->num_channels == 1) { return lame_encode_buffer(gfp,buffer, NULL ,nsamples,mp3buf,mp3buf_size); } if (gfp->resample_ratio!=1) { 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 -1; } for (i=0; iframeNum==0 && !frame_buffered) { memset((char *) mfbuf, 0, sizeof(mfbuf)); frame_buffered=1; mf_samples_to_encode = ENCDELAY+288; mf_size=ENCDELAY-MDCTDELAY; /* we pad input with this many 0's */ } if (gfp->frameNum==1) { /* reset, for the next time frameNum==0 */ frame_buffered=0; } if (gfp->num_channels==2 && gfp->stereo==1) { /* downsample to mono */ for (i=0; i 0) { int n_out; /* copy in new samples */ n_out = Min(gfp->framesize,nsamples); for (i=0; i= mf_needed) { /* encode the frame */ ret = lame_encode_frame(gfp,mfbuf[0],mfbuf[1],mf_size,mp3buf,mp3buf_size); if (ret == -1) { /* fatel error: mp3buffer was too small */ return -1; } mp3buf += ret; mp3size += ret; /* shift out old samples */ mf_size -= gfp->framesize; mf_samples_to_encode -= gfp->framesize; for (ch=0; chstereo; ch++) for (i=0; iframesize]; } } assert(nsamples==0); return mp3size; } /* old LAME interface */ /* With this interface, it is the users responsibilty to keep track of the * buffered, unencoded samples. Thus mf_samples_to_encode is not incremented. * * lame_encode() is also used to flush the PCM input buffer by * lame_encode_finish() */ int lame_encode(lame_global_flags *gfp, short int in_buffer[2][1152],char *mp3buf,int size){ int imp3,save; save = mf_samples_to_encode; imp3= lame_encode_buffer(gfp,in_buffer[0],in_buffer[1],576*gfp->mode_gr, mp3buf,size); mf_samples_to_encode = save; return imp3; } /* initialize mp3 encoder */ void lame_init(lame_global_flags *gfp) { /* * Disable floating point exepctions */ #if defined(__FreeBSD__) && !defined(__alpha__) # include { /* 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)); /* fprintf(stderr,"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) && !defined(__riscos__) #if defined(_MSC_VER) { #include 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 0x00000001 /* inexact (precision) */ # define _EM_UNDERFLOW 0x00000002 /* underflow */ # define _EM_OVERFLOW 0x00000004 /* overflow */ # define _EM_ZERODIVIDE 0x00000008 /* zero divide */ # define _EM_INVALID 0x00000010 /* invalid */ { unsigned int mask; _FPU_GETCW(mask); /* Set the FPU control word to abort on most FPEs */ mask &= ~(_EM_UNDERFLOW | _EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID); _FPU_SETCW(mask); } # else { # include #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 unsigned int mask; _FPU_GETCW(mask); /* 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 );*/ mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM ); _FPU_SETCW(mask); } #endif #endif /* ABORTFP && !__riscos__ */ /* Global flags. set defaults here */ gfp->allow_diff_short=0; gfp->ATHonly=0; gfp->noATH=0; gfp->bWriteVbrTag=1; gfp->cwlimit=0; gfp->disable_reservoir=0; gfp->experimentalX = 0; gfp->experimentalY = 0; gfp->experimentalZ = 0; gfp->frameNum=0; gfp->gtkflag=0; gfp->quality=5; gfp->input_format=sf_unknown; gfp->filter_type=0; gfp->lowpassfreq=0; gfp->highpassfreq=0; gfp->lowpasswidth=-1; gfp->highpasswidth=-1; gfp->lowpass1=0; gfp->lowpass2=0; gfp->highpass1=0; gfp->highpass2=0; gfp->lowpass_band=32; gfp->highpass_band=-1; gfp->no_short_blocks=0; gfp->resample_ratio=1; gfp->padding_type=2; gfp->padding=0; gfp->swapbytes=0; gfp->silent=0; gfp->totalframes=0; gfp->VBR=0; gfp->VBR_q=4; gfp->VBR_min_bitrate_kbps=0; gfp->VBR_max_bitrate_kbps=0; gfp->VBR_min_bitrate=1; gfp->VBR_max_bitrate=13; gfp->version = 1; /* =1 Default: MPEG-1 */ gfp->mode = MPG_MD_JOINT_STEREO; gfp->mode_fixed=0; gfp->force_ms=0; gfp->brate=0; gfp->copyright=0; gfp->original=1; gfp->extension=0; gfp->error_protection=0; gfp->emphasis=0; gfp->in_samplerate=1000*44.1; gfp->out_samplerate=0; gfp->num_channels=2; gfp->num_samples=MAX_U_32_NUM; gfp->inPath=NULL; gfp->outPath=NULL; id3tag.used=0; } /*****************************************************************/ /* flush internal mp3 buffers, */ /*****************************************************************/ int lame_encode_finish(lame_global_flags *gfp,char *mp3buffer, int mp3buffer_size) { int imp3,mp3count,mp3buffer_size_remaining; short int buffer[2][1152]; memset((char *)buffer,0,sizeof(buffer)); mp3count = 0; while (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; imp3=lame_encode(gfp,buffer,mp3buffer,mp3buffer_size_remaining); if (imp3 == -1) { /* fatel error: mp3buffer too small */ desalloc_buffer(&bs); /* Deallocate all buffers */ return -1; } mp3buffer += imp3; mp3count += imp3; mf_samples_to_encode -= gfp->framesize; } gfp->frameNum--; if (!gfp->gtkflag && !gfp->silent) { timestatus(gfp->out_samplerate,gfp->frameNum,gfp->totalframes,gfp->framesize); #ifdef BRHIST if (disp_brhist) { brhist_add_count(); brhist_disp(); brhist_disp_total(gfp); } #endif fprintf(stderr,"\n"); fflush(stderr); } III_FlushBitstream(); mp3buffer_size_remaining = mp3buffer_size - mp3count; /* if user specifed buffer size = 0, dont check size */ if (mp3buffer_size == 0) mp3buffer_size_remaining=0; imp3= copy_buffer(mp3buffer,mp3buffer_size_remaining,&bs); if (imp3 == -1) { /* fatel error: mp3buffer too small */ desalloc_buffer(&bs); /* Deallocate all buffers */ return -1; } mp3count += imp3; desalloc_buffer(&bs); /* Deallocate all buffers */ return mp3count; } /*****************************************************************/ /* write VBR Xing header, and ID3 tag, if asked for */ /*****************************************************************/ void lame_mp3_tags(lame_global_flags *gfp) { if (gfp->bWriteVbrTag) { /* Calculate relative quality of VBR stream * 0=best, 100=worst */ int nQuality=gfp->VBR_q*100/9; /* Write Xing header again */ PutVbrTag(gfp->outPath,nQuality,1-gfp->version); } /* write an ID3 tag */ if(id3tag.used) { id3_buildtag(&id3tag); id3_writetag(gfp->outPath, &id3tag); } } void lame_version(lame_global_flags *gfp,char *ostring) { strncpy(ostring,get_lame_version(),20); }