?? lame.c
字號:
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; gfc->mode_ext = MPG_MD_LR_LR; if (gfc->lame_encode_frame_init==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; avg_slots_per_frame = (bit_rate*gfp->framesize) / (sampfreq* 8); /* -f fast-math option causes some strange rounding here, be carefull: */ gfc->frac_SpF = avg_slots_per_frame - floor(avg_slots_per_frame + 1e-9); if (fabs(gfc->frac_SpF) < 1e-9) gfc->frac_SpF = 0; gfc->slot_lag = -gfc->frac_SpF; gfc->padding = 1; if (gfc->frac_SpF==0) gfc->padding = 0;#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->difference = ((gfp->version+1)*72000L*gfp->brate) % gfp->out_samplerate; gfc->remainder = gfc->difference;#endif gfc->lame_encode_frame_init=1; /* check FFT will not use a negative starting offset */ assert(576>=FFTOFFSET); /* 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; short primebuff0[286+1152+576]; short 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->stereo) primebuff1[i]=0; }else{ primebuff0[i]=inbuf[0][j]; if (gfc->stereo) primebuff1[i]=inbuf[1][j]; ++j; } } /* polyphase filtering / mdct */ for ( gr = 0; gr < gfc->mode_gr; gr++ ) { for ( ch = 0; ch < gfc->stereo; ch++ ) { gfc->l3_side.gr[gr].ch[ch].tt.block_type=SHORT_TYPE; } } mdct_sub48(gfp,primebuff0, primebuff1, xr, &gfc->l3_side); } } /********************** padding *****************************/ switch (gfp->padding_type) { case 0: gfc->padding=0; break; case 1: gfc->padding=1; break; case 2: default: if (gfp->VBR!=vbr_off) { gfc->padding=0; } else { if (gfp->disable_reservoir) { gfc->padding = 0; /* if the user specified --nores, dont very gfc->padding either */ /* tiny changes in frac_SpF rounding will cause file differences */ }else{#if 0 if (gfc->frac_SpF != 0) { if (gfc->slot_lag > (gfc->frac_SpF-1.0) ) { gfc->slot_lag -= gfc->frac_SpF; gfc->padding = 0; DEBUGF("%i padding = 0 \n",gfp->frameNum); } else { gfc->padding = 1; gfc->slot_lag += (1-gfc->frac_SpF); } }#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->remainder -= gfc->difference; if (gfc->remainder < 0) { gfc->remainder += gfp->out_samplerate; gfc->padding = 1; } else { gfc->padding = 0; }#endif } /* reservoir enabled */ } } /********************** status display *****************************/ if (!gfp->gtkflag && !gfp->silent) { int mod = gfp->version == 0 ? 100 : 50; if (gfp->frameNum%mod==0) { timestatus(gfp->out_samplerate,gfp->frameNum,gfp->totalframes,gfp->framesize); if (gfp->brhist_disp) brhist_disp(gfp->totalframes); } } if (gfc->psymodel) { /* psychoacoustic model * psy model has a 1 granule (576) delay that we must compensate for * (mt 6/99). */ int ret; short int *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->stereo; ch++ ) bufp[ch] = &inbuf[ch][576 + gr*576-FFTOFFSET]; ret=L3psycho_anal( gfp,bufp, gr, &gfc->ms_ratio[gr],&ms_ratio_next,&gfc->ms_ener_ratio[gr], masking_ratio, masking_MS_ratio, pe[gr],pe_MS[gr],blocktype); if (ret!=0) return -4; for ( ch = 0; ch < gfc->stereo; ch++ ) gfc->l3_side.gr[gr].ch[ch].tt.block_type=blocktype[ch]; } }else{ for (gr=0; gr < gfc->mode_gr ; gr++) for ( ch = 0; ch < gfc->stereo; ch++ ) { gfc->l3_side.gr[gr].ch[ch].tt.block_type=NORM_TYPE; pe[gr][ch]=700; } } /* block type flags */ for( gr = 0; gr < gfc->mode_gr; gr++ ) { for ( ch = 0; ch < gfc->stereo; 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(gfp,inbuf[0], inbuf[1], xr, &gfc->l3_side); /* re-order the short blocks, for more efficient encoding below */ for (gr = 0; gr < gfc->mode_gr; gr++) { for (ch = 0; ch < gfc->stereo; 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->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 = (gfc->l3_side.gr[0].ch[0].tt.block_type==gfc->l3_side.gr[0].ch[1].tt.block_type) && (gfc->l3_side.gr[1].ch[0].tt.block_type==gfc->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_ratio_ave = .5*(ms_ratio[0] + ms_ratio[1]);*/ ms_ratio_ave = .25*(gfc->ms_ratio[0] + gfc->ms_ratio[1]+ ms_ratio_prev + ms_ratio_next); if ( (ms_ratio_ave <.35) && (.5*(gfc->ms_ratio[0]+gfc->ms_ratio[1])<.45) ) gfc->mode_ext = MPG_MD_MS_LR; } if (gfp->force_ms) gfc->mode_ext = MPG_MD_MS_LR; if (gfp->gtkflag && gfc->pinfo != NULL) { for ( gr = 0; gr < gfc->mode_gr; gr++ ) { for ( ch = 0; ch < gfc->stereo; ch++ ) { gfc->pinfo->ms_ratio[gr]=gfc->ms_ratio[gr]; gfc->pinfo->ms_ener_ratio[gr]=gfc->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])); /* if MS stereo, switch to MS psy 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])); } } } } /* bit and noise allocation */ if (MPG_MD_MS_LR == gfc->mode_ext) { masking = &masking_MS_ratio; /* use MS masking */ pe_use=&pe_MS; } else { masking = &masking_ratio; /* use LR masking */ pe_use=&pe; } switch (gfp->VBR){ default: case vbr_off: iteration_loop( gfp,*pe_use, gfc->ms_ener_ratio, xr, *masking, l3_enc, scalefac); break; case vbr_mt: VBR_quantize( gfp,*pe_use, gfc->ms_ener_ratio, xr, *masking, l3_enc, scalefac); break; case vbr_rh: VBR_iteration_loop( gfp,*pe_use, gfc->ms_ener_ratio, xr, *masking, l3_enc, scalefac); break; case vbr_abr: ABR_iteration_loop( gfp,*pe_use, gfc->ms_ener_ratio, xr, *masking, l3_enc, scalefac); break; } /* update VBR histogram data */ brhist_add_count(gfc->bitrate_index); /* 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(mp3buf,mp3buf_size,&gfc->bs); if (gfp->bWriteVbrTag) AddVbrFrame(gfp); if (gfp->gtkflag && gfc->pinfo != NULL) { int j; for ( ch = 0; ch < gfc->stereo; 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]; } } } gfp->frameNum++; return mp3count;}/* routine to feed exactly one frame (gfp->framesize) worth of data to the encoding engine. All buffering, resampling, etc, handled by callingprogram. */int lame_encode_frame(lame_global_flags *gfp,short int inbuf_l[],short int inbuf_r[],char *mp3buf, int mp3buf_size){ if (gfp->ogg) {#ifdef HAVEVORBIS return lame_encode_ogg_frame(gfp,inbuf_l,inbuf_r,mp3buf,mp3buf_size);#else return -5; /* wanna encode ogg without vorbis */#endif } else { return lame_encode_mp3_frame(gfp,inbuf_l,inbuf_r,mp3buf,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(lame_global_flags *gfp, short int buffer_l[], short int buffer_r[],int nsamples, char *mp3buf, int mp3buf_size){ int mp3size=0,ret=0,i,ch,mf_needed; lame_internal_flags *gfc=gfp->internal_flags; short int *mfbuf[2]; short int *in_buffer[2]; in_buffer[0] = buffer_l; in_buffer[1] = buffer_r; if (!gfc->lame_init_params_init) return -3; /* some sanity checks */ assert(ENCDELAY>=MDCTDELAY); assert(BLKSIZE-FFTOFFSET >= 0); mf_needed = BLKSIZE+gfp->framesize-FFTOFFSET; /* ammount needed for FFT */ mf_needed = Max(mf_needed,286+576*(1+gfc->mode_gr)); /* ammount needed for MDCT/filterbank */ assert(MFSIZE>=mf_needed); mfbuf[0]=gfc->mfbuf[0]; mfbuf[1]=gfc->mfbuf[1]; if (gfp->num_channels==2 && gfc->stereo==1) { /* downsample to mono */ for (i=0; i<nsamples; ++i) { in_buffer[0][i]=((int)in_buffer[0][i]+(int)in_buffer[1][i])/2; in_buffer[1][i]=0; } } while (nsamples > 0) { int n_in=0; int n_out=0; /* copy in new samples into mfbuf, with filtering */ for (ch=0; ch<gfc->stereo; ch++) { if (gfc->resample_ratio>1) { n_out=fill_buffer_downsample(gfp,&mfbuf[ch][gfc->mf_size],gfp->framesize, in_buffer[ch],nsamples,&n_in,ch); } else if (gfc->resample_ratio<1) { n_out=fill_buffer_upsample(gfp,&mfbuf[ch][gfc->mf_size],gfp->framesize, in_buffer[ch],nsamples,&n_in,ch); } else {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -