From 66d19246851bdf50fd7380218cecbcdeed5e4571 Mon Sep 17 00:00:00 2001 From: Rob French Date: Wed, 10 Jun 2020 23:23:15 -0500 Subject: [PATCH] Added speech compressor. Works. Added some menu code. But this needs to be redesigned. Commented out. Work this on a branch. --- iopcomm/iopcomm.cpp | 1 - iopcomm/iopcomm.h | 8 +++-- ubitx_iop/audio.ino | 5 +++ ubitx_iop/config.h | 2 ++ ubitx_iop/config.ino | 9 ++++++ ubitx_iop/menu.h | 47 +++++++++++++++++++++++++--- ubitx_iop/menu.ino | 62 +++++++++++++++++++++++++++++++++++++ ubitx_iop/tx_audio_proc.ino | 4 ++- ubitx_iop/ubitx_iop.ino | 5 +++ 9 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 ubitx_iop/config.ino diff --git a/iopcomm/iopcomm.cpp b/iopcomm/iopcomm.cpp index 2b699cd..8d54b63 100644 --- a/iopcomm/iopcomm.cpp +++ b/iopcomm/iopcomm.cpp @@ -184,7 +184,6 @@ void sendIOPMenuDisplay(const char* text) } m.data[16] = '\0'; sendIOPMessage(m); - Serial.println((char *)m.data); } //====================================================================== diff --git a/iopcomm/iopcomm.h b/iopcomm/iopcomm.h index 5348812..2fa8336 100644 --- a/iopcomm/iopcomm.h +++ b/iopcomm/iopcomm.h @@ -163,7 +163,11 @@ class SSBConfig : public IConfig { public: SSBConfig(RxFilter f): filter(f) {} // parameters - RxFilter filter; // = RX_FILTER_MEDIUM; + RxFilter filter = RX_FILTER_MEDIUM; +// bool comp_enable = false; +// float comp_threshold = 0.1; +// float comp_ratio = 20.0; +// float comp_gain = 2.0; }; //====================================================================== @@ -204,7 +208,7 @@ class TTConfig : public IConfig { public: TTConfig(RxFilter f): filter(f) {} // parameters - RxFilter filter = RX_FILTER_MEDIUM; + RxFilter filter = RX_FILTER_MEDIUM; }; //====================================================================== diff --git a/ubitx_iop/audio.ino b/ubitx_iop/audio.ino index 9a66544..8de1ad0 100644 --- a/ubitx_iop/audio.ino +++ b/ubitx_iop/audio.ino @@ -337,6 +337,11 @@ void BPFilter::disable() { } //====================================================================== + +SpeechCompressor speechCompressor(compTX, compAmp, compRMS); + +//====================================================================== + /* // array based on mode right now BPFilter *rxFilter[NUM_RIG_MODES][NUM_RX_FILTERS]; diff --git a/ubitx_iop/config.h b/ubitx_iop/config.h index 08f119a..7b31863 100644 --- a/ubitx_iop/config.h +++ b/ubitx_iop/config.h @@ -44,6 +44,8 @@ class AudioConfig { float rxLineOutCal = 1.0; // USB-out parameters (RX) float rxUSBOutCal = 1.0; + // sidetone parameters (really a TX thing, but "RX" side of audio) + float sideToneVol = 1.0; //-------------------------------------------------------------------- // TRANSMIT PARAMETERS diff --git a/ubitx_iop/config.ino b/ubitx_iop/config.ino new file mode 100644 index 0000000..29fdd24 --- /dev/null +++ b/ubitx_iop/config.ino @@ -0,0 +1,9 @@ +//====================================================================== +// config.ino +//====================================================================== + +#include "config.h" + +//====================================================================== +// EOF +//====================================================================== diff --git a/ubitx_iop/menu.h b/ubitx_iop/menu.h index 4183c53..3d3bcb5 100644 --- a/ubitx_iop/menu.h +++ b/ubitx_iop/menu.h @@ -5,7 +5,12 @@ #ifndef __menu_h__ #define __menu_h__ +#include +#include #include "rig.h" +#include "tx_audio_proc.h" + +extern SpeechCompressor speechCompressor; // This should be somewhere else. // 16 characters on display #define MAX_TEXT_LEN 16 @@ -24,7 +29,25 @@ class MenuItem { virtual MenuItem* prev() = 0; virtual MenuItem* next() = 0; }; - +/* +class ListMenu : public MenuItem { + public: + ListMenu(const char* title, std::initializer_list items) { + _items = new MenuItem*[items.size()]; + } + virtual ~MenuItem() { + delete _items; + } + virtual void update() { + //sprintf(_text, " + } + + private: + + MenuItem** _items; + char _text[MAX_TEXT_LEN+1]; +}; +*/ const char modeID[] = {'s', 'S', 'c', 'C', 'd', 'D', 't', 'T'}; const char* const filterID[NUM_RIG_MODES][NUM_RX_FILTERS] = { {"2.8", "2.4", "1.8"}, // LSB @@ -39,7 +62,7 @@ const char* const filterID[NUM_RIG_MODES][NUM_RX_FILTERS] = { class TopMenu : public MenuItem { public: - TopMenu(Rig& rig): _rig(rig), _dirty(false), _visible(false), _adjust_tx(false) { + TopMenu(Rig& rig): _rig(rig), _dirty(false), _visible(false), _adjust_tx(false), _comp_on(false) { strcpy(_text0, "R: T: "); strcpy(_text1, "0123456789ABCDEF"); } @@ -50,10 +73,11 @@ class TopMenu : public MenuItem { }*/ virtual void update() { - sprintf(_text0, "%1cR:%3s %1cT: ", + sprintf(_text0, "%1cR:%3s %1cT:%3s ", _adjust_tx ? ' ' : MENU_SELECTED_CHAR, filterID[_rig.modeNum()][_rig.filterNum()], - _adjust_tx ? MENU_SELECTED_CHAR : ' '); + _adjust_tx ? MENU_SELECTED_CHAR : ' ', + _rig.isSSBMode() && _comp_on ? "CMP" : " "); if ((strcmp(_text0, _text1) != 0) || _dirty) { if (_visible) { sendIOPMenuDisplay(_text0); @@ -97,6 +121,13 @@ class TopMenu : public MenuItem { virtual MenuItem* prev() { if (_visible) { if (_adjust_tx) { + if (_rig.isSSBMode()) { + _comp_on = !_comp_on; + if (_comp_on) + speechCompressor.enable(); + else + speechCompressor.disable(); + } } else { _rig.switchRxFilter(true); } @@ -108,6 +139,13 @@ class TopMenu : public MenuItem { virtual MenuItem* next() { if (_visible) { if (_adjust_tx) { + if (_rig.isSSBMode()) { + _comp_on = !_comp_on; + if (_comp_on) + speechCompressor.enable(); + else + speechCompressor.disable(); + } } else { _rig.switchRxFilter(); } @@ -121,6 +159,7 @@ class TopMenu : public MenuItem { bool _dirty; bool _visible; bool _adjust_tx; + bool _comp_on; char _text0[MAX_TEXT_LEN+1]; char _text1[MAX_TEXT_LEN+1]; }; diff --git a/ubitx_iop/menu.ino b/ubitx_iop/menu.ino index fd8c4f2..e162bfe 100644 --- a/ubitx_iop/menu.ino +++ b/ubitx_iop/menu.ino @@ -3,8 +3,70 @@ //====================================================================== #include +#include "config.h" #include "menu.h" +/* +ListMenu("Configuration", + ListMenu("LSB Mode", + ParameterFilter("Filter", c.lsb.filter), + ParameterOnOff ("Compressor", c.lsb.comp_enable), + ParameterFloat ("Comp Thresh", c.lsb.comp_threshold, 0.0, 1.0, 0.1), + ParameterFloat ("Comp Ratio", c.lsb.comp_ratio, 0.0, 50.0, 1.0), + ParameterFloat ("Comp Gain", c.lsb.comp_gain, 0.0, 99.9, 0.1)), + ListMenu("USB Mode", + ParameterFilter("Filter", c.usb.filter), + ParameterOnOff ("Compressor", c.usb.comp_enable), + ParameterFloat ("Comp Thresh", c.usb.comp_threshold, 0.0, 1.0, 0.1), + ParameterFloat ("Comp Ratio", c.usb.comp_ratio, 0.0, 50.0, 1.0), + ParameterFloat ("Comp Gain", c.usb.comp_gain, 0.0, 99.9, 0.1)), + ListMenu("CWL Mode", + ParameterFilter("Filter", c.cwl.filter), + ParameterKeyer ("Keyer Mode", c.cwl.mode), + ParameterOnOff ("Keyer Rev?", c.cwl.reversed), + ParameterInt ("Keyer WPM", c.cwl.wpm, 0, 60, 1), + ParameterFloat ("Keyer Weight", c.cwl.weight, 0.0, 9.9, 0.1), + ParameterInt ("ST Freq", c.sidetone, 300, 3000, 10)), + ListMenu("CWU Mode", + ParameterFilter("Filter", c.cwl.filter), + ParameterKeyer ("Keyer Mode", c.cwl.mode), + ParameterOnOff ("Keyer Rev?", c.cwl.reversed), + ParameterInt ("Keyer WPM", c.cwl.wpm, 0, 60, 1), + ParameterFloat ("Keyer Weight", c.cwl.weight, 0.0, 9.9, 0.1), + ParameterInt ("ST Freq", c.sidetone, 300, 3000, 10)), + ListMenu("DGL Mode", + ParameterFilter("Filter", c.dgl.filter)), + ListMenu("DGU Mode", + ParameterFilter("Filter", c.dgu.filter)), + ListMenu("TTL Mode", + ParameterFilter("Filter", c.dgl.filter)), + ListMenu("TTU Mode", + ParameterFilter("Filter", c.dgu.filter)), + ListMenu("Audio", + ParameterInt ("RX ADC Lvl", c.rxRigInLevel, 0, 15, 1), + ParameterInt ("RX DAC Lvl", c.rxLineOutLevel, 13, 31, 1), + ParameterFloat ("RX Inp Lvl", c.rxRigInVol, 0.0, 1.0, 0.1), + ParameterFloat ("RX Inp Cal", c.rxRigInCal, 0.0, 99.9, 0.1), + ParameterFloat ("RX Spkr Cal", c.rxSpkrOutCal, 0.0, 99.9, 0.1), + ParameterFloat ("RX Line Cal", c.rxLineOutCal, 0.0, 99.9, 0.1), + ParameterFloat ("RX USB Cal", c.rxUSBOutCal, 0.0, 99.9, 0.1), + ParameterOnOff ("RX USB Dbg", c.rxUSBInEnable), + ParameterInt ("TX Mic Gain", c.txMicInGain, 0, 63, 1), + ParameterInt ("TX ADC Lvl", c.txLineInLevel, 0, 15, 1), + ParameterInt ("TX DAC Lvl", c.txRigOutLevel, 13, 31, 1), + ParameterFloat ("TX Out Cal", c.txRigOutCal, 0.0, 99.9, 0.1), + ParameterFloat ("TX Mic Lvl", c.txMicInVol, 0.0, 1.0, 0.1), + ParameterFloat ("TX Mic Cal", c.txMicInCal, 0.0, 99.9, 0.1), + ParameterFloat ("TX Line Lvl", c.txLineInVol, 0.0, 1.0, 0.1), + ParameterFloat ("TX Line Cal", c.txLineInCal, 0.0, 99.9, 0.1), + ParameterFloat ("TX USB Lvl", c.txUSBInVol, 0.0, 1.0, 0.1), + ParameterFloat ("TX USB Cal", c.txUSBInCal, 0.0, 99.9, 0.1), + ParameterOnOff ("TX USB Dbg", c.txUSBOutEnable), + ParameterFloat ("Tone 1 Lvl", c.txSine1Vol, 0.0, 1.0, 0.1), + ParameterFloat ("Tone 2 Lvl", c.txSine2Vol, 0.0, 1.0, 0.1), + ParameterFloat ("ST Lvl", c.sideToneVol, 0.0, 1.0, 0.1))); +*/ + //====================================================================== // EOF //====================================================================== diff --git a/ubitx_iop/tx_audio_proc.ino b/ubitx_iop/tx_audio_proc.ino index 72b519a..218915e 100644 --- a/ubitx_iop/tx_audio_proc.ino +++ b/ubitx_iop/tx_audio_proc.ino @@ -25,13 +25,15 @@ bool SpeechCompressor::isEnabled() const void SpeechCompressor::enable() { _enabled = true; - _compress.begin(1, 0.5, 4); // Need to make configurable + _compress.begin(1, 0.1, 20); // Need to make configurable + _amp.gain(2.0); } void SpeechCompressor::disable() { _enabled = false; _compress.disable(); + _amp.gain(1.0); } // Speech compressor code based on post by 'hyperdyne': https://forum.pjrc.com/threads/36245-Changing-Pitch-of-Voice diff --git a/ubitx_iop/ubitx_iop.ino b/ubitx_iop/ubitx_iop.ino index 14efd30..ce6b4b6 100644 --- a/ubitx_iop/ubitx_iop.ino +++ b/ubitx_iop/ubitx_iop.ino @@ -263,10 +263,15 @@ void loop() // strcpy(old_mode_text, rig.modeText()); // } + // update the speech compressor. Really should do this elsewhere. + if (speechCompressor.isEnabled()) + speechCompressor.update(); + // update the menu at a 10 Hz rate if (menuUpdateMillis > 100) { menu->update(); menuUpdateMillis = 0; + } if (frameMillis > 5000) {