请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

Windows 音频重采样问题

使用的是 Win11 环境,获取的 Packet Size 为 88200。直接用视频里的公式将 512 改为 11025 ,使用下面命令播放时出现杂音。

ffplay -ar 44100 -ac 2 -f s16le .\audio.pcm

完成代码

void RecThread::recAudio()
{
	AVFormatContext* fmt_ctx = nullptr;
	AVDictionary* options = nullptr;
	char* device_name = QString("audio=麦克风 (Realtek(R) Audio)").toUtf8().data();

	// Register audio device.
	avdevice_register_all();
	// Get format.
	const AVInputFormat* i_format = av_find_input_format("dshow");
	char errors[1024];
	int ret = 0;
	if ((ret = avformat_open_input(&fmt_ctx, device_name, i_format, &options)) < 0)
	{
		av_strerror(ret, errors, 1024);
		printf("Failed to open audio device, [%d]%s", ret, errors);
		exit(-1);
	}
	else
	{
		emit sendDeviceInfo(QString("Device:") + QString(device_name));
	}

	// Create file.
	FILE* out_file = fopen("C:/Users/rolfm/Desktop/audio.pcm", "wb+");
	int count = 0;
	AVPacket pkt;
	av_init_packet(&pkt);
	printf("Start.\n");

	SwrContext* swr_ctx = NULL;
	swr_ctx = swr_alloc_set_opts(NULL,
		AV_CH_LAYOUT_STEREO,
		AV_SAMPLE_FMT_S16,
		44100,
		AV_CH_LAYOUT_STEREO,
		AV_SAMPLE_FMT_FLT,
		44100,
		0,
		NULL);
	if (swr_init(swr_ctx) < 0)
	{
		printf("Fail to init swr.\n");
		exit(-1);
	}

	uint8_t** src_data = NULL;
	int src_linesize = 0;
	av_samples_alloc_array_and_samples(&src_data,
		&src_linesize,
		2,
		11025,
		AV_SAMPLE_FMT_FLT,
		0);

	uint8_t** dst_data = NULL;
	int dst_linesize = 0;
	av_samples_alloc_array_and_samples(&dst_data,
		&dst_linesize,
		2,
		11025,
		AV_SAMPLE_FMT_S16,
		0);

	while ((ret = av_read_frame(fmt_ctx, &pkt)) == 0 && is_started)
	{
		printf("Pkt size is %d(%p), count=%2d.\n", pkt.size, pkt.data, count);

		memcpy((void*)src_data[0], (const void*)pkt.data, pkt.size);
		swr_convert(swr_ctx, dst_data, 11025, (const uint8_t**)src_data, 11025);

		// Write file.
		fwrite((const void*)dst_data[0], dst_linesize, 1, out_file);
		count++;
		av_packet_unref(&pkt); // Release pkt.
	}
	// Close file.
	fclose(out_file);
	if (src_data)
	{
		av_freep(&src_data[0]);
	}
	av_freep(&dst_data);
	if (dst_data)
	{
		av_freep(&dst_data[0]);
	}
	av_freep(&dst_data);
	swr_free(&swr_ctx);
	// Release ctx.
	if (fmt_ctx != nullptr)
	{
		avformat_close_input(&fmt_ctx);
	}
	printf("Stop.\n");
}

正在回答 回答被采纳积分+3

1回答

李超 2022-02-10 11:45:33

问题解决了吧?

0 回复 有任何疑惑可以回复我~
  • 我也是一样的问题,碰到了。。。请问有什么解决办法吗?
    回复 有任何疑惑可以回复我~ 2023-10-24 22:22:13
  • 李超 回复 Wzq_3806295 #2
    你要先确定你的音频参数是多少,采样率,采样大小,和通道数。你可以使用ffmpeg 命令从设备上采集一下数据将它保存成.wav文件,然后用ffplay 播放一下,就能拿到参数了,拿到参数之后再按照程序中的公式进行计算
    回复 有任何疑惑可以回复我~ 2023-10-25 06:29:58
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信