//====================================================================== // DSP.cpp //====================================================================== #include "DSP.h" #include //#include //#include //#include //#include #define RX_AUDIO_CH 0 const int txMicInChannel = TX_MIC_IN_CH; const int txLineInChannel = TX_LINE_IN_CH; const int txUSBInChannel = TX_USB_IN_CH; const int txNumChannels = TX_NUM_CHANNELS; const int txLineInVOX = TX_LINE_IN_VOX; const int txUSBInLVOX = TX_USB_IN_L_VOX; const int txUSBInRVOX = TX_USB_IN_R_VOX; const int txNumVOX = TX_NUM_VOX; UBitxDSP DSP; //static struct { // GUItool: begin automatically generated code AudioInputUSB usbIn; //xy=227,290 AudioInputI2S lineIn; //xy=235,182 AudioAnalyzeRMS usbInRMS_R; //xy=350,380 AudioAnalyzeRMS usbInRMS_L; //xy=409,341 AudioAnalyzeRMS lineInRMS; //xy=461,222 AudioMixer4 rxAudio; //xy=492,96 AudioMixer4 txAudio; //xy=496,284 AudioFilterFIR rxFilter; //xy=657,88 AudioAmplifier usbOutAmp; //xy=822,84 AudioAmplifier lineOutAmp; //xy=823,147 AudioOutputI2S lineOut; //xy=1040,279 AudioOutputUSB usbOut; //xy=1042,240 AudioConnection patchCord1(usbIn, 0, txAudio, 1); AudioConnection patchCord2(usbIn, 0, usbInRMS_L, 0); AudioConnection patchCord3(usbIn, 1, usbInRMS_R, 0); AudioConnection patchCord4(lineIn, 0, rxAudio, 0); AudioConnection patchCord5(lineIn, 1, txAudio, 0); AudioConnection patchCord6(lineIn, 1, lineInRMS, 0); AudioConnection patchCord7(rxAudio, rxFilter); AudioConnection patchCord8(rxAudio, 0, usbOut, 1); AudioConnection patchCord9(txAudio, 0, lineOut, 1); AudioConnection patchCord10(rxFilter, usbOutAmp); AudioConnection patchCord11(rxFilter, lineOutAmp); AudioConnection patchCord12(usbOutAmp, 0, usbOut, 0); AudioConnection patchCord13(lineOutAmp, 0, lineOut, 0); AudioControlSGTL5000 audioCtrl; //xy=501,425 // GUItool: end automatically generated code //} audio; UBitxDSP::UBitxDSP() { voxRMS[txLineInVOX] = &lineInRMS; voxRMS[txUSBInLVOX] = &usbInRMS_L; voxRMS[txUSBInRVOX] = &usbInRMS_R; } void UBitxDSP::begin() { AudioMemory(16); audioCtrl.enable(); audioCtrl.volume(0.0); // headphone volume... audioCtrl.muteHeadphone(); // ...not used by UBitxDSP for (int i = 0; i < 4; i++) { if (i == RX_AUDIO_CH) rxAudio.gain(i, 1.0); else rxAudio.gain(i, 0.0); } for (int i = 0; i < 4; i++) { txAudio.gain(i, 0.0); } // SETUP THE AUDIO INPUTS // Rig (Line) Input (RX) audioCtrl.inputSelect(AUDIO_INPUT_LINEIN); audioCtrl.unmuteLineout(); audioCtrl.lineInLevel(9, 5); // RX, TX audioCtrl.lineOutLevel(29, 31); //RX, TX // Mic Input (TX) audioCtrl.micGain(0); // TODO: set value // Line Input (TX) // USB Input (TX) // SETUP THE AUDIO OUTPUTS // Line Output (RX) lineOutAmp.gain(0.0); // USB Output (RX) usbOutAmp.gain(0.0); // Rig (Line) Output (TX) // Default to RX. rx(); // Setup the VOX - clean this up state.voxActive[TX_LINE_IN_VOX] = false; state.voxThresh[TX_LINE_IN_VOX] = TX_LINE_IN_VOX_THRESH; state.voxDelay[TX_LINE_IN_VOX] = TX_LINE_IN_VOX_DELAY; state.voxTimeout[TX_LINE_IN_VOX] = 0; state.voxActive[TX_USB_IN_L_VOX] = false; state.voxThresh[TX_USB_IN_L_VOX] = TX_USB_IN_L_VOX_THRESH; state.voxDelay[TX_USB_IN_L_VOX] = TX_USB_IN_L_VOX_DELAY; state.voxTimeout[TX_USB_IN_L_VOX] = 0; state.voxActive[TX_USB_IN_R_VOX] = false; state.voxThresh[TX_USB_IN_R_VOX] = TX_USB_IN_R_VOX_THRESH; state.voxDelay[TX_USB_IN_R_VOX] = TX_USB_IN_R_VOX_DELAY; state.voxTimeout[TX_USB_IN_R_VOX] = 0; sinceLastUpdate = 0; } void UBitxDSP::update() { // Only going to adjust the USB volume periodically. if (sinceLastUpdate > DSP_MILLIS_PER_UPDATE) { float vol = usbIn.volume(); setTxInputLevel(txUSBInChannel, vol); sinceLastUpdate = 0; } // Update the VOX switches. // TODO: Move the enable logic in here, so we don't process unnecessarily. for (int i = 0; i < txNumVOX; i++) { if (voxRMS[i]->available()) { float lvl = voxRMS[i]->read(); if (lvl > state.voxThresh[i]) { state.voxTimeout[i] = millis() + state.voxDelay[i]; state.voxActive[i] = true; } } if (millis() > state.voxTimeout[i]) { state.voxActive[i] = false; } } } void UBitxDSP::end() { } void UBitxDSP::rx() { // mute all tx audio audioCtrl.micGain(0); for (int i = 0; i < 4; i++) { txAudio.gain(i, 0.0); } // select line in for rx audioCtrl.inputSelect(AUDIO_INPUT_LINEIN); // restore rx audio rxAudio.gain(RX_AUDIO_CH, 1.0); // restore the RX audio } void UBitxDSP::txMicIn() { // mute the rx audio rxAudio.gain(RX_AUDIO_CH, 0.0); // restore the tx mic audio audioCtrl.inputSelect(AUDIO_INPUT_MIC); audioCtrl.micGain(12); for (int i = 0; i < 4; i++) { if (i == TX_MIC_IN_CH) txAudio.gain(i, 0.1); else txAudio.gain(i, 0.0); } } void UBitxDSP::txLineIn() { // mute the rx audio rxAudio.gain(RX_AUDIO_CH, 0.0); // restore the tx line in audio audioCtrl.inputSelect(AUDIO_INPUT_LINEIN); for (int i = 0; i < 4; i++) { if (i == TX_LINE_IN_CH) txAudio.gain(i, 0.1); else txAudio.gain(i, 0.0); } } void UBitxDSP::txUSBIn() { // mute the rx audio rxAudio.gain(RX_AUDIO_CH, 0.0); // restore the tx usb in audio audioCtrl.inputSelect(AUDIO_INPUT_LINEIN); for (int i = 0; i < 4; i++) { if (i == TX_USB_IN_CH) txAudio.gain(i, 0.1); else txAudio.gain(i, 0.0); } } /**********************************************************************/ // RX filter settings const int minRxFilterLo = MIN_RX_FILTER_LO; const int maxRxFilterHi = MAX_RX_FILTER_HI; const int minRxFilterWidth = MIN_RX_FILTER_WIDTH; const int maxRxFilterWidth = MAX_RX_FILTER_WIDTH; const int minRxFilterCenter = MIN_RX_FILTER_CENTER; const int maxRxFilterCenter = MAX_RX_FILTER_CENTER; /*! * @brief Bypass the RX audio filter. */ void UBitxDSP::bypassRxFilter() { rxFilter.begin(FIR_PASSTHRU, NUM_COEFFICIENTS); } /*! * @brief Update the RX audio filter using the currently set low and * high frequencies. This is called by each of the public * filter methods to update the filter with new frequencies. */ void UBitxDSP::updateRxFilter() { audioFilter(coefficients, NUM_COEFFICIENTS, ID_BANDPASS, W_HAMMING, double(state.rxFilterLo), double(state.rxFilterHi)); rxFilter.begin(coefficients, NUM_COEFFICIENTS); } void UBitxDSP::setRxFilter(int lo, int hi) { if (hi < lo + minRxFilterWidth) { hi = lo + minRxFilterWidth; } if (hi > maxRxFilterHi) { hi = maxRxFilterHi; } if (lo > hi - minRxFilterWidth) { lo = hi - minRxFilterWidth; } if (lo < minRxFilterLo) { lo = minRxFilterLo; } state.rxFilterHi = hi; state.rxFilterLo = lo; updateRxFilter(); } void UBitxDSP::setRxFilterLo(int lo) { if (lo > state.rxFilterHi - minRxFilterWidth) { lo = state.rxFilterHi - minRxFilterWidth; } if (lo < minRxFilterLo) { lo = minRxFilterLo; } state.rxFilterLo = lo; updateRxFilter(); } void UBitxDSP::setRxFilterHi(int hi) { if (hi < state.rxFilterLo + minRxFilterWidth) { hi = state.rxFilterLo + minRxFilterWidth; } if (hi > maxRxFilterHi) { hi = maxRxFilterHi; } state.rxFilterHi = hi; updateRxFilter(); } void UBitxDSP::setRxFilterWidth(int width) { if (width < minRxFilterWidth) { width = minRxFilterWidth; } else if (width > maxRxFilterWidth) { width = maxRxFilterWidth; } int center = (state.rxFilterHi + state.rxFilterLo) / 2; int lo = center - (width / 2); int hi = center + (width / 2); setRxFilter(lo, hi); } void UBitxDSP::setRxFilterCenter(int center) { if (center < minRxFilterCenter) { center = minRxFilterCenter; } else if (center > maxRxFilterCenter) { center = maxRxFilterCenter; } int width = state.rxFilterHi - state.rxFilterLo; int lo = center - (width / 2); int hi = center + (width / 2); setRxFilter(lo, hi); } /**********************************************************************/ // TX audio input settings void UBitxDSP::setTxInputLevel(int ch, float lvl) { if ((ch > -1) && (ch < txNumChannels)) { state.txInLvl[ch] = lvl; float vol = lvl * float(state.txInEnable[ch] * state.txInTx[ch]); txAudio.gain(ch, vol); } } void UBitxDSP::enableTxInput(int ch) { if ((ch > -1) && (ch < txNumChannels)) { state.txInEnable[ch] = 1; float vol = state.txInLvl[ch] * float(state.txInEnable[ch] * state.txInTx[ch]); txAudio.gain(ch, vol); } } void UBitxDSP::disableTxInput(int ch) { if ((ch > -1) && (ch < txNumChannels)) { state.txInEnable[ch] = 0; float vol = state.txInLvl[ch] * float(state.txInEnable[ch] * state.txInTx[ch]); txAudio.gain(ch, vol); } } void UBitxDSP::startTxInput(int ch) { if ((ch > -1) && (ch < txNumChannels)) { state.txInTx[ch] = 1; float vol = state.txInLvl[ch] * float(state.txInEnable[ch] * state.txInTx[ch]); txAudio.gain(ch, vol); } } void UBitxDSP::stopTxInput(int ch) { if ((ch > -1) && (ch < txNumChannels)) { state.txInTx[ch] = 0; float vol = state.txInLvl[ch] * float(state.txInEnable[ch] * state.txInTx[ch]); txAudio.gain(ch, vol); } } // VOX settings bool UBitxDSP::isVoxActive(int vox) { if ((vox > -1) && (vox < 3)) { return state.voxActive[vox]; } else { return false; } } //====================================================================== // EOF //======================================================================