📄 lame.c
字号:
/* -*- mode: C; mode: fold -*- *//* * LAME MP3 encoding engine * * Copyright (c) 1999-2000 Mark Taylor * Copyright (c) 2000-2005 Takehiro Tominaga * Copyright (c) 2000-2005 Robert Hegemann * Copyright (c) 2000-2005 Gabriel Bouvigne * Copyright (c) 2000-2004 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: lame.c,v 1.278.2.2 2005/11/20 14:08:24 bouvigne Exp $ */#ifdef HAVE_CONFIG_H# include <config.h>#endif#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 "psymodel.h"#include "VbrTag.h"#include "machine.h"#include "gain_analysis.h"#include "set_get.h"#if defined(__FreeBSD__) && !defined(__alpha__)#include <floatingpoint.h>#endif#ifdef __riscos__#include "asmstuff.h"#endif#ifdef WITH_DMALLOC#include <dmalloc.h>#endif#ifdef __sun__/* woraround for SunOS 4.x, it has SEEK_* defined here */#include <unistd.h>#endif#define LAME_DEFAULT_QUALITY 3static FLOATfilter_coef(FLOAT x){ if (x > 1.0) return 0.0; if (x <= 0.0) return 1.0; return cos(PI/2 * x);}static voidlame_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; FLOAT freq; int lowpass_band = 32; int highpass_band = -1; if (gfc->lowpass1 > 0) { minband = 999; for (band = 0; band <= 31; band++) { freq = band / 31.0; /* this band and above will be zeroed: */ if (freq >= gfc->lowpass2) { lowpass_band = Min(lowpass_band, band); } if (gfc->lowpass1 < freq && freq < gfc->lowpass2) { minband = Min(minband, band); } } /* compute the *actual* transition band implemented by * the polyphase filter */ if (minband == 999) { gfc->lowpass1 = (lowpass_band - .75) / 31.0; } else { gfc->lowpass1 = (minband - .75) / 31.0; } gfc->lowpass2 = lowpass_band / 31.0; } /* 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) { maxband = -1; for (band = 0; band <= 31; band++) { freq = band / 31.0; /* this band and below will be zereod */ if (freq <= gfc->highpass1) { highpass_band = Max(highpass_band, band); } if (gfc->highpass1 < freq && freq < gfc->highpass2) { maxband = Max(maxband, band); } } /* compute the *actual* transition band implemented by * the polyphase filter */ gfc->highpass1 = highpass_band / 31.0; if (maxband == -1) { gfc->highpass2 = (highpass_band + .75) / 31.0; } else { gfc->highpass2 = (maxband + .75) / 31.0; } } for (band = 0; band < 32; band++) { freq = band / 31.0; gfc->amp_filter[band] = filter_coef((gfc->highpass2 - freq) / (gfc->highpass2 - gfc->highpass1 + 1e-37)) * filter_coef((freq - gfc->lowpass1) / (gfc->lowpass2 - gfc->lowpass1 - 1e-37)); }}static voidoptimum_bandwidth(double *const lowerlimit, double *const upperlimit, const unsigned bitrate){/* * Input: * bitrate total bitrate in kbps * * Output: * lowerlimit: best lowpass frequency limit for input filter in Hz * upperlimit: best highpass frequency limit for input filter in Hz */ int index; typedef struct { int bitrate; /* only indicative value */ int lowpass; } band_pass_t; const band_pass_t freq_map[] = { { 8, 2000}, { 16, 3700}, { 24, 3900}, { 32, 5500}, { 40, 7000}, { 48, 7500}, { 56, 10000}, { 64, 11000}, { 80, 13500}, { 96, 15100}, {112, 15600}, {128, 17000}, {160, 17500}, {192, 18600}, {224, 19400}, {256, 19700}, {320, 20500} }; index = nearestBitrateFullIndex(bitrate); *lowerlimit = freq_map[index].lowpass;/* * 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 (upperlimit != NULL) *upperlimit = f_high;*/}static intoptimum_samplefreq(int lowpassfreq, int input_samplefreq){/* * Rules: * - if possible, sfb21 should NOT be used * */ int suggested_samplefreq; if (input_samplefreq >= 48000) suggested_samplefreq = 48000; else if (input_samplefreq >= 44100) suggested_samplefreq = 44100; else if (input_samplefreq >= 32000) suggested_samplefreq = 32000; else if (input_samplefreq >= 24000) suggested_samplefreq = 24000; else if (input_samplefreq >= 22050) suggested_samplefreq = 22050; else if (input_samplefreq >= 16000) suggested_samplefreq = 16000; else if (input_samplefreq >= 12000) suggested_samplefreq = 12000; else if (input_samplefreq >= 11025) suggested_samplefreq = 11025; else if (input_samplefreq >= 8000) suggested_samplefreq = 8000; if (lowpassfreq == -1) return suggested_samplefreq; if (lowpassfreq <= 15960) suggested_samplefreq = 44100; if (lowpassfreq <= 15250) suggested_samplefreq = 32000; if (lowpassfreq <= 11220) suggested_samplefreq = 24000; if (lowpassfreq <= 9970) suggested_samplefreq = 22050; if (lowpassfreq <= 7230) suggested_samplefreq = 16000; if (lowpassfreq <= 5420) suggested_samplefreq = 12000; if (lowpassfreq <= 4510) suggested_samplefreq = 11025; if (lowpassfreq <= 3970) suggested_samplefreq = 8000; if (input_samplefreq < suggested_samplefreq) suggested_samplefreq = input_samplefreq; return suggested_samplefreq;}/* set internal feature flags. USER should not access these since * some combinations will produce strange results */voidlame_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; gfc->full_outer_loop = 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; gfc->full_outer_loop = 0; break; case 6: gfc->filter_type = 0; gfc->psymodel = 1; gfc->quantization = 0; if (gfc->noise_shaping == 0) gfc->noise_shaping = 1; gfc->noise_shaping_amp = 0; gfc->noise_shaping_stop = 0; if (gfc->subblock_gain == -1) gfc->subblock_gain = 1; gfc->use_best_huffman = 0; gfc->full_outer_loop = 0; break; case 5: gfc->filter_type = 0; gfc->psymodel = 1; gfc->quantization = 1; if (gfc->noise_shaping == 0) gfc->noise_shaping = 1; gfc->noise_shaping_amp = 0; gfc->noise_shaping_stop = 0; if (gfc->subblock_gain == -1) gfc->subblock_gain = 1; gfc->use_best_huffman = 0; gfc->full_outer_loop = 0; break; case 4: gfc->filter_type = 0; gfc->psymodel = 1; gfc->quantization = 1; if (gfc->noise_shaping == 0) gfc->noise_shaping = 1; gfc->noise_shaping_amp = 0; gfc->noise_shaping_stop = 0; if (gfc->subblock_gain == -1) gfc->subblock_gain = 1; gfc->use_best_huffman = 1; gfc->full_outer_loop = 0; break; case 3: gfc->filter_type = 0; gfc->psymodel = 1; gfc->quantization = 1; if (gfc->noise_shaping == 0) gfc->noise_shaping = 1; gfc->noise_shaping_amp = 1; gfc->noise_shaping_stop = 1; if (gfc->subblock_gain == -1) gfc->subblock_gain = 1; gfc->use_best_huffman = 1; gfc->full_outer_loop = 0; break; case 2: gfc->filter_type = 0; gfc->psymodel = 1; gfc->quantization = 1; if (gfc->noise_shaping == 0) gfc->noise_shaping = 1; if (gfc->substep_shaping == 0) gfc->substep_shaping = 2; gfc->noise_shaping_amp = 1; gfc->noise_shaping_stop = 1; if (gfc->subblock_gain == -1) gfc->subblock_gain = 1; gfc->use_best_huffman = 1; /* inner loop */ gfc->full_outer_loop = 0; break; case 1: gfc->filter_type = 0; /* 1 not yet coded */ gfc->psymodel = 1; gfc->quantization = 1; if (gfc->noise_shaping == 0) gfc->noise_shaping = 1; if (gfc->substep_shaping == 0) gfc->substep_shaping = 2; gfc->noise_shaping_amp = 2; gfc->noise_shaping_stop = 1; if (gfc->subblock_gain == -1) gfc->subblock_gain = 1; gfc->use_best_huffman = 1; gfc->full_outer_loop = 0; break; case 0: gfc->filter_type = 0; /* 1 not yet coded */ gfc->psymodel = 1; gfc->quantization = 1; if (gfc->noise_shaping == 0) gfc->noise_shaping = 1; if (gfc->substep_shaping == 0) gfc->substep_shaping = 2; gfc->noise_shaping_amp = 2; gfc->noise_shaping_stop = 1; if (gfc->subblock_gain == -1) gfc->subblock_gain = 1; gfc->use_best_huffman = 1; /*type 2 disabled because of it slowness, in favor of full outer loop search */ gfc->full_outer_loop = 1; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -