Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/hitenpatel/songprint/llms.txt

Use this file to discover all available pages before exploring further.

SignatureGenerator is the core class of songprint. It accepts 16kHz mono 16-bit PCM samples and produces a binary signature in the Shazam constellation-map format. The algorithm applies a Hanning-windowed 2048-point FFT every 128 samples, spreads and recognises spectral peaks across four frequency bands, and encodes them into the compact binary format that Shazam clients send to the discovery endpoint.

Class declaration

class SignatureGenerator
SignatureGenerator is not thread-safe. Use one instance per thread or coroutine. Do not share instances across concurrent callers.
Each call to generateSignature resets all internal state — the same instance can be called multiple times sequentially without creating a new object. Instances are cheap to create.

Constructor

SignatureGenerator()
No parameters. Allocates the internal ring buffers and FFT workspace once; all mutable state is reset at the start of each generateSignature call.

Methods

generateSignature

fun generateSignature(monoSamples16k: ShortArray): ByteArray
Processes the supplied PCM samples and returns a binary Shazam-compatible signature.
monoSamples16k
ShortArray
required
16kHz mono 16-bit PCM samples. Use Pcm.resampleToMono16k to convert from other sample rates or channel counts. The generator processes up to MAX_TIME_SECONDS (3.1 s) of audio and stops early once MAX_PEAKS peaks have been collected; samples beyond that point are ignored. Provide at least a few seconds of audio for the most reliable results.
Returns ByteArray — the binary signature ready to pass to RecognitionClient.recognise. A typical signature is a few kilobytes in size. Processing stops early if both conditions are met: the elapsed audio time reaches MAX_TIME_SECONDS and the total collected peak count reaches MAX_PEAKS. Samples beyond that point are ignored.
import io.github.hitenpatel.songprint.Pcm
import io.github.hitenpatel.songprint.SignatureGenerator

// Convert raw bytes captured from an audio source
val samples = Pcm.bytesToShorts(pcmBytes)
val mono16k = Pcm.resampleToMono16k(samples, sampleRate = 44100, channels = 2)

// Generate the fingerprint — pure Kotlin, typically takes milliseconds
val generator = SignatureGenerator()
val signature: ByteArray = generator.generateSignature(mono16k)

// The same generator can be reused for a subsequent recording
val signature2: ByteArray = generator.generateSignature(nextMono16k)

Companion object constants

These constants define the fixed parameters of the fingerprinting algorithm. They are exposed publicly so that callers can correctly size buffers and interpret timing values without hard-coding magic numbers.
ConstantValueDescription
SAMPLE_RATE16000Required input sample rate in Hz. Pass samples at exactly this rate; use Pcm.resampleToMono16k to convert.
FFT_SIZE2048FFT window size in samples. Each transform covers 128ms of audio at 16kHz.
HOP_SIZE128FFT hop/stride in samples (~8ms per frame). Determines the time resolution of the spectrogram.
FFT_OUTPUT_SIZE1025Number of frequency bins per frame (FFT_SIZE / 2 + 1).
MAX_TIME_SECONDS3.1Maximum audio duration (in seconds) processed before peak collection stops — used in conjunction with MAX_PEAKS.
MAX_PEAKS255Maximum total peaks collected across all bands before processing stops early.
// Correctly compute the expected number of output samples for 10 seconds
val tenSecondSamples = SignatureGenerator.SAMPLE_RATE * 10  // 160_000

// Check how many FFT frames fit in a given sample count
val frameCount = sampleCount / SignatureGenerator.HOP_SIZE

Nested data class

Peak

data class Peak(
    val fftPassNumber: Int,
    val peakMagnitude: Int,
    val correctedFrequencyBin: Int,
)
Represents a single spectral peak detected during fingerprint generation. This is an internal data structure used during the encoding phase — library consumers do not normally interact with it directly.
fftPassNumber
Int
The zero-based index of the FFT frame in which this peak was detected. Multiplying by HOP_SIZE and dividing by SAMPLE_RATE gives the approximate time offset in seconds.
peakMagnitude
Int
The log-scaled magnitude of the peak, computed as ln(magnitude) * 1477.3 + 6144.0 and truncated to an integer. Stored as a little-endian unsigned 16-bit value in the binary encoding.
correctedFrequencyBin
Int
The frequency bin index refined to 1/64-bin precision using parabolic interpolation of the log-magnitudes of the peak and its immediate neighbours. Stored as a little-endian unsigned 16-bit value in the binary encoding.

Build docs developers (and LLMs) love