diff --git a/ubitx_iop/audio.h b/ubitx_iop/audio.h index 7b6441e..be26d78 100644 --- a/ubitx_iop/audio.h +++ b/ubitx_iop/audio.h @@ -5,6 +5,7 @@ #ifndef __iop_audio_h__ #define __iop_audio_h__ +#include #include "config.h" enum RxInput { @@ -30,6 +31,35 @@ enum TxOutput { TX_USB_OUT = 1, }; +//====================================================================== + +class BPFilter { + + public: + + BPFilter(double f1, double f2, bool use_center, short int window, short int coeff); + 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); + + private: + + double _freq_lo; + double _freq_hi; + short int _window; + short int _coeff; + float _recovery; // recovery amplifier value + + static AudioFilterFIR* _filter; // = &filterRX; + static short _coefficients[]; +}; + +//====================================================================== + void audioInit(); void audioSelectTxInput(TxInput); void audioTransmit(); diff --git a/ubitx_iop/audio.ino b/ubitx_iop/audio.ino index dfb40ff..d6aab7e 100644 --- a/ubitx_iop/audio.ino +++ b/ubitx_iop/audio.ino @@ -3,7 +3,10 @@ //====================================================================== #include +#include + #include "audio.h" +#include "tx_audio_proc.h" extern IOPConfig iopConfig; @@ -19,51 +22,57 @@ extern IOPConfig iopConfig; #include // GUItool: begin automatically generated code -AudioSynthWaveformSine sideTone; //xy=204,221 -AudioInputI2S inLine; //xy=208,170 -AudioSynthWaveformSine sine2; //xy=207,423 -AudioInputUSB inUSB; //xy=208,279 -AudioSynthWaveformSine sine1; //xy=208,382 -AudioAnalyzeRMS rmsRX; //xy=383,47 -AudioAnalyzePeak peakRX; //xy=387,98 +AudioInputI2S inLine; //xy=134,131 +AudioInputUSB inUSB; //xy=134,303 +AudioSynthWaveformSine sideTone; //xy=136,214 +AudioSynthWaveformSine sine2; //xy=323,482 +AudioSynthWaveformSine sine1; //xy=324,428 +AudioAnalyzeRMS rmsRX; //xy=362,20 +AudioAnalyzePeak peakRX; //xy=362,65 +AudioEffectCompressor compTX; //xy=383,256 +AudioAnalyzeRMS compRMS; //xy=388,224 AudioMixer4 mixRX; //xy=444,163 -AudioMixer4 mixTX; //xy=444,279 +AudioAmplifier compAmp; //xy=514,257 AudioFilterFIR filterRX; //xy=577,161 +AudioMixer4 mixTX; //xy=652,321 AudioAmplifier filterAmp; //xy=700,160 +AudioAnalyzeRMS rmsTX; //xy=841,449 +AudioAnalyzePeak peakTX; //xy=843,393 AudioAmplifier calRxUSB; //xy=873,172 AudioAmplifier calRxSpkr; //xy=877,62 AudioAmplifier calRxLine; //xy=880,119 AudioAmplifier calTxLine; //xy=892,255 AudioAmplifier calTxUSB; //xy=893,312 -AudioAnalyzePeak peakTX; //xy=908,385 -AudioAnalyzeRMS rmsTX; //xy=922,440 AudioOutputAnalog outSpkr; //xy=1053,62 -AudioOutputUSB outUSB; //xy=1062,262 -AudioOutputI2S outLine; //xy=1065,211 -AudioConnection patchCord1(sideTone, 0, mixRX, 2); -AudioConnection patchCord2(inLine, 0, rmsRX, 0); -AudioConnection patchCord3(inLine, 0, peakRX, 0); -AudioConnection patchCord4(inLine, 0, mixRX, 0); -AudioConnection patchCord5(inLine, 1, mixTX, 0); -AudioConnection patchCord6(sine2, 0, mixTX, 3); -//AudioConnection patchCord7(inUSB, 0, mixRX, 1); -AudioConnection patchCord8(inUSB, 1, mixTX, 1); -AudioConnection patchCord9(sine1, 0, mixTX, 2); -AudioConnection patchCord10(mixRX, filterRX); -AudioConnection patchCord11(mixTX, calTxLine); -AudioConnection patchCord12(mixTX, calTxUSB); -AudioConnection patchCord13(mixTX, peakTX); -AudioConnection patchCord14(mixTX, rmsTX); -AudioConnection patchCord15(filterRX, filterAmp); -AudioConnection patchCord16(filterAmp, calRxSpkr); -AudioConnection patchCord17(filterAmp, calRxLine); -AudioConnection patchCord18(filterAmp, calRxUSB); -AudioConnection patchCord19(calRxUSB, 0, outUSB, 0); -AudioConnection patchCord20(calRxSpkr, outSpkr); -AudioConnection patchCord21(calRxLine, 0, outLine, 0); -AudioConnection patchCord22(calTxLine, 0, outLine, 1); -//AudioConnection patchCord23(calTxUSB, 0, outUSB, 1); -AudioControlSGTL5000 audioCtrl; //xy=391,443 +AudioOutputUSB outUSB; //xy=1066,307 +AudioOutputI2S outLine; //xy=1070,192 +AudioConnection patchCord1(inLine, 0, rmsRX, 0); +AudioConnection patchCord2(inLine, 0, peakRX, 0); +AudioConnection patchCord3(inLine, 0, mixRX, 0); +AudioConnection patchCord4(inLine, 1, compTX, 0); +AudioConnection patchCord5(inLine, 1, compRMS, 0); +AudioConnection patchCord6(inUSB, 0, mixRX, 1); +AudioConnection patchCord7(inUSB, 1, mixTX, 1); +AudioConnection patchCord8(sideTone, 0, mixRX, 2); +AudioConnection patchCord9(sine2, 0, mixTX, 3); +AudioConnection patchCord10(sine1, 0, mixTX, 2); +AudioConnection patchCord11(compTX, compAmp); +AudioConnection patchCord12(mixRX, filterRX); +AudioConnection patchCord13(compAmp, 0, mixTX, 0); +AudioConnection patchCord14(filterRX, filterAmp); +AudioConnection patchCord15(mixTX, calTxLine); +AudioConnection patchCord16(mixTX, calTxUSB); +AudioConnection patchCord17(mixTX, peakTX); +AudioConnection patchCord18(mixTX, rmsTX); +AudioConnection patchCord19(filterAmp, calRxSpkr); +AudioConnection patchCord20(filterAmp, calRxLine); +AudioConnection patchCord21(filterAmp, calRxUSB); +AudioConnection patchCord22(calRxUSB, 0, outUSB, 0); +AudioConnection patchCord23(calRxSpkr, outSpkr); +AudioConnection patchCord24(calRxLine, 0, outLine, 0); +AudioConnection patchCord25(calTxLine, 0, outLine, 1); +AudioConnection patchCord26(calTxUSB, 0, outUSB, 1); +AudioControlSGTL5000 audioCtrl; //xy=648,517 // GUItool: end automatically generated code RxInput audioRxInput; @@ -71,7 +80,95 @@ RxOutput audioRxOutput; TxInput audioTxInput; TxOutput audioTxOutput; -short firActive[NUM_COEFFICIENTS]; +//====================================================================== + +BPFilter::BPFilter(double f1, double f2, bool use_center=false, short int window=W_HAMMING, short int coeff=NUM_COEFFICIENTS): +_window(window), _coeff(coeff) +{ + if (use_center) { // treat f1 as center frequency, f2 as filter width + _freq_lo = f1 - (0.5 * f2); + _freq_hi = f1 + (0.5 * f2); + } else { + _freq_lo = f1; + _freq_hi = f2; + } +} + +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; + +} + +void BPFilter::setCenter(double c) { + double w = _freq_hi - _freq_lo; + setCenterAndWidth(c, w); +} + +void BPFilter::setWidth(double w) { + double c = (_freq_lo + _freq_hi) * 0.5; + setCenterAndWidth(c, w); +} + +void BPFilter::setCenterAndWidth(double c, double w) { + _freq_lo = c - (0.5 * 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); +} + +static AudioFilterFIR* BPFilter::_filter = &filterRX; +static short BPFilter::_coefficients[NUM_COEFFICIENTS]; + +//====================================================================== + +enum FilterWidth { + FILTER_WIDE = 0, + FILTER_NORMAL, + FILTER_NARROW, + NUM_FILTER_WIDTHS +}; + +// array based on mode right now +BPFilter *rxFilter[NUM_RIG_MODES][NUM_FILTER_WIDTHS]; + +//====================================================================== + +void audioSetupFilters() +{ + rxFilter[RIG_MODE_SSB][FILTER_WIDE] = new BPFilter( 300.0, 3100.0); + rxFilter[RIG_MODE_SSB][FILTER_NORMAL] = new BPFilter( 500.0, 2900.0); + rxFilter[RIG_MODE_SSB][FILTER_NARROW] = new BPFilter( 700.0, 2500.0); + + // Need to make the NARROW filter center frequency configurable. + rxFilter[RIG_MODE_DIGI][FILTER_WIDE] = new BPFilter( 300.0, 3100.0); + rxFilter[RIG_MODE_DIGI][FILTER_NORMAL] = new BPFilter( 500.0, 2900.0); + rxFilter[RIG_MODE_DIGI][FILTER_NARROW] = new BPFilter(1500.0, 500.0, true); + + // Need to use the sidetone frequency for the NORMAL and NARROW filters. + rxFilter[RIG_MODE_CW][FILTER_WIDE] = new BPFilter( 300.0, 1300.0); + rxFilter[RIG_MODE_CW][FILTER_NORMAL] = new BPFilter( 700.0, 500.0, true); + rxFilter[RIG_MODE_CW][FILTER_NARROW] = new BPFilter( 700.0, 250.0, true); +} + +//====================================================================== + +SpeechCompressor speechCompressor(compTX, compAmp, compRMS); + +//====================================================================== // audioInit() // Setup the audio subsystem. @@ -113,9 +210,14 @@ void audioInit() 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 + //compTX.disable(); + //compAmp.gain(1.0); + speechCompressor.enable(); } inline void updateRxRigIn() @@ -397,6 +499,13 @@ void audioReceive() //====================================================================== +void audioUpdate() +{ + speechCompressor.update(); +} + +//====================================================================== + void audioCalibrate(IOPConfig* c, char cmd, char subcmd, char parm, float value, bool set_value=true) { switch(cmd) { diff --git a/ubitx_iop/ubitx_iop.ino b/ubitx_iop/ubitx_iop.ino index aba2704..0c74b62 100644 --- a/ubitx_iop/ubitx_iop.ino +++ b/ubitx_iop/ubitx_iop.ino @@ -9,7 +9,7 @@ #define BOUNCE_WITH_PROMPT_DETECTION RigMode rigMode = RIG_MODE_SSB; -RxFilter rxFilter = RX_FILTER_NORMAL; +//RxFilter rxFilter = RX_FILTER_NORMAL; IOPConfig iopConfig; #define MIC_PTT_PIN 21 @@ -214,7 +214,7 @@ void setRigMode(RigMode m) // SSB sets the TX audio input to line-in. Note that this will be // automatically overridden by mic-in, if the mic PTT is pressed. audioSelectTxInput(TX_LINE_IN); - audioSSBFilter(); +// audioSSBFilter(); // dspMenu = &ssbMenu; break; @@ -227,14 +227,14 @@ void setRigMode(RigMode m) // the mic PTT line would need to be keyed by the computer rather // than using CAT for PTT control. audioSelectTxInput(TX_USB_IN); - audioDigiFilter(); +// audioDigiFilter(); // dspMenu = &digiMenu; break; case RIG_MODE_CW: // CW just gets the radio off of Mic-In; but it won't use Line-In. audioSelectTxInput(TX_LINE_IN); - audioCWFilter(); +// audioCWFilter(); // dspMenu = &cwMenu; break; } @@ -273,7 +273,7 @@ void setup() { void loop() { // elapsedMillis elapsed = 0; RigMode oldRigMode = rigMode; - RxFilter oldRxFilter = rxFilter; + //RxFilter oldRxFilter = rxFilter; switch(rigMode) { case RIG_MODE_CW: @@ -298,7 +298,7 @@ void loop() { // send current status @ 10 Hz //if (frame10Hz > 100) { - if ((rigMode != oldRigMode) || (rxFilter != oldRxFilter)) { + if ((rigMode != oldRigMode)) { // || (rxFilter != oldRxFilter)) { switch(rigMode) { case RIG_MODE_SSB: sendIOPSSBStatus(iopConfig.ssb); @@ -318,6 +318,7 @@ void loop() { //frame10Hz = 0; } + audioUpdate(); //dspMenu->update(); /*