21

I want to change the frequency of an audio file. Meaning: the whole file should sound (say) one octave higher or lower. How to do it? Using ffmpeg or other command line open source tool would be preferable.

slhck
  • 223,558
  • 70
  • 607
  • 592
tanon
  • 255
  • 3
  • 4
  • 6

3 Answers3

25

With ffmpeg:

ffmpeg -i <input> -af 'asetrate=44100*1/2,atempo=2/1' <output>

Here, 1/2 is the pitch factor. See the other answer for more details.


If you need a GUI, use Audacity, it's a free, open source, cross platform audio editing tool.

Features: Change the pitch without altering the tempo, or vice-versa.


As an alternative, try sox. Something like that:

sox <infile> <outfile> pitch <shift>

where gives the pitch shift as positive or negative ‘cents’ (i.e. 100ths of a semitone). There are 12 semitones to an octave, so that would mean ±1200 as a parameter.

slhck
  • 223,558
  • 70
  • 607
  • 592
  • awesome... sox is just what i need! – tanon Jun 04 '11 at 10:36
  • Does method using ffmpeg change the duration of the audio? – mrgloom May 22 '19 at 10:21
  • @mrgloom No, it should not. – slhck May 22 '19 at 10:22
  • After using `ffmpeg -i man.wav -af asetrate=48000*0.75,aresample=48000 man_pitch_down.wav` I see by `ffmpeg -i` original wav `Duration: 00:00:01.95, bitrate: 3080 kb/s` and modified wav `Duration: 00:00:02.60, bitrate: 1536 kb/s`. As I understand `Duration` is length in seconds. – mrgloom May 22 '19 at 10:27
  • I have tried this solution (https://superuser.com/a/1076762/213959) and it produce audios with same length (looking at `Duration` from `ffmpeg -i` output) – mrgloom May 22 '19 at 10:34
  • @slhck you are wrong. As mrgloom said your ffmpeg line also changes duration af the audio. – F. Vosnim Jun 30 '20 at 16:51
  • @slhck It's 100% your example: `ffmpeg -i -af asetrate=44100*0.5,aresample=44100 ` where `asetrate` changes sample rate to 22050 AND increases the duration by 2. Then `aresample` upsamples it to 44100 keeping increased duration the same. The [asetrate documentation](https://ffmpeg.org/ffmpeg-filters.html#asetrate) clearly says `This will result in a change of speed and pitch.` – F. Vosnim Jul 01 '20 at 12:55
  • @F.Vosnim You're right. This must have changed (note that my answer was posted in 2011) in the meantime. Fixed the post. – slhck Jul 02 '20 at 13:08
15

Find input audio rate beforehand thus:

ffmpeg -i input.mp4

Assuming input audio rate 44,100 Hz, this command will do the job:

ffmpeg -i input.mp4 -af asetrate=44100*3/4,atempo=4/3 output.mp4

The factor of 3/4 will change most female and “skinny” (chipmunk) voices into male and “fat” voices. Use 4/3 for the opposite:

ffmpeg -i input.mp4 -af atempo=3/4,asetrate=44100*4/3 output.mp4

Notice reversed filter order to prevent signal degradation. Whenever possible, lossless operation should come before lossy operation. I’m not 100% sure whether I’m not making some mistake here from misunderstanding FFmpeg filters.

FFmpeg filter asetrate should have a variable named ir for input audio rate, in analogy to iw×ih in some video filters, but I couldn’t find any mention of it in the documentation.

For factors greater than 2 (such as 4/1 or 1/4), you must use multiple atempo filters (1/4 = 1/2 * 1/2 or 4/1 = 2/1 * 2/1):

ffmpeg -i input.mp4 -af asetrate=44100*4,atempo=1/2,atempo=1/2 output.mp4

I don’t know how to obtain “skinny” male voice and “fat” female voice.

Instead of -af, you can write -filter:audio or -filter:a.

References

7vujy0f0hy
  • 541
  • 1
  • 5
  • 10
1

@slhck answer with better quality resampler:

ffmpeg -i <input> -af 'asetrate=44100*1/2:resampler=soxr:precision=33,atempo=2/1' <output>
F. Vosnim
  • 111
  • 3