ffmpeg 解码amr音频 到pcm文件有噪音
分析了下,amr音频采样编码为AV_SAMPLE_FMT_FLT,而MP3音频文件采样编码为AV_SAMPLE_FMT_S16P
网上查了下,说是要用swr_convert函数转换,但是转换了还是不对。请高手给看看啊
代码如下:
char *outfilename="D:/cvsroot/ffmpeg/ffmpegDecodeAndEncode/Debug/3.pcm";
FILE* pcm;
pcm = fopen(outfilename,"wb");
av_register_all();
AVFrame* frame = avcodec_alloc_frame();
if (!frame)
{
printf( "Error allocating the frame" );
return 1;
}
AVFormatContext* formatContext = NULL;
//if (avformat_open_input(&formatContext, "D:/cvsroot/ffmpeg/ffmpegDecodeAndEncode/Debug/1.mp3", NULL, NULL) != 0)
if (avformat_open_input(&formatContext, "D:/cvsroot/ffmpeg/ffmpegDecodeAndEncode/Debug/1.amr", NULL, NULL) != 0)
{
av_free(frame);
printf( "Error opening the file" );
return 1;
}
if (avformat_find_stream_info(formatContext, NULL) < 0)
{
av_free(frame);
av_close_input_file(formatContext);
printf( "Error finding the stream info" );
return 1;
}
AVStream* audioStream = NULL;
for (unsigned int i = 0; i < formatContext->nb_streams; ++i)
{
if (formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
audioStream = formatContext->streams[i];
break;
}
}
if (audioStream == NULL)
{
av_free(frame);
av_close_input_file(formatContext);
printf( "Could not find any audio stream in the file" );
return 1;
}
AVCodecContext* codecContext = audioStream->codec;
codecContext->codec = avcodec_find_decoder(codecContext->codec_id);
if (codecContext->codec == NULL)
{
av_free(frame);
av_close_input_file(formatContext);
printf( "Couldn't find a proper decoder" );
return 1;
}
else if (avcodec_open2(codecContext, codecContext->codec, NULL) != 0)
{
av_free(frame);
av_close_input_file(formatContext);
printf( "Couldn't open the context with the decoder" );
return 1;
}
SwrContext* swrContext = NULL;
swrContext = swr_alloc_set_opts(swrContext,
codecContext->channel_layout, // out channel layout
codecContext->sample_fmt, // out sample format
codecContext->sample_rate, // out sample rate
codecContext->channel_layout, // in channel layout
codecContext->sample_fmt, // in sample format
codecContext->sample_rate, // in sample rate
0, // log offset
NULL); // log context
swr_init(swrContext);
if(codecContext->sample_fmt==AV_SAMPLE_FMT_S16)
{
swrContext = swr_alloc_set_opts(swrContext,
codecContext->channel_layout,
AV_SAMPLE_FMT_S16P,
codecContext->sample_rate,
codecContext->channel_layout,
AV_SAMPLE_FMT_S16,
codecContext->sample_rate,
0,
0);
if(swr_init(swrContext)<0)
{
printf("swr_init() for AV_SAMPLE_FMT_S16P fail");
return 0;
}
}
else if(codecContext->sample_fmt==AV_SAMPLE_FMT_FLT)
{
swrContext = swr_alloc_set_opts(swrContext,
codecContext->channel_layout,
AV_SAMPLE_FMT_S16P,
codecContext->sample_rate,
codecContext->channel_layout,
AV_SAMPLE_FMT_FLT,
codecContext->sample_rate,
0,
0);
if(swr_init(swrContext)<0)
{
printf("swr_init() for AV_SAMPLE_FMT_S16P fail");
return 0;
}
}
if (!swrContext)
{
av_free(frame);
avcodec_close(codecContext);
av_close_input_file(formatContext);
printf( "Couldn't allocate and set the resampling context" );
return 1;
}
printf(" bit_rate = %d \r\n", codecContext->bit_rate);
printf(" sample_rate = %d \r\n", codecContext->sample_rate);
printf(" channels = %d \r\n", codecContext->channels);
printf(" code_name = %s \r\n", codecContext->codec->name);
int bufSize = av_samples_get_buffer_size(NULL, codecContext->channels, codecContext->sample_rate, codecContext->sample_fmt, 0);
uint8_t* buf = new uint8_t[bufSize];
AVPacket packet;
av_init_packet(&packet);
int packetCount = 0;
int decodedFrameCount = 0;
static uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
uint8_t *out[]={audio_buf};
uint8_t *pktdata;
int pktsize,flush_complete=0;
while (av_read_frame(formatContext, &packet) == 0)
{
++packetCount;
if (packet.stream_index == audioStream->index)
{
pktdata = packet.data;
pktsize = packet.size;
int frameFinished = 0;
avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet);
if (frameFinished)
{
pktsize -= len;
pktdata += len;
int data_size = av_samples_get_buffer_size(NULL,codecContext->channels,frame->nb_samples,codecContext->sample_fmt, 1);
/*****************************************************
以下代码使用swr_convert函数进行转换,但是转换后的文件连mp3到pcm文件都不能播放了,所以注释了
const uint8_t *in[] = {frame->data[0]};
int len=swr_convert(swrContext,out,sizeof(audio_buf)/codecContext->channels/av_get_bytes_per_sample(AV_SAMPLE_FMT_S16P),
in,frame->linesize[0]/codecContext->channels/av_get_bytes_per_sample(codecContext->sample_fmt));
len=len*codecContext->channels*av_get_bytes_per_sample(AV_SAMPLE_FMT_S16P);
if (len < 0) {
fprintf(stderr, "audio_resample() failed\n");
break;
}
if (len == sizeof(audio_buf) / codecContext->channels / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16P)) {
fprintf(stderr, "warning: audio buffer is probably too small\n");
swr_init(swrContext);
}
*****************************************************/
char *data = (char *)malloc(data_size);
short *sample_buffer = (short *)frame->data[0];
for (int i = 0; i < data_size/2; i++)
{
data[i*2] = (char)(sample_buffer[i/2] & 0xFF);
data[i*2+1] = (char)((sample_buffer[i/2] >>8) & 0xFF);
}
fwrite(data, data_size, 1, pcm);
fflush(pcm);
}
}
av_free_packet(&packet);
}
delete [] buf;
swr_free(&swrContext);
av_free(frame);
avcodec_close(codecContext);
av_close_input_file(formatContext);
fclose(pcm);
相关推荐
普通话识别,运用百度API,python
需要在pycharm安装百度aip, ffmpeg, pydub 的包,可识别mp3,wav,pcm, amr文件
微信语音Silk v3解码器:原理、部署与批量转换实战
音频编码是数字音频处理的基础技术,它将模拟声音信号转换为数字数据以便存储和传输。其核心原理是通过采样、量化和压缩算法,在保证音质的同时减少数据量。在语音通信领域,专有编码格式如Silk因其在网络自适应和低带宽下的优异表现而被广泛应用,这带来了高效的数据交换,但也造成了格式兼容性问题。Silk v3解码器正是为解决这一痛点而生的技术方案,它能将Silk格式的专有码流转换为通用的PCM或WAV格式。这一工具在需要本地化、批量化处理微信语音文件的场景中极具价值,例如内容归档、语音分析或集成到自动化工作流中,有效避
工业互联网工控安全与工业质检AI大模型建设方案.pptx
工业互联网工控安全与工业质检AI大模型建设方案.pptx
2024 《计算机网络》实验教学指导书.doc
2024 《计算机网络》实验教学指导书.doc
不平衡电网下自抗扰顺序模型预测PWM整流器控制仿真模型(Simulink仿真实现)
内容概要:本文围绕面向城市空中交通的多无人机路径规划问题展开研究,提出了一套融合全局规划、动态避障与局部协同调整的综合路径规划方法。研究内容涵盖基于改进RRT算法与图论的全局路径规划、基于动态风险场和动态窗口法(DWA)的模型预测控制实现动态避障,以及基于分布式协同控制的多无人机局部路径协同策略。通过Matlab平台构建仿真环境,在多种典型城市交通场景下对所提方法进行了系统性验证,结果表明该方法在路径安全性、编队稳定性与任务效率方面表现优异。文章还深入探讨了算法的创新点与未来研究方向,为复杂城市环境下多无人机系统的自主协同提供了理论支撑与技术路径。; 适合人群:具备自动化、控制理论、计算机科学或相关领域基础知识,从事无人机系统、智能交通、路径规划、多智能体协同控制等方向研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①为城市空中交通系统中的多无人机安全、高效飞行提供可靠的路径规划解决方案;②支持在复杂、动态的城市场景中开展无人机自主导航、编队飞行与协同控制的技术研究与仿真验证。; 阅读建议:建议结合提供的Matlab代码进行实践操作,重点关注算法的具体实现细节、参数配置对性能的影响以及不同仿真场景下的实验设计,以深入理解各模块的集成逻辑与实际应用效果。


图形处理/算法

