ubitx-v5x/TeensyDSP/DSP.cpp

361 lines
9.9 KiB
C++

//======================================================================
// DSP.cpp
//======================================================================
#include "DSP.h"
#include <i2c_t3.h>
//#include <Wire.h>
//#include <SPI.h>
//#include <SD.h>
//#include <SerialFlash.h>
#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=153,341
AudioInputI2S lineIn; //xy=161,233
AudioAnalyzeRMS usbInRMS_R; //xy=276,431
AudioAnalyzeRMS usbInRMS_L; //xy=335,392
AudioAnalyzeRMS lineInRMS; //xy=387,273
AudioMixer4 rxAudio; //xy=418,147
AudioMixer4 txAudio; //xy=422,335
AudioFilterFIR rxFilter; //xy=583,139
AudioAmplifier usbOutAmp; //xy=748,135
AudioAmplifier lineOutAmp; //xy=749,198
AudioAmplifier usbBypassAmp; //xy=756,261
AudioOutputI2S lineOut; //xy=966,330
AudioOutputUSB usbOut; //xy=968,291
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, usbBypassAmp);
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);
AudioConnection patchCord14(usbBypassAmp, 0, usbOut, 1);
AudioControlSGTL5000 audioCtrl; //xy=427,476
// 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(1.0);
// USB Output (RX)
usbOutAmp.gain(1.0);
usbBypassAmp.gain(1.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;
// Setup the RX Filter.
setRxFilter(300, 3000);
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 float minRxFilterLo = MIN_RX_FILTER_LO;
const float maxRxFilterHi = MAX_RX_FILTER_HI;
const float minRxFilterWidth = MIN_RX_FILTER_WIDTH;
const float maxRxFilterWidth = MAX_RX_FILTER_WIDTH;
const float minRxFilterCenter = MIN_RX_FILTER_CENTER;
const float 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(float lo, float 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(float lo) {
if (lo > state.rxFilterHi - minRxFilterWidth) {
lo = state.rxFilterHi - minRxFilterWidth;
}
if (lo < minRxFilterLo) {
lo = minRxFilterLo;
}
state.rxFilterLo = lo;
updateRxFilter();
}
void UBitxDSP::setRxFilterHi(float hi) {
if (hi < state.rxFilterLo + minRxFilterWidth) {
hi = state.rxFilterLo + minRxFilterWidth;
}
if (hi > maxRxFilterHi) {
hi = maxRxFilterHi;
}
state.rxFilterHi = hi;
updateRxFilter();
}
void UBitxDSP::setRxFilterWidth(float width) {
if (width < minRxFilterWidth) {
width = minRxFilterWidth;
} else if (width > maxRxFilterWidth) {
width = maxRxFilterWidth;
}
float center = (state.rxFilterHi + state.rxFilterLo) / 2;
float lo = center - (width / 2);
float hi = center + (width / 2);
setRxFilter(lo, hi);
}
void UBitxDSP::setRxFilterCenter(float center) {
if (center < minRxFilterCenter) {
center = minRxFilterCenter;
} else if (center > maxRxFilterCenter) {
center = maxRxFilterCenter;
}
float width = state.rxFilterHi - state.rxFilterLo;
float lo = center - (width / 2);
float 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
//======================================================================