Discussion:
[Libav-user] Audio resampling changes slightly the speed of the music
Matthieu Regnauld
2018-10-24 15:50:29 UTC
Permalink
Hello,

Thanks to FFMpeg, I manage to extract audio samples from an audio file, and
also resample it (since my file is encoded in 44100 Hz, and my device
expects 48000 Hz sound).

The problem is: even if the sound quality is perfect, the speed is a little
bit higher than the regular speed of the music.

The difference is very small (small enough so you won't hear it), but you
can hear it when you play the same song at the same time on a regular
player (like VLC for example).

I think it comes from the resampling, but I don't know how to fix it.

Here is my code:
https://gist.github.com/mregnauld/2538d98308ad57eb75cfcd36aab5099a

How can I correct the speed of the music?

Thanks for your help.
Yurii Monakov
2018-10-25 09:12:00 UTC
Permalink
Resampling can introduce additional samples in the output (because
out_samples is rounded).
You should keep track of input time and output time to calculate number of
output samples.

Yurii
Post by Matthieu Regnauld
Hello,
Thanks to FFMpeg, I manage to extract audio samples from an audio file,
and also resample it (since my file is encoded in 44100 Hz, and my device
expects 48000 Hz sound).
The problem is: even if the sound quality is perfect, the speed is a
little bit higher than the regular speed of the music.
The difference is very small (small enough so you won't hear it), but you
can hear it when you play the same song at the same time on a regular
player (like VLC for example).
I think it comes from the resampling, but I don't know how to fix it.
https://gist.github.com/mregnauld/2538d98308ad57eb75cfcd36aab5099a
How can I correct the speed of the music?
Thanks for your help.
_______________________________________________
Libav-user mailing list
http://ffmpeg.org/mailman/listinfo/libav-user
Matthieu Regnauld
2018-10-25 09:24:39 UTC
Permalink
Thank you very much for your help.

Actually, it was my fault (again). I changed this :

while (av_read_frame(formatContext, &packet) >= 0 && !extraxted)

by this:

while (!extraxted && av_read_frame(formatContext, &packet) >= 0)

Because of that mistake, sometimes, a frame was read but never processed.

And now, it works like a charm!

Thanks!
Hristo Ivanov
2018-10-25 11:29:28 UTC
Permalink
Hi Yury
Post by Yurii Monakov
Resampling can introduce additional samples in the output (because
out_samples is rounded).
You should keep track of input time and output time to calculate number of
output samples.
Yurii
I am not sure if that is true or not.

In his sample code he is rounding up when allocating memory:

int out_samples = (int) av_rescale_rnd(
swr_get_delay(swrContext, codecContext->sample_rate) + frame->nb_samples,
out_sample_rate,
codecContext->sample_rate,
AV_ROUND_UP);
av_samples_alloc(&localBuffer, NULL, 2, out_samples, AV_SAMPLE_FMT_FLT, 0);

Lets say out_samples is 1000.6 without rounding and 1001 rounded. Memory
for 1001 samples is allocated.

Then he calls swr_convert which returns the number of converted samples:

int numberSampleOutputPerChannel = swr_convert(swrContext,
&localBuffer, out_samples,
(const uint8_t **) frame->extended_data, frame->nb_samples);

To my understanding the first call of swr_convert will return 1000
samples(numberSampleOutputPerChannel is 1000).

The following is not technically correct but helps me illustrate my point:
*The 0.6 extra samples will be buffered and returned in the next call to
swr_convert. The second call will be fed 1000.6 + 0.6 samples and return
1001 samples and buffer 0.2.*

I am not 100% sure that the previous is true, can someone confirm it?
I will test it later.

Thanks.

Loading...