Updates to the DSP. One issue that needs to be resolved: in order to use the VOX the way it is currently setup, muting of the overall TX chain needs to be at the END, not the beginning; whatever is setup as the default TX audio source, needs to be unmuted even during RX.
This commit is contained in:
parent
962a3ce80f
commit
20b475dace
@ -10,64 +10,59 @@
|
||||
//#include <SD.h>
|
||||
//#include <SerialFlash.h>
|
||||
|
||||
#define RX_AUDIO_CH 0
|
||||
const int rxRigInChannel = RX_RIG_IN_CH;
|
||||
|
||||
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
|
||||
AudioInputUSB usbIn; //xy=161,313
|
||||
AudioInputI2S lineIn; //xy=169,205
|
||||
AudioSynthWaveformSine tone1; //xy=234,386
|
||||
AudioSynthWaveformSine tone2; //xy=234,422
|
||||
AudioMixer4 rxAudio; //xy=426,119
|
||||
AudioMixer4 txAudio; //xy=430,307
|
||||
AudioAnalyzeRMS txVoxLevel; //xy=588,348
|
||||
AudioFilterFIR rxFilter; //xy=591,111
|
||||
AudioAmplifier usbOutAmp; //xy=756,107
|
||||
AudioAmplifier lineOutAmp; //xy=757,170
|
||||
AudioAmplifier usbBypassAmp; //xy=764,233
|
||||
AudioAmplifier txOutAmp; //xy=811,309
|
||||
AudioOutputI2S lineOut; //xy=974,302
|
||||
AudioOutputUSB usbOut; //xy=976,263
|
||||
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 patchCord2(lineIn, 0, rxAudio, 0);
|
||||
AudioConnection patchCord3(lineIn, 1, txAudio, 0);
|
||||
AudioConnection patchCord4(tone1, 0, txAudio, 2);
|
||||
AudioConnection patchCord5(tone2, 0, txAudio, 3);
|
||||
AudioConnection patchCord6(rxAudio, rxFilter);
|
||||
AudioConnection patchCord7(rxAudio, usbBypassAmp);
|
||||
AudioConnection patchCord8(txAudio, txVoxLevel);
|
||||
AudioConnection patchCord9(txAudio, txOutAmp);
|
||||
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
|
||||
AudioConnection patchCord15(txOutAmp, 0, lineOut, 1);
|
||||
AudioControlSGTL5000 audioCtrl; //xy=435,448
|
||||
// GUItool: end automatically generated code
|
||||
|
||||
|
||||
//} audio;
|
||||
|
||||
UBitxDSP::UBitxDSP() {
|
||||
voxRMS[txLineInVOX] = &lineInRMS;
|
||||
voxRMS[txUSBInLVOX] = &usbInRMS_L;
|
||||
voxRMS[txUSBInRVOX] = &usbInRMS_R;
|
||||
}
|
||||
|
||||
void UBitxDSP::begin() {
|
||||
AudioMemory(16);
|
||||
|
||||
// Basic audio setup
|
||||
AudioMemory(16); // TODO: optimize this
|
||||
audioCtrl.enable();
|
||||
audioCtrl.volume(0.0); // headphone volume...
|
||||
audioCtrl.muteHeadphone(); // ...not used by UBitxDSP
|
||||
@ -89,7 +84,7 @@ void UBitxDSP::begin() {
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
audioCtrl.unmuteLineout();
|
||||
audioCtrl.lineInLevel(9, 5); // RX, TX
|
||||
audioCtrl.lineOutLevel(29, 31); //RX, TX
|
||||
audioCtrl.lineOutLevel(29, 31); // RX, TX
|
||||
|
||||
// Mic Input (TX)
|
||||
audioCtrl.micGain(0); // TODO: set value
|
||||
@ -108,23 +103,15 @@ void UBitxDSP::begin() {
|
||||
usbBypassAmp.gain(1.0);
|
||||
|
||||
// Rig (Line) Output (TX)
|
||||
txOutAmp.gain(1.0);
|
||||
|
||||
// Default to RX.
|
||||
muteRxIn();
|
||||
muteTxIn();
|
||||
isTx = true; // so that rx() call works
|
||||
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 VOX - TBD
|
||||
|
||||
// Setup the RX Filter.
|
||||
setRxFilter(300, 3000);
|
||||
@ -136,78 +123,135 @@ void UBitxDSP::update() {
|
||||
// Only going to adjust the USB volume periodically.
|
||||
if (sinceLastUpdate > DSP_MILLIS_PER_UPDATE) {
|
||||
float vol = usbIn.volume();
|
||||
setTxInputLevel(txUSBInChannel, vol);
|
||||
setTxInLevel(TX_USB, 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;
|
||||
if (txVoxLevel.available()) {
|
||||
if (txVoxLevel.read() > state.vox.threshold) {
|
||||
state.vox.timeout = millis() + state.vox.delay;
|
||||
state.vox.active = true;
|
||||
}
|
||||
}
|
||||
if (millis() > state.vox.timeout) {
|
||||
state.vox.active = 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);
|
||||
if (isTx) {
|
||||
muteTxIn();
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
unmuteRxIn(RX_AUDIO);
|
||||
isTx = false;
|
||||
}
|
||||
}
|
||||
|
||||
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::setRxInLevel(RxAudioCh ch, float level) {
|
||||
if (ch < NUM_RX_AUDIO_CH) {
|
||||
state.rx[ch].level = level;
|
||||
rxAudio.gain(ch, state.rx[ch].mute ? 0.0 : state.rx[ch].level);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
void UBitxDSP::muteRxIn() {
|
||||
for (RxAudioCh i = RX_AUDIO; i < NUM_RX_AUDIO_CH; i++) {
|
||||
state.rx[ch].mute = true;
|
||||
rxAudio.gain(ch, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void UBitxDSP::muteRxIn(RxAudioCh ch) {
|
||||
if (ch < NUM_RX_AUDIO_CH) {
|
||||
if (!state.rx[ch].mute) {
|
||||
state.rx[ch].mute = true;
|
||||
rxAudio.gain(ch, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UBitxDSP::unmuteRxIn(RxAudioCh ch) {
|
||||
if (ch < NUM_RX_AUDIO_CH) {
|
||||
if (state.rx[ch].mute) {
|
||||
state.rx[ch].mute = false;
|
||||
rxAudio.gain(ch, state.rx[ch].level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UBitxDSP::tx(TxAudioIn src) {
|
||||
if (!isTx) {
|
||||
muteRxIn(RX_AUDIO);
|
||||
|
||||
switch (src) {
|
||||
case MIC_IN:
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_MIC);
|
||||
audioCtrl.micGain(12); // TODO: Make this dynamic
|
||||
unmuteTxIn(TX_LINE);
|
||||
|
||||
case LINE_IN:
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
unmuteTxIn(TX_LINE);
|
||||
break;
|
||||
|
||||
case USB_IN:
|
||||
unmuteTxIn(TX_USB);
|
||||
break;
|
||||
|
||||
case TUNE_IN:
|
||||
tone1.amplitude(1.0); // TODO - just do this once.
|
||||
tone1.frequency(1500); // TODO: Make this dynamic based on CW (sidetone freq) versus data (1500 Hz)
|
||||
unmuteTxIn(TX_TONE1);
|
||||
break;
|
||||
|
||||
case TWO_TONE_IN:
|
||||
tone1.amplitude(1.0); // TODO - just do this once.
|
||||
tone1.amplitude(1.0); // TODO - just do this once.
|
||||
tone1.frequency(700);
|
||||
tone2.frequency(1900);
|
||||
unmuteTxIn(TX_TONE1);
|
||||
unmuteTxIn(TX_TONE2);
|
||||
break;
|
||||
}
|
||||
|
||||
isTx = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UBitxDSP::setTxInLevel(TxAudioCh ch, float level) {
|
||||
if (ch < NUM_TX_AUDIO_CH) {
|
||||
state.tx[ch].level = level;
|
||||
txAudio.gain(ch, state.tx[ch].mute ? 0.0 : state.tx[ch].level);
|
||||
}
|
||||
}
|
||||
|
||||
void UBitxDSP::muteTxIn() {
|
||||
for (TxAudioCh i = TX_LINE; i < NUM_TX_AUDIO_CH; i++) {
|
||||
state.tx[ch].mute = true;
|
||||
txAudio.gain(ch, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void UBitxDSP::muteTxIn(TxAudioCh ch) {
|
||||
if (ch < NUM_TX_AUDIO_CH) {
|
||||
if (!state.tx[ch].mute) {
|
||||
state.tx[ch].mute = true;
|
||||
txAudio.gain(ch, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UBitxDSP::unmuteTxIn(TxAudioCh ch) {
|
||||
if (ch < NUM_TX_AUDIO_CH) {
|
||||
if (state.tx[ch].mute) {
|
||||
state.tx[ch].mute = false;
|
||||
rxAudio.gain(ch, state.tx[ch].level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,17 +266,17 @@ const int minRxFilterCenter = MIN_RX_FILTER_CENTER;
|
||||
const int maxRxFilterCenter = MAX_RX_FILTER_CENTER;
|
||||
|
||||
/*!
|
||||
* @brief Bypass the RX audio filter.
|
||||
*/
|
||||
@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.
|
||||
*/
|
||||
@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);
|
||||
@ -247,7 +291,7 @@ void UBitxDSP::setRxFilter(int lo, int hi) {
|
||||
}
|
||||
if (lo > hi - minRxFilterWidth) {
|
||||
lo = hi - minRxFilterWidth;
|
||||
}
|
||||
}
|
||||
if (lo < minRxFilterLo) {
|
||||
lo = minRxFilterLo;
|
||||
}
|
||||
@ -319,7 +363,7 @@ void UBitxDSP::enableTxInput(int ch) {
|
||||
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) {
|
||||
@ -346,14 +390,18 @@ void UBitxDSP::stopTxInput(int ch) {
|
||||
}
|
||||
}
|
||||
|
||||
// VOX settings
|
||||
bool UBitxDSP::isVoxActive(int vox) {
|
||||
if ((vox > -1) && (vox < 3)) {
|
||||
return state.voxActive[vox];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
NOTES
|
||||
|
||||
Major functions:
|
||||
- tx() - start transmitting / pause receiving
|
||||
- rx() - stop transmitting / resume receiving
|
||||
- setTxSource() - set the TX audio source to MIC_IN, LINE_IN, or USB_IN
|
||||
- also sets the relevant VOX source/parameters (as applicable)
|
||||
|
||||
Receive audio chain:
|
||||
-
|
||||
*/
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
|
@ -18,23 +18,16 @@
|
||||
|
||||
#define DSP_MILLIS_PER_UPDATE 100
|
||||
|
||||
#define RX_RIG_IN_CH 0
|
||||
|
||||
#define TX_MIC_IN_CH 0
|
||||
#define TX_LINE_IN_CH 0
|
||||
#define TX_USB_IN_CH 1
|
||||
#define TX_NUM_CHANNELS 2
|
||||
|
||||
#define TX_LINE_IN_VOX 0
|
||||
#define TX_USB_IN_L_VOX 1
|
||||
#define TX_USB_IN_R_VOX 2
|
||||
#define TX_NUM_VOX 3
|
||||
|
||||
#define TX_LINE_IN_VOX_THRESH 0.25
|
||||
#define TX_USB_IN_L_VOX_THRESH 0.25
|
||||
#define TX_USB_IN_R_VOX_THRESH 0.25
|
||||
|
||||
#define TX_LINE_IN_VOX_DELAY 500
|
||||
#define TX_USB_IN_L_VOX_DELAY 500
|
||||
#define TX_USB_IN_R_VOX_DELAY 500
|
||||
#define TX_VOX_USB_THRESH 0.25
|
||||
#define TX_VOX_LINE_THRESH 0.25
|
||||
#define TX_VOX_DELAY 500
|
||||
|
||||
struct DSPState {
|
||||
|
||||
@ -49,10 +42,23 @@ struct DSPState {
|
||||
int txInEnable[4] = {1, 1, 0, 0};
|
||||
int txInTx[4] = {0, 0, 0, 0};
|
||||
|
||||
struct {
|
||||
bool mute = true;
|
||||
float level = 0.1;
|
||||
} tx[NUM_TX_AUDIO_CH];
|
||||
|
||||
struct {
|
||||
bool mute = true;
|
||||
float level = 1.0;
|
||||
} rx[NUM_RX_AUDIO_CH];
|
||||
|
||||
// VOX settings
|
||||
bool voxActive[3];
|
||||
float voxThresh[3];
|
||||
unsigned voxDelay[3];
|
||||
/* struct {
|
||||
bool isActive = false;
|
||||
bool isUSB = false;
|
||||
float usbThresh = TX_VOX_USB_THRESH;
|
||||
float lineLevel = TX_VOX_LINE_THRESH;
|
||||
unsigned delay = TX_VOX_DELAY;*/
|
||||
unsigned voxTimeout[3];
|
||||
};
|
||||
|
||||
@ -62,13 +68,33 @@ enum TRState {
|
||||
};
|
||||
|
||||
enum RxAudioIn {
|
||||
RIG_AUDIO
|
||||
RIG_IN = 0,
|
||||
NUM_RX_AUDIO_IN
|
||||
};
|
||||
|
||||
enum RxAudioCh {
|
||||
RX_AUDIO = 0,
|
||||
RX_SPARE1,
|
||||
RX_SPARE2,
|
||||
RX_SPARE3,
|
||||
NUM_RX_AUDIO_CH
|
||||
};
|
||||
|
||||
enum TxAudioIn {
|
||||
MIC_IN,
|
||||
MIC_IN = 0,
|
||||
LINE_IN,
|
||||
USB_IN
|
||||
USB_IN,
|
||||
TUNE_IN,
|
||||
TWO_TONE_IN,
|
||||
NUM_TX_AUDIO_IN
|
||||
};
|
||||
|
||||
enum TxAudioCh {
|
||||
TX_LINE = 0,
|
||||
TX_USB,
|
||||
TX_TONE1,
|
||||
TX_TONE2,
|
||||
NUM_TX_AUDIO_CH
|
||||
};
|
||||
|
||||
class UBitxDSP {
|
||||
@ -78,9 +104,11 @@ class UBitxDSP {
|
||||
void update();
|
||||
void end();
|
||||
void rx();
|
||||
void txMicIn();
|
||||
void txLineIn();
|
||||
void txUSBIn();
|
||||
inline void tx() { tx(txSrc); }
|
||||
void tx(TxAudioIn src);
|
||||
|
||||
inline void setTxAudioIn(TxAudioIn src) { txSrc = src; }
|
||||
TxAudionIn getTxAudioIn() const { return txSrc; }
|
||||
|
||||
// RX audio output settings
|
||||
|
||||
@ -124,16 +152,32 @@ class UBitxDSP {
|
||||
void stopTxInput(int ch);
|
||||
|
||||
// VOX settings
|
||||
bool isVoxActive(int vox);
|
||||
inline void setDataVoxOn() { state.vox.isActive = true; }
|
||||
inline void setDataVoxOff() { state.vox.isActive = false; }
|
||||
inline void setDataVoxThreshold(float val) {
|
||||
|
||||
}
|
||||
inline void setDataVoxThreshold(float val, bool isUSB) {
|
||||
if (isUSB) {
|
||||
state.vox.usbThresh = val;
|
||||
} else {
|
||||
state.vox.lineThresh = val;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool isTx = false;
|
||||
|
||||
void updateRxFilter();
|
||||
|
||||
DSPState state;
|
||||
short coefficients[NUM_COEFFICIENTS];
|
||||
elapsedMillis sinceLastUpdate;
|
||||
|
||||
AudioAnalyzeRMS* voxRMS[3];
|
||||
TxAudioIn txSrc;
|
||||
|
||||
unsigned voxTimeout;
|
||||
};
|
||||
|
||||
extern UBitxDSP DSP;
|
||||
|
Loading…
Reference in New Issue
Block a user