Я хочу преобразовать необработанные данные PCM (взятые с микрофона Android Phone) в файл libGSM Wave.После кодирования в файл проигрыватель VLC показывает правильную информацию и длительность кодека, но не может воспроизвести содержимое.Пожалуйста, помогите мне понять, что я делаю неправильно.
Ниже приведен мой код для кодирования и написания заголовка:
void EncodeTest(uint8_t *audioData, size_t audioSize)
{
AVCodecContext *audioCodec;
AVCodec *codec;
uint8_t *buf; int bufSize, frameBytes;
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"Lets encode :%u with size %d\n",(int)audioData, (int)audioSize);
//Set up audio encoder
codec = avcodec_find_encoder(CODEC_ID_GSM);
if (codec == NULL){
__android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to find encoder(CODEC_ID_GSM)");
codec = avcodec_find_encoder(CODEC_ID_GSM);
if (codec == NULL){
__android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to find encoder(CODEC_ID_GSM)");
return;
}
}
audioCodec = avcodec_alloc_context();
audioCodec->channels = 1;
audioCodec->sample_rate = 8000;
audioCodec->sample_fmt = SAMPLE_FMT_S16;
audioCodec->bit_rate = 13200;
audioCodec->priv_data = gsm_create();
switch(audioCodec->codec_id) {
case CODEC_ID_GSM:
audioCodec->frame_size = GSM_FRAME_SIZE;
audioCodec->block_align = GSM_BLOCK_SIZE;
int one = 1;
gsm_option(audioCodec->priv_data, GSM_OPT_WAV49, &one);
break;
case CODEC_ID_GSM_MS: {
int one = 1;
gsm_option(audioCodec->priv_data, GSM_OPT_WAV49, &one);
audioCodec->frame_size = 2*GSM_FRAME_SIZE;
audioCodec->block_align = GSM_MS_BLOCK_SIZE;
}
}
audioCodec->coded_frame= avcodec_alloc_frame();
audioCodec->coded_frame->key_frame= 1;
audioCodec->time_base = (AVRational){1, audioCodec->sample_rate};
audioCodec->codec_type = CODEC_TYPE_AUDIO;
if (avcodec_open(audioCodec, codec) < 0){
__android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to avcodec_open");
return;
}
bufSize = FF_MIN_BUFFER_SIZE * 10;
buf = (uint8_t *)malloc(bufSize);
if (buf == NULL) return;
frameBytes = audioCodec->frame_size * audioCodec->channels * 2;
FILE *fileWrite = fopen(FILE_NAME,"w+b");
if(NULL == fileWrite){
__android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to open file for reading.");
}
/*Write wave header*/
WriteWav(fileWrite, 32505);/*Just for test*/
/*Lets encode raw packet and write into file after header.*/
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"Lets Encode Actual Bytes");
int nChunckSize = 0;
while (audioSize >= frameBytes)
{
int packetSize;
packetSize = avcodec_encode_audio(audioCodec, buf, bufSize, (short *)audioData);
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"Encoder returned %d bytes of data\n", packetSize);
nChunckSize += packetSize;
audioData += frameBytes;
audioSize -= frameBytes;
if(NULL != fileWrite){
fwrite(buf, packetSize, 1, fileWrite);
}
else{
__android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"Unable to open file for writting... NULL");
}
}
if(NULL != fileWrite){
fclose(fileWrite);
}
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"----- Done with nChunckSize: %d --- ",nChunckSize);
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"*****************************");
wavReadnDisplayHeader(FILE_NAME);
__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"*****************************");
wavReadnDisplayHeader("/sdcard/Voicemail2.wav");
}
Запись заголовка:
/** Writes WAV headers */
void WriteWav(FILE *f, long int bytes)
{
/* quick and dirty */
fwrite("RIFF",sizeof(char),4,f); /* 0-3 */ //RIFF
PutNum(bytes+44-8,f,1,4); /* 4-7 */ //ChunkSize
fwrite("WAVEfmt ",sizeof(char),8,f); /* 8-15 */ //WAVE Header + FMT header
PutNum(16,f,1,4); /* 16-19 */ //Size of the fmt chunk
PutNum(49,f,1,2); /* 20-21 */ //Audio format, 49=libgsm wave, 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
PutNum(1,f,1,2); /* 22-23 */ //Number of channels 1=Mono 2=Sterio
PutNum(8000,f,1,4); /* 24-27 */ //Sampling Frequency in Hz
PutNum(2*8000,f,1,4); /* 28-31 */ //bytes per second /Sample/persec
PutNum(2,f,1,2); /* 32-33 */ // 2=16-bit mono, 4=16-bit stereo
PutNum(16,f,1,2); /* 34-35 */ // Number of bits per sample
fwrite("data",sizeof(char),4,f); /* 36-39 */
PutNum(bytes,f,1,4); /* 40-43 */ //Sampled data length
}
Пожалуйста, помогите ....