Skip to content

Repository files navigation

Shazam

core fingerprinting and matching pipeline is functional, cloud storage and message brokers to decouple the multi-store write pipelines are in development

Shazam like audio fingerprinting system built from scratch in C# and .NET 8. Given a YouTube URL, downloads the audio, generates audio fingerprint and stores it. Given a short audio snippet as hashes it identifies the song using time-coherent offset voting, it is similar but simplified algorithm which Shazam uses.

No third-party fingerprinting libraries or API's used. The entire pipeline — STFT, peak detection, hash generation, and voting is custom implemented.


How It Works

Indexing a Song

POST /api/song?url={youtubeUrl}

Pipeline for Youtube URL to Audio fingerprint, Audio Metadata:

  1. Extracts metadata (title, artist, duration) from the YouTube URL.
  2. Checks for duplicates — skips if the song is already indexed.
  3. Downloads the audio file to local disk. (In future bucket or different kind of storage will be included, this is just for testing at the moment)
  4. Runs the fingerprinting pipeline:
    • STFT with Hann windowing -> frequency spectrum over time, Generates spectogram which is represented as 2D array, Hann Window
    • 2D local maxima detection -> (time, freq) kept if it's strict maximum within (2·timeRadius + 1) × (2·freqRadius + 1) and exceeds minimum db threshhold float threshold = -60f;
    • Combinatorial hashing - each peak is paired with nearby peaks to generate (frequency1, frequency2, timeDelta) hashes, hash algorithm just contains simple bit shifting public uint Hash => ((uint)Freq1 << 20) | ((uint)Freq2 << 10) | (uint)DeltaTime;
  5. Stores all hashes in Redis under the fingerprint: prefix, each mapping to the song ID and time offset. Uses redis persistence
  6. Stores song metadata in MS SQL Server.

Recognizing a Song

POST /api/recognize

Accepts a dictionary of { hash -> queryOffset } from a recorded audio snippet and runs voting:

  1. For each hash, fetches candidate entries from Redis.
  2. For each candidate, computes timeDelta = storedOffset - queryOffset - this represents where in the original song the snippet was recorded from.
  3. Votes are accumulated per (songId, timeDelta) pair. A high vote count for a specific delta means the snippet consistently aligns with one song at one position.
  4. The (songId, timeDelta) pair with the most votes wins.
  5. Song metadata is fetched from MS SQL Server by the winning songId and returned.

This approach should be inherently noise-robust — a few bad hashes should not break matching because only consistent time-alignment accumulates votes. Well at least that's what this Research Paper claims. ¯_(ツ)_/¯


Architecture

Clean Architecture with the following layers:

  • API - SongController, RecognizeController
  • Application - services and interfaces: Youtube, Audio Fingerprint and Song matching services
  • Domain - Just includs models no bussines logic in here
  • Infrastructure - Redis fingerprint repository, MSSQL song repository

Tech Stack

  • .NET 8 — ASP.NET Core Web API, Clean Architecture
  • Redis — fingerprint hash storage (fingerprint:{hash} keys, persistent)
  • MS SQL Server + EF Core — song metadata
  • STFT + Hann windowing — custom spectral analysis implementation

Storage

Data Store
Fingerprint hashes Redis (fingerprint: prefix)
Song metadata MS SQL Server
Audio files Local disk (D:) — cloud bucket is planned in future

Planned

  • RabbitMQ to decouples the multi step storage pipeline (disk, MSSQL, Redis)
  • Cloud storage for audio files (S3-compatible bucket)
  • Improved peak detection tuning for noisy recordings

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages