Sonido-Sonar ๐ต
March 10, 2026 ยท View on GitHub
A pure Go audio fingerprinting and temporal alignment library. Originally developed during my Summer 2025 internship at TuneIn Inc. to benchmark CDN stream end-to-end latency relative to their source streams.
Calculations are performed based on content type. To optimize performance, you can pass in the content type to skip the acoustic content type detection phase.
๐ Table of Contents
- Features
- Installation
- Quick Start
- Usage Examples
- Modules & Structure
- Content Detection
- Configuration
- Technical Reference
- License
โจ Features
| Category | Capabilities |
|---|---|
| Fingerprinting | Multi-feature audio signatures (MFCC, spectral, chroma, speech features) |
| Alignment | Temporal alignment using DTW and cross-correlation (up to configurable lag offset) |
| Content Detection | Auto-detect music, speech, news, sports, and mixed content types |
| Spectral Analysis | MFCC, spectral contrast/centroid/flux, Mel/Bark scales, STFT/FFT |
| Windowing | 9 window functions: Hamming, Hann, Blackman, Kaiser, Welch & more |
| Comparison | Similarity scoring tailored by content type (music vs speech optimized weights) |
| CDN Latency | End-to-end latency measurement for streaming pipeline diagnostics |
๐ฆ Installation
go get github.com/RyanBlaney/sonido-sonar
Or add to your go.mod:
require github.com/RyanBlaney/sonido-sonar v0.1.0
๐ Quick Start
Basic Fingerprint Generation
package main
import (
"fmt"
"github.com/RyanBlaney/sonido-sonar/fingerprint"
"github.com/RyanBlaney/sonido-sonar/transcode"
)
func main() {
// Load audio data via the decoder
config := &transcode.DecoderConfig{
TargetSampleRate: 44100,
EnableNormalization: true,
}
decoder := transcode.NewDecoder(config)
audioData, err := decoder.DecodeFile("path/to/audio.wav")
if err != nil {
panic(err)
}
// Generate fingerprint
fpConfig := &fingerprint.Config{
WindowSize: 1024,
HopSize: 256,
ContentType: "music", // or "speech", "news", "sports"
}
generator := fingerprint.NewFingerprintGenerator(fpConfig)
fp, err := generator.GenerateFingerprint(audioData)
if err != nil {
panic(err)
}
fmt.Printf("Generated fingerprint with %d feature points\n", len(fp.Features))
}
Temporal Alignment (Two Streams)
package main
import (
"fmt"
"github.com/RyanBlaney/sonido-sonar/fingerprint"
"github.com/RyanBlaney/sonido-sonar/fingerprint/extractors"
)
func main() {
// Assume fp1 and fp2 are fingerprints from source & CDN streams
fp1 := loadFingerprint("source.mp3")
fp2 := loadFingerprint("cdn_stream.mp3")
extractor := extractors.NewAlignmentExtractorWithMaxLag(
fpConfig,
alignmentConfig,
maxOffsetSeconds: 60.0,
)
features, err := extractor.ExtractAlignmentFeatures(fp1.Features, fp2.Features,
srcPCM, cdnPCM, sampleRate)
if err != nil {
panic(err)
}
fmt.Printf("Detected latency: %.3f seconds\n", features.TemporalOffset)
fmt.Printf("Alignment confidence: %.2f%%\n", features.OffsetConfidence*100)
}
Stream Similarity Comparison
package main
import (
"github.com/RyanBlaney/sonido-sonar/fingerprint"
)
func main() {
fpConfig := fingerprint.Config{ContentType: "music"}
// Generate fingerprints for both streams
f1 := generateFingerprintForStream(sourceURL, fpConfig)
f2 := generateFingerprintForStream(cdnURL, fpConfig)
comparator := fingerprint.NewFingerprintComparator(&fpConfig.ComparisonSettings)
result, err := comparator.Compare(f1, f2)
fmt.Printf("Overall Similarity: %.2f%%\n", result.OverallSimilarity*100)
fmt.Printf("Confidence Score: %.2f%%\n", result.Confidence*100)
}
๐ Modules & Structure
โโโ algorithms/ # DSP and feature extraction primitives
โ โโโ chroma/ # Tonal features (HPCP, pitch class, key detection)
โ โโโ spectral/ # STFT, MFCC, power spectrum, centroid/rolloff/etc.
โ โโโ speech/ # LPC, voice quality metrics for spoken content
โ โโโ rhythm/ # Tempo & meter estimation
โ โโโ windowing/ # Window functions (Hamming, Hann, Kaiser...)
โ โโโ stats/ # Statistical tools: DTW, correlation, clustering
โโโ fingerprint/ # Core fingerprint module
โ โโโ extractors/* # Content-specific feature extractors (music/speech)
โ โโโ analyzers/* # Fingerprint comparison logic
โโโ transcode/ # Audio decoding & format normalization
โโโ logging/ # Structured logging interfaces
๐ฏ Content Detection
The library automatically detects content type to optimize feature extraction:
| Content Type | Optimal Features | Use Case Example |
|---|---|---|
music | Chroma + Spectral + MFCC | Music streaming services |
speech | LPC, Pitch Detection, ZCR | Podcasts, Talk Radio |
news | Speech Features + Energy | News Broadcasts |
sports | Mixed (energy spikes, speech) | Live Sports Commentary |
detector := fingerprint.NewContentDetector(&fingerprint.Config{AutoDetect: true})
contentType := detector.DetectContentType(audioData) // Returns "music"|"speech"|...
โ Configuration
Key configuration parameters:
| Parameter | Default | Description |
|---|---|---|
WindowSize | 1024 | FFT window size |
HopSize | 256 | Frame hop (for STFT) |
ContentType | "music" | Content type for weighting |
EnableSpeechFeatures | false | Enable LPC & speech analysis |
MFCCCoefficients | 13 | Number of MFCC to extract |
MinSimilarity | 0.70 | Acceptable fingerprint match threshold |
Example config:
config := &fingerprint.Config{
WindowSize: 1024,
HopSize: 256,
ContentType: "news",
EnableSpeechFeatures: true,
MFCCCoefficients: 12,
}
๐ Technical Reference
Algorithms Implemented
- MFCC (Itakura 1975) โ mel-frequency cepstral coefficients
- STFT / DFT (Cooley & Tukey 1965) โ time-frequency analysis
- Spectral Metrics โ centroid, contrast, flux, rolloff (Brown 1991)
- Chroma Features โ pitch class profiles & Tonalnetz
- DTW Alignment (Dynamic Time Warping)
- Correlation Analysis โ Pearson / cross-correlation
- Window Functions โ Hamming, Hann, Kaiser, Welch, Bartlett...
Key Citations
Davis, S. B., & Mermelstein, P. (1980). Comparison of parametric representation...
Haitsma, J., & Kalker, T. (2002). A highly robust audio fingerprinting system.
๐ License
MIT License โ See LICENSE for more info.
Built with โค๏ธ at TuneIn Inc. | Summer 2025 Internship Project
Author: Ryan Blaney
Repo: github.com/RyanBlaney/sonido-sonar