/*this method expects a block at a time instead of the whole file, which lame_encoder does */ static int lame_realtime_encoder(lame_global_flags * gf, FILE * outf, int nogap, short *inInt,int sizeInInt ) { unsigned char mp3buffer[LAME_MAXMP3BUFFER]; //Buffer is read by the get_audio method. it has 2 arrays because of stereo aka numchannels. //only the first buffer is used for mono. int Buffer[2][1152]; int iread, imp3, owrite, id3v2_size; imp3 = lame_get_id3v2_tag(gf, mp3buffer, sizeof(mp3buffer)); if ((size_t)imp3 > sizeof(mp3buffer)) { error_printf("Error writing ID3v2 tag: buffer too small: buffer size=%d ID3v2 size=%d\n" , sizeof(mp3buffer) , imp3 ); return 1; } /* encode */ //char outp[150]; // sprintf(outp,"inInt: %i",sizeInInt); //LOGV(outp); short blank[sizeInInt]; imp3 = lame_encode_buffer(gf, inInt, blank, sizeInInt, mp3buffer, sizeof(mp3buffer)); /* was our output buffer big enough? */ if (imp3 < 0) { if (imp3 == -1) LOGV("mp3 buffer is not big enough... \n"); else { char outp[150]; sprintf(outp,"mp3 X internal error: error code=%i\n", imp3); LOGV(outp); } return 1; } LOGV(mp3buffer); char outp[150]; sprintf(outp,"mp3 X internal error: error code=%i\n", imp3); LOGV(outp); owrite = (int) fwrite(mp3buffer, 1, imp3, outf); if (owrite != imp3) { LOGV("Error writing mp3 output \n"); return 1; } fflush(outf); }
//this is an attempt to convert raw data frame by frame, if anyone can find a solution, send a patch. void Java_com_test_lame_TestLameActivity_convertMP3Realtime(JNIEnv* env,jobject thiz,jstring aaa,jstring outF, jshortArray inBytes, int sampleRate, int bitRate){ userCancel=0; lame_global_flags *gf = lame_init(); lame_set_num_channels(gf, 1); lame_set_in_samplerate(gf,sampleRate); lame_set_brate(gf,bitRate); lame_set_bWriteVbrTag(gf,0); int ipr = lame_init_params(gf); const char* outfs; outfs = (*env)->GetStringUTFChars(env, outF, NULL); int enc_delay = -1; int enc_padding = -1; FILE * outf; int outFopen=0; if(outFopen == 0) { outf = fopen(outfs,"a+b"); unsigned char mp3buffer[LAME_MAXMP3BUFFER]; int imp3 = lame_get_id3v2_tag(gf, mp3buffer, sizeof(mp3buffer)); fwrite(mp3buffer, 1, imp3, outf); outFopen =1; } jshort* jInBytes = (*env)->GetShortArrayElements(env,inBytes,NULL); jsize sizeIn = (*env)->GetArrayLength(env,inBytes); short inInts[sizeIn]; int totRead=0; int amountRead; while(totRead < sizeIn) { if(sizeIn - totRead < 1152) { amountRead = sizeIn -totRead; } else { amountRead = 1152; } int i; for(i=0;i< amountRead;i++) { inInts[i] = jInBytes[i]; totRead++; } lame_realtime_encoder(gf, outf,0 ,inInts,amountRead); } //failing on JNI: unpinPrimitiveArray() failed to find entry (valid=0) //(*env)->ReleaseByteArrayElements(env,jInBytes,inBytes,0); }
int id3tag_write_v2(lame_global_flags * gfp) { lame_internal_flags *gfc = gfp->internal_flags; #if 0 debug_tag_spec_flags(gfc, "write v2"); #endif if (test_tag_spec_flags(gfc, V1_ONLY_FLAG)) { return 0; } if (test_tag_spec_flags(gfc, CHANGED_FLAG)) { unsigned char *tag = 0; size_t tag_size, n; n = lame_get_id3v2_tag(gfp, 0, 0); tag = malloc(n); if (tag == 0) { return -1; } tag_size = lame_get_id3v2_tag(gfp, tag, n); if (tag_size > n) { free(tag); return -1; } else { size_t i; /* write tag directly into bitstream at current position */ for (i = 0; i < tag_size; ++i) { add_dummy_byte(gfc, tag[i], 1); } } free(tag); return (int) tag_size; /* ok, tag should not exceed 2GB */ } return 0; }
static void mp3_close(void) { if (output_file) { int imp3, encout; /* write remaining mp3 data */ encout = lame_encode_flush_nogap(gfp, encbuffer, LAME_MAXMP3BUFFER); write_output(encbuffer, encout); /* set gfp->num_samples for valid TLEN tag */ lame_set_num_samples(gfp, numsamples); /* append v1 tag */ imp3 = lame_get_id3v1_tag(gfp, encbuffer, sizeof(encbuffer)); if (imp3 > 0) write_output(encbuffer, imp3); /* update v2 tag */ imp3 = lame_get_id3v2_tag(gfp, encbuffer, sizeof(encbuffer)); if (imp3 > 0) { if (vfs_fseek(output_file, 0, SEEK_SET) != 0) { AUDDBG("can't rewind\n"); } else { write_output(encbuffer, imp3); } } /* update lame tag */ if (id3v2_size) { if (vfs_fseek(output_file, id3v2_size, SEEK_SET) != 0) { AUDDBG("fatal error: can't update LAME-tag frame!\n"); } else { imp3 = lame_get_lametag_frame(gfp, encbuffer, sizeof(encbuffer)); write_output(encbuffer, imp3); } } } g_free (write_buffer); lame_close(gfp); AUDDBG("lame_close() done\n"); free_lameid3(&lameid3); numsamples = 0; }
audio_encoder_queue_lame_impl::audio_encoder_queue_lame_impl(const audio_format * _AudioFormat, const audio_encoder_lame_utils::properties * _Properties) : m_Lame(NULL), m_AudioBuffer( audio_buffer::create( audio_buffer::audio_buffer_SameFormat, _AudioFormat ) ) , sampleRate_( _AudioFormat ? _AudioFormat->get_sample_rate() : 0 ), lastData_(false) { std::auto_ptr<lame_encoder_impl_internal> lameEnc = std::auto_ptr<lame_encoder_impl_internal>( new lame_encoder_impl_internal() ); lameEnc->set_input_sample_rate( _AudioFormat->get_sample_rate() ); lameEnc->set_channels_count( _AudioFormat->get_channels_count() ); if (1 == _AudioFormat->get_channels_count()) { lameEnc->set_stereo_mode( lame_encoder_impl_internal::StereoMode_MONO ); } // TODO: default preset // if (_Properties->bitrate() > 0) lameEnc->set_bit_rate(_Properties->bitrate()); else { lameEnc->set_preset( lame_encoder_impl_internal::PresetMode_V2); } lameEnc->set_quality(5); if (!_Properties->artist_w().empty()) lameEnc->set_artist(_Properties->artist_w().c_str()); if (!_Properties->title_w().empty()) lameEnc->set_title(_Properties->title_w().c_str()); lameEnc->start(); boost::shared_ptr<openmedia::codec_extra_data_common> extraData = boost::make_shared<openmedia::codec_extra_data_common>(); unsigned char mp3buffer[LAME_MAXMP3BUFFER]; int imp3 = lame_get_id3v2_tag(lameEnc->lame().get(), mp3buffer, sizeof(mp3buffer)); DT_ASSERT(imp3 <= LAME_MAXMP3BUFFER); extraData->setter()->add_data("ID3V2TAG", mp3buffer, imp3, openmedia::bufferAllocNew); m_CodecExtraData = extraData; m_Lame = lameEnc.release(); }
static int lame_encoder_loop(lame_global_flags * gf, FILE * outf, int nogap, char *inPath, char *outPath) { unsigned char mp3buffer[LAME_MAXMP3BUFFER]; int Buffer[2][1152]; int iread, imp3, owrite; size_t id3v2_size; encoder_progress_begin(gf, inPath, outPath); id3v2_size = lame_get_id3v2_tag(gf, 0, 0); if (id3v2_size > 0) { unsigned char *id3v2tag = malloc(id3v2_size); if (id3v2tag != 0) { size_t n_bytes = lame_get_id3v2_tag(gf, id3v2tag, id3v2_size); size_t written = fwrite(id3v2tag, 1, n_bytes, outf); free(id3v2tag); if (written != n_bytes) { encoder_progress_end(gf); error_printf("Error writing ID3v2 tag \n"); return 1; } } } else { unsigned char* id3v2tag = getOldTag(gf); id3v2_size = sizeOfOldTag(gf); if ( id3v2_size > 0 ) { size_t owrite = fwrite(id3v2tag, 1, id3v2_size, outf); if (owrite != id3v2_size) { encoder_progress_end(gf); error_printf("Error writing ID3v2 tag \n"); return 1; } } } if (global_writer.flush_write == 1) { fflush(outf); } /* encode until we hit eof */ do { /* read in 'iread' samples */ iread = get_audio(gf, Buffer); if (iread >= 0) { encoder_progress(gf); /* encode */ imp3 = lame_encode_buffer_int(gf, Buffer[0], Buffer[1], iread, mp3buffer, sizeof(mp3buffer)); /* was our output buffer big enough? */ if (imp3 < 0) { if (imp3 == -1) error_printf("mp3 buffer is not big enough... \n"); else error_printf("mp3 internal error: error code=%i\n", imp3); return 1; } owrite = (int) fwrite(mp3buffer, 1, imp3, outf); if (owrite != imp3) { error_printf("Error writing mp3 output \n"); return 1; } } if (global_writer.flush_write == 1) { fflush(outf); } } while (iread > 0); if (nogap) imp3 = lame_encode_flush_nogap(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */ else imp3 = lame_encode_flush(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */ if (imp3 < 0) { if (imp3 == -1) error_printf("mp3 buffer is not big enough... \n"); else error_printf("mp3 internal error: error code=%i\n", imp3); return 1; } encoder_progress_end(gf); owrite = (int) fwrite(mp3buffer, 1, imp3, outf); if (owrite != imp3) { error_printf("Error writing mp3 output \n"); return 1; } if (global_writer.flush_write == 1) { fflush(outf); } imp3 = write_id3v1_tag(gf, outf); if (global_writer.flush_write == 1) { fflush(outf); } if (imp3) { return 1; } write_xing_frame(gf, outf, id3v2_size); if (global_writer.flush_write == 1) { fflush(outf); } if (global_ui_config.silent <= 0) { print_trailing_info(gf); } return 0; }
static int lame_encoder(lame_global_flags * gf, FILE * outf, int nogap, char *inPath, char *outPath) { unsigned char mp3buffer[LAME_MAXMP3BUFFER]; int Buffer[2][1152]; int iread, imp3, owrite, id3v2_size; imp3 = lame_get_id3v2_tag(gf, mp3buffer, sizeof(mp3buffer)); if ((size_t)imp3 > sizeof(mp3buffer)) { error_printf("Error writing ID3v2 tag: buffer too small: buffer size=%d ID3v2 size=%d\n" , sizeof(mp3buffer) , imp3 ); return 1; } owrite = (int) fwrite(mp3buffer, 1, imp3, outf); if (owrite != imp3) { error_printf("Error writing ID3v2 tag \n"); return 1; } if (flush_write == 1) { fflush(outf); } id3v2_size = imp3; /* encode until we hit eof */ do { /* read in 'iread' samples. The value of iread is 1152 (2010/07/11) on my nexus one. */ iread = get_audio(gf, Buffer); //needed to add a multiplier of 2 to achieve bytes on my G1. 2010/01/09 totBytes += iread *2; rewind(progFile); fprintf(progFile,"%d",totBytes); if (iread >= 0) { //char buf[50]; //sprintf(buf,"%i",iread); //LOGV(buf); /* encode */ imp3 = lame_encode_buffer_int(gf, Buffer[0], Buffer[1], iread, mp3buffer, sizeof(mp3buffer)); /* was our output buffer big enough? */ if (imp3 < 0) { if (imp3 == -1) error_printf("mp3 buffer is not big enough... \n"); else error_printf("mp3 X internal error: error code=%i\n", imp3); return 1; } owrite = (int) fwrite(mp3buffer, 1, imp3, outf); if (owrite != imp3) { error_printf("Error writing mp3 output \n"); return 1; } } if (flush_write == 1) { fflush(outf); } } while (iread > 0 && userCancel != 1); if (nogap) imp3 = lame_encode_flush_nogap(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */ else imp3 = lame_encode_flush(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */ if (imp3 < 0) { if (imp3 == -1) error_printf("mp3 buffer is not big enough... \n"); else error_printf("mp3 internal error: error code=%i\n", imp3); return 1; } owrite = (int) fwrite(mp3buffer, 1, imp3, outf); if (owrite != imp3) { error_printf("Error writing mp3 output \n"); return 1; } if (flush_write == 1) { fflush(outf); } imp3 = lame_get_id3v1_tag(gf, mp3buffer, sizeof(mp3buffer)); if ((size_t)imp3 > sizeof(mp3buffer)) { error_printf("Error writing ID3v1 tag: buffer too small: buffer size=%d ID3v1 size=%d\n" , sizeof(mp3buffer) , imp3 ); } else { if (imp3 > 0) { owrite = (int) fwrite(mp3buffer, 1, imp3, outf); if (owrite != imp3) { error_printf("Error writing ID3v1 tag \n"); return 1; } if (flush_write == 1) { fflush(outf); } } } if (silent <= 0) { print_lame_tag_leading_info(gf); } if (fseek(outf, id3v2_size, SEEK_SET) != 0) { error_printf("fatal error: can't update LAME-tag frame!\n"); } else { write_xing_frame(gf, outf); } if (silent <= 0) { print_trailing_info(gf); } return 0; }
static int lame_encoder(lame_global_flags * gf, FILE * outf, int nogap, char *inPath, char *outPath) { unsigned char mp3buffer[LAME_MAXMP3BUFFER]; int Buffer[2][1152]; int iread, imp3, owrite, id3v2_size; encoder_progress_begin(gf, inPath, outPath); imp3 = lame_get_id3v2_tag(gf, mp3buffer, sizeof(mp3buffer)); if ((size_t)imp3 > sizeof(mp3buffer)) { encoder_progress_end(gf); error_printf("Error writing ID3v2 tag: buffer too small: buffer size=%d ID3v2 size=%d\n" , sizeof(mp3buffer) , imp3 ); return 1; } owrite = (int) fwrite(mp3buffer, 1, imp3, outf); if (owrite != imp3) { encoder_progress_end(gf); error_printf("Error writing ID3v2 tag \n"); return 1; } if (flush_write == 1) { fflush(outf); } id3v2_size = imp3; /* encode until we hit eof */ do { /* read in 'iread' samples */ iread = get_audio(gf, Buffer); if (iread >= 0) { encoder_progress(gf); /* encode */ imp3 = lame_encode_buffer_int(gf, Buffer[0], Buffer[1], iread, mp3buffer, sizeof(mp3buffer)); /* was our output buffer big enough? */ if (imp3 < 0) { if (imp3 == -1) error_printf("mp3 buffer is not big enough... \n"); else error_printf("mp3 internal error: error code=%i\n", imp3); return 1; } owrite = (int) fwrite(mp3buffer, 1, imp3, outf); if (owrite != imp3) { error_printf("Error writing mp3 output \n"); return 1; } } if (flush_write == 1) { fflush(outf); } } while (iread > 0); if (nogap) imp3 = lame_encode_flush_nogap(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */ else imp3 = lame_encode_flush(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */ if (imp3 < 0) { if (imp3 == -1) error_printf("mp3 buffer is not big enough... \n"); else error_printf("mp3 internal error: error code=%i\n", imp3); return 1; } encoder_progress_end(gf); owrite = (int) fwrite(mp3buffer, 1, imp3, outf); if (owrite != imp3) { error_printf("Error writing mp3 output \n"); return 1; } if (flush_write == 1) { fflush(outf); } imp3 = lame_get_id3v1_tag(gf, mp3buffer, sizeof(mp3buffer)); if ((size_t)imp3 > sizeof(mp3buffer)) { error_printf("Error writing ID3v1 tag: buffer too small: buffer size=%d ID3v1 size=%d\n" , sizeof(mp3buffer) , imp3 ); } else { if (imp3 > 0) { owrite = (int) fwrite(mp3buffer, 1, imp3, outf); if (owrite != imp3) { error_printf("Error writing ID3v1 tag \n"); return 1; } if (flush_write == 1) { fflush(outf); } } } if (silent <= 0) { print_lame_tag_leading_info(gf); } if (fseek(outf, id3v2_size, SEEK_SET) != 0) { error_printf("fatal error: can't update LAME-tag frame!\n"); } else { write_xing_frame(gf, outf); } if (silent <= 0) { print_trailing_info(gf); } return 0; }
int CEncoderLame::prepare( const sp<IMediaSource>& pMediaSource_in, const sp<IAudioSink>& pAudioSink_out, const sp<AMessage>& pOption_in ) { AUTO_LOG(); if (m_pGobalFlags != NULL) { RETURN(ALREADY_EXISTS); } CHECK_PTR_EXT(pMediaSource_in, BAD_VALUE); CHECK_PTR_EXT(pAudioSink_out, BAD_VALUE); sp<MetaData> pMeta = pMediaSource_in->getFormat(); CHECK_PTR_EXT(pMeta, BAD_VALUE); m_pGobalFlags = lame_init(); CHECK_PTR_EXT(m_pGobalFlags, BAD_VALUE); lame_set_errorf(m_pGobalFlags, CEncoderLame::errorf); lame_set_debugf(m_pGobalFlags, CEncoderLame::debugf); lame_set_msgf(m_pGobalFlags, CEncoderLame::msgf); id3tag_init(m_pGobalFlags); // TO DO // pass the user option to encoder //if (pOption_in != NULL) { //} int ret = OK; bool chk = false; int32_t iChannelNum = 0; chk = pMeta->findInt32(kKeyChannelCount, &iChannelNum); CHECK_IS_EXT((true == chk), UNKNOWN_ERROR); ret = lame_set_num_channels(m_pGobalFlags, iChannelNum); CHECK_IS_EXT((ret == OK), ret); int32_t iSampleRate = 0; chk = pMeta->findInt32(kKeySampleRate, &iSampleRate); CHECK_IS_EXT((true == chk), UNKNOWN_ERROR); ret = lame_set_in_samplerate(m_pGobalFlags, iSampleRate); CHECK_IS_EXT((ret == OK), ret); int32_t iBitsPerSample = 0; chk = pMeta->findInt32(kKeyBitsPerSample, &iBitsPerSample); CHECK_IS_EXT((true == chk), UNKNOWN_ERROR); int32_t iDataSize = 0; chk = pMeta->findInt32(kKeyDataSize, &iDataSize); CHECK_IS_EXT((true == chk), UNKNOWN_ERROR); ret = lame_set_num_samples(m_pGobalFlags, iDataSize / (iChannelNum * ((iBitsPerSample + 7) / 8))); CHECK_IS_EXT((ret == OK), ret); lame_set_write_id3tag_automatic(m_pGobalFlags, 0); ret = lame_init_params(m_pGobalFlags); CHECK_IS_EXT((ret == OK), ret); size_t id3v2_size = lame_get_id3v2_tag(m_pGobalFlags, 0, 0); if (id3v2_size > 0) { unsigned char *id3v2tag = new unsigned char[id3v2_size]; if (id3v2tag != 0) { int iTagSz = lame_get_id3v2_tag(m_pGobalFlags, id3v2tag, id3v2_size); int iWrite = (int) pAudioSink_out->write(id3v2tag, iTagSz); delete(id3v2tag); CHECK_IS_EXT((iTagSz == iWrite), UNKNOWN_ERROR); } } RETURN(OK); }
static gint mp3_open(void) { int imp3; gfp = lame_init(); if (gfp == NULL) return 0; /* setup id3 data */ id3tag_init(gfp); if (tuple) { /* XXX write UTF-8 even though libmp3lame does id3v2.3. --yaz */ lameid3.track_name = tuple_get_str (tuple, FIELD_TITLE, NULL); id3tag_set_title(gfp, lameid3.track_name); lameid3.performer = tuple_get_str (tuple, FIELD_ARTIST, NULL); id3tag_set_artist(gfp, lameid3.performer); lameid3.album_name = tuple_get_str (tuple, FIELD_ALBUM, NULL); id3tag_set_album(gfp, lameid3.album_name); lameid3.genre = tuple_get_str (tuple, FIELD_GENRE, NULL); id3tag_set_genre(gfp, lameid3.genre); lameid3.year = str_printf ("%d", tuple_get_int (tuple, FIELD_YEAR, NULL)); id3tag_set_year(gfp, lameid3.year); lameid3.track_number = str_printf ("%d", tuple_get_int (tuple, FIELD_TRACK_NUMBER, NULL)); id3tag_set_track(gfp, lameid3.track_number); if (force_v2_val) { id3tag_add_v2(gfp); } if (only_v1_val) { id3tag_v1_only(gfp); } if (only_v2_val) { id3tag_v2_only(gfp); } } /* input stream description */ lame_set_in_samplerate(gfp, input.frequency); lame_set_num_channels(gfp, input.channels); /* Maybe implement this? */ /* lame_set_scale(lame_global_flags *, float); */ lame_set_out_samplerate(gfp, out_samplerate_val); /* general control parameters */ lame_set_bWriteVbrTag(gfp, toggle_xing_val); lame_set_quality(gfp, algo_quality_val); if (audio_mode_val != 4) { AUDDBG("set mode to %d\n", audio_mode_val); lame_set_mode(gfp, audio_mode_val); } lame_set_errorf(gfp, lame_debugf); lame_set_debugf(gfp, lame_debugf); lame_set_msgf(gfp, lame_debugf); if (enc_toggle_val == 0 && vbr_on == 0) lame_set_brate(gfp, bitrate_val); else if (vbr_on == 0) lame_set_compression_ratio(gfp, compression_val); /* frame params */ lame_set_copyright(gfp, mark_copyright_val); lame_set_original(gfp, mark_original_val); lame_set_error_protection(gfp, error_protect_val); lame_set_strict_ISO(gfp, enforce_iso_val); if (vbr_on != 0) { if (vbr_type == 0) lame_set_VBR(gfp, 2); else lame_set_VBR(gfp, 3); lame_set_VBR_q(gfp, vbr_quality_val); lame_set_VBR_mean_bitrate_kbps(gfp, abr_val); lame_set_VBR_min_bitrate_kbps(gfp, vbr_min_val); lame_set_VBR_max_bitrate_kbps(gfp, vbr_max_val); lame_set_VBR_hard_min(gfp, enforce_min_val); } /* not to write id3 tag automatically. */ lame_set_write_id3tag_automatic(gfp, 0); if (lame_init_params(gfp) == -1) return 0; /* write id3v2 header */ imp3 = lame_get_id3v2_tag(gfp, encbuffer, sizeof(encbuffer)); if (imp3 > 0) { write_output(encbuffer, imp3); id3v2_size = imp3; } else { id3v2_size = 0; } write_buffer = NULL; write_buffer_size = 0; return 1; }