v0.9.1
v0.9.1
What's Changed
Two additive analysis features aimed squarely at the DJ app: real broadcast-grade loudness metering for track autogain, and evidence-ranked tempo octave alternatives for one-tap BPM correction — now on crates.io.
Loudness Metering (BS.1770-4 / EBU R128)
measure_loudness(interleaved, channels, sample_rate)returns gated integrated loudness (LUFS), oversampled true peak (dBTP), and loudness range (LU) as aLoudnessMeasurement, withgain_db_to/gain_linear_tohelpers for track autogain — via the pure-Rustebur128crate (#24)- Measured on the original interleaved channels, not the mono analysis downmix: BS.1770 sums per-channel energies, so a mid downmix reads up to ~3 dB low.
analyze_for_dj(mono-only) therefore doesn't fill the field — callers measure and assign, astimestretch-cli analyzenow does PreAnalysisArtifact.loudness— schema v6, purely additive; v4/v5 sidecars stay compatible- Validated against BS.1770 reference points (full-scale 997 Hz stereo sine reads ~0.0 LUFS / 0 dBTP) and commercial masters: Music Sounds Better With You −8.9 LUFS / 1.0 dBTP, Cold Heart −7.9 LUFS / 2.1 dBTP
- The simplified RMS
estimate_lufsstays untouched as a benchmark-only A/B utility, so quality baselines don't shift
Ranked Tempo Candidates
- The tempo tracker now scores the half/double metrical alternatives of its chosen Viterbi path with the same normalized tempogram-salience measure and exposes them ranked:
TempoTrack::octave_saliences,BeatGrid::tempo_candidates, andPreAnalysisArtifact::tempo_candidates(schema v7, additive) (#25) - Enables a one-tap "halve/double BPM" correction ranked by measured evidence instead of blind ×2/÷2 buttons; alternatives outside the analyzed tempo range (50–220 BPM by default) are not offered
- UX insurance, not an accuracy change — the corpus stays at 100% acc1 and detection behavior is untouched. Real-track check: 123.0 BPM committed at salience 1.000, half-tempo 61.5 offered at 0.612
timestretch-cli analyzeprints the alternatives, plusMETRIClines with--verbose
Full Changelog: v0.9.0...v0.9.1