How to change pitch and tempo together, reliably with ffmpeg
Asked Answered
H

2

11

I know how to change tempo with atempo, but the audio file becomes distorted a bit, and I can't find a reliable way to change pitch. (say, increase tempo and pitch together 140%)

Sox has a speed option, but truncates the volume AND isn't as widely available as ffmpeg. mplayer has a speed option which works perfectly, but I can't output without additional libraries.

I seem to understand ffmpeg doesn't have a way to change pitch (maybe it does recently?) but is there a way to change frequency or some other flags to emulate changing pitch? Looked quite far and can't find a decent solution.

Edit: asetrate:48k*1.4 (assuming originally 48k) doesn't seem to work, still distortion and pitch doesn't really change much.

Edit2: https://superuser.com/a/1076762 this answer sort of works, but the quality is so much lower than sox speed 1.4 option

Hereto answered 12/11, 2016 at 15:34 Comment(0)
G
13

ffmpeg -i <input file name> -filter:a "asetrate=<new frequency>" -y <output file name> seems to be working for me. I checked the properties of both input and output files with ffprobe and there doesn't seem to be any differences that could affect its quality. Although it's true that I've run it a few times and the resulting file on some of those had some artifacts, even if the line of code was the same, so it may be caused by some ffmpeg bug; try to run it again if you aren't satisfied with the quality.

For example, if your source audio rate is 48000 Hz then to speed it up to 140% you would need to use 48000 * 1.4 = 67200 as <new frequency>.

Gaygaya answered 12/11, 2016 at 16:18 Comment(3)
You're right that does seem to work. Maybe it's because before I was also touching the atempo with the asetrate but alone it seems to work. The quality does seem a tad worse than sox or mplayer but it is close enough I suppose. Thanks for the help. Do you know if there is a way to set a multiplicative <new frequency> of the original without checking first? Like instead of 48k*1.4 I can just put 1.4 and it'll increase frequency of asetrate by 1.4?Hereto
Hmm I don't know if there's a direct way to do it, the only thing I can think of is getting the value of the original frequency with ffprobe -just the value, and removing all the extra info so that you can pass it as a variable to the original line of code. You could do it like this: ffmpeg -i <input file name> -filter:a "asetrate=$(ffprobe -v error -show_entries stream=sample_rate -of default=noprint_wrappers=1:nokey=1 <input file name>)*1.4" -y <output file name>Gaygaya
should add -filter:a aresample=resampler=soxr:out_sample_rate=48000 to produce a standard sample rate, otherwise players must resample to 48KHz or 44.1KHz for the soundcard which can hurt quality. use soxr for high-quality resampling, see also src.infinitewave.caLian
F
10

As of 2022 (though contributed in 2015), FFmpeg has a rubberband filter that works out of the box without any aforementioned ugly, allegedly slow and poor quality and unintuitive workarounds.

To change the pitch using the rubber band filter, you will have to specify the pitch using the frequency ratio of a semi-tone. This is based on using the formula (2^x/12), where x represents the number of semitones you would like to transpose.

For example, to transpose up by one semitone you would use the following command:

ffmpeg -i my.mp3 -filter:a "rubberband=pitch=1.059463094352953" -acodec copy my-up.mp3

To transpose down, simply use a negative number for x.

To alter both properties simultaneously, specify tempo and pitch values. The tempo value is specified as a multiple of the original speed.

The following command transposes down by one semitone and bumps the speed up 4x:

ffmpeg -i slow.mp3 -filter:a "rubberband=pitch=0.9438743126816935, rubberband=tempo=4" -acodec copy fast.mp3

Quality degradation is imperceptible unless measured statistically.

Fer answered 28/2, 2022 at 17:54 Comment(2)
This is a great answer! -acodec copy was giving me an error: Filtering and streamcopy cannot be used together. Which makes sense because this is not a lossless operation. Removing -acodec copy worked.Horrify
This produces lower quality audio than if you change pitch by speeding the audio up.Armor

© 2022 - 2024 — McMap. All rights reserved.