📄 lame.c
字号:
}/******************************************************************** * 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); * ********************************************************************/intlame_init_params(lame_global_flags * const gfp){ int i; int j; lame_internal_flags *gfc = gfp->internal_flags; gfc->Class_ID = 0; /* report functions */ gfc->report.msgf = gfp->report.msgf; gfc->report.debugf = gfp->report.debugf; gfc->report.errorf = gfp->report.errorf; if (gfp->asm_optimizations.amd3dnow ) gfc->CPU_features.AMD_3DNow = has_3DNow(); else gfc->CPU_features.AMD_3DNow = 0; if (gfp->asm_optimizations.mmx ) gfc->CPU_features.MMX = has_MMX(); else gfc->CPU_features.MMX = 0; if (gfp->asm_optimizations.sse ) { gfc->CPU_features.SSE = has_SSE(); gfc->CPU_features.SSE2 = has_SSE2(); } else { gfc->CPU_features.SSE = 0; gfc->CPU_features.SSE2 = 0; } 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->PSY) gfc->PSY = calloc(1, sizeof(PSY_t)); if (NULL == gfc->PSY) return -2; if (NULL == gfc->rgdata) gfc->rgdata = calloc(1, sizeof(replaygain_t)); if (NULL == gfc->rgdata) return -2; 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_MS_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->VBR_mean_bitrate_kbps != 128 && gfp->brate == 0) gfp->brate = gfp->VBR_mean_bitrate_kbps; 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 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); } 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 a filter has not been enabled, see if we should add one: */ /****************************************************************/ if (gfp->lowpassfreq == 0) { double lowpass = 16000; double highpass; switch (gfp->VBR) { case vbr_off: { optimum_bandwidth(&lowpass, &highpass, gfp->brate); break; } case vbr_abr: { optimum_bandwidth(&lowpass, &highpass, gfp->VBR_mean_bitrate_kbps); break; } default: { switch (gfp->VBR_q) { case 9: { lowpass = 10000; break; } case 8: { lowpass = 12500; break; } case 7: { lowpass = 14900; break; } case 6: { lowpass = 15600; break; } case 5: { lowpass = 16000; break; } case 4: { lowpass = 17500; break; } case 3: { lowpass = 18000; break; } case 2: { lowpass = 18600; break; } case 1: { lowpass = 19000; break; } case 0: { lowpass = 19500; break; } } } } if (gfp->mode == MONO && (gfp->VBR == vbr_off || gfp->VBR == vbr_abr)) lowpass *= 1.5; gfp->lowpassfreq = lowpass; } if (gfp->out_samplerate == 0) gfp->out_samplerate = optimum_samplefreq( (int)gfp->lowpassfreq, gfp->in_samplerate); gfp->lowpassfreq = Min(20500, gfp->lowpassfreq); gfp->lowpassfreq = Min(gfp->out_samplerate / 2, gfp->lowpassfreq); if (gfp->VBR == vbr_off) { gfp->compression_ratio = gfp->out_samplerate * 16 * gfc->channels_out / (1.e3 * gfp->brate); } if (gfp->VBR == vbr_abr) { gfp->compression_ratio = gfp->out_samplerate * 16 * gfc->channels_out / (1.e3 * gfp-> VBR_mean_bitrate_kbps); } /* do not compute ReplayGain values and do not find the peak sample if we can't store them */ if (!gfp->bWriteVbrTag){ gfp->findReplayGain = 0; gfp->decode_on_the_fly = 0; gfc->findPeakSample = 0; } gfc->findReplayGain = gfp->findReplayGain; gfc->decode_on_the_fly = gfp->decode_on_the_fly; if (gfc->decode_on_the_fly) gfc->findPeakSample = 1; if (gfc->findReplayGain) { if (InitGainAnalysis(gfc->rgdata, gfp->out_samplerate) == INIT_GAIN_ANALYSIS_ERROR) return -6; }#ifdef DECODE_ON_THE_FLY if (gfc->decode_on_the_fly && !gfp->decode_only) lame_decode_init(); /* initialize the decoder */#endif 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->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: { /*numbers are a bit strange, but they determine the lowpass value*/ FLOAT cmp[] = { 5.7, 6.5, 7.3, 8.2, 10, 11.9, 13, 14, 15, 16.5 }; 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 not been set, then select J-STEREO */ if (gfp->mode == NOT_SET) { gfp->mode = JOINT_STEREO; } /* apply user driven high pass filter */ if (gfp->highpassfreq > 0) { gfc->highpass1 = 2. * gfp->highpassfreq; if (gfp->highpasswidth >= 0) gfc->highpass2 = 2. * (gfp->highpassfreq + gfp->highpasswidth); else /* 0% above on default */ gfc->highpass2 = (1 + 0.00) * 2. * gfp->highpassfreq; gfc->highpass1 /= gfp->out_samplerate; gfc->highpass2 /= gfp->out_samplerate; } /* apply user driven low pass filter */ if (gfp->lowpassfreq > 0) { gfc->lowpass2 = 2. * gfp->lowpassfreq; if (gfp->lowpasswidth >= 0) { gfc->lowpass1 = 2. * (gfp->lowpassfreq - gfp->lowpasswidth); if (gfc->lowpass1 < 0) /* has to be >= 0 */ gfc->lowpass1 = 0; } else { /* 0% below on default */ gfc->lowpass1 = (1 - 0.00) * 2. * gfp->lowpassfreq; } gfc->lowpass1 /= gfp->out_samplerate; gfc->lowpass2 /= 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; } } /* for CBR, we will write an "info" tag. */ /* if ((gfp->VBR == vbr_off)) */ /* gfp->bWriteVbrTag = 0; */#if defined(HAVE_GTK) if (gfp->analysis) gfp->bWriteVbrTag = 0; /* some file options not allowed if output is: not specified or stdout */ if (gfc->pinfo != NULL) gfp->bWriteVbrTag = 0; /* disable Xing VBR tag */#endif 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 < PSFB21 + 1; i++){ int size = (gfc->scalefac_band.l[ 22 ] - gfc->scalefac_band.l[ 21 ])/PSFB21; int start = gfc->scalefac_band.l[ 21 ] + i*size; gfc->scalefac_band.psfb21[i] = start; } gfc->scalefac_band.psfb21[PSFB21] = 576;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -