/* ======================================================================= */ BOOL EncodeAudioBuffer(PBYTE CDBuffer, DWORD CDBytesWritten, DWORD dwWAVBufferSize, HANDLE MP3FileHandle, PBYTE MP3Buffer, lame_global_flags *GFP) { DWORD BufferPosition; INT nOutputSamples; DWORD MP3BytesWritten; BOOL Success = TRUE; for(BufferPosition = 0; BufferPosition < CDBytesWritten; BufferPosition += dwWAVBufferSize*2) { if(BufferPosition+(dwWAVBufferSize*2) > CDBytesWritten) nOutputSamples = (CDBytesWritten - BufferPosition) / 4; else nOutputSamples = dwWAVBufferSize/2; nOutputSamples = lame_encode_buffer_interleaved(GFP, (PSHORT)(PBYTE)(CDBuffer + BufferPosition), nOutputSamples, MP3Buffer, 0); if(nOutputSamples > 0) { if(WriteFile(MP3FileHandle, MP3Buffer, nOutputSamples, &MP3BytesWritten, NULL) == FALSE) { Log(LOG_WRITE, "Error code %u writing %u bytes to file", GetLastError(), nOutputSamples); Success = FALSE; break; } } else if(nOutputSamples < 0) { Log(LOG_WRITE, "Error code %u encoding audio buffer", nOutputSamples); Success = FALSE; break; } } return Success; }
static void mp3_write(void *ptr, gint length) { gint encoded; if (write_buffer_size == 0) { write_buffer_size = 8192; write_buffer = g_realloc (write_buffer, write_buffer_size); } RETRY: if (input.channels == 1) encoded = lame_encode_buffer (gfp, ptr, ptr, length / 2, write_buffer, write_buffer_size); else encoded = lame_encode_buffer_interleaved (gfp, ptr, length / 4, write_buffer, write_buffer_size); if (encoded == -1) { write_buffer_size *= 2; write_buffer = g_realloc (write_buffer, write_buffer_size); goto RETRY; } if (encoded > 0) write_output (write_buffer, encoded); numsamples += length / (2 * input.channels); }
int main(int argc, char** argv) { if(argc != 2) { printf("Usage: %s <wav file>\n", argv[0]); exit(0); } lame_global_flags *gfp; //set params gfp = lame_init(); lame_set_num_channels(gfp,2); lame_set_in_samplerate(gfp,44100); lame_set_brate(gfp,128); lame_set_mode(gfp,1); lame_set_quality(gfp,2); int ret_code = lame_init_params(gfp); if(ret_code < 0) { printf("ret_code < 0\n"); exit(-1); } //read input file int read, write; FILE* pcm = fopen(argv[1], "rb"); char* outPath; outPath = strdup(argv[1]); sprintf(outPath+strlen(argv[1])-3, "mp3"); FILE* mp3 = fopen(outPath, "wb"); short int pcm_buffer[PCM_SIZE * 2]; unsigned char mp3_buffer[MP3_SIZE]; do { read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm); if(read == 0) write = lame_encode_flush(gfp, mp3_buffer, MP3_SIZE); else write = lame_encode_buffer_interleaved(gfp, pcm_buffer, read, mp3_buffer, MP3_SIZE); fwrite(mp3_buffer, write, sizeof (unsigned char), mp3); } while (read != 0); lame_close(gfp); fclose(mp3); fclose(pcm); exit(0); }
// we expect the AVPacket.data to contain either interleaved S16, or interleaved F32 audio bool AudioEncoderMP3::encodePacket(AVPacket* p, FLVTag& tag) { assert(lame_flags); assert(settings.in_interleaved); /* we only support interleaved audio for now */ int nsamples = 0; int written = 0; #if defined(USE_GRAPH) uint64_t enc_start = uv_hrtime() / 1000000; #endif if(settings.in_bitsize == AV_AUDIO_BITSIZE_S16) { nsamples = p->data.size() / (sizeof(int16_t) * nchannels); //printf("----------------- samples: %d, channels: %d, data.size(): %zu\n", nsamples, nchannels, p->data.size()); written = lame_encode_buffer_interleaved(lame_flags, (short int*)&p->data.front(), nsamples, mp3_buffer, AUDIO_ENCODER_BUFFER_SIZE); } else if(settings.in_bitsize == AV_AUDIO_BITSIZE_F32) { nsamples = p->data.size() / (sizeof(float) * nchannels); written = lame_encode_buffer_interleaved_ieee_float(lame_flags, (const float*)&p->data.front(), nsamples, mp3_buffer, AUDIO_ENCODER_BUFFER_SIZE); } if(written > 0) { bitrate_nbytes += written; } uint64_t time_now = uv_hrtime(); if(time_now >= bitrate_timeout) { bitrate_timeout = time_now + bitrate_delay; double duration = (time_now - bitrate_time_started) / 1000000000.0; // in s. bitrate_in_kbps = ((bitrate_nbytes * 8) / 1000) / duration; STREAMER_STATUS("audio bitrate: %0.2f kbps\n", bitrate_in_kbps); } #if defined(USE_GRAPH) frames_graph["enc_audio"] += ((uv_hrtime()/1000000) - enc_start); frames_graph["enc_audio_video"] += ((uv_hrtime()/1000000) - enc_start); network_graph["mp3"] += written; #endif #if AUDIO_USE_DATA_PTR if(written) { tag.setData(mp3_buffer, written); } #elif AUDIO_USE_COPY_DATA tag.bs.clear(); if(written) { tag.bs.putBytes((uint8_t*)mp3_buffer, written); tag.setData(tag.bs.getPtr(), tag.bs.size()); } #endif tag.makeAudioTag(); tag.setTimeStamp(p->timestamp); return written > 0; }
media_packet_ptr lame_encoder_impl_internal::encode(const audio_data * _AudioData) { static const size_t mp3TimeBase = 14112000; // Least common multiple of 44100 and 32000 const int predSamplesInLame = lame_get_mf_samples_to_encode( m_Lame.get() ); // from lame: // The required mp3buf_size can be computed from num_samples, // samplerate and encoding rate, but here is a worst case estimate: // mp3buf_size in bytes = 1.25*num_samples + 7200 const size_t samplesCount = (_AudioData) ? _AudioData->get_samples_count() : 0; const size_t bufSize = static_cast<size_t>( 1.25 * samplesCount ) + 7200 ; uint8_t * buffer = m_Buffer.get_buffer( bufSize ); int lameRet = 0; if (_AudioData) { const size_t channelsCount = _AudioData->get_channels_count(); if (channelsCount == 1) { lameRet = lame_encode_buffer( m_Lame.get(), (short*)_AudioData->get_raw_data(), (short*)_AudioData->get_raw_data(), _AudioData->get_samples_count(), buffer, bufSize); } else { lameRet = lame_encode_buffer_interleaved( m_Lame.get(), (short*)_AudioData->get_raw_data(), _AudioData->get_samples_count(), buffer, bufSize); } } else { lameRet = lame_encode_flush(m_Lame.get(), buffer, bufSize) ; } const int samplesEncoded = predSamplesInLame + samplesCount - lame_get_mf_samples_to_encode( m_Lame.get() ); m_TotalSamplesEncoded += samplesEncoded; common_media_packet2_ptr mediaPacket = common_media_packet2_ptr( new common_media_packet2() ); mediaPacket->setter()->set_data(buffer, lameRet, bufferAllocNew); mediaPacket->setter()->set_media_type(DT_AVMEDIA_TYPE_AUDIO); mediaPacket->setter()->set_time_base(dt_rational_t(1, mp3TimeBase)); mediaPacket->setter()->set_duration( samplesEncoded * (mp3TimeBase / get_input_sample_rate()) ); const dt_ts_t ts = m_TotalSamplesEncoded * (mp3TimeBase / get_input_sample_rate()); mediaPacket->setter()->set_pts( ts ); mediaPacket->setter()->set_dts( ts ); return mediaPacket; }
static int encode_lame(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size) { int n = 0; if(encoder->params.channels == 1) n = lame_encode_buffer(lame, (short *)src, (short *)src, len/2, dest, max_size); else n = lame_encode_buffer_interleaved(lame,(short *)src, len/4, dest, max_size); return (n < 0 ? 0 : n); }
void AudioReader::exportAudioDataToMP3(const char* data) { QSettings settings; emit TCMessage("Exporting MP3..."); int read, write; FILE *pcm = fopen("TCTemp.wav", "wb"); fwrite(data,1,format.chunkSize,pcm); fflush(pcm); pcm = fopen("TCTemp.wav", "rb"); f = fopen(this->outfile.toLocal8Bit().constData(), "wb"); const int PCM_SIZE = 8192; const int MP3_SIZE = 8192*2; short int pcm_buffer[PCM_SIZE*2]; unsigned char mp3_buffer[MP3_SIZE]; lame_t lame = lame_init(); lame_set_in_samplerate(lame, format.SampleRate); lame_set_VBR(lame, (vbr_mode)settings.value("vbr",0).toInt()); if(lame_get_VBR(lame)) { lame_set_VBR_min_bitrate_kbps(lame,settings.value("min",128).toInt()); lame_set_VBR_max_bitrate_kbps(lame,settings.value("max",192).toInt()); } else { lame_set_brate(lame,settings.value("min",128).toInt()); } lame_set_num_channels(lame,(int)format.Channels); lame_set_quality(lame,0); if(format.Channels==1)lame_set_mode(lame,MONO); else lame_set_mode(lame,STEREO); lame_init_params(lame); do { if(!knock->running)break; read = fread(pcm_buffer, 2*byte_size, PCM_SIZE, pcm); fflush(f); if (read == 0) write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE); else write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE); fwrite(mp3_buffer, write, 1, f); fflush(f); } while (read != 0); lame_close(lame); fclose(pcm); if(unlink("TCTemp.wav")!=0) { emit TCColor("color: red;"); emit TCMessage(QString("Error while removing TCTemp.wav")); } }
int WMp3Encoder::EncodeSamples(void *pSamples, unsigned int nNumberOfSamples) { ASSERT_W(c_nBitBerSample == 16); if(c_fReady == 0) { err(ENCODER_NOT_READY); return 0; } int nOutputBytes; short *samples = (short*) pSamples; unsigned int nHaveSamples = nNumberOfSamples; if(nNumberOfSamples == 0) { nOutputBytes = lame_encode_flush(gfp, c_pWorkingBuffer, c_nSamplesBufferSizeInBytes); if(nOutputBytes > 0) c_write_callback(c_pWorkingBuffer, nOutputBytes, c_user_data); // Chunk ID return 1; } while(nHaveSamples) { unsigned int nFill = c_NumberOfInputSamples; if(nFill > nHaveSamples) nFill = nHaveSamples; if ( 1 == lame_get_num_channels( gfp ) ) { nOutputBytes = lame_encode_buffer(gfp, samples, samples, nFill, c_pWorkingBuffer, 0); samples = &samples[nFill]; } else { nOutputBytes = lame_encode_buffer_interleaved(gfp, samples, nFill, c_pWorkingBuffer, 0); samples = &samples[nFill * 2]; } nHaveSamples -= nFill; if(nOutputBytes > 0) c_write_callback(c_pWorkingBuffer, nOutputBytes, c_user_data); // Chunk ID } return 1; }
int doEncode(LameConf* conf, short* pcmSamples, int pcmLengthInFrames, char* encodedBytes, int encodedArrayByteSize) { if (conf->gf==NULL) { //throwRuntimeException(env, "not initialized"); return org_tritonus_lowlevel_lame_Lame_NOT_INITIALIZED; } if (conf->channels==1) { return lame_encode_buffer(conf->gf, pcmSamples, pcmSamples, pcmLengthInFrames, encodedBytes, encodedArrayByteSize); } else { return lame_encode_buffer_interleaved(conf->gf, pcmSamples, pcmLengthInFrames, encodedBytes, encodedArrayByteSize); } }
void MP3Writer::addAudioInterleaved(const short int* data, size_t nbytes, int nsamples) { if(!is_setup) { return; } if(!is_started) { return; } int written = lame_encode_buffer_interleaved(lame_flags, (short int*)data, nsamples, mp3_buffer, MP3_WRITER_BUFFER_SIZE); if(written > 0 && config.cb_data) { config.cb_data((const char*)mp3_buffer, written, config.user); } }
jint simple_lame_lib_encodeBufferInterleaved( JNIEnv* env, lame_global_flags* glf, jshortArray pcm, jint samples, jbyteArray mp3buf) { jshort* j_pcm = (*env)->GetShortArrayElements(env, pcm, NULL); const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf); jbyte* j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL); int result = lame_encode_buffer_interleaved(glf, j_pcm, samples, j_mp3buf, mp3buf_size); (*env)->ReleaseShortArrayElements(env, pcm, j_pcm, 0); (*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0); return result; }
int lame_enc_encode(lame_enc *lame, short *pcm_buf, char *enc_buf, int samples, int size) { int rc; if(samples == 0 || lame->gfp == NULL) return 0; lame->state = LAME_BUSY; if(lame->channel == 2) rc = lame_encode_buffer_interleaved(lame->gfp, pcm_buf, samples, (unsigned char*)enc_buf, size); else rc = lame_encode_buffer(lame->gfp, pcm_buf, pcm_buf, samples, (unsigned char*)enc_buf, size); lame->state = LAME_READY; return rc; }
void Encoder(char* src, char* dst){ //printf("Inside Encoder : %s \n",src); //printf("Inside Encoder : %s \n",dst); if(src == NULL || dst == NULL) return; int read, write; FILE* wav; FILE* mp3; wav = fopen(src, "rb"); if(wav == NULL){ printf(" Unable to open the file %s \n", src); return; } mp3 = fopen(dst, "wb"); if(mp3 == NULL){ printf(" Unable to open the file %s \n", dst); return; } const int PCM_SIZE = 8192; const int MP3_SIZE = 8192; short int PCM_BUFFER[2*PCM_SIZE]; char MP3_BUFFER[MP3_SIZE]; lame_t lame = lame_init(); lame_set_in_samplerate(lame, 44100); lame_set_VBR(lame, vbr_default); lame_init_params(lame); do { read = fread(PCM_BUFFER, 2*sizeof(short int), PCM_SIZE, wav); if (read == 0) write = lame_encode_flush(lame, MP3_BUFFER, MP3_SIZE); else write = lame_encode_buffer_interleaved(lame, PCM_BUFFER, read, MP3_BUFFER, MP3_SIZE); fwrite(MP3_BUFFER, write, 1, mp3); } while (read != 0); lame_close(lame); fclose(wav); fclose(mp3); }
bool LameEncodeChunk(lame_global_flags * gf, int nsamples, PBYTE inbuffer, PBYTE &outbuffer, int outBufferSize, int &encoded_bytes) { int samples = nsamples / lame_get_num_channels(gf); if ( 1 == lame_get_num_channels( gf ) ) { encoded_bytes = lame_encode_buffer(gf, (short *)inbuffer, (short *)inbuffer, samples, outbuffer, outBufferSize); } else { encoded_bytes = lame_encode_buffer_interleaved(gf, (short *)inbuffer, samples, outbuffer, outBufferSize); } if(encoded_bytes < 0) { encoded_bytes = 0; return false; } return true; }
bool ACMStream::ConvertBuffer(LPACMDRVSTREAMHEADER a_StreamHeader) { bool result; if (my_debug != NULL) { my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "enter ACMStream::ConvertBuffer"); } DWORD InSize = a_StreamHeader->cbSrcLength / 2, OutSize = a_StreamHeader->cbDstLength; // 2 for 8<->16 bits // Encode it int dwSamples; int nOutputSamples = 0; dwSamples = InSize / lame_get_num_channels( gfp ); if ( 1 == lame_get_num_channels( gfp ) ) { nOutputSamples = lame_encode_buffer(gfp,(PSHORT)a_StreamHeader->pbSrc,(PSHORT)a_StreamHeader->pbSrc,dwSamples,a_StreamHeader->pbDst,a_StreamHeader->cbDstLength); } else { nOutputSamples = lame_encode_buffer_interleaved(gfp,(PSHORT)a_StreamHeader->pbSrc,dwSamples,a_StreamHeader->pbDst,a_StreamHeader->cbDstLength); } a_StreamHeader->cbSrcLengthUsed = a_StreamHeader->cbSrcLength; a_StreamHeader->cbDstLengthUsed = nOutputSamples; result = a_StreamHeader->cbDstLengthUsed <= a_StreamHeader->cbDstLength; my_debug->OutPut(DEBUG_LEVEL_FUNC_CODE, "UsedSize = %d / EncodedSize = %d, result = %d (%d <= %d)", InSize, OutSize, result, a_StreamHeader->cbDstLengthUsed, a_StreamHeader->cbDstLength); if (my_debug != NULL) { my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "ACMStream::ConvertBuffer result = %d (0x%02X 0x%02X)",result,a_StreamHeader->pbDst[0],a_StreamHeader->pbDst[1]); } return result; }
/* note: num is number of samples in the L (or R) channel not the total number of samples in pcm[] */ int OutLame::encode() { int num, smp; /* num is number of bytes read from pipe sound in pipe is always 16bit stereo ... */ num = erbapipa->read(OUT_CHUNK<<2,pcm); if(num<0) return num; /* ... therefore samples are num/4 */ smp = num>>2; if(!enc_flags) { error("Lame encoder is not initialized"); return -5; } encoded = lame_encode_buffer_interleaved (enc_flags, pcm, smp, (unsigned char *)buffer, 0); //ENCBUFFER_SIZE); if(encoded<0) switch(encoded) { case -1: error("lame encoder: mp3 buffer is too small"); break; case -2: error("lame encoder: malloc() problem"); break; case -3: error("lame encoder: lame_init_params() not called"); break; case -4: error("lame encoder: psycho acoustic problems (yes, shamanic indeed)"); break; default: error("lame encoder: internal error"); break; } return encoded; }
/** \fn send \brief Encode a block */ int AUDMEncoder_Lame::send(uint32_t nbSample, uint8_t *dest) { int nbout; dither16 (&(tmpbuffer[tmphead]), nbSample, wavheader.channels); ADM_assert (tmptail >= tmphead); int16_t *sample16=(int16_t *)& (tmpbuffer[tmphead]); if (wavheader.channels == 1) { nbout = lame_encode_buffer (MYFLAGS, sample16, sample16, nbSample, dest, 16 * 1024); } else { nbout = lame_encode_buffer_interleaved (MYFLAGS, sample16, nbSample / 2, dest, 16 * 1024); } return nbout; }
nframes_t LameAudioWriter::write_private(void* buffer, nframes_t frameCount) { if (m_bufferSize < frameCount * 1.25 + 7200) { if (m_buffer) { delete [] m_buffer; } m_bufferSize = (long)(frameCount * 1.25 + 7200); m_buffer = new char[m_bufferSize]; } int size; if (m_channels == 1) { size = lame_encode_buffer(m_lameInfo->flags, (short*)buffer, (short*)buffer, frameCount, (unsigned char*)m_buffer, m_bufferSize); } else { size = lame_encode_buffer_interleaved(m_lameInfo->flags, (short*)buffer, frameCount, (unsigned char*)m_buffer, m_bufferSize); } if (size < 0) { PERROR("lame_encode_buffer_interleaved failed."); return 0; } if (size > 0 && fwrite(m_buffer, 1, size, m_fid) != (nframes_t)size) { PERROR("writing mp3 data failed."); return 0; } return frameCount; }
uint8_t AUDMEncoder_Lame::getPacket(uint8_t *dest, uint32_t *len, uint32_t *samples) { int32_t nbout; *samples = BLOCK_SIZE; //FIXME *len = 0; if(!refillBuffer(_chunk )) { return 0; } if(tmptail-tmphead<_chunk) { return 0; } dither16(&(tmpbuffer[tmphead]),_chunk,_wavheader->channels); ADM_assert(tmptail>=tmphead); if (_wavheader->channels == 1) { nbout = lame_encode_buffer(MYFLAGS, (int16_t *)&(tmpbuffer[tmphead]),(int16_t *)&(tmpbuffer[tmphead]), _chunk, dest, 16 * 1024); } else { nbout = lame_encode_buffer_interleaved(MYFLAGS, (int16_t *)&(tmpbuffer[tmphead]), _chunk/2, dest, 16 * 1024); } tmphead+=_chunk; if (nbout < 0) { printf("\n Error !!! : %ld\n", nbout); return 0; } *len=nbout; if(!*len) *samples=0; //printf("Audio packet : size %u, sample %u\n",*len,*samples); return 1; }
EmErrorCode LameEncoder::Encode(char* buf, uint32_t len) { // prepare buffer int samplesPerChannel = len / ::lame_get_num_channels(m_gfp) / (m_BitsPerSample / 8); int minsz = 1.25 * samplesPerChannel + 7200; if (m_Buffer.size() < minsz) { m_Buffer.resize(minsz); } // encode int ret = lame_encode_buffer_interleaved( m_gfp, (short int*)buf, samplesPerChannel, m_Buffer.data(), m_Buffer.size()); if (ret >= 0) { if ((int)::fwrite(m_Buffer.data(), 1, ret, m_OutputFile) == ret) { return ErrorCode::Ok; } } return ErrorCode::EncoderFailedToEncode; }
////////////////////////////////////////////////////////////////////// // Encode - encodes data placed on pdata and returns // the number of processed bytes ////////////////////////////////////////////////////////////////////// int CEncoder::Encode(const short * pdata, int data_size) { CAutoLock l(&m_lock); if (!pgf || !m_outFrameBuf || !pdata || data_size < 0 || (data_size & (sizeof(short) - 1))) return -1; // some data left in the buffer, shift to start if (m_outReadOffset > 0) { if (m_outOffset > m_outReadOffset) memmove(m_outFrameBuf, m_outFrameBuf + m_outReadOffset, m_outOffset - m_outReadOffset); m_outOffset -= m_outReadOffset; } m_outReadOffset = 0; m_bFinished = FALSE; int bytes_processed = 0; int const nch = lame_get_num_channels(pgf); while (1) { int nsamples = (data_size - bytes_processed) / (sizeof(short) * nch); if (nsamples <= 0) break; if (nsamples > 1152) nsamples = 1152; if (m_outOffset >= OUT_BUFFER_MAX) break; int out_bytes = 0; if (nch == 2) out_bytes = lame_encode_buffer_interleaved( pgf, (short *)(pdata + (bytes_processed / sizeof(short))), nsamples, m_outFrameBuf + m_outOffset, OUT_BUFFER_SIZE - m_outOffset); else out_bytes = lame_encode_buffer( pgf, pdata + (bytes_processed / sizeof(short)), pdata + (bytes_processed / sizeof(short)), nsamples, m_outFrameBuf + m_outOffset, OUT_BUFFER_SIZE - m_outOffset); if (out_bytes < 0) return -1; m_outOffset += out_bytes; bytes_processed += nsamples * nch * sizeof(short); } return bytes_processed; }
////////////////////////////////////////////////////////////////////// // Init - initialized or reiniyialized encoder SDK with given input // and output settings ////////////////////////////////////////////////////////////////////// HRESULT CEncoder::Init() { CAutoLock l(&m_lock); m_outOffset = 0; m_outReadOffset = 0; m_bFinished = FALSE; m_frameCount = 0; if (!pgf) { if (!m_bInpuTypeSet || !m_bOutpuTypeSet) return E_UNEXPECTED; // Init Lame library // note: newer, safer interface which doesn't // allow or require direct access to 'gf' struct is being written // see the file 'API' included with LAME. if (pgf = lame_init()) { lame_set_num_channels(pgf, m_wfex.nChannels); lame_set_in_samplerate(pgf, m_wfex.nSamplesPerSec); lame_set_out_samplerate(pgf, m_mabsi.dwSampleRate); if ((lame_get_out_samplerate(pgf) >= 32000) && (m_mabsi.dwBitrate < 32)) lame_set_brate(pgf, 32); else lame_set_brate(pgf, m_mabsi.dwBitrate); lame_set_VBR(pgf, m_mabsi.vmVariable); lame_set_VBR_min_bitrate_kbps(pgf, m_mabsi.dwVariableMin); lame_set_VBR_max_bitrate_kbps(pgf, m_mabsi.dwVariableMax); lame_set_copyright(pgf, m_mabsi.bCopyright); lame_set_original(pgf, m_mabsi.bOriginal); lame_set_error_protection(pgf, m_mabsi.bCRCProtect); lame_set_bWriteVbrTag(pgf, m_mabsi.dwXingTag); lame_set_strict_ISO(pgf, m_mabsi.dwStrictISO); lame_set_VBR_hard_min(pgf, m_mabsi.dwEnforceVBRmin); if (lame_get_num_channels(pgf) == 2 && !m_mabsi.bForceMono) { //int act_br = pgf->VBR ? pgf->VBR_min_bitrate_kbps + pgf->VBR_max_bitrate_kbps / 2 : pgf->brate; // Disabled. It's for user's consideration now //int rel = pgf->out_samplerate / (act_br + 1); //pgf->mode = rel < 200 ? m_mabsi.ChMode : JOINT_STEREO; lame_set_mode(pgf, m_mabsi.ChMode); } else lame_set_mode(pgf, MONO); if (lame_get_mode(pgf) == JOINT_STEREO) lame_set_force_ms(pgf, m_mabsi.dwForceMS); else lame_set_force_ms(pgf, 0); // pgf->mode_fixed = m_mabsi.dwModeFixed; if (m_mabsi.dwVoiceMode != 0) { lame_set_lowpassfreq(pgf,12000); ///pgf->VBR_max_bitrate_kbps = 160; } if (m_mabsi.dwKeepAllFreq != 0) { ///pgf->lowpassfreq = -1; ///pgf->highpassfreq = -1; /// not available anymore } lame_set_quality(pgf, m_mabsi.dwQuality); lame_set_VBR_q(pgf, m_mabsi.dwVBRq); lame_init_params(pgf); // encoder delay compensation { int const nch = lame_get_num_channels(pgf); short * start_padd = (short *)calloc(48, nch * sizeof(short)); int out_bytes = 0; if (nch == 2) out_bytes = lame_encode_buffer_interleaved(pgf, start_padd, 48, m_outFrameBuf, OUT_BUFFER_SIZE); else out_bytes = lame_encode_buffer(pgf, start_padd, start_padd, 48, m_outFrameBuf, OUT_BUFFER_SIZE); if (out_bytes > 0) m_outOffset += out_bytes; free(start_padd); } return S_OK; } return E_FAIL; } return S_OK; }
bool WaveEncoder::ToMP3(const std::string &destFileName) { FILE *pcm = fopen(m_source.c_str(), "rb"); FILE *mp3 = fopen(destFileName.c_str(), "wb"); fseek(pcm, 0, SEEK_END); float pcm_length = ftell(pcm); float pcm_read = 0; int percentage = 0; fseek(pcm, 0, SEEK_SET); if(pcm == 0 || mp3 == 0) { m_lastErrorMessage = "Failed to open output stream."; return false; } int read, write; const int PCM_SIZE = 8192; const int MP3_SIZE = 8192; short int pcm_buffer[PCM_SIZE*2]; unsigned char mp3_buffer[MP3_SIZE]; lame_t lame = lame_init(); lame_set_num_channels(lame, 2); if(m_quality == 3) { lame_set_in_samplerate(lame, 48000); lame_set_brate(lame, 320); lame_set_quality(lame, 2); } else if(m_quality == 2) { lame_set_in_samplerate(lame, 48000); lame_set_brate(lame, 192); lame_set_quality(lame, 5); } else if(m_quality == 1) { lame_set_in_samplerate(lame, 48000); lame_set_brate(lame, 128); lame_set_quality(lame, 7); } lame_set_mode(lame, JOINT_STEREO); lame_init_params(lame); printf("0%%"); do { read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm); if (read == 0) write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE); else write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE); fwrite(mp3_buffer, write, 1, mp3); pcm_read += PCM_SIZE * 2 * sizeof(short int); if(percentage < 10) printf("\b\b"); else if(percentage < 100) printf("\b\b\b"); else printf("\b\b\b\b"); percentage = (int)(pcm_read / pcm_length * 100.f); printf("%d%%", percentage); } while (read != 0); lame_close(lame); fclose(mp3); fclose(pcm); return true; }
int encode(char *inpath, char *outpath) { int status = 0; lame_global_flags *gfp; int ret_code; FILE *infp; FILE *outfp; short *input_buffer; int input_samples; char *mp3_buffer; int mp3_bytes; /* Initialize the library. */ gfp = lame_init(); if (gfp == NULL) { printf("lame_init returned NULL\n"); status = -1; goto exit; } /* Set the encoding parameters. */ ret_code = lame_init_params(gfp); if (ret_code < 0) { printf("lame_init_params returned %d\n", ret_code); status = -1; goto close_lame; } /* Open our input and output files. */ infp = fopen(inpath, "rb"); outfp = fopen(outpath, "wb"); /* Allocate some buffers. */ input_buffer = (short*)malloc(INBUFSIZE*2); mp3_buffer = (char*)malloc(MP3BUFSIZE); /* Read from the input file, encode, and write to the output file. */ do { input_samples = fread(input_buffer, 2, INBUFSIZE, infp); if (input_samples > 0) { mp3_bytes = lame_encode_buffer_interleaved( gfp, input_buffer, input_samples / 2, mp3_buffer, MP3BUFSIZE ); if (mp3_bytes < 0) { printf("lame_encode_buffer_interleaved returned %d\n", mp3_bytes); status = -1; goto free_buffers; } else if (mp3_bytes > 0) { fwrite(mp3_buffer, 1, mp3_bytes, outfp); } } } while (input_samples == INBUFSIZE); /* Flush the encoder of any remaining bytes. */ mp3_bytes = lame_encode_flush(gfp, mp3_buffer, sizeof(mp3_buffer)); if (mp3_bytes > 0) { printf("writing %d mp3 bytes\n", mp3_bytes); fwrite(mp3_buffer, 1, mp3_bytes, outfp); } /* Clean up. */ free_buffers: free(mp3_buffer); free(input_buffer); fclose(outfp); fclose(infp); close_lame: lame_close(gfp); exit: return status; }
/// 编码 int32_t CMp3Encoder::Encodec(const char* pSrcBuffer, uint32_t nSrcBuffSize, char* pDestBuffer, uint32_t nDestBufferSize) { return lame_encode_buffer_interleaved(m_hHandleEncoder, (short*)pSrcBuffer, 24, (unsigned char*)pDestBuffer, nDestBufferSize); }
/* encode PCM data to mp3 stream */ static void mp3write_encode(t_mp3write *x) { unsigned short i, wp; int err = -1; int n = x->x_lamechunk; #ifdef UNIX if(x->x_lamechunk < (int)sizeof(x->x_mp3inbuf)) #else if(x->x_lamechunk < sizeof(x->x_mp3inbuf)) #endif { error("not enough memory!"); return; } /* on start/reconnect set outpoint so that it won't interfere with inpoint */ if(x->x_start == -1) { post("mp3write~: reseting buffer positions"); /* we try to keep 2.5 times the data the encoder needs in the buffer */ if(x->x_inp > (2 * x->x_lamechunk)) { x->x_outp = (short) x->x_inp - (2.5 * x->x_lamechunk); } else if(x->x_inp < (2 * x->x_lamechunk)) { x->x_outp = (short) MY_MP3_MALLOC_IN_SIZE - (2.5 * x->x_lamechunk); } x->x_start = 1; } if((unsigned short)(x->x_outp - x->x_inp) < x->x_lamechunk)error("mp3write~: buffers overlap!"); i = MY_MP3_MALLOC_IN_SIZE - x->x_outp; /* read from buffer */ if(x->x_lamechunk <= i) { /* enough data until end of buffer */ for(n = 0; n < x->x_lamechunk; n++) /* fill encode buffer */ { x->x_mp3inbuf[n] = x->x_buffer[n + x->x_outp]; } x->x_outp += x->x_lamechunk; } else /* split data */ { for(wp = 0; wp < i; wp++) /* data at end of buffer */ { x->x_mp3inbuf[wp] = x->x_buffer[wp + x->x_outp]; } for(wp = i; wp < x->x_lamechunk; wp++) /* write rest of data at beginning of buffer */ { x->x_mp3inbuf[wp] = x->x_buffer[wp - i]; } x->x_outp = x->x_lamechunk - i; } /* encode mp3 data */ x->x_mp3size = lame_encode_buffer_interleaved(x->lgfp, x->x_mp3inbuf, x->x_lamechunk/lame_get_num_channels(x->lgfp), x->x_mp3outbuf, MY_MP3_MALLOC_OUT_SIZE); // post( "mp3write~ : encoding returned %d frames", x->x_mp3size ); /* check result */ if(x->x_mp3size<0) { lame_close( x->lgfp ); error("mp3write~: lame_encode_buffer_interleaved failed (%d)", x->x_mp3size); x->x_lame = -1; } }
//core function to encide WAV to MP3, relying on LAME library void encode(char* wavFilePath, char* mp3FilePath) { FILE* wavFile = fopen(wavFilePath, "rb"); FILE* mp3File = fopen(mp3FilePath, "wb+"); int readPCMSampleCount; short int pcmBuffer[PCM_BUF_SIZE]; unsigned char mp3Buffer[MP3_BUF_SIZE]; unsigned short channel; unsigned long sampleRate; unsigned short blockAlign; lame_t lame = lame_init(); if((wavFile == NULL) || (mp3File == NULL)) { printErrorMessage(FILE_IO_EXCEPTION); return; } if(lame == NULL) { printErrorMessage(LAME_API_ERROR); return; } //Set number of channels else if(fseek(wavFile, 22, SEEK_SET) != 0) { printErrorMessage(FILE_IO_EXCEPTION); return; } else if(fread(&channel, 2, 1, wavFile) < 1) { printErrorMessage(FILE_IO_EXCEPTION); return; } else { lame_set_num_channels(lame, channel); lame_set_mode(lame, (channel == 1) ? MONO : JOINT_STEREO); } //Set number of sample rate if(fseek(wavFile, 24, SEEK_SET) != 0) { printErrorMessage(FILE_IO_EXCEPTION); return; } else if(fread(&sampleRate, 4, 1, wavFile) < 1) { printErrorMessage(FILE_IO_EXCEPTION); return; } else { lame_set_in_samplerate(lame, sampleRate); lame_set_out_samplerate(lame, sampleRate); } //Set block align (byte/sample) if(fseek(wavFile, 32, SEEK_SET) != 0) { printErrorMessage(FILE_IO_EXCEPTION); return; } else if(fread(&blockAlign, 4, 1, wavFile) < 1) { printErrorMessage(FILE_IO_EXCEPTION); return; } //Look for data chank in the WAV file if(fseek(wavFile, 36, SEEK_SET) != 0) { printErrorMessage(FILE_IO_EXCEPTION); return; } else { char data[5]; data[4] = '\0'; while(fread(data, 4, 1, wavFile) == 1) { if(strcmp(data, "data") != 0) { //Search data chank by 1 byte fseek(wavFile, -3, SEEK_CUR); continue; } else if(fseek(wavFile, 4, SEEK_CUR)) { //data chank was found, then skip next 4 byte(indicating data size) to proceed printErrorMessage(FILE_IO_EXCEPTION); return; } else { //Now we are pointing the head of the PCM data, let's proceed break; } } //If data chank cannot be detected if(feof(wavFile)) { printErrorMessage(NOT_WAV_HEADER); return; } } //Encoding conficuration with "good" level quality lame_set_quality(lame, 5); lame_set_VBR(lame, vbr_default); lame_set_VBR_q(lame, 5); if(lame_init_params(lame) == -1) { printErrorMessage(LAME_API_ERROR); return; } //Perfoem encoding do { int encodedSampleCount; readPCMSampleCount = fread(pcmBuffer, blockAlign, PCM_BUF_SIZE / blockAlign, wavFile); if(readPCMSampleCount != 0) { if(channel == 1) { //For monoral case short int pcmBufferRight[PCM_BUF_SIZE]; short int pcmBufferLeft[PCM_BUF_SIZE]; int i; for(i = 0; i < PCM_BUF_SIZE; i++) { pcmBufferRight[i] = pcmBuffer[i]; pcmBufferLeft[i] = pcmBuffer[i]; } encodedSampleCount = lame_encode_buffer(lame, pcmBufferLeft, pcmBufferRight, readPCMSampleCount, mp3Buffer, MP3_BUF_SIZE); } else { //For stereo case encodedSampleCount = lame_encode_buffer_interleaved(lame, pcmBuffer, readPCMSampleCount, mp3Buffer, MP3_BUF_SIZE); } } else { encodedSampleCount = lame_encode_flush(lame, mp3Buffer, MP3_BUF_SIZE); } if(encodedSampleCount < 0) { printErrorMessage(LAME_API_ERROR); } else { fwrite(mp3Buffer, encodedSampleCount, 1, mp3File); } } while(readPCMSampleCount != 0); lame_close(lame); fclose(wavFile); fclose(mp3File); }