From 519a20850840ba474a70659d15d1a7c240208c77 Mon Sep 17 00:00:00 2001 From: Rob French Date: Wed, 27 May 2020 22:45:37 -0500 Subject: [PATCH] Fixes to get it running, working for the most part (currently using DGU mode on 40 meter FT8, so it can't be all bad). Filters added, although not currently selectable (til I get the rotary encoder added). --- ubitx_iop/RigMode.h | 125 ++++++++++++++++++++++++++++++++++++---- ubitx_iop/audio.h | 19 ++++-- ubitx_iop/audio.ino | 60 +++++++++++++------ ubitx_iop/config.h | 7 ++- ubitx_iop/rig.h | 49 +++++++++++----- ubitx_iop/ubitx_iop.h | 2 +- ubitx_iop/ubitx_iop.ino | 26 ++++++++- 7 files changed, 238 insertions(+), 50 deletions(-) diff --git a/ubitx_iop/RigMode.h b/ubitx_iop/RigMode.h index fcb4291..19cc28b 100644 --- a/ubitx_iop/RigMode.h +++ b/ubitx_iop/RigMode.h @@ -5,6 +5,8 @@ #ifndef __RigMode_h__ #define __RigMode_h__ +#include "audio.h" + // Exceptions not active (for Arduino, I assume?). //enum IModeExceptions { // MODE_ALREADY_ACTIVE = -1, @@ -22,8 +24,8 @@ class IMode { public: - IMode(IConfig& c, RigAudio& a): - _config(c), _audio(a), _active(false), _transmitting(false) + IMode(IConfig& c, RigAudio& a, IFilter& f): + _config(c), _audio(a), _filter(f), _active(false), _transmitting(false) { } @@ -33,6 +35,8 @@ class IMode { inline RigAudio& audio() { return _audio; } + inline IFilter& filter() { return _filter; } + // Called upon mode entry. Should assume that the rig's state is // "clean", i.e. that it still needs to enable anything it needs for // use in the mode. @@ -98,10 +102,17 @@ class IMode { inline bool isTx() const { return _transmitting; } inline bool isRx() const { return !_transmitting; } + virtual void setWideRxFilter()= 0; + + virtual void setMediumRxFilter()= 0; + + virtual void setNarrowRxFilter()= 0; + private: IConfig& _config; RigAudio& _audio; + IFilter& _filter; bool _active; bool _transmitting; }; @@ -114,13 +125,14 @@ class SSBMode : public IMode { public: - SSBMode(IConfig& c, RigAudio& a, bool default_mic=true): - IMode(c, a), _use_mic(default_mic) + SSBMode(IConfig& c, RigAudio& a, IFilter& f, bool default_mic=true): + IMode(c, a, f), _use_mic(default_mic) { } virtual void onEntry() { + setWideRxFilter(); audio().unmuteRx(); audio().muteAllTx(); USBDEBUG("SSB mode entered"); @@ -172,6 +184,24 @@ class SSBMode : public IMode USBDEBUG("SSB mode - Line In set"); } + virtual void setWideRxFilter(){ + ((BPFilter&)filter()).setBand(300.0, 3100.0); + filter().enable(); + USBDEBUG("set wide RX SSB filter"); + } + + virtual void setMediumRxFilter(){ + ((BPFilter&)filter()).setBand(500.0, 2900.0); + filter().enable(); + USBDEBUG("set medium RX SSB filter"); + } + + virtual void setNarrowRxFilter(){ + ((BPFilter&)filter()).setBand(700.0, 2500.0); + filter().enable(); + USBDEBUG("set narrow RX SSB filter"); + } + private: bool _use_mic; @@ -185,13 +215,14 @@ class DGTMode : public IMode { public: - DGTMode(IConfig& c, RigAudio& a): - IMode(c, a) + DGTMode(IConfig& c, RigAudio& a, IFilter& f): + IMode(c, a, f) { } virtual void onEntry() { + setWideRxFilter(); audio().unmuteRx(); audio().muteAllTx(); USBDEBUG("DGT mode entered"); @@ -216,6 +247,24 @@ class DGTMode : public IMode audio().unmuteRx(); USBDEBUG("DGT mode receiving"); } + + virtual void setWideRxFilter(){ + ((BPFilter&)filter()).setBand(300.0, 3100.0); + filter().enable(); + USBDEBUG("set wide RX DGT filter"); + } + + virtual void setMediumRxFilter(){ + ((BPFilter&)filter()).setBand(500.0, 2900.0); + filter().enable(); + USBDEBUG("set medium RX DGT filter"); + } + + virtual void setNarrowRxFilter(){ + ((BPFilter&)filter()).setCenterAndWidth(1500.0, 500.0); + filter().enable(); + USBDEBUG("set narrow RX DGT filter"); + } }; @@ -227,13 +276,14 @@ class CWMode : public IMode { public: - CWMode(IConfig& c, RigAudio& a): - IMode(c, a) + CWMode(IConfig& c, RigAudio& a, IFilter& f): + IMode(c, a, f) { } virtual void onEntry() { + setWideRxFilter(); audio().unmuteRx(); audio().muteAllTx(); USBDEBUG("CW mode entered"); @@ -257,6 +307,42 @@ class CWMode : public IMode { USBDEBUG("CW mode receiving"); } + + virtual void setWideRxFilter(){ + float st = float(((CWConfig&)config()).sidetone); + float width = 1000.0; + float low = st - (width * 0.5); + if (low < 300.0) { + low = 300.0; + } + ((BPFilter&)filter()).setBand(low, low + width); + filter().enable(); + USBDEBUG("set wide RX CW filter"); + } + + virtual void setMediumRxFilter(){ + float st = float(((CWConfig&)config()).sidetone); + float width = 500.0; + float low = st - (width * 0.5); + if (low < 300.0) { + low = 300.0; + } + ((BPFilter&)filter()).setBand(low, low + width); + filter().enable(); + USBDEBUG("set medium RX CW filter"); + } + + virtual void setNarrowRxFilter(){ + float st = float(((CWConfig&)config()).sidetone); + float width = 250.0; + float low = st - (width * 0.5); + if (low < 300.0) { + low = 300.0; + } + ((BPFilter&)filter()).setBand(low, low + width); + filter().enable(); + USBDEBUG("set narrow RX CW filter"); + } }; //====================================================================== @@ -267,13 +353,14 @@ class TTMode : public IMode { public: - TTMode(IConfig& c, RigAudio& a): - IMode(c, a) + TTMode(IConfig& c, RigAudio& a, IFilter& f): + IMode(c, a, f) { } virtual void onEntry() { + setWideRxFilter(); audio().unmuteRx(); audio().muteAllTx(); USBDEBUG("Test (Two-Tone) mode entered"); @@ -298,6 +385,24 @@ class TTMode : public IMode audio().unmuteRx(); USBDEBUG("Test (Two-Tone) mode receiving"); } + + virtual void setWideRxFilter(){ + ((BPFilter&)filter()).setBand(300.0, 3100.0); + filter().enable(); + USBDEBUG("set wide RX TT filter"); + } + + virtual void setMediumRxFilter(){ + ((BPFilter&)filter()).setBand(500.0, 2900.0); + filter().enable(); + USBDEBUG("set medium RX TT filter"); + } + + virtual void setNarrowRxFilter(){ + ((BPFilter&)filter()).setBand(700.0, 2500.0); + filter().enable(); + USBDEBUG("set narrow RX TT filter"); + } }; #endif diff --git a/ubitx_iop/audio.h b/ubitx_iop/audio.h index e26b811..dadb7d3 100644 --- a/ubitx_iop/audio.h +++ b/ubitx_iop/audio.h @@ -49,18 +49,27 @@ class RigAudio //====================================================================== -class BPFilter { +class IFilter { + public: + virtual ~IFilter() {} + virtual void enable() = 0; + virtual void disable()= 0; +}; + +class BPFilter : public IFilter { public: - BPFilter(double f1, double f2, bool use_center, short int window, short int coeff); + BPFilter(double f1, double f2, bool use_center, short int window=-1, short int coeff=-1); + void init(AudioFilterFIR* filter=NULL, short* coefficients=NULL); void setFreqLo(double f); void setFreqHi(double f); void setBand(double f1, double f2); void setCenter(double c); void setWidth(double w); void setCenterAndWidth(double c, double w); - void update(AudioFilterFIR* filter, short* coefficients); + virtual void enable(); + virtual void disable(); private: @@ -70,8 +79,8 @@ class BPFilter { short int _coeff; float _recovery; // recovery amplifier value - static AudioFilterFIR* _filter; // = &filterRX; - static short _coefficients[]; + AudioFilterFIR* _filter; // = &filterRX; + short* _coefficients; }; //====================================================================== diff --git a/ubitx_iop/audio.ino b/ubitx_iop/audio.ino index 13d8fb2..ce6fbfd 100644 --- a/ubitx_iop/audio.ino +++ b/ubitx_iop/audio.ino @@ -13,7 +13,7 @@ #include "audio.h" #include "tx_audio_proc.h" -short firActive[NUM_COEFFICIENTS]; +//short firActive[NUM_COEFFICIENTS]; #define RX_RIG_IN 0 #define RX_USB_IN 1 @@ -97,6 +97,15 @@ void RigAudio::init() const { USBDEBUG("audio initialization started"); audioCtrl.enable(); + audioCtrl.adcHighPassFilterEnable(); // default + audioCtrl.dacVolume(1.0); // default + audioCtrl.dacVolumeRampDisable(); // not default; just trying to cull out culprits for my high freq hiss + audioCtrl.audioProcessorDisable(); + audioCtrl.autoVolumeDisable(); + audioCtrl.surroundSoundDisable(); + audioCtrl.enhanceBassDisable(); + audioCtrl.eqSelect(FLAT_FREQUENCY); // eventually, use this to smooth out the normal uBITX passband + audioCtrl.muteHeadphone(); // not using the headphone output audioCtrl.volume(0.0); // not using the headphone output audioCtrl.inputSelect(AUDIO_INPUT_LINEIN); // required for RX audio @@ -133,8 +142,8 @@ void RigAudio::init() const { sine1.amplitude(0); sine2.amplitude(0); - audioFilter(firActive, NUM_COEFFICIENTS, ID_BANDPASS, W_HAMMING, 300.0, 3100.0); // 2.8 kHz filter - filterRX.begin(firActive, NUM_COEFFICIENTS); + //audioFilter(firActive, NUM_COEFFICIENTS, ID_BANDPASS, W_HAMMING, 300.0, 3100.0); // 2.8 kHz filter + //filterRX.begin(firActive, NUM_COEFFICIENTS); filterAmp.gain(1.0); // for now, just pass through the compressor @@ -257,9 +266,17 @@ TxOutput audioTxOutput; //====================================================================== -BPFilter::BPFilter(double f1, double f2, bool use_center=false, short int window=W_HAMMING, short int coeff=NUM_COEFFICIENTS): +short _internal_coefficients[NUM_COEFFICIENTS]; + +BPFilter::BPFilter(double f1, double f2, bool use_center=false, short int window, short int coeff): _window(window), _coeff(coeff) { + if (window == -1) { + _window = W_HAMMING; + } + if (coeff == -1) { + _coeff = NUM_COEFFICIENTS; + } if (use_center) { // treat f1 as center frequency, f2 as filter width _freq_lo = f1 - (0.5 * f2); _freq_hi = f1 + (0.5 * f2); @@ -269,14 +286,28 @@ _window(window), _coeff(coeff) } } +void BPFilter::init(AudioFilterFIR* filter, short* coefficients) { + if (filter == NULL) { + _filter = &filterRX; + } else { + _filter = filter; + } + if (coefficients == NULL) { + _coefficients = _internal_coefficients; + } else { + _coefficients = coefficients; + } + //audioFilter(coefficients, NUM_COEFFICIENTS, ID_BANDPASS, _window, _freq_lo, _freq_hi); + //filter->begin(coefficients, NUM_COEFFICIENTS); +} + void BPFilter::setFreqLo(double f) { _freq_lo = f; } void BPFilter::setFreqHi(double f) { _freq_hi = f; } void BPFilter::setBand(double f1, double f2) { _freq_lo = f1; - _freq_hi = f2; - + _freq_hi = f2; } void BPFilter::setCenter(double c) { @@ -294,19 +325,14 @@ void BPFilter::setCenterAndWidth(double c, double w) { _freq_hi = c + (0.5 * w); } -void BPFilter::update(AudioFilterFIR* filter=NULL, short* coefficients=NULL) { - if (filter == NULL) { - filter = _filter; - } - if (coefficients == NULL) { - coefficients = _coefficients; - } - audioFilter(coefficients, NUM_COEFFICIENTS, ID_BANDPASS, _window, _freq_lo, _freq_hi); - filter->begin(coefficients, NUM_COEFFICIENTS); +void BPFilter::enable() { + audioFilter(_coefficients, NUM_COEFFICIENTS, ID_BANDPASS, _window, _freq_lo, _freq_hi); + _filter->begin(_coefficients, NUM_COEFFICIENTS); } -AudioFilterFIR* BPFilter::_filter = &filterRX; -short BPFilter::_coefficients[NUM_COEFFICIENTS]; +void BPFilter::disable() { + _filter->begin(FIR_PASSTHRU, NUM_COEFFICIENTS); +} //====================================================================== /* diff --git a/ubitx_iop/config.h b/ubitx_iop/config.h index 4eeae57..08f119a 100644 --- a/ubitx_iop/config.h +++ b/ubitx_iop/config.h @@ -30,9 +30,9 @@ class AudioConfig { //-------------------------------------------------------------------- // rig-in parameters (RX) - uint8_t rxRigInLevel = 5; + uint8_t rxRigInLevel = 8; //5; float rxRigInVol = 1.0; //0.7; - float rxRigInCal = 1.0; + float rxRigInCal = 8.0; //1.0; // USB-in parameters (RX) - debug/monitor use only bool rxUSBInEnable = false; float rxUSBInVol = 1.0; @@ -147,7 +147,8 @@ class RigConfig { TTConfig ttu{RX_FILTER_WIDE}; // General rig configuration entries. - RigMode mode = RIG_MODE_LSB; + RigMode numModes = NUM_RIG_MODES; + RigMode startMode = RIG_MODE_LSB; }; extern RigConfig rigConfig; diff --git a/ubitx_iop/rig.h b/ubitx_iop/rig.h index 305757c..f9662d8 100644 --- a/ubitx_iop/rig.h +++ b/ubitx_iop/rig.h @@ -22,17 +22,17 @@ class Rig { Rig(RigConfig& c, RigAudio& a): _config(c), _audio(a) { - _modes = new IMode*[NUM_RIG_MODES]; - _modesLen = NUM_RIG_MODES; - _modesIndex = c.mode; - _modes[RIG_MODE_LSB] = new SSBMode(c.lsb, a); + _modes = new IMode*[c.numModes]; + _modesLen = c.numModes; + _modesIndex = c.startMode; +/* _modes[RIG_MODE_LSB] = new SSBMode(c.lsb, a); _modes[RIG_MODE_USB] = new SSBMode(c.usb, a); _modes[RIG_MODE_CWL] = new CWMode(c.cwl, a); _modes[RIG_MODE_CWU] = new CWMode(c.cwu, a); _modes[RIG_MODE_DGL] = new DGTMode(c.dgl, a); _modes[RIG_MODE_DGU] = new DGTMode(c.dgu, a); _modes[RIG_MODE_TTL] = new TTMode(c.ttl, a); - _modes[RIG_MODE_TTU] = new TTMode(c.ttu, a); + _modes[RIG_MODE_TTU] = new TTMode(c.ttu, a);*/ /* _rxFilters = new (IFilter*)[NUM_RX_FILTERS]; _rxFiltersLen = NUM_RX_FILTERS; @@ -45,7 +45,7 @@ class Rig { ~Rig() { - for (int i = 0; i < _modesLen; i++) { + for (unsigned i = 0; i < _modesLen; i++) { delete _modes[i]; } delete _modes; @@ -67,14 +67,25 @@ class Rig { inline bool isTTMode() const { return (_modesIndex == RIG_MODE_TTU || _modesIndex == RIG_MODE_TTL); } inline bool isTTUMode() const { return (_modesIndex == RIG_MODE_TTU); } inline bool isTTLMode() const { return (_modesIndex == RIG_MODE_TTL); } + + // Assign a pointer to a mode object. Returns true if successful, false otherwise. + bool addNewMode(RigMode i, IMode* mode) { + if (i > _modesLen) { + return false; + } else { + _modes[i] = mode; + return true; + } + } // Returns a pointer to the current mode. inline IMode* mode() const { return _modes[_modesIndex]; } + // Returns the array index of the current mode. inline RigMode modeNum() const { - return RigMode(_modesIndex); + return _modesIndex; } /* // Returns a pointer to the specified mode. @@ -89,7 +100,7 @@ class Rig { mode()->exit(); // NOTE: This could currently occur during TX, which is NOT desirable. // select the new mode - _modesIndex = i % _modesLen; // do I need the modulo? + _modesIndex = RigMode(i % _modesLen); //enter the new mode mode()->enter(); @@ -107,11 +118,10 @@ class Rig { // select the new mode if (prev) { - _modesIndex--; + _modesIndex = RigMode((_modesIndex > 0 ? _modesIndex - 1 : _modesLen - 1)); } else { - _modesIndex++; + _modesIndex = RigMode((_modesIndex + 1) % _modesLen); } - _modesIndex %= _modesLen; // enter the new mode mode()->enter(); @@ -144,6 +154,19 @@ class Rig { //-------------------------------------------------------------------- // RX filter control. //-------------------------------------------------------------------- + + inline void setWideRxFilter() { + mode()->setWideRxFilter(); + } + + inline void setMediumRxFilter() { + mode()->setMediumRxFilter(); + } + + inline void setNarrowRxFilter() { + mode()->setNarrowRxFilter(); + } + /* // Returns a pointer to the current RX filter. IFilter* rxFilter() { @@ -247,8 +270,8 @@ class Rig { RigAudio& _audio; IMode** _modes; - uint8_t _modesLen; - uint8_t _modesIndex; + RigMode _modesLen; + RigMode _modesIndex; /* IFilter** _rxFilters; diff --git a/ubitx_iop/ubitx_iop.h b/ubitx_iop/ubitx_iop.h index efbd3ce..4b02f11 100644 --- a/ubitx_iop/ubitx_iop.h +++ b/ubitx_iop/ubitx_iop.h @@ -14,7 +14,7 @@ #define PTT_KEY_OUT_PIN 2 // comment this out to disable debugging code -#define DEBUG +//#define DEBUG #if defined(DEBUG) #define USBDEBUG(x) USBSERIAL.print("IOP: "); USBSERIAL.println(x); diff --git a/ubitx_iop/ubitx_iop.ino b/ubitx_iop/ubitx_iop.ino index 8e3ddba..49d323a 100644 --- a/ubitx_iop/ubitx_iop.ino +++ b/ubitx_iop/ubitx_iop.ino @@ -16,6 +16,17 @@ RigConfig rigConfig; RigAudio rigAudio{rigConfig.audio}; Rig rig{rigConfig, rigAudio}; +BPFilter rxFilter{300, 3100, false}; + +SSBMode lsbMode{rigConfig.lsb, rigAudio, rxFilter}; +SSBMode usbMode{rigConfig.usb, rigAudio, rxFilter}; +CWMode cwlMode{rigConfig.cwl, rigAudio, rxFilter}; +CWMode cwuMode{rigConfig.cwu, rigAudio, rxFilter}; +DGTMode dglMode{rigConfig.dgl, rigAudio, rxFilter}; +DGTMode dguMode{rigConfig.dgu, rigAudio, rxFilter}; +TTMode ttlMode{rigConfig.ttl, rigAudio, rxFilter}; +TTMode ttuMode{rigConfig.ttu, rigAudio, rxFilter}; + CATSwitch catPTT; //MicSwitch micPTTHelper; GPIOSwitch micPTT(true, MIC_PTT_PIN); @@ -35,7 +46,20 @@ void setup() { initCAT(38400, SERIAL_8N1); USBDEBUG("setup started"); - AudioMemory(20); // NOTE: Need to fine tune this. Have had errors due to this being too low. + AudioMemory(16); // NOTE: Need to fine tune this. Have had errors due to this being too low. + + // initialize the filter(s) + rxFilter.init(); + + // adding all of the modes to the rig + rig.addNewMode(RIG_MODE_LSB, &lsbMode); + rig.addNewMode(RIG_MODE_USB, &usbMode); + rig.addNewMode(RIG_MODE_CWL, &cwlMode); + rig.addNewMode(RIG_MODE_CWU, &cwuMode); + rig.addNewMode(RIG_MODE_DGL, &dglMode); + rig.addNewMode(RIG_MODE_DGU, &dguMode); + rig.addNewMode(RIG_MODE_TTL, &ttlMode); + rig.addNewMode(RIG_MODE_TTU, &ttuMode); initKeyLine(); rigAudio.init();