Tsh*_*err 0 c++ audio ffmpeg downsampling resampling
我正在尝试使用ffmpeg / libswresample对我的c ++应用程序中的流音频进行重新采样。更改样本宽度效果很好,结果听起来像人们期望的那样。但是,更改采样率时,结果会有些混乱。我不确定这是由于对libswresample库的使用不正确,还是由于我误解了重采样理论。
这是我的重采样过程,为演示起见简化了:
//Externally supplied data
const uint8_t* in_samples //contains the audio data to be resampled
int in_num_samples = 256
//Set up resampling context
SwrContext *swr = swr_alloc();
av_opt_set_channel_layout(swr, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0);
av_opt_set_channel_layout(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
av_opt_set_int(swr, "in_sample_rate", 44100, 0);
av_opt_set_int(swr, "out_sample_rate", 22050, 0);
av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
swr_init(swr);
//Perform the resampe
uint8_t* out_samples;
int out_num_samples = av_rescale_rnd(swr_get_delay(swr, in_samplerate) + in_num_samples, out_samplerate, in_samplerate, AV_ROUND_UP);
av_samples_alloc(&out_samples, NULL, out_num_channels, out_num_samples, AV_SAMPLE_FMT_FLT, 0);
out_num_samples = swr_convert(swr, &out_samples, out_num_samples, &in_samples, in_num_samples);
av_freep(&out_samples);
swr_free(&swr);
Run Code Online (Sandbox Code Playgroud)
我怀疑重新采样的音频听起来不正确的原因是因为 swr_convert()返回112,我希望它返回128(重新采样的音频的采样数):将256个采样从44100的采样率降采样为22050的采样率128个样本,但swr_convert()正在产生112个样本。当以音频持续时间表示时,这也令人困惑。在44100 = 5.8毫秒时为256个样本,但在22050 = 5.07毫秒时为112个样本。下采样过程是否不应该改变重采样音频的持续时间?
我还逐步完成了ffmpeg附带的示例,其中swr_convert()返回的数字也比我期望的小。因此,我怀疑该问题不是由于libswresample中的错误所致,而是由于我本人缺乏理解。
减少样本数量的原因是因为对多个时间相邻样本进行了重采样过滤。想象一下,我们正在使用32抽头滤波器进行重采样,样本127需要输入127-16至127 + 16(或为采样率调整而校正的可比位置)。由于只有128个输入样本,因此在此示例中,最多只能输出112个。其余的存储在内部队列中,直到下一个输入可用为止。
要获取最终(跟踪)样本(输入完成时),请输入NULL作为输入,这将刷新内部队列。