📄 lame.c
字号:
*/ 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 + -