android 转音频格式,android_Lame转换音频格式
Lame雖然沒有ffmpeg強大,但是也可以做一些事情。轉碼的步驟:
1.(optional) Get the version number of the encoder, if you are interested.
void get_lame_version(char *strbuf, size_tbuflen, const char *prefix);
2.Error messages.? By default, LAME willwrite error messages to?stderrusing vfprintf().? For GUI applications,this is often a problem?and you need to set your own error message handlers:
lame_set_errorf(gfp,error_handler_function);
lame_set_debugf(gfp,error_handler_function);
lame_set_msgf(gfp,error_handler_function);
3.Initialize the encoder.? sets default forall encoder parameters.初始化編碼器,設置默認參數
#include "lame.h"
lame_global_flags *gfp;//在lame.h中typedeflame_global_flags *lame_t;
gfp = lame_init();
默認是 44.1khz、128kbps,音質是5,需要的時候設置自己的參數覆蓋默認
lame_set_num_channels(gfp,2);/* 默認也是2 */
lame_set_in_samplerate(gfp,44100); /* 采樣率 */
lame_set_brate(gfp,128); /* 比特率 */
lame_set_mode(gfp,1); /* mode = 0,1,2,3 = stereo,jstereo,dualchannel(not supported),mono default */
lame_set_quality(gfp,2); /* 2=high 5 = medium 7=low */
4. 檢查配置確保返回值ret_code>= 0
ret_code = lame_init_params(gfp);
5? 編碼: 緩沖區mp3buffer_size大小可以通過 num_samples,samplerate和 encoding rate計算, 最壞的估計是
mp3buffer_size(in bytes) = 1.25*num_samples + 7200.其中num_samples = the number of PCMsamples in each channel.
返回的數字code = 輸出到mp3buffer緩沖的大小(number of bytesoutput in mp3buffer),可以為0,但是小于0就出錯了
int lame_encode_buffer(lame_global_flags*gfp,
short intleftpcm[],
short int rightpcm[],
int num_samples,
char *mp3buffer,
int mp3buffer_size);
5? 調用lame_encode_flush刷新緩沖區,可能返回最后的mp3幀數(return a finalfew mp3 frames).? mp3buffer緩沖區至少是7200 bytes.
返回值code = number of bytes output to mp3buffer.? This can be 0.
int lame_encode_flush(lame_global_flags*,char *mp3buffer, int mp3buffer_size);
6? 往mp3文件寫入Xing VBR/INFO標簽
void lame_mp3_tags_fid(lame_global_flags*,FILE* fid);
7? 釋放資源的結構(free the internal datastructures)
void lame_close(lame_global_flags *);
這些都是從api中提取出來的。下面是原文:
The LAME API
This is the simple interface to the encoding part of libmp3lame.so.The library also contains routines for adding id3 tags and?mp3 decoding. ?These routines are not fully documented,but you can figure them out by looking at "include/lame.h" and the?example frontend encoder/decoder source code in frontend/main.c
All of these steps should be done for every MP3 to be encoded.
=========================================================================
1. (optional) Get the version number of the encoder, if you are interested. ??void get_lame_version(char *strbuf, size_t buflen, const char *prefix);
2. Error messages. ?By default, LAME will write error messages to?stderr using vfprintf(). ?For GUI applications, this is often a problem?and you need to set your own error message handlers:
lame_set_errorf(gfp,error_handler_function);
lame_set_debugf(gfp,error_handler_function);
lame_set_msgf(gfp,error_handler_function);
See lame.h for details.
3. Initialize the encoder. ?sets default for all encoder parameters.
#include "lame.h"
lame_global_flags *gfp;
gfp = lame_init();
The default (if you set nothing) is a ?J-Stereo, 44.1khz?128kbps CBR mp3 file at quality 5. ?Override various default settings ?as necessary, for example:
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); /* 2=high 5 = medium 7=low */
See lame.h for the complete list of options. ?Note that there are?some lame_set_*() calls not documented in lame.h. ?These functions?are experimental and for testing only. ?They may be removed in?the future.
4. Set more internal configuration based on data provided above,?as well as checking for problems. ?Check that ret_code >= 0.
ret_code = lame_init_params(gfp);
5. Encode some data. ?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.
num_samples = the number of PCM samples in each channel. It is
not the sum of the number of samples in the L and R channels.
The return code = number of bytes output in mp3buffer. ?This can be 0.If it is <0, an error occured.
int lame_encode_buffer(lame_global_flags *gfp,
short int leftpcm[], short int rightpcm[],
int num_samples,char *mp3buffer,int mp3buffer_size);
There are also routines for various types of input ?(float, long, interleaved, etc). ?See lame.h for details.
6. lame_encode_flush will flush the buffers and may return a
final few mp3 frames. ?mp3buffer should be at least 7200 bytes.
return code = number of bytes output to mp3buffer. ?This can be 0.
int lame_encode_flush(lame_global_flags *,char *mp3buffer, int mp3buffer_size);
7. ?Write the Xing VBR/INFO tag to mp3 file.
void lame_mp3_tags_fid(lame_global_flags *,FILE* fid);
This adds a valid mp3 frame which contains information about the?bitstream some players may find usefull. ?It is used for CBR,ABR and?VBR. ?The routine will attempt to rewind the output stream to the?beginning. ?If this is not possible, (for example, you are encoding to?stdout) you should specifically disable the tag by calling
lame_set_bWriteVbrTag(gfp,0) in step 3 above, and call?lame_mp3_tags_fid() with fid=NULL. ?If the rewind fails and?the tag was not disabled, the first mp3 frame in the bitstream?will be all 0's.
8. free the internal data structures.
void lame_close(lame_global_flags *);
下面是一個小例子:
// java中的jstring, 轉化為c的一個字符數組
char* Jstring2CStr(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = (*env)->FindClass(env,"java/lang/String");
jstring strencode = (*env)->NewStringUTF(env,"GB2312");
jmethodID mid = (*env)->GetMethodID(env,clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312");
jsize alen = (*env)->GetArrayLength(env,barr);
jbyte* ba = (*env)->GetByteArrayElements(env,barr,JNI_FALSE);
if(alen > 0)
{
rtn = (char*)malloc(alen+1); //new char[alen+1]; "\0"
memcpy(rtn,ba,alen);
rtn[alen]=0;
}
(*env)->ReleaseByteArrayElements(env,barr,ba,0); //釋放內存
return rtn;
}
JNIEXPORT jstring JNICALL Java_cn_itcast_lame_LameActivity_getLameVersion
(JNIEnv * env, jobject obj){
return (*env)->NewStringUTF(env,get_lame_version() );
}
JNIEXPORT void JNICALL Java_cn_itcast_lame_LameActivity_convertAudio
(JNIEnv * env , jobject obj , jstring jinputname , jstring joutputname){
char* input = Jstring2CStr(env,jinputname);
char* output = Jstring2CStr(env,joutputname);
LOGI("INPUT FILE NAME %s",input);
LOGI("output FILE NAME %s",output);
//只讀形式打開源文件的句柄 ,
FILE* wav = fopen(input,"rb");
//目標文件 ,可寫的形式打開目標文件
FILE* mp3 = fopen(output,"wb");
//讀到的字節數,和寫出的字節數
int read, write;
// 開創兩個buffer 存放音頻轉換的中間數據
short int wav_buffer[8192*2];
unsigned char mp3_buffer[8192];
//初始化lame編碼器
lame_t lame = lame_init();
//指定采樣率
lame_set_in_samplerate(lame,44100);
//指定編碼后文件的聲道數 雙聲道
lame_set_num_samples(lame, 2);
//指定編碼方式 是vbr
lame_set_VBR(lame,vbr_default);
lame_init_params(lame);
LOGI("INIT LAME FINISH");
do{
//從wav里面讀數據
read = fread(wav_buffer, 2*sizeof(short int), 8192, wav);
if(read==0){
//讀到了文件的末尾
write = lame_encode_flush(lame,mp3_buffer,8192);
}else{
write = lame_encode_buffer_interleaved(lame,wav_buffer,read,mp3_buffer,8192);
}
fwrite(mp3_buffer,1,write,mp3);
}while(read!=0);
LOGI("CONVER COMPLETE");
//反初始化編碼器
lame_close(lame);
fclose(mp3);
fclose(wav);
}
總結
以上是生活随笔為你收集整理的android 转音频格式,android_Lame转换音频格式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BERT 中wordPiece的原理
- 下一篇: sentencePiece入门小结