diff --git a/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/extra_i2s.xc b/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/extra_i2s.xc index 2cf7f48..b019a3d 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/extra_i2s.xc +++ b/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/extra_i2s.xc @@ -76,9 +76,9 @@ void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudi } #if C1_DFS_EN - /* Proactive output mute around FPS on/off: zeroes the playback path for - * ~C1_SWITCH_MUTE_SAMPLES after each toggle, masking the path-switch pop - * and the stale FPS data tail until the flushed pipeline refills. */ + /* Smooth fade-out / hold / fade-in around the FPS on/off toggle: masks + * the path-switch pop and the stale FPS data tail without the click a + * hard zero would make at the mute edges. gain is 0..1024 (Q10), 1024 = unity. */ { static unsigned sw_mute_samps = 0; static unsigned prev_sw_mute = 0; @@ -86,9 +86,20 @@ void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudi GET_SHARED_GLOBAL(sw_mute, g_fps_switch_mute); if (sw_mute) { - if (!prev_sw_mute) sw_mute_samps = 0; /* re-armed: restart count */ - sampsFromUsbToAudio[0] = 0; - sampsFromUsbToAudio[1] = 0; + unsigned n, gain; + int s0, s1; + if (!prev_sw_mute) sw_mute_samps = 0; /* re-armed: restart at fade-out */ + n = sw_mute_samps; + if (n < C1_SWITCH_FADE_SAMPLES) + gain = 1024u - (n * 1024u / C1_SWITCH_FADE_SAMPLES); /* fade out: 1024 -> 0 */ + else if (n >= C1_SWITCH_MUTE_SAMPLES - C1_SWITCH_FADE_SAMPLES) + gain = ((n - (C1_SWITCH_MUTE_SAMPLES - C1_SWITCH_FADE_SAMPLES)) * 1024u / C1_SWITCH_FADE_SAMPLES); /* fade in: 0 -> ~1024 */ + else + gain = 0; /* hold */ + s0 = (int)sampsFromUsbToAudio[0]; + s1 = (int)sampsFromUsbToAudio[1]; + sampsFromUsbToAudio[0] = (unsigned)(((long long)s0 * gain) >> 10); + sampsFromUsbToAudio[1] = (unsigned)(((long long)s1 * gain) >> 10); if (++sw_mute_samps >= C1_SWITCH_MUTE_SAMPLES) { SET_SHARED_GLOBAL(g_fps_switch_mute, 0); diff --git a/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/tile1_clk.h b/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/tile1_clk.h index 781810c..76f021f 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/tile1_clk.h +++ b/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/tile1_clk.h @@ -62,6 +62,12 @@ * pipeline flush + 1-frame refill. 2880 ~= 60 ms. */ #define C1_SWITCH_MUTE_SAMPLES 2880 +/* Per-edge fade length (fade-out and fade-in each) inside the mute window, in + * audio samples (@ 48 kHz). The window fades out over this many samples, holds + * near-zero, then fades in -- avoids the click a hard mute makes at its edges. + * Must be <= C1_SWITCH_MUTE_SAMPLES/2. 512 ~= 10.7 ms. */ +#define C1_SWITCH_FADE_SAMPLES 512 + /* One-time enable of the tile[1] core divider output path. MUST run on tile[1]. */ void c1_tile1_clk_enable(void);