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