⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lame.c

📁 音频编码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- 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 + -