Overview
AudioAnalyzer is a family of .NET 9 command-line tools and libraries for analysing and processing audio at archive scale. It was built to replace a set of ageing native tools inside a broadcast media asset management (MAM) system, where every recording — from a three-minute track to a multi-hour radio show captured as one RF64 file — has to be measured, cut, segmented and described automatically.
All tools share one core library on top of the ManagedBass ecosystem, so more than 20 input formats (WAV, RF64/BWF, FLAC, MP3, AAC, OGG, WMA, …) are handled by the same code path.
Components
- AudioAnalyzer.Console — duration, modulation start/end, peak and RMS levels, FFT snapshot, tag extraction; SHA-256
checksum/verify; Whisper speech-to-text with timecoded segments, language detection, speaker diarization and voiceprint enrolment. Routed JSON output following a fixed persistence contract, so results can be written straight into a database. - AudioEnvWriter — generates, validates and renders amplitude envelope files (
.env) for waveform displays: RMS/peak variants, PNG and console rendering, sample-accurate validation against the source. - AudioCutter — cuts time slices from PCM/RF64 WAV files and concatenates them into one output. Drop-in replacement for a 2007-era native tool, adding >4 GB RF64 support and bit-exact 16/24-bit preservation.
- AudioSegmenter — detects track boundaries (silence gaps) and speech/music segments in long recordings, tags speech with a spoken-language guess (Whisper.net), and can emit a cut list for AudioCutter.
- AudioAnalyzer.Core / .Speech — RF64 decoding, repair of WAV files with broken
datachunk headers, envelope generation, segmentation DSP, anti-aliased 16 kHz resampling and the Whisper model wrapper.
Speech, speakers and language
The speech side grew well past "transcribe a file":
- Checkpointed transcription — long jobs stream one JSON object per segment to an NDJSON file as they go, so an hour-long recording that is interrupted after fifty minutes keeps those fifty minutes instead of losing everything.
- Windowed processing —
--start/--durationdecode only the part you asked for, with a real seek; timecodes stay absolute file time, so a window can be analysed and its results still line up with the whole recording. - Language detection and override — ask what language a recording is in (optionally restricted to a candidate list) without paying for a full transcription pass, or force the language when you already know it.
- Speaker diarization — "who spoke when", through sherpa-onnx in native .NET, no Python: speech-activity and speaker-change segmentation, a speaker embedding per segment, then clustering. CPU only.
- Speaker-labelled transcripts — diarization runs on the same decoded buffer before transcription, so every segment carries its speaker as it streams.
- Named speakers — voiceprints turn
SPEAKER_00into a person's name across recordings, with a manual speaker map for the rest. Voiceprints are biometric data; the tool treats them accordingly (opt-in, local store, delete a person with one command).
Engineering highlights
- Real-world robustness: corrupt WAV headers are repaired on the fly instead of failing the job
- Idempotent re-runs for multi-target processing pipelines
- Cross-platform:
win-x64by default, withlinux-x64,linux-arm64and macOS runtime identifiers proven end-to-end - xUnit test suite covering envelope round-trips, cutting, classification and resampling regressions
Typical use cases
- Automated ingest analysis in broadcast and archive systems
- Waveform data for web players without decoding the whole file
- Splitting long recordings into individual tracks or segments
- Transcription and language detection for unlabelled speech recordings
- Meeting recordings turned into speaker-labelled transcripts on your own machine — see analysing meetings locally