Pink noise as a source (mode "pink")

Core: aes67_tx_pink_noise(), a ready-made TX source: xorshift32 white noise
through Paul Kellet's pink filter, -18 dBFS RMS (peaks about -6 dBFS), same
on L and R. The player uses it like the tone (straight to TX, no volume or
gain). Checked on the board: -18 dBFS RMS, octave bands 63 Hz-4 kHz flat
within +-0.4 dB, L = R.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 23:37:05 +10:00
parent bbeb7d3fd2
commit 122e46e862
8 changed files with 58 additions and 16 deletions
+30
View File
@@ -170,6 +170,36 @@ static int64_t samples_to_ns(int64_t s, int rate)
// 1 kHz tone, phase from the PTP sample index, so every sender's tone lines up.
// One period is rate / 1000 samples (48 at 48 kHz, 96 at 96 kHz): precomputed table.
// Pink noise: xorshift32 white noise through Paul Kellet's refined pink filter (within 0.05 dB
// above 9 Hz). The scale gives -18 dBFS RMS (measured over 10 s; peaks about -6 dBFS).
#define PINK_SCALE 0.0714f
size_t aes67_tx_pink_noise(int32_t *buf, size_t frames)
{
static uint32_t rnd = 0x12345678;
static float b0, b1, b2, b3, b4, b5, b6;
for (size_t i = 0; i < frames; i++) {
rnd ^= rnd << 13;
rnd ^= rnd >> 17;
rnd ^= rnd << 5;
float w = (int32_t)rnd * (1.0f / 2147483648.0f); // -1..1
b0 = 0.99886f * b0 + w * 0.0555179f;
b1 = 0.99332f * b1 + w * 0.0750759f;
b2 = 0.96900f * b2 + w * 0.1538520f;
b3 = 0.86650f * b3 + w * 0.3104856f;
b4 = 0.55000f * b4 + w * 0.5329522f;
b5 = -0.7616f * b5 - w * 0.0168980f;
float pink = b0 + b1 + b2 + b3 + b4 + b5 + b6 + w * 0.5362f;
b6 = w * 0.115926f;
float x = pink * PINK_SCALE;
x = x > 0.999f ? 0.999f : x < -0.999f ? -0.999f : x; // never reached in practice
int32_t v = (int32_t)(x * 2147483647.0f);
buf[i * AES67_TX_SRC_CHANNELS] = v;
buf[i * AES67_TX_SRC_CHANNELS + 1] = v;
}
return frames;
}
// Stereo source -> 1-channel stream, in place. The sum is in 64 bit, so it can't clip; identical
// L/R comes out at the same level.
static void to_mono(int32_t *buf, int frames, bool sum)
+3
View File
@@ -19,3 +19,6 @@ esp_err_t aes67_tx_init(void);
esp_err_t aes67_tx_start(void);
// Set the audio source. NULL = built-in 1 kHz test tone at -18 dBFS, phase-locked to PTP time.
void aes67_tx_set_source(aes67_tx_read_cb_t read);
// Ready-made source: pink noise at -18 dBFS RMS (peaks about -6 dBFS), same on L and R.
// Pass it to aes67_tx_set_source(). Keeps state: use for one stream only.
size_t aes67_tx_pink_noise(int32_t *buf, size_t frames);