Analysis

Find the tempo and beats, look at the spectrum, and find silence.

On this page

Tempo and beats

audioBpm finds the tempo and where the beats fall. It builds an onset curve from the change of the spectrum, finds the tempo from its autocorrelation (with a mild preference for the tempi people tap around 120, and for the faster of two equally strong candidates), then tracks the beats with dynamic programming.

kick = audioDrum( type="kick", seconds=0.5 );
bar  = audioConcat( [ kick, kick, kick, kick, kick, kick, kick, kick ] );   // a kick every 0.35 s, which is 171 BPM
r = audioBpm( bar );
println( r.bpm & " BPM, confidence " & r.confidence & ", " & r.beats.len() & " beats" );
KeyMeaning
bpmThe tempo; 0 when there is no clear pulse (silence, a drone)
confidence0 to 1: how much the pulse stands out
beatsBeat times in seconds

minBpm and maxBpm (default 60 and 200) limit the search. Tempo detection is a guess: music that is half or double a common tempo can be read either way, and confidence tells you how sure it is. A click track is found within 1.5 BPM.

Spectrum

audioSpectrum returns the level in dB of log spaced bands. audioSpectrogram gives the bands over time for drawing, and audioFft the raw frequencies and magnitudes of one window.

tone = audioOsc( "sine", 1000, 1 );
bands = audioSpectrum( audio=tone, bands=8, minHz=100, maxHz=10000 );
println( bands );                                     // the band holding 1 kHz is the loudest

fft = audioFft( audio=tone, size=4096 );              // fft.frequencies, fft.magnitudes
grid = audioSpectrogram( audio=tone, bands=16, frames=32 );    // 32 slices of 16 bands

Levels are -120 for nothing. audioFft magnitudes are scaled so a full scale sine reads 1.

Silence

tone = audioOsc( "sine", 440, 1, 44100 );
gap = audioSilence( seconds=1, channels=1 );
clip = audioConcat( [ gap, tone, gap, tone ] );

println( audioDetectSilence( audio=clip, thresholdDb=-50, minSeconds=0.3 ) );  // [ {start 0, end 1}, {start 2, end 3} ]
trimmed = audioTrimSilence( audio=clip, thresholdDb=-50, pad=0.1 );           // cut off the ends, keep 0.1 s

Silence is judged on the peak over 10 ms windows across all channels. audioTrimSilence removes it from the start and the end only.

Loudness

See Loudness and mastering for audioLoudness. For a waveform to draw, audioWaveform( audio, points ) returns the loudest level in each of points equal slices.

bx-audio bpm song.wav --beats
bx-audio silence interview.wav --db=-45 --min=0.5
bx-audio waveform song.wav
Edit this page Download Markdown Last updated Oct 16, 2026, 11:59:46 AM Report an issue