From 0697e6dfe459a1f45e4df22935bef65088076643 Mon Sep 17 00:00:00 2001 From: Jonathan Oakley Date: Sun, 18 Sep 2022 23:11:29 +0100 Subject: [PATCH 01/13] Make AudioOutputSPDIF3 sync to AudioInputSPDIF3 to avoid glitches AudioOutputSPDIF3 can use the Teensy audio clock at 44.1kHz, OR, if an AudioInputSPDIF3 object (which derives its clock from the incoming audio stream) is instantiated, it can and must be synchronised to that. This approach allows a glitch-free system using SPDIF I/O only. The design GUI has been modified to allow this combination to pass conflict checks; a better implementation may be required. --- gui/index.html | 2 +- gui/red/ui/view.js | 40 +++++++++++++++++++++++++++++++++------- input_spdif3.cpp | 2 +- output_spdif3.cpp | 34 ++++++++++++++++++++++++++-------- output_spdif3.h | 3 ++- 5 files changed, 63 insertions(+), 18 deletions(-) diff --git a/gui/index.html b/gui/index.html index 5635869d9..d61395afb 100644 --- a/gui/index.html +++ b/gui/index.html @@ -423,7 +423,7 @@
Keyboard Shortcuts SADDR = &SPDIF_SRL; diff --git a/output_spdif3.cpp b/output_spdif3.cpp index e08808c53..bb92486d1 100644 --- a/output_spdif3.cpp +++ b/output_spdif3.cpp @@ -38,6 +38,7 @@ audio_block_t * AudioOutputSPDIF3::block_right_1st = nullptr; audio_block_t * AudioOutputSPDIF3::block_left_2nd = nullptr; audio_block_t * AudioOutputSPDIF3::block_right_2nd = nullptr; bool AudioOutputSPDIF3::update_responsibility = false; +bool AudioOutputSPDIF3::syncToInput = false; DMAChannel AudioOutputSPDIF3::dma(false); DMAMEM __attribute__((aligned(32))) @@ -222,7 +223,7 @@ uint32_t AudioOutputSPDIF3::dpll_Gain(void) } FLASHMEM -void AudioOutputSPDIF3::config_spdif3(void) +void AudioOutputSPDIF3::config_spdif3(bool extSync /* = false */) { delay(1); //WHY IS THIS NEEDED? @@ -250,20 +251,37 @@ void AudioOutputSPDIF3::config_spdif3(void) CCM_CCGR5 |= CCM_CCGR5_SPDIF(CCM_CCGR_ON); //Clock gate on - if (!(SPDIF_SCR & (SPDIF_SCR_DMA_RX_EN | SPDIF_SCR_DMA_TX_EN))) { + if (!(SPDIF_SCR & (SPDIF_SCR_DMA_RX_EN | SPDIF_SCR_DMA_TX_EN))) // not yet configured... + { //Serial.print("Reset SPDIF3"); - SPDIF_SCR = SPDIF_SCR_SOFT_RESET; //Reset SPDIF + SPDIF_SCR = SPDIF_SCR_SOFT_RESET; // ...reset SPDIF while (SPDIF_SCR & SPDIF_SCR_SOFT_RESET) {;} //Wait for Reset (takes 8 cycles) - } else return; + } + else // already configured ... + { + if (extSync && !syncToInput) // ...but not completely + { + syncToInput = true; + SPDIF_SCR = (SPDIF_SCR & ~SPDIF_SCR_TXSEL(7)) | SPDIF_SCR_TXSEL(1); // Feed-though SPDIFIN + } + return; // because for some reason configuring twice crashes it + } + + // Set flag to say we want S/PDIF output rate to sync with the + // input. We don't know which object gets initialised first, so + // we ensure it "sticks" in sync even if the output object is + // the second to be configured. + if (extSync) + syncToInput = true; SPDIF_SCR = SPDIF_SCR_RXFIFOFULL_SEL(0) | // Full interrupt if at least 1 sample in Rx left and right FIFOs SPDIF_SCR_RXAUTOSYNC | SPDIF_SCR_TXAUTOSYNC | - SPDIF_SCR_TXFIFOEMPTY_SEL(2) | // Empty interrupt if at most 8 samples in Tx left and right FIFOs - SPDIF_SCR_TXFIFO_CTRL(1) | // 0:Send zeros 1: normal operation - SPDIF_SCR_VALCTRL | // Outgoing Validity always clear - SPDIF_SCR_TXSEL(5) | // 0:off and output 0, 1:Feed-though SPDIFIN, 5:Tx Normal operation + SPDIF_SCR_TXFIFOEMPTY_SEL(2) | // Empty interrupt if at most 8 samples in Tx left and right FIFOs + SPDIF_SCR_TXFIFO_CTRL(1) | // 0: Send zeros; 1: normal operation + SPDIF_SCR_VALCTRL | // Outgoing Validity always clear + SPDIF_SCR_TXSEL(syncToInput?1:5) | // 0: off and output 0; 1: Feed-though SPDIFIN; 5: Tx Normal operation SPDIF_SCR_USRC_SEL(3); SPDIF_SRPC = diff --git a/output_spdif3.h b/output_spdif3.h index 651dfe78c..ed6a7a82f 100644 --- a/output_spdif3.h +++ b/output_spdif3.h @@ -37,9 +37,10 @@ class AudioOutputSPDIF3 : public AudioStream friend class AsyncAudioInputSPDIF3; static void mute_PCM(const bool mute); static bool pll_locked(void); + static bool syncToInput; // use S/PDIF input to provide Tx clock: avoids glitches protected: //AudioOutputSPDIF3(int dummy): AudioStream(2, inputQueueArray) {} - static void config_spdif3(void); + static void config_spdif3(bool extSync=false); static audio_block_t *block_left_1st; static audio_block_t *block_right_1st; static bool update_responsibility; From 81a7262dbca07f6c10fc927c5dc5ca9e86116fa1 Mon Sep 17 00:00:00 2001 From: Jonathan Oakley Date: Sun, 18 Sep 2022 23:20:14 +0100 Subject: [PATCH 02/13] Make syncToInput flag private --- output_spdif3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/output_spdif3.h b/output_spdif3.h index ed6a7a82f..173975fd7 100644 --- a/output_spdif3.h +++ b/output_spdif3.h @@ -37,7 +37,6 @@ class AudioOutputSPDIF3 : public AudioStream friend class AsyncAudioInputSPDIF3; static void mute_PCM(const bool mute); static bool pll_locked(void); - static bool syncToInput; // use S/PDIF input to provide Tx clock: avoids glitches protected: //AudioOutputSPDIF3(int dummy): AudioStream(2, inputQueueArray) {} static void config_spdif3(bool extSync=false); @@ -47,6 +46,7 @@ class AudioOutputSPDIF3 : public AudioStream static DMAChannel dma; static void isr(void); private: + static bool syncToInput; // use S/PDIF input to provide Tx clock: avoids glitches static uint32_t dpll_Gain() __attribute__ ((const)); static audio_block_t *block_left_2nd; static audio_block_t *block_right_2nd; From 2bb4e537d460db1e932bd93e2652c2c4913fc96f Mon Sep 17 00:00:00 2001 From: Jonathan Oakley Date: Mon, 19 Sep 2022 09:33:15 +0100 Subject: [PATCH 03/13] Info pane update for SPDIF3 objects --- gui/index.html | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/gui/index.html b/gui/index.html index d61395afb..3f26db90b 100644 --- a/gui/index.html +++ b/gui/index.html @@ -860,6 +860,8 @@

Summary

Receive S/PDIF digital audio, at the rate of the external digital audio source.

This input is incompatible with most other inputs and outputs which run at a speed controlled by Teensy's internal sample rate.

+

It is compatible with the AudioOutputSPDIF3 output: when used together the audio system + will run at the external source's sample rate.

Boards Supported

    @@ -1894,7 +1896,13 @@

    Notes