#!/usr/bin/env python3 """Regenerate the JRay audio-signature golden fixture. python3 make_fixture.py # writes jray_audio_v1_tone.flac here This is the *source of truth* for the fixture media: `jray_audio_v1_tone.flac` is a lossless FLAC encoding of exactly the PCM this script emits, so any repo that wants to check its own audio-signature implementation against the golden vector in `jray_audio_v1_golden.json` can regenerate the input from scratch and confirm it is byte-identical (the golden file records `pcm_fnv1a64`, a hash of the decoded 16-bit samples). Deliberately dependency-free (no numpy) and written in plain arithmetic so it ports to any language in ~20 lines. Signal — 120.000 s, mono, 11025 Hz, 16-bit signed PCM: * split into segments of 32768 samples (~2.97 s), 40.4 segments in total; * segment `s` carries one sine at the geometric centre of log-band `(s * 7) mod 32` of the 300-3000 Hz band, so all 32 bands are exercised; * its amplitude walks a golden-ratio low-discrepancy sequence over [10^-1.55, 10^-0.02] so frame energies spread continuously across ~1.5 decades and all four energy classes are exercised, without a dense cluster of frames sitting on a class boundary; * phase is carried across segment boundaries (no clicks); * a constant, far quieter 777 Hz tone sits underneath so no frame is degenerate; * samples are quantised with floor(x * 32767 + 0.5). Why FLAC and not WAV: 120 s of 11025 Hz 16-bit PCM is 2.6 MB and does not compress in git. FLAC is lossless — FFmpeg decodes it to exactly the PCM written here — and is ~3.5x smaller. `--wav` writes the uncompressed original if you want to diff it. """ import math import struct import subprocess import sys import os SAMPLE_RATE = 11025 DURATION_SEC = 120.0 SEGMENT = 32768 # samples per tone segment BAND_STRIDE = 7 # coprime with 32 -> visits every band BAND_LO_HZ = 300.0 BAND_HI_HZ = 3000.0 NUM_BANDS = 32 AMP_LOG_MIN = -1.55 # 10^-1.55 ~= 0.028 AMP_LOG_SPAN = 1.53 # up to 10^-0.02 ~= 0.955 PHI_FRAC = 0.6180339887498949 BG_HZ = 777.0 BG_AMP = 0.004 OUT_FLAC = "jray_audio_v1_tone.flac" OUT_WAV = "jray_audio_v1_tone.wav" def generate(): """Return the 120 s signal as a list of int16 sample values.""" n = int(round(SAMPLE_RATE * DURATION_SEC)) out = [0] * n phase = 0.0 two_pi = 2.0 * math.pi for start in range(0, n, SEGMENT): s = start // SEGMENT end = min(n, start + SEGMENT) band = (s * BAND_STRIDE) % NUM_BANDS # geometric centre of log-band `band` freq = BAND_LO_HZ * (BAND_HI_HZ / BAND_LO_HZ) ** ((band + 0.5) / NUM_BANDS) amp = 10.0 ** (AMP_LOG_MIN + AMP_LOG_SPAN * ((s * PHI_FRAC) % 1.0)) step = two_pi * freq / SAMPLE_RATE for k in range(end - start): i = start + k x = amp * math.sin(phase + step * k) x += BG_AMP * math.sin(two_pi * BG_HZ * i / SAMPLE_RATE) if x > 1.0: x = 1.0 elif x < -1.0: x = -1.0 out[i] = int(math.floor(x * 32767.0 + 0.5)) phase = (phase + step * (end - start)) % two_pi return out def write_wav(path, samples): data = struct.pack("<%dh" % len(samples), *samples) hdr = b"RIFF" + struct.pack("