apulsator

Watch on youtube.com
doc

https://ffmpeg.org/ffmpeg-filters.html#apulsator

see also

tremolo

Quotes from the official documentation:

Audio pulsator is something between an autopanner and a tremolo. But it can produce funny stereo effects as well.

Pulsator changes the volume of the left and right channel based on a LFO (low frequency oscillator) with different waveforms and shifted phases. This filter have the ability to define an offset between left and right channel.

An offset of 0 means that both LFO shapes match each other. The left and right channel are altered equally - a conventional tremolo.

An offset of 50% means that the shape of the right channel is exactly shifted in phase (or moved backwards about half of the frequency) - pulsator acts as an autopanner.

At 1 both curves match again. Every setting in between moves the phase shift gapless between all stages and produces some “bypassing” sounds with sine and triangle waveforms.

The more you set the offset near 1 (starting from the 0.5) the faster the signal passes from the left to the right speaker.

[me@host: ~]$ ffplay some.wav -af "apulsator"
[me@host: ~]$ # In short, the following is shaking in sync with the beat.
[me@host: ~]$ ffplay some.wav -af "apulsator=bpm=136:timing=bpm"
[me@host: ~]$ ffplay some.wav -af "apulsator=bpm=136/2:timing=bpm"
[me@host: ~]$ # mode can be one of sine, triangle, square, sawup or sawdown.
[me@host: ~]$ ffplay some.wav -af "apulsator=bpm=136:timing=bpm:mode=square"
[me@host: ~]$ # specifying by hz
[me@host: ~]$ ffplay some.wav -af "apulsator=hz=0.5:timing=hz"
[me@host: ~]$ # right channel offset
[me@host: ~]$ ffplay some.wav -af "apulsator=bpm=136:timing=bpm:offset_r=0.7"
[me@host: ~]$ # visualizing by showvolume
[me@host: ~]$ ffplay -f lavfi "
> amovie=wolframtones_02.wav
> , apulsator=mode=triangle:timing=bpm:bpm=136:offset_r=0.7
> , asplit[out1],showvolume,scale=1000:-1[out0]" 2>/dev/null
[me@host: ~]$ # visualizing by showwaves and showvolume
[me@host: ~]$ ffplay -f lavfi "
> amovie=wolframtones_02.wav
> , apulsator=mode=sine:timing=bpm:bpm=136:offset_r=0.9
> , asplit=3[out1][a1][a2];
> [a1]showwaves=split_channels=1:mode=cline,scale=960:-1,setsar=1[v1];
> [a2]showvolume,scale=960:-1,setsar=1[v2];
> [v1][v2]vstack[out0]"
see also

showspatial

How to estimate song’s beats per minutes

If you want to use apulsator based on bpm, you need to know a bpm of your audio. But there is no way to estimate a bpm with ffmpeg alone. So you must rely on external tools.

I found Online Song BPM detector, and there may be more. If you are a Python user and are willing to install large external libraries, librosa is one of the options. If so, you can:

getbpm.py
# -*- coding: utf-8 -*-
import sys
import librosa  # required: librosa

ifn = sys.argv[1]

# Estimate a static tempo
y, sr = librosa.load(ifn)
onset_env = librosa.onset.onset_strength(y, sr=sr)
tempo = librosa.beat.tempo(onset_envelope=onset_env, sr=sr)
print("%r: %5.1f bpm" % (ifn, tempo[0]))
[me@host: ~]$ ls *.wav
wolframtones_01.wav
wolframtones_02.wav
wolframtones_03.wav
wolframtones_04.wav
wolframtones_05.wav
[me@host: ~]$ for i in *.wav ; do python3 getbpm.py $i ; done
'wolframtones_01.wav': 107.7 bpm
'wolframtones_02.wav': 136.0 bpm
'wolframtones_03.wav': 112.3 bpm
'wolframtones_04.wav': 117.5 bpm
'wolframtones_05.wav':  95.7 bpm

At least in the default state, the evaluation results vary from tool to tool. If you need more accurate and satisfying evaluation results, you will need more fine-grained control if you use librosa.