From 9b0fed975c6e03ef035fcc438c03b7f7fd319440 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Fri, 8 May 2020 15:48:03 +0100 Subject: [PATCH] Buffer output after adding some initial silence. --- FM.cpp | 43 +++++++++++++++--- FM.h | 5 ++- FMDownsampleRB.h | 4 +- FMDownsampler.h | 2 +- FMRB.cpp | 110 +++++++++++++++++++++++++++++++++++++++++++++++ FMRB.h | 72 +++++++++++++++++++++++++++++++ SerialPort.cpp | 2 +- 7 files changed, 226 insertions(+), 12 deletions(-) create mode 100644 FMRB.cpp create mode 100644 FMRB.h diff --git a/FM.cpp b/FM.cpp index c79a822..5c882d0 100644 --- a/FM.cpp +++ b/FM.cpp @@ -44,12 +44,13 @@ m_blanking(), m_useCOS(true), m_cosInvert(false), m_rfAudioBoost(1U), -m_downsampler(128),//Size might need adjustement -m_rxLevel(1) +m_downsampler(128U),//Size might need adjustement +m_rxLevel(1), +m_outputRB(2400U) // 100ms of audio { } -void CFM::samples(bool cos, q15_t* samples, uint8_t length) +void CFM::samples(bool cos, const q15_t* samples, uint8_t length) { if (m_useCOS) { if (m_cosInvert) @@ -115,15 +116,32 @@ void CFM::samples(bool cos, q15_t* samples, uint8_t length) currentSample += m_ctcssTX.getAudio(); - samples[i] = currentSample; + if (m_modemState == STATE_FM) + m_outputRB.put(currentSample); } - - if (m_modemState == STATE_FM) - io.write(STATE_FM, samples, i);//only write the actual number of processed samples to IO } void CFM::process() { + if (m_modemState != STATE_FM) + return; + + uint16_t length = m_outputRB.getData(); + if (length == 0U) + return; + + uint16_t space = io.getSpace(); + if (space == 0U) + return; + + if (space < length) + length = space; + + for (uint16_t i = 0U; i < length; i++) { + q15_t sample; + m_outputRB.get(sample); + io.write(STATE_FM, &sample, 1U); + } } void CFM::reset() @@ -141,6 +159,8 @@ void CFM::reset() m_rfAck.stop(); m_callsign.stop(); m_timeoutTone.stop(); + + m_outputRB.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) @@ -263,6 +283,8 @@ void CFM::listeningState(bool validSignal) sendCallsign(); } + insertSilence(50U); + beginRelaying(); m_callsignTimer.start(); @@ -438,3 +460,10 @@ void CFM::beginRelaying() m_ackMinTimer.start(); } +void CFM::insertSilence(uint16_t ms) +{ + uint32_t nSamples = ms * 24U; + + for (uint32_t i = 0U; i < nSamples; i++) + m_outputRB.put(0); +} diff --git a/FM.h b/FM.h index ef0f419..4901d6a 100644 --- a/FM.h +++ b/FM.h @@ -27,6 +27,7 @@ #include "FMTimeout.h" #include "FMKeyer.h" #include "FMTimer.h" +#include "FMRB.h" #include "FMDirectForm1.h" #include "FMDownsampler.h" @@ -47,7 +48,7 @@ class CFM { public: CFM(); - void samples(bool cos, q15_t* samples, uint8_t length); + void samples(bool cos, const q15_t* samples, uint8_t length); void process(); @@ -83,6 +84,7 @@ private: q15_t m_rfAudioBoost; CFMDownsampler m_downsampler; q15_t m_rxLevel; + CFMRB m_outputRB; void stateMachine(bool validSignal); void listeningState(bool validSignal); @@ -97,6 +99,7 @@ private: void sendCallsign(); void beginRelaying(); + void insertSilence(uint16_t ms); }; #endif diff --git a/FMDownsampleRB.h b/FMDownsampleRB.h index 6e8e466..df60daf 100644 --- a/FMDownsampleRB.h +++ b/FMDownsampleRB.h @@ -16,8 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if !defined(FMRB_H) -#define FMRB_H +#if !defined(FMDOWNSAMPLERB_H) +#define FMDOWNSAMPLERB_H #if defined(STM32F4XX) #include "stm32f4xx.h" diff --git a/FMDownsampler.h b/FMDownsampler.h index fd17e0a..48b0d44 100644 --- a/FMDownsampler.h +++ b/FMDownsampler.h @@ -40,4 +40,4 @@ private: uint8_t m_downSampleIndex; }; -#endif \ No newline at end of file +#endif diff --git a/FMRB.cpp b/FMRB.cpp new file mode 100644 index 0000000..0d8c6ef --- /dev/null +++ b/FMRB.cpp @@ -0,0 +1,110 @@ +/* +TX fifo control - Copyright (C) KI6ZUM 2015 +Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the +Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +Boston, MA 02110-1301, USA. +*/ + +#include "FMRB.h" + +CFMRB::CFMRB(uint16_t length) : +m_length(length), +m_head(0U), +m_tail(0U), +m_full(false), +m_overflow(false) +{ + m_samples = new q15_t[length]; +} + +uint16_t CFMRB::getSpace() const +{ + uint16_t n = 0U; + + if (m_tail == m_head) + n = m_full ? 0U : m_length; + else if (m_tail < m_head) + n = m_length - m_head + m_tail; + else + n = m_tail - m_head; + + if (n > m_length) + n = 0U; + + return n; +} + +uint16_t CFMRB::getData() const +{ + if (m_tail == m_head) + return m_full ? m_length : 0U; + else if (m_tail < m_head) + return m_head - m_tail; + else + return m_length - m_tail + m_head; +} + +bool CFMRB::put(q15_t sample) +{ + if (m_full) { + m_overflow = true; + return false; + } + + m_samples[m_head] = sample; + + m_head++; + if (m_head >= m_length) + m_head = 0U; + + if (m_head == m_tail) + m_full = true; + + return true; +} + +bool CFMRB::get(q15_t& sample) +{ + if (m_head == m_tail && !m_full) + return false; + + sample = m_samples[m_tail]; + + m_full = false; + + m_tail++; + if (m_tail >= m_length) + m_tail = 0U; + + return true; +} + +bool CFMRB::hasOverflowed() +{ + bool overflow = m_overflow; + + m_overflow = false; + + return overflow; +} + +void CFMRB::reset() +{ + m_head = 0U; + m_tail = 0U; + m_full = false; + m_overflow = false; +} diff --git a/FMRB.h b/FMRB.h new file mode 100644 index 0000000..7cf6cf4 --- /dev/null +++ b/FMRB.h @@ -0,0 +1,72 @@ +/* +Serial fifo control - Copyright (C) KI6ZUM 2015 +Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the +Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +Boston, MA 02110-1301, USA. +*/ + +#if !defined(FMRB_H) +#define FMRB_H + +#if defined(STM32F4XX) +#include "stm32f4xx.h" +#elif defined(STM32F7XX) +#include "stm32f7xx.h" +#elif defined(STM32F105xC) +#include "stm32f1xx.h" +#include +#else +#include +#endif + +#if defined(__SAM3X8E__) || defined(STM32F105xC) +#define ARM_MATH_CM3 +#elif defined(STM32F7XX) +#define ARM_MATH_CM7 +#elif defined(STM32F4XX) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) +#define ARM_MATH_CM4 +#else +#error "Unknown processor type" +#endif + +#include + +class CFMRB { +public: + CFMRB(uint16_t length); + + uint16_t getSpace() const; + + uint16_t getData() const; + + bool put(q15_t sample); + + bool get(q15_t& sample); + + bool hasOverflowed(); + + void reset(); + +private: + uint16_t m_length; + volatile q15_t* m_samples; + volatile uint16_t m_head; + volatile uint16_t m_tail; + volatile bool m_full; + bool m_overflow; +}; + +#endif diff --git a/SerialPort.cpp b/SerialPort.cpp index 711ba6e..69d691b 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -101,7 +101,7 @@ const uint8_t MMDVM_DEBUG5 = 0xF5U; #define HW_TYPE "MMDVM" #endif -#define DESCRIPTION "20200506 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG/FM)" +#define DESCRIPTION "20200508 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG/FM)" #if defined(GITVERSION) #define concat(h, a, b, c) h " " a " " b " GitID #" c ""