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

📄 lame.c

📁 音频编码
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* make a copy of input buffer, changing type to sample_t */    for (i = 0; i < nsamples; i++) {        in_buffer[0][i] = buffer_l[i];        if (gfc->channels_in>1)	    in_buffer[1][i] = buffer_r[i];    }    return lame_encode_buffer_sample_t(gfp,in_buffer[0],in_buffer[1],				      nsamples, mp3buf, mp3buf_size);}intlame_encode_buffer_interleaved(lame_global_flags * gfp,                               short int buffer[],                               int nsamples,                               unsigned char *mp3buf, int mp3buf_size){    lame_internal_flags *gfc = gfp->internal_flags;    int     i;    sample_t *in_buffer[2];    if (update_inbuffer_size( gfc, nsamples ) != 0) {        return -2;    }    in_buffer[0] = gfc->in_buffer_0;    in_buffer[1] = gfc->in_buffer_1;    for (i = 0; i < nsamples; i++) {        in_buffer[0][i] = buffer[2 * i];        in_buffer[1][i] = buffer[2 * i + 1];    }    return lame_encode_buffer_sample_t(gfp, in_buffer[0], in_buffer[1], nsamples, mp3buf,                           mp3buf_size);}intlame_encode(lame_global_flags * const gfp,            const short int in_buffer[2][1152],            unsigned char *const mp3buf, const int size){    lame_internal_flags *gfc = gfp->internal_flags;    if (gfc->Class_ID != LAME_ID)        return -3;    return lame_encode_buffer(gfp, in_buffer[0], in_buffer[1], gfp->framesize,                              mp3buf, size);}/***************************************************************** Flush mp3 buffer, pad with ancillary data so last frame is complete. Reset reservoir size to 0                   but keep all PCM samples and MDCT data in memory              This option is used to break a large file into several mp3 files  that when concatenated together will decode with no gaps          Because we set the reservoir=0, they will also decode seperately  with no errors. *********************************************************************/intlame_encode_flush_nogap(lame_global_flags * gfp,                  unsigned char *mp3buffer, int mp3buffer_size){    lame_internal_flags *gfc = gfp->internal_flags;    flush_bitstream(gfp);    return copy_buffer(gfc,mp3buffer, mp3buffer_size,1);}/* called by lame_init_params.  You can also call this after flush_nogap    if you want to write new id3v2 and Xing VBR tags into the bitstream */intlame_init_bitstream(lame_global_flags * gfp){    lame_internal_flags *gfc = gfp->internal_flags;    gfp->frameNum=0;    id3tag_write_v2(gfp);#ifdef BRHIST    /* initialize histogram data optionally used by frontend */    memset(gfc->bitrate_stereoMode_Hist, 0,	   sizeof(gfc->bitrate_stereoMode_Hist));    memset(gfc->bitrate_blockType_Hist, 0,	   sizeof(gfc->bitrate_blockType_Hist));#endif    gfc->PeakSample = 0.0;    /* Write initial VBR Header to bitstream and init VBR data */    if (gfp->bWriteVbrTag)         InitVbrTag(gfp);    return 0;}/*****************************************************************//* flush internal PCM sample buffers, then mp3 buffers           *//* then write id3 v1 tags into bitstream.                        *//*****************************************************************/intlame_encode_flush(lame_global_flags * gfp,                  unsigned char *mp3buffer, int mp3buffer_size){    lame_internal_flags *gfc = gfp->internal_flags;    short int buffer[2][1152];    int     imp3 = 0, mp3count, mp3buffer_size_remaining;    /* we always add POSTDELAY=288 padding to make sure granule with real     * data can be complety decoded (because of 50% overlap with next granule */    int end_padding=POSTDELAY;      memset(buffer, 0, sizeof(buffer));    mp3count = 0;    while (gfc->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;        /* send in a frame of 0 padding until all internal sample buffers         * are flushed          */        imp3 = lame_encode_buffer(gfp, buffer[0], buffer[1], gfp->framesize,                                  mp3buffer, mp3buffer_size_remaining);        /* don't count the above padding: */        gfc->mf_samples_to_encode -= gfp->framesize;        if (gfc->mf_samples_to_encode < 0) {            /* we added extra padding to the end */            end_padding += -gfc->mf_samples_to_encode;          }        if (imp3 < 0) {            /* some type of fatal error */            return imp3;        }        mp3buffer += imp3;        mp3count += imp3;    }    mp3buffer_size_remaining = mp3buffer_size - mp3count;    /* if user specifed buffer size = 0, dont check size */    if (mp3buffer_size == 0)        mp3buffer_size_remaining = 0;    /* mp3 related stuff.  bit buffer might still contain some mp3 data */    flush_bitstream(gfp);    imp3 = copy_buffer(gfc,mp3buffer, mp3buffer_size_remaining, 1);    if (imp3 < 0) {	/* some type of fatal error */	return imp3;    }    mp3buffer += imp3;    mp3count += imp3;    mp3buffer_size_remaining = mp3buffer_size - mp3count;    /* if user specifed buffer size = 0, dont check size */    if (mp3buffer_size == 0)	mp3buffer_size_remaining = 0;    /* write a id3 tag to the bitstream */    id3tag_write_v1(gfp);    imp3 = copy_buffer(gfc,mp3buffer, mp3buffer_size_remaining, 0);    if (imp3 < 0) {        return imp3;    }    mp3count += imp3;    gfp->encoder_padding=end_padding;    return mp3count;}/*********************************************************************** * *      lame_close () * *  frees internal buffers * ***********************************************************************/intlame_close(lame_global_flags * gfp){    lame_internal_flags *gfc = gfp->internal_flags;    if (gfc->Class_ID != LAME_ID)        return -3;    if (gfp->exp_nspsytune2.pointer[0]) {      fclose((FILE *)gfp->exp_nspsytune2.pointer[0]);      gfp->exp_nspsytune2.pointer[0] = NULL;    }    gfc->Class_ID = 0;    /* this routien will free all malloc'd data in gfc, and then free gfc: */    freegfc(gfc);    gfp->internal_flags = NULL;    if (gfp->lame_allocated_gfp) {        gfp->lame_allocated_gfp = 0;        free(gfp);    }    return 0;}/*****************************************************************//* flush internal mp3 buffers, and free internal buffers         *//*****************************************************************/intlame_encode_finish(lame_global_flags * gfp,                   unsigned char *mp3buffer, int mp3buffer_size){    int     ret = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);    lame_close(gfp);    return ret;}/*****************************************************************//* write VBR Xing header, and ID3 version 1 tag, if asked for    *//*****************************************************************/voidlame_mp3_tags_fid(lame_global_flags * gfp, FILE * fpStream){    if (gfp->bWriteVbrTag) {        /* Map VBR_q to Xing quality value: 0=worst, 100=best */        int     nQuality = ((9-gfp->VBR_q) * 100) / 9;        /* Write Xing header again */        if (fpStream && !fseek(fpStream, 0, SEEK_SET))            PutVbrTag(gfp, fpStream, nQuality);    }}lame_global_flags *lame_init(void){    lame_global_flags *gfp;    int     ret;    init_log_table();    gfp = calloc(1, sizeof(lame_global_flags));    if (gfp == NULL)        return NULL;    ret = lame_init_old(gfp);    if (ret != 0) {        free(gfp);        return NULL;    }    gfp->lame_allocated_gfp = 1;    return gfp;}/* initialize mp3 encoder */intlame_init_old(lame_global_flags * gfp){    lame_internal_flags *gfc;    disable_FPE();      /* disable floating point exceptions */    memset(gfp, 0, sizeof(lame_global_flags));    if (NULL ==        (gfc = gfp->internal_flags =         calloc(1, sizeof(lame_internal_flags)))) return -1;    /* Global flags.  set defaults here for non-zero values */    /* see lame.h for description */    /* set integer values to -1 to mean that LAME will compute the     * best value, UNLESS the calling program as set it     * (and the value is no longer -1)     */    gfp->mode = NOT_SET;    gfp->original = 1;    gfp->in_samplerate = 1000 * 44.1;    gfp->num_channels = 2;    gfp->num_samples = MAX_U_32_NUM;    gfp->bWriteVbrTag = 1;    gfp->quality = -1;    gfp->short_blocks = short_block_not_set;    gfc->subblock_gain = -1;    gfp->lowpassfreq = 0;    gfp->highpassfreq = 0;    gfp->lowpasswidth = -1;    gfp->highpasswidth = -1;    gfp->VBR = vbr_off;    gfp->VBR_q = 4;    gfp->ATHcurve = -1;    gfp->VBR_mean_bitrate_kbps = 128;    gfp->VBR_min_bitrate_kbps = 0;    gfp->VBR_max_bitrate_kbps = 0;    gfp->VBR_hard_min = 0;    gfc->VBR_min_bitrate = 1; /* not  0 ????? */    gfc->VBR_max_bitrate = 13; /* not 14 ????? */    gfp->quant_comp = -1;    gfp->quant_comp_short = -1;    gfp->msfix = -1;    gfc->resample_ratio = 1;    gfc->OldValue[0] = 180;    gfc->OldValue[1] = 180;    gfc->CurrentStep[0] = 4;    gfc->CurrentStep[1] = 4;    gfc->masking_lower = 1;    gfc->nsPsy.attackthre   = -1;    gfc->nsPsy.attackthre_s = -1;    gfp->scale = -1;    gfp->athaa_type = -1;    gfp->ATHtype = -1;  /* default = -1 = set in lame_init_params */    gfp->athaa_loudapprox = -1;	/* 1 = flat loudness approx. (total energy) */                                /* 2 = equal loudness curve */    gfp->athaa_sensitivity = 0.0; /* no offset */    gfp->useTemporal = -1;    gfp->interChRatio = -1;    /* The reason for     *       int mf_samples_to_encode = ENCDELAY + POSTDELAY;     * ENCDELAY = internal encoder delay.  And then we have to add POSTDELAY=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.     */    gfc->mf_samples_to_encode = ENCDELAY + POSTDELAY;    gfp->encoder_padding = 0;    gfc->mf_size = ENCDELAY - MDCTDELAY; /* we pad input with this many 0's */    gfp->findReplayGain = 0;    gfp->decode_on_the_fly = 0;    gfc->decode_on_the_fly = 0;    gfc->findReplayGain = 0;    gfc->findPeakSample = 0;    gfc->RadioGain = 0;    gfc->AudiophileGain = 0;    gfc->noclipGainChange = 0;    gfc->noclipScale = -1.0;    gfp->asm_optimizations.mmx = 1;    gfp->asm_optimizations.amd3dnow = 1;    gfp->asm_optimizations.sse = 1;    gfp->preset = 0;        gfp->psymodel = -1;    gfp->sparsing = 0;    gfp->sparse_low = 9.0;    gfp->sparse_high = 3.0;        return 0;}/*********************************************************************** * *  some simple statistics * *  Robert Hegemann 2000-10-11 * ***********************************************************************//*  histogram of used bitrate indexes: *  One has to weight them to calculate the average bitrate in kbps * *  bitrate indices: *  there are 14 possible bitrate indices, 0 has the special meaning  *  "free format" which is not possible to mix with VBR and 15 is forbidden *  anyway. * *  stereo modes: *  0: LR   number of left-right encoded frames *  1: LR-I number of left-right and intensity encoded frames *  2: MS   number of mid-side encoded frames *  3: MS-I number of mid-side and intensity encoded frames * *  4: number of encoded frames * */voidlame_bitrate_kbps(const lame_global_flags * const gfp, int bitrate_kbps[14]){    const lame_internal_flags *gfc;    int     i;    if (NULL == bitrate_kbps)        return;    if (NULL == gfp)        return;    gfc = gfp->internal_fl

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -