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

📄 lame.c

📁 音频编码
💻 C
📖 第 1 页 / 共 5 页
字号:
     */    MSGF( gfc, "\npsychoacoustic:\n\n" );        MSGF( gfc, "\tusing psychoacoustic model: %d\n", gfc->psymodel);    MSGF( gfc, "\tpsychoacoustic model: %s\n", (gfp->psymodel == PSY_NSPSYTUNE) ? "NSPsytune" : "GPsycho" );    MSGF( gfc, "\ttonality estimation limit: %f Hz %s\n", gfc->PSY->cwlimit, (gfp->psymodel == PSY_NSPSYTUNE) ? "(not relevant)" : "");    switch ( gfp->short_blocks ) {    default:    case short_block_not_set:   pc = "?";               break;    case short_block_allowed:   pc = "allowed";         break;    case short_block_coupled:   pc = "channel coupled"; break;    case short_block_dispensed: pc = "dispensed";       break;    case short_block_forced:    pc = "forced";          break;    }    MSGF( gfc, "\tusing short blocks: %s\n", pc );        MSGF( gfc, "\tsubblock gain: %d\n", gfc->subblock_gain );    MSGF( gfc, "\tadjust masking: %g dB\n", gfp->maskingadjust );    MSGF( gfc, "\tadjust masking short: %g dB\n", gfp->maskingadjust_short );    MSGF( gfc, "\tquantization comparison: %d\n", gfp->quant_comp );    MSGF( gfc, "\t ^ comparison short blocks: %d\n", gfp->quant_comp_short );    MSGF( gfc, "\tnoise shaping: %d\n", gfc->noise_shaping );    MSGF( gfc, "\t ^ amplification: %d\n", gfc->noise_shaping_amp );    MSGF( gfc, "\t ^ stopping: %d\n", gfc->noise_shaping_stop );        pc = "using";    if ( gfp->ATHshort ) pc = "the only masking for short blocks";    if ( gfp->ATHonly  ) pc = "the only masking";    if ( gfp->noATH    ) pc = "not used";    MSGF( gfc, "\tATH: %s\n", pc );    MSGF( gfc, "\t ^ type: %d\n", gfp->ATHtype );    MSGF( gfc, "\t ^ shape: %g%s\n", gfp->ATHcurve, " (only for type 4)" );    MSGF( gfc, "\t ^ level adjustement: %g\n", gfp->ATHlower );    MSGF( gfc, "\t ^ adjust type: %d\n", gfc->ATH->use_adjust );    MSGF( gfc, "\t ^ adjust sensitivity power: %f\n", gfc->ATH->aa_sensitivity_p );    MSGF( gfc, "\t ^ adapt threshold type: %d\n", gfp->athaa_loudapprox );        if ( gfp->psymodel == PSY_NSPSYTUNE ) {	MSGF(gfc, "\texperimental psy tunings by Naoki Shibata\n" );	MSGF(gfc, "\t   adjust masking bass=%g dB, alto=%g dB, treble=%g dB, sfb21=%g dB\n", 	     10*log10(gfc->nsPsy.longfact[ 0]),	     10*log10(gfc->nsPsy.longfact[ 7]),	     10*log10(gfc->nsPsy.longfact[14]),	     10*log10(gfc->nsPsy.longfact[21]));    }    pc = gfp->useTemporal ? "yes" : "no";    MSGF( gfc, "\tusing temporal masking effect: %s\n", pc );    MSGF( gfc, "\tinterchannel masking ratio: %g\n", gfp->interChRatio );    MSGF( gfc, "\t...\n" );        /*  that's all ?     */    MSGF( gfc, "\n" );    return;}/* routine to feed exactly one frame (gfp->framesize) worth of data to the encoding engine.  All buffering, resampling, etc, handled by callingprogram.  */intlame_encode_frame(lame_global_flags * gfp,                  sample_t inbuf_l[], sample_t inbuf_r[],                  unsigned char *mp3buf, int mp3buf_size){    int     ret;    ret = lame_encode_mp3_frame(gfp, inbuf_l, inbuf_r, mp3buf, mp3buf_size);    gfp->frameNum++;    return ret;}static intupdate_inbuffer_size(lame_internal_flags * gfc, const int nsamples){    if (gfc->in_buffer_0 == 0 || gfc->in_buffer_nsamples < nsamples) {        if (gfc->in_buffer_0) {            free(gfc->in_buffer_0);                    }        if (gfc->in_buffer_1) {            free(gfc->in_buffer_1);        }        gfc->in_buffer_0 = calloc(sizeof(sample_t), nsamples);        gfc->in_buffer_1 = calloc(sizeof(sample_t), nsamples);        gfc->in_buffer_nsamples = nsamples;    }    if (gfc->in_buffer_0 == NULL || gfc->in_buffer_1 == NULL) {        if (gfc->in_buffer_0) {            free(gfc->in_buffer_0);                    }        if (gfc->in_buffer_1) {            free(gfc->in_buffer_1);        }        gfc->in_buffer_0 = 0;        gfc->in_buffer_1 = 0;        gfc->in_buffer_nsamples = 0;        ERRORF(gfc, "Error: can't allocate in_buffer buffer\n");        return -2;    }    return 0;}/* * 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 * * NOTE: this routine uses LAME's internal PCM data representation, * 'sample_t'.  It should not be used by any application.   * applications should use lame_encode_buffer(),  *                         lame_encode_buffer_float() *                         lame_encode_buffer_int() * etc... depending on what type of data they are working with.  */intlame_encode_buffer_sample_t(lame_global_flags * gfp,                   sample_t buffer_l[],                   sample_t buffer_r[],                   int nsamples, unsigned char *mp3buf, const int mp3buf_size){    lame_internal_flags *gfc = gfp->internal_flags;    int     mp3size = 0, ret, i, ch, mf_needed;    int mp3out;    sample_t *mfbuf[2];    sample_t *in_buffer[2];    if (gfc->Class_ID != LAME_ID)        return -3;    if (nsamples == 0)        return 0;    /* copy out any tags that may have been written into bitstream */    mp3out = copy_buffer(gfc,mp3buf,mp3buf_size,0);    if (mp3out<0) return mp3out;  /* not enough buffer space */    mp3buf += mp3out;    mp3size += mp3out;    in_buffer[0]=buffer_l;    in_buffer[1]=buffer_r;      /* Apply user defined re-scaling */    /* user selected scaling of the samples */    if (gfp->scale != 0 && gfp->scale != 1.0) {	for (i=0 ; i<nsamples; ++i) {	    in_buffer[0][i] *= gfp->scale;	    if (gfc->channels_out == 2)		in_buffer[1][i] *= gfp->scale;	    }    }    /* user selected scaling of the channel 0 (left) samples */    if (gfp->scale_left != 0 && gfp->scale_left != 1.0) {	for (i=0 ; i<nsamples; ++i) {	    in_buffer[0][i] *= gfp->scale_left;	    }    }    /* user selected scaling of the channel 1 (right) samples */	if (gfp->scale_right != 0 && gfp->scale_right != 1.0) {	    for (i=0 ; i<nsamples; ++i) {		in_buffer[1][i] *= gfp->scale_right;	    }	}    /* Downsample to Mono if 2 channels in and 1 channel out */	if (gfp->num_channels == 2 && gfc->channels_out == 1) {		for (i=0; i<nsamples; ++i) {			in_buffer[0][i] =				0.5 * ((FLOAT) in_buffer[0][i] + in_buffer[1][i]);			in_buffer[1][i] = 0.0;		}	}    /* some sanity checks */#if ENCDELAY < MDCTDELAY# error ENCDELAY is less than MDCTDELAY, see encoder.h#endif#if FFTOFFSET > BLKSIZE# error FFTOFFSET is greater than BLKSIZE, see encoder.h#endif    mf_needed = BLKSIZE + gfp->framesize - FFTOFFSET; /* amount needed for FFT */    /*mf_needed = Max(mf_needed, 286 + 576 * (1 + gfc->mode_gr)); */    mf_needed = Max(mf_needed, 512+gfp->framesize-32 );    assert(MFSIZE >= mf_needed);    mfbuf[0] = gfc->mfbuf[0];    mfbuf[1] = gfc->mfbuf[1];    while (nsamples > 0) {        int     n_in = 0;    /* number of input samples processed with fill_buffer */        int     n_out = 0;   /* number of samples output with fill_buffer */        /* n_in <> n_out if we are resampling */        /* copy in new samples into mfbuf, with resampling */        fill_buffer(gfp, mfbuf, in_buffer, nsamples, &n_in, &n_out);        /* compute ReplayGain of resampled input if requested */        if (gfc->findReplayGain && !gfc->decode_on_the_fly)             if (AnalyzeSamples(gfc->rgdata, &mfbuf[0][gfc->mf_size], &mfbuf[1][gfc->mf_size], n_out, gfc->channels_out) == GAIN_ANALYSIS_ERROR)                 return -6;        /* update in_buffer counters */        nsamples -= n_in;        in_buffer[0] += n_in;        if (gfc->channels_out == 2)            in_buffer[1] += n_in;        /* update mfbuf[] counters */        gfc->mf_size += n_out;        assert(gfc->mf_size <= MFSIZE);        gfc->mf_samples_to_encode += n_out;        if (gfc->mf_size >= mf_needed) {            /* encode the frame.  */            /* mp3buf              = pointer to current location in buffer */            /* mp3buf_size         = size of original mp3 output buffer */            /*                     = 0 if we should not worry about the */            /*                       buffer size because calling program is  */            /*                       to lazy to compute it */            /* mp3size             = size of data written to buffer so far */            /* mp3buf_size-mp3size = amount of space avalable  */            int buf_size=mp3buf_size - mp3size;            if (mp3buf_size==0) buf_size=0;            ret =                lame_encode_frame(gfp, mfbuf[0], mfbuf[1], mp3buf,buf_size);            if (ret < 0) return ret;            mp3buf += ret;            mp3size += ret;            /* shift out old samples */            gfc->mf_size -= gfp->framesize;            gfc->mf_samples_to_encode -= gfp->framesize;            for (ch = 0; ch < gfc->channels_out; ch++)                for (i = 0; i < gfc->mf_size; i++)                    mfbuf[ch][i] = mfbuf[ch][i + gfp->framesize];        }    }    assert(nsamples == 0);    return mp3size;}intlame_encode_buffer(lame_global_flags * gfp,                   const short int buffer_l[],                   const short int buffer_r[],                   const int nsamples, unsigned char *mp3buf, const int mp3buf_size){    lame_internal_flags *gfc = gfp->internal_flags;    int     i;    sample_t *in_buffer[2];    if (gfc->Class_ID != LAME_ID)        return -3;    if (nsamples == 0)        return 0;    if (update_inbuffer_size( gfc, nsamples ) != 0) {        return -2;    }    in_buffer[0] = gfc->in_buffer_0;    in_buffer[1] = gfc->in_buffer_1;    /* 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_float(lame_global_flags * gfp,                   const float buffer_l[],                   const float buffer_r[],                   const int nsamples, unsigned char *mp3buf, const int mp3buf_size){    lame_internal_flags *gfc = gfp->internal_flags;    int     i;    sample_t *in_buffer[2];    if (gfc->Class_ID != LAME_ID)        return -3;    if (nsamples == 0)        return 0;    if (update_inbuffer_size( gfc, nsamples ) != 0) {        return -2;    }    in_buffer[0] = gfc->in_buffer_0;    in_buffer[1] = gfc->in_buffer_1;    /* 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_int(lame_global_flags * gfp,                   const int buffer_l[],                   const int buffer_r[],                   const int nsamples, unsigned char *mp3buf, const int mp3buf_size){    lame_internal_flags *gfc = gfp->internal_flags;    int     i;    sample_t *in_buffer[2];    if (gfc->Class_ID != LAME_ID)        return -3;    if (nsamples == 0)        return 0;    if (update_inbuffer_size( gfc, nsamples ) != 0) {        return -2;    }    in_buffer[0] = gfc->in_buffer_0;    in_buffer[1] = gfc->in_buffer_1;        /* make a copy of input buffer, changing type to sample_t */    for (i = 0; i < nsamples; i++) {                                /* internal code expects +/- 32768.0 */      in_buffer[0][i] = buffer_l[i] * (1.0 / ( 1L << (8 * sizeof(int) - 16)));      if (gfc->channels_in>1)	  in_buffer[1][i] = buffer_r[i] * (1.0 / ( 1L << (8 * sizeof(int) - 16)));    }    return lame_encode_buffer_sample_t(gfp,in_buffer[0],in_buffer[1],				      nsamples, mp3buf, mp3buf_size);}intlame_encode_buffer_long2(lame_global_flags * gfp,                   const long buffer_l[],                   const long buffer_r[],                   const int nsamples, unsigned char *mp3buf, const int mp3buf_size){    lame_internal_flags *gfc = gfp->internal_flags;    int     i;    sample_t *in_buffer[2];    if (gfc->Class_ID != LAME_ID)        return -3;    if (nsamples == 0)        return 0;    if (update_inbuffer_size( gfc, nsamples ) != 0) {        return -2;    }    in_buffer[0] = gfc->in_buffer_0;    in_buffer[1] = gfc->in_buffer_1;    /* make a copy of input buffer, changing type to sample_t */    for (i = 0; i < nsamples; i++) {                                /* internal code expects +/- 32768.0 */      in_buffer[0][i] = buffer_l[i] * (1.0 / ( 1L << (8 * sizeof(long) - 16)));      if (gfc->channels_in>1)	  in_buffer[1][i] = buffer_r[i] * (1.0 / ( 1L << (8 * sizeof(long) - 16)));    }    return lame_encode_buffer_sample_t(gfp,in_buffer[0],in_buffer[1],				      nsamples, mp3buf, mp3buf_size);    }intlame_encode_buffer_long(lame_global_flags * gfp,                   const long buffer_l[],                   const long buffer_r[],                   const int nsamples, unsigned char *mp3buf, const int mp3buf_size){    lame_internal_flags *gfc = gfp->internal_flags;    int     i;    sample_t *in_buffer[2];    if (gfc->Class_ID != LAME_ID)        return -3;    if (nsamples == 0)        return 0;    if (update_inbuffer_size( gfc, nsamples ) != 0) {        return -2;    }    in_buffer[0] = gfc->in_buffer_0;    in_buffer[1] = gfc->in_buffer_1;

⌨️ 快捷键说明

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