From 95e76f387c4c980ca85960cafb63010f9a504926 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 16 Apr 2020 21:15:15 +0100 Subject: [PATCH] Complete the CW keyer. --- FMCTCSSTX.cpp | 12 +++++----- FMKeyer.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++--------- FMKeyer.h | 8 +++++-- 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/FMCTCSSTX.cpp b/FMCTCSSTX.cpp index 0513f13..4c92577 100644 --- a/FMCTCSSTX.cpp +++ b/FMCTCSSTX.cpp @@ -24,7 +24,7 @@ const struct CTCSS_TABLE { uint8_t frequency; uint16_t length; q15_t increment; -} CTCSS_TABLE[] = { +} CTCSS_TABLE_DATA[] = { { 67U, 358U, 92}, { 69U, 346U, 95}, { 71U, 334U, 99}, @@ -77,7 +77,7 @@ const struct CTCSS_TABLE { {254U, 94U, 347} }; -const uint8_t CTCSS_TABLE_LEN = 50U; +const uint8_t CTCSS_TABLE_DATA_LEN = 50U; CFMCTCSSTX::CFMCTCSSTX() : m_values(NULL), @@ -88,11 +88,11 @@ m_n(0U) uint8_t CFMCTCSSTX::setParams(uint8_t frequency, uint8_t level) { - struct CTCSS_TABLE* entry = NULL; + const CTCSS_TABLE* entry = NULL; - for (uint8_t i = 0U; i < CTCSS_TABLE_LEN; i++) { - if (CTCSS_TABLE[i].frequency == frequency) { - entry = CTCSS_TABLE + i; + for (uint8_t i = 0U; i < CTCSS_TABLE_DATA_LEN; i++) { + if (CTCSS_TABLE_DATA[i].frequency == frequency) { + entry = CTCSS_TABLE_DATA + i; break; } } diff --git a/FMKeyer.cpp b/FMKeyer.cpp index 56aa3d3..925a484 100644 --- a/FMKeyer.cpp +++ b/FMKeyer.cpp @@ -76,18 +76,20 @@ const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02 #define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) CFMKeyer::CFMKeyer() : -m_level(128 * 128), m_wanted(false), -m_running(false), m_poBuffer(), -m_poLen(0U) +m_poLen(0U), +m_poPos(0U), +m_dotLen(0U), +m_dotPos(0U), +m_audio(NULL), +m_audioLen(0U), +m_audioPos(0U) { } uint8_t CFMKeyer::setParams(const char* text, uint8_t speed, uint16_t frequency, uint8_t level) { - m_level = q15_t(level * 128); - for (uint8_t i = 0U; text[i] != '\0'; i++) { for (uint8_t j = 0U; SYMBOL_LIST[j].c != 0U; j++) { if (SYMBOL_LIST[j].c == text[i]) { @@ -107,27 +109,66 @@ uint8_t CFMKeyer::setParams(const char* text, uint8_t speed, uint16_t frequency, } } + q15_t value = q15_t(level * 128); + + m_dotLen = 24000U / speed; // In samples + + m_audioLen = 24000U / frequency; // In samples + + m_audio = new q15_t[m_audioLen]; + + for (uint16_t i = 0U; i < m_audioLen; i++) { + if (i < (m_audioLen / 2U)) + m_audio[i] = value; + else + m_audio[i] = -value; + } + return 0U; } void CFMKeyer::getAudio(q15_t* samples, uint8_t length) { - if (!m_wanted && !m_running) + if (!m_wanted) return; + + for (uint8_t i = 0U; i < length; i++) { + bool b = READ_BIT(m_poBuffer, m_poPos); + if (b) + samples[i] += m_audio[m_audioPos]; + + m_audioPos++; + if (m_audioPos >= m_audioLen) + m_audioPos = 0U; + m_dotPos++; + if (m_dotPos >= m_dotLen) { + m_dotPos = 0U; + m_poPos++; + if (m_poPos >= m_poLen) { + stop(); + return; + } + } + } } void CFMKeyer::start() { - m_wanted = true; + m_wanted = true; + m_poPos = 0U; + m_dotPos = 0U; + m_audioPos = 0U; } void CFMKeyer::stop() { - m_wanted = false; - m_running = false; + m_wanted = false; + m_poPos = 0U; + m_dotPos = 0U; + m_audioPos = 0U; } bool CFMKeyer::isRunning() const { - return m_running; + return m_poPos > 0U || m_dotPos > 0U || m_audioPos > 0U; } diff --git a/FMKeyer.h b/FMKeyer.h index dbcb011..3676522 100644 --- a/FMKeyer.h +++ b/FMKeyer.h @@ -35,11 +35,15 @@ public: bool isRunning() const; private: - q15_t m_level; bool m_wanted; - bool m_running; uint8_t m_poBuffer[1000U]; uint16_t m_poLen; + uint16_t m_poPos; + uint16_t m_dotLen; + uint16_t m_dotPos; + q15_t* m_audio; + uint16_t m_audioLen; + uint16_t m_audioPos; }; #endif