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
+17 -9
View File
@@ -27,9 +27,9 @@
static const char *TAG = "player";
typedef enum { MODE_TONE, MODE_OFF, MODE_HLS, MODE_SPOTIFY, MODE_AUTO } mode_t_;
static const char *const SRC_NAME[] = { "tone", "off", "hls", "spotify" };
static const char *const MODE_NAME[] = { "tone", "off", "hls", "spotify", "auto" };
typedef enum { MODE_TONE, MODE_OFF, MODE_HLS, MODE_SPOTIFY, MODE_AUTO, MODE_PINK } mode_t_;
static const char *const SRC_NAME[] = { "tone", "off", "hls", "spotify", "pink" };
static const char *const MODE_NAME[] = { "tone", "off", "hls", "spotify", "auto", "pink" };
static volatile mode_t_ s_mode = MODE_OFF;
static volatile player_src_t s_src = PLAYER_SRC_OFF; // what is playing now
@@ -110,7 +110,7 @@ static void apply_fade(int32_t *buf, size_t frames, int *left, bool in)
static mode_t_ mode_of(const char *m)
{
return !strcmp(m, "tone") ? MODE_TONE : !strcmp(m, "hls") ? MODE_HLS : !strcmp(m, "spotify") ? MODE_SPOTIFY :
!strcmp(m, "auto") ? MODE_AUTO : MODE_OFF;
!strcmp(m, "auto") ? MODE_AUTO : !strcmp(m, "pink") ? MODE_PINK : MODE_OFF;
}
/* ----- output (AES67 TX pull callback, TX task, must not block) ----- */
@@ -168,8 +168,14 @@ static size_t player_read(int32_t *buf, size_t frames)
return got;
}
// Set the source to play. Tone comes from TX itself (phase-locked to PTP), so switches from/to it
// are immediate; everything else fades through player_read.
// Test signals: straight from the core to TX, not through the ring, volume or gain.
static bool is_test_signal(player_src_t src)
{
return src == PLAYER_SRC_TONE || src == PLAYER_SRC_PINK;
}
// Set the source to play. Test signals come from the core (the tone phase-locked to PTP), so
// switches from/to them are immediate; everything else fades through player_read.
static void select_source(player_src_t src)
{
if (src == s_target) {
@@ -180,10 +186,11 @@ static void select_source(player_src_t src)
s_hls_paused = false;
hls_suspend(HLS_SUSPEND_USER, false);
}
if (src == PLAYER_SRC_TONE || s_src == PLAYER_SRC_TONE) {
if (is_test_signal(src) || is_test_signal(s_src)) {
s_target = s_src = src;
s_flush = true;
aes67_tx_set_source(src == PLAYER_SRC_TONE ? NULL : player_read);
aes67_tx_set_source(src == PLAYER_SRC_TONE ? NULL : src == PLAYER_SRC_PINK ? aes67_tx_pink_noise :
player_read);
return;
}
s_target = src; // player_read fades out and switches
@@ -213,6 +220,7 @@ static void apply_mode(void)
hls_suspend(HLS_SUSPEND_FAILOVER, mode == MODE_AUTO);
switch (mode) {
case MODE_TONE: select_source(PLAYER_SRC_TONE); break;
case MODE_PINK: select_source(PLAYER_SRC_PINK); break;
case MODE_HLS: select_source(PLAYER_SRC_HLS); break;
case MODE_SPOTIFY: select_source(PLAYER_SRC_SPOTIFY); break;
case MODE_AUTO: select_source(PLAYER_SRC_SPOTIFY); break; // Spotify inactive: HLS after the delay
@@ -369,7 +377,7 @@ static void on_ota(bool starting)
static const char *source_state(player_src_t src)
{
return src == PLAYER_SRC_TONE ? "playing" : src == PLAYER_SRC_OFF ? "idle" :
return is_test_signal(src) ? "playing" : src == PLAYER_SRC_OFF ? "idle" :
src == PLAYER_SRC_SPOTIFY && !spotify_session_active() ? "idle" :
src == PLAYER_SRC_SPOTIFY && s_paused ? "paused" :
src == PLAYER_SRC_HLS && s_hls_paused ? "paused" : s_playing ? "playing" : "buffering";