libswresample: swr_convert() not producing enough samples

瘦欲@ 提交于 2021-01-28 22:28:35

问题


I'm trying to use ffmpeg/libswresample to resample streaming audio in my c++ application. Changing the sample width works well and the result sounds as one would expect; however, when changing the sample rate the result is somewhat crackly. I am unsure if it is due to incorrect usage of the libswresample library, or if I'm misunderstanding the resampling theory.

Here is my resampling process, simplified for demonstration's sake:

//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);

I suspect that the reason the resampled audio does not sound right is because swr_convert() returns 112, where I expect it to return 128 (the number of samples of the resampled audio): Downsampling 256 samples from a samplerate of 44100 to a samplerate of 22050 should yield 128 samples, yet swr_convert() is producing 112 samples. When expressed in terms of audio duration this is also puzzling. 256 samples at 44100 = 5.8 ms, but 112 samples at 22050 = 5.07 ms. Shouldn't the downsampling process not alter the duration of the resampled audio?

I have also stepped through an example provided with ffmpeg, in which swr_convert() also returns a smaller number than I would expect. So, I suspect that the problem is not due to a bug in libswresample but rather my own lack of understanding.


回答1:


The reason the number of samples is decreased is because the resampling filters over a number of temporally adjacent samples. Imagine that we're resampling using a 32-tap filter, sample 127 needs input 127-16 to 127+16 (or comparable positions corrected for the sample rate adjustment). Since you only have 128 input samples, you can only output up until 112 in this example. The rest is stored in an internal queue until the next input is available.

To get the final (trailing) samples (when the input is finished), input NULL as input, which will flush the internal queue.



来源:https://stackoverflow.com/questions/39587839/libswresample-swr-convert-not-producing-enough-samples

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!