From 0e2a83bc7b2ae31eab18f568614d91dcc81fe5d6 Mon Sep 17 00:00:00 2001 From: Geoffrey Merck Date: Sat, 9 May 2020 07:57:45 +0200 Subject: [PATCH 1/4] Add incoming network data buffer --- FM.cpp | 22 +++++++++++++--------- FM.h | 1 + 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/FM.cpp b/FM.cpp index bfb81cf..36c1ecd 100644 --- a/FM.cpp +++ b/FM.cpp @@ -51,10 +51,11 @@ m_useCOS(true), m_cosInvert(false), m_rfAudioBoost(1U), m_extAudioBoost(1U), -m_downsampler(128U),//Size might need adjustement +m_downsampler(1200U),// 100 ms of audio m_extEnabled(false), m_rxLevel(1), -m_outputRB(2400U) // 100ms of audio +m_outputRB(2400U), // 100ms of audio +m_incomingNetworkRB(2400U) //100ms of Audio { } @@ -656,14 +657,11 @@ void CFM::beginRelaying() uint8_t CFM::getSpace() const { // The amount of free space for receiving external audio, in bytes. - return 0U; + return m_incomingNetworkRB.getSpace(); } uint8_t CFM::writeData(const uint8_t* data, uint8_t length) { - q15_t samples[170U]; - uint8_t nSamples = 0U; - for (uint8_t i = 0U; i < length; i += 3U) { uint16_t sample1 = 0U; uint16_t sample2 = 0U; @@ -679,9 +677,15 @@ uint8_t CFM::writeData(const uint8_t* data, uint8_t length) sample2 = uint16_t(pack & MASK); sample1 = uint16_t(pack >> 12); - // Convert from uint16_t (0 - +4095) to Q15 (-2048 - +2047) - samples[nSamples++] = q15_t(sample1) - 2048; - samples[nSamples++] = q15_t(sample2) - 2048; + // Convert from uint16_t (0 - +4095) to Q15 (-2048 - +2047). + // Incoming data has sample rate 8kHz, just add 2 empty samples after + // every incoming sample to upsample to 24kHz + m_incomingNetworkRB.put(q15_t(sample1) - 2048); + m_incomingNetworkRB.put(0); + m_incomingNetworkRB.put(0); + m_incomingNetworkRB.put(q15_t(sample2) - 2048); + m_incomingNetworkRB.put(0); + m_incomingNetworkRB.put(0); } // Received audio is now in Q15 format in samples, with length nSamples. diff --git a/FM.h b/FM.h index 1bf6cf1..4e801bc 100644 --- a/FM.h +++ b/FM.h @@ -96,6 +96,7 @@ private: bool m_extEnabled; q15_t m_rxLevel; CFMRB m_outputRB; + CFMRB m_incomingNetworkRB; void stateMachine(bool validRFSignal, bool validExtSignal); void listeningState(bool validRFSignal, bool validExtSignal); From ff3e6feeb674efa04fa6b3fbc2073b7541c4c191 Mon Sep 17 00:00:00 2001 From: Geoffrey Merck Date: Sat, 9 May 2020 08:00:24 +0200 Subject: [PATCH 2/4] Use more explicit names --- FM.cpp | 30 +++++++++++++++--------------- FM.h | 4 ++-- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/FM.cpp b/FM.cpp index 36c1ecd..96643c2 100644 --- a/FM.cpp +++ b/FM.cpp @@ -54,8 +54,8 @@ m_extAudioBoost(1U), m_downsampler(1200U),// 100 ms of audio m_extEnabled(false), m_rxLevel(1), -m_outputRB(2400U), // 100ms of audio -m_incomingNetworkRB(2400U) //100ms of Audio +m_outputRFRB(2400U), // 100ms of audio +m_inputExtRB(2400U) //100ms of Audio { } @@ -78,7 +78,7 @@ void CFM::samples(bool cos, const q15_t* samples, uint8_t length) uint8_t ctcssState = m_ctcssRX.process(currentSample); if (CTCSS_NOT_READY(ctcssState) && m_modemState != STATE_FM) { - //Not enough samples to determine if you have CTCSS, just carry on + //Not enough samples to determine if you have CTCSS, just carry on. continue; } else if (CTCSS_READY(ctcssState) && m_modemState != STATE_FM) { //we had enough samples for CTCSS and we are in some other mode than FM @@ -138,7 +138,7 @@ void CFM::samples(bool cos, const q15_t* samples, uint8_t length) currentSample += m_ctcssTX.getAudio(); if (m_modemState == STATE_FM) - m_outputRB.put(currentSample); + m_outputRFRB.put(currentSample); } } @@ -147,7 +147,7 @@ void CFM::process() if (m_modemState != STATE_FM) return; - uint16_t length = m_outputRB.getData(); + uint16_t length = m_outputRFRB.getData(); if (length == 0U) return; @@ -162,7 +162,7 @@ void CFM::process() for (uint16_t i = 0U; i < length; i++) { q15_t sample; - m_outputRB.get(sample); + m_outputRFRB.get(sample); io.write(STATE_FM, &sample, 1U); } } @@ -184,7 +184,7 @@ void CFM::reset() m_callsign.stop(); m_timeoutTone.stop(); - m_outputRB.reset(); + m_outputRFRB.reset(); } uint8_t CFM::setCallsign(const char* callsign, uint8_t speed, uint16_t frequency, uint8_t time, uint8_t holdoff, uint8_t highLevel, uint8_t lowLevel, bool callsignAtStart, bool callsignAtEnd, bool callsignAtLatch) @@ -657,7 +657,7 @@ void CFM::beginRelaying() uint8_t CFM::getSpace() const { // The amount of free space for receiving external audio, in bytes. - return m_incomingNetworkRB.getSpace(); + return m_inputExtRB.getSpace(); } uint8_t CFM::writeData(const uint8_t* data, uint8_t length) @@ -680,12 +680,12 @@ uint8_t CFM::writeData(const uint8_t* data, uint8_t length) // Convert from uint16_t (0 - +4095) to Q15 (-2048 - +2047). // Incoming data has sample rate 8kHz, just add 2 empty samples after // every incoming sample to upsample to 24kHz - m_incomingNetworkRB.put(q15_t(sample1) - 2048); - m_incomingNetworkRB.put(0); - m_incomingNetworkRB.put(0); - m_incomingNetworkRB.put(q15_t(sample2) - 2048); - m_incomingNetworkRB.put(0); - m_incomingNetworkRB.put(0); + m_inputExtRB.put(q15_t(sample1) - 2048); + m_inputExtRB.put(0); + m_inputExtRB.put(0); + m_inputExtRB.put(q15_t(sample2) - 2048); + m_inputExtRB.put(0); + m_inputExtRB.put(0); } // Received audio is now in Q15 format in samples, with length nSamples. @@ -698,5 +698,5 @@ void CFM::insertSilence(uint16_t ms) uint32_t nSamples = ms * 24U; for (uint32_t i = 0U; i < nSamples; i++) - m_outputRB.put(0); + m_outputRFRB.put(0); } diff --git a/FM.h b/FM.h index 4e801bc..3e68e28 100644 --- a/FM.h +++ b/FM.h @@ -95,8 +95,8 @@ private: CFMDownsampler m_downsampler; bool m_extEnabled; q15_t m_rxLevel; - CFMRB m_outputRB; - CFMRB m_incomingNetworkRB; + CFMRB m_outputRFRB; + CFMRB m_inputExtRB; void stateMachine(bool validRFSignal, bool validExtSignal); void listeningState(bool validRFSignal, bool validExtSignal); From e91c4417cb944cec49a801a892cda5694771bb52 Mon Sep 17 00:00:00 2001 From: Geoffrey Merck Date: Sat, 9 May 2020 08:23:02 +0200 Subject: [PATCH 3/4] Handle incoming audio --- FM.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/FM.cpp b/FM.cpp index 96643c2..b2195e7 100644 --- a/FM.cpp +++ b/FM.cpp @@ -73,35 +73,38 @@ void CFM::samples(bool cos, const q15_t* samples, uint8_t length) uint8_t i = 0U; for (; i < length; i++) { // ARMv7-M has hardware integer division - q15_t currentSample = q15_t((q31_t(samples[i]) << 8) / m_rxLevel); + q15_t currentRFSample = q15_t((q31_t(samples[i]) << 8) / m_rxLevel); + uint8_t ctcssState = m_ctcssRX.process(currentRFSample); - uint8_t ctcssState = m_ctcssRX.process(currentSample); + q15_t currentExtSample; + bool inputExt = m_inputExtRB.get(currentExtSample);//always consume the external input data so it does not overflow - if (CTCSS_NOT_READY(ctcssState) && m_modemState != STATE_FM) { + if ((!inputExt || CTCSS_NOT_READY(ctcssState)) && m_modemState != STATE_FM) { //Not enough samples to determine if you have CTCSS, just carry on. continue; - } else if (CTCSS_READY(ctcssState) && m_modemState != STATE_FM) { + } else if ((inputExt || CTCSS_READY(ctcssState)) && m_modemState != STATE_FM) { //we had enough samples for CTCSS and we are in some other mode than FM bool validCTCSS = CTCSS_VALID(ctcssState); - // XXX Need to have somewhere to get the ext audio state - stateMachine(validCTCSS && cos, false); + stateMachine(validCTCSS && cos, inputExt); if (m_modemState != STATE_FM) continue; - } else if (CTCSS_READY(ctcssState) && m_modemState == STATE_FM) { + } else if ((inputExt || CTCSS_READY(ctcssState)) && m_modemState == STATE_FM) { //We had enough samples for CTCSS and we are in FM mode, trigger the state machine bool validCTCSS = CTCSS_VALID(ctcssState); - // XXX Need to have somewhere to get the ext audio state - stateMachine(validCTCSS && cos, false); + stateMachine(validCTCSS && cos, inputExt); if (m_modemState != STATE_FM) break; - } else if (CTCSS_NOT_READY(ctcssState) && m_modemState == STATE_FM && i == length - 1) { + } else if ((inputExt || CTCSS_NOT_READY(ctcssState)) && m_modemState == STATE_FM && i == length - 1) { //Not enough samples for CTCSS but we already are in FM, trigger the state machine //but do not trigger the state machine on every single sample, save CPU! bool validCTCSS = CTCSS_VALID(ctcssState); - // XXX Need to have somewhere to get the ext audio state - stateMachine(validCTCSS && cos, false); + stateMachine(validCTCSS && cos, inputExt); } + q15_t currentSample = currentRFSample; + if(m_state == FS_RELAYING_EXT || m_state == FS_KERCHUNK_EXT) + currentSample = currentExtSample; + // Only let RF audio through when relaying RF audio if (m_state == FS_RELAYING_RF || m_state == FS_KERCHUNK_RF) { if (m_extEnabled) @@ -110,7 +113,6 @@ void CFM::samples(bool cos, const q15_t* samples, uint8_t length) currentSample = m_blanking.process(currentSample); currentSample *= m_rfAudioBoost; } else if (m_state == FS_RELAYING_EXT || m_state == FS_KERCHUNK_EXT) { - // XXX Where do we receive the ext audio? currentSample = m_blanking.process(currentSample); currentSample *= m_extAudioBoost; } else { From 5d45649096b4cc653823444fe49a342630eb72f0 Mon Sep 17 00:00:00 2001 From: Geoffrey Merck Date: Sat, 9 May 2020 08:29:31 +0200 Subject: [PATCH 4/4] Simplify code --- FM.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/FM.cpp b/FM.cpp index b2195e7..3d47941 100644 --- a/FM.cpp +++ b/FM.cpp @@ -102,19 +102,19 @@ void CFM::samples(bool cos, const q15_t* samples, uint8_t length) } q15_t currentSample = currentRFSample; - if(m_state == FS_RELAYING_EXT || m_state == FS_KERCHUNK_EXT) + q15_t currentBoost = m_rfAudioBoost; + if(m_state == FS_RELAYING_EXT || m_state == FS_KERCHUNK_EXT){ currentSample = currentExtSample; + currentBoost = m_extAudioBoost; + } // Only let RF audio through when relaying RF audio - if (m_state == FS_RELAYING_RF || m_state == FS_KERCHUNK_RF) { - if (m_extEnabled) + if (m_state == FS_RELAYING_RF || m_state == FS_KERCHUNK_RF || m_state == FS_RELAYING_EXT || m_state == FS_KERCHUNK_EXT) { + if (m_extEnabled && (m_state == FS_RELAYING_RF || m_state == FS_KERCHUNK_RF)) m_downsampler.addSample(currentSample); currentSample = m_blanking.process(currentSample); - currentSample *= m_rfAudioBoost; - } else if (m_state == FS_RELAYING_EXT || m_state == FS_KERCHUNK_EXT) { - currentSample = m_blanking.process(currentSample); - currentSample *= m_extAudioBoost; + currentSample *= currentBoost; } else { currentSample = 0; }