我試圖將.m4a文件轉換爲原始PCM文件,以便我可以在Audacity中播放它。使用libavcodec將.m4a轉換爲PCM
根據AVCodecContext,它是一個使用AV_SAMPLE_FMT_FLTP採樣格式的44100 Hz音軌,據我瞭解,當使用avcodec_decode_audio4進行解碼時,我應該得到兩個浮點值數組(每個通道一個)。
我不確定的AVCodecContext的bits_per_coded_sample的意義= 16
不幸的是無畏扮演的結果早在,如果我有原來的軌道上與一些白噪聲混合。
以下是我所做的一些示例代碼。請注意,我還爲使用帶符號16位非交織數據(sample_format = AC_SAMPLE_FMT_S16P)的軌道添加了一個案例,Audacity可以很好地播放。
int AudioDecoder::decode(std::string path)
{
const char* input_filename=path.c_str();
av_register_all();
AVFormatContext* container=avformat_alloc_context();
if(avformat_open_input(&container,input_filename,NULL,NULL)<0){
printf("Could not open file");
}
if(avformat_find_stream_info(container, NULL)<0){
printf("Could not find file info");
}
av_dump_format(container,0,input_filename,false);
int stream_id=-1;
int i;
for(i=0;i<container->nb_streams;i++){
if(container->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){
stream_id=i;
break;
}
}
if(stream_id==-1){
printf("Could not find Audio Stream");
}
AVDictionary *metadata=container->metadata;
AVCodecContext *ctx=container->streams[stream_id]->codec;
AVCodec *codec=avcodec_find_decoder(ctx->codec_id);
if(codec==NULL){
printf("cannot find codec!");
}
if(avcodec_open2(ctx,codec,NULL)<0){
printf("Codec cannot be found");
}
AVSampleFormat sfmt = ctx->sample_fmt;
AVPacket packet;
av_init_packet(&packet);
AVFrame *frame = avcodec_alloc_frame();
int buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE+ FF_INPUT_BUFFER_PADDING_SIZE;;
uint8_t buffer[buffer_size];
packet.data=buffer;
packet.size =buffer_size;
FILE *outfile = fopen("test.raw", "wb");
int len;
int frameFinished=0;
while(av_read_frame(container,&packet) >= 0)
{
if(packet.stream_index==stream_id)
{
//printf("Audio Frame read \n");
int len=avcodec_decode_audio4(ctx, frame, &frameFinished, &packet);
if(frameFinished)
{
if (sfmt==AV_SAMPLE_FMT_S16P)
{ // Audacity: 16bit PCM little endian stereo
int16_t* ptr_l = (int16_t*)frame->extended_data[0];
int16_t* ptr_r = (int16_t*)frame->extended_data[1];
for (int i=0; i<frame->nb_samples; i++)
{
fwrite(ptr_l++, sizeof(int16_t), 1, outfile);
fwrite(ptr_r++, sizeof(int16_t), 1, outfile);
}
}
else if (sfmt==AV_SAMPLE_FMT_FLTP)
{ //Audacity: big endian 32bit stereo start offset 7 (but has noise)
float* ptr_l = (float*)frame->extended_data[0];
float* ptr_r = (float*)frame->extended_data[1];
for (int i=0; i<frame->nb_samples; i++)
{
fwrite(ptr_l++, sizeof(float), 1, outfile);
fwrite(ptr_r++, sizeof(float), 1, outfile);
}
}
}
}
}
fclose(outfile);
av_close_input_file(container);
return 0;
}
我希望我剛剛做了一個幼稚的轉換(最多/少顯著位的問題),但目前我一直無法弄清楚。請注意,Audacity只能導入RAW浮點數據,如果其32位或64位浮點數(大或小)。
感謝您的任何見解。