Files
ubitx-v5x/TeensyDSP/DSP.h
T

372 lines
14 KiB
C++

//======================================================================
// DSP.h
//======================================================================
#ifndef __DSP_h__
#define __DSP_h__
#include <Audio.h>
#include <dynamicFilters.h>
#include "Debug.h"
/**********************************************************************
* Macros
**********************************************************************/
#define MIN_RX_FILTER_LO (0) //! Min allowable value of the RX filter low-cut frequency
#define MAX_RX_FILTER_HI (5000) //! Max allowable value of the RX filter hi-cut frequency
#define MIN_RX_FILTER_WIDTH (0) //! Min allowable value of the RX filter bandwidth
#define MAX_RX_FILTER_WIDTH (5000) //! Max allowable value of the RX filter bandwidth
#define MIN_RX_FILTER_CENTER (0) //! Min allowable value of the RX filter center frequency
#define MAX_RX_FILTER_CENTER (5000) //! Max allowable value of the RX filter center frequency
#define DSP_MILLIS_PER_UPDATE (100) //! Number of milliseconds between update of the DSP object
#define TX_VOX_MIC_THRESH (0.0) //! Threshold for mic VOX (not implemented, since mic requires special handling)
#define TX_VOX_LINE_THRESH (0.25) //! Threshold for line in VOX
#define TX_VOX_USB_THRESH (0.25) //! Threshold for USB VOX
#define TX_VOX_TUNE_THRESH (0.0) //! Threshold for tune (single tone) VOX (not expected to be used)
#define TX_VOX_TT_THRESH (0.0) //! Threshold for two-tone VOX (not expected to be used)
#define TX_VOX_DELAY (500) //! VOX delay in milliseconds
/**********************************************************************
* Enumerations
**********************************************************************/
//! Defines the four separate RX audio input channels available.
enum RxAudioCh {
RX_AUDIO = 0, // Normal receiver audio input channel
RX_SPARE1, // Not used
RX_SPARE2, // Not used
RX_SPARE3, // Not used
NUM_RX_AUDIO_CH // Total number of channels
};
//! Defines the different RX audio inputs (not channels).
enum RxAudioIn {
RIG_IN = 0, // Normal rig input (receiver audio)
NUM_RX_AUDIO_IN // Total number of inputs
};
//! Defines the different RX audio outputs.
enum RxAudioOut {
LINE_OUT = 0, // Line audio out (and speaker)
USB_OUT, // USB audio out
NUM_RX_AUDIO_OUT
};
//! Defines the four separate TX audio input channels available.
enum TxAudioCh {
TX_LINE = 0, // Line and/or mic audio input channel
TX_USB, // USB audio input channel
TX_TONE1, // Audio tone #1 input channel
TX_TONE2, // Audio tone #2 input channel
NUM_TX_AUDIO_CH // Toal number of channels
};
//! Defines the different TX audio input sources (not channels!).
enum TxAudioIn {
MIC_IN = 0, // Microphone transmit audio input
LINE_IN, // Line ("AUX") transmit audio input
USB_IN, // USB transmit audio input
TUNE_IN, // Tune input (transmits a single tone)
TWO_TONE_IN, // Two tone audio input (transmits two tones)
NUM_TX_AUDIO_IN // Total number of inputs
};
/**********************************************************************
* Classes
**********************************************************************/
//! Defines parameters for a simple audio channel that can be muted.
struct AudioChannel {
bool mute = false;
float level = 0.0;
};
/*!
* Contains the current 'persistent' state of the DSP.
* This includes all audio-specific state that can be saved to, or
* restored from, EEPROM. It does not include 'transient' state (such
* as whether we're currently transmitting or receiving).
*/
struct DSPState {
//! Receiver audio inputs; all default to muted.
AudioChannel rxIn[NUM_RX_AUDIO_CH] = {
{true, 1.0}, // audio
{true, 0.0}, // spare 1
{true, 0.0}, // spare 2
{true, 0.0} // spare 3
};
//! Receiver audio output; defaults to muted.
AudioChannel rxOut[NUM_RX_AUDIO_OUT] = {
{false, 1.0}, // line
{false, 1.0} // USB
};
//! Transmitter audio inputs; all default to muted.
AudioChannel txIn[NUM_TX_AUDIO_CH] = {
{true, 0.1}, // line
{true, 0.1}, // USB
{true, 0.1}, // tone 1
{true, 0.1} // tone 2
};
//! Tranmitter audio output; defaults to muted.
AudioChannel txOut = {true, 1.0};
//! Transmitter VOX settings, per audio input (not channel).
struct {
bool enable = false;
float threshold = 1.0;
} vox[NUM_TX_AUDIO_IN] = {
{false, TX_VOX_MIC_THRESH},
{true, TX_VOX_LINE_THRESH},
{true, TX_VOX_USB_THRESH},
{false, TX_VOX_TUNE_THRESH},
{false, TX_VOX_TT_THRESH}
};
//! VOX delay (regardless of input).
unsigned voxDelay = TX_VOX_DELAY;
//! Current RX filter settings
int rxFilterLo = 300;
int rxFilterHi = 3000;
};
/*!
* Defines the DSP subsystem of the UBitx V5X.
* The DSP subsystem, which relies on the Teensy Audio Library, is
* responsible for setting up the audio inputs and outputs for both
* receive (RX) and transmit (TX) audio, maintaining the correct path
* between inputs and outputs based on current TX/RX state, and setting
* up audio filters and other audio-based modules for the RX and TX
* audio paths.
*/
class UBitxDSP {
/********************************************************************
* Object creation/deletion
********************************************************************/
public:
UBitxDSP() {}
/********************************************************************
* Basic administration
********************************************************************/
public:
void begin();
void update();
void end();
/********************************************************************
* Transmit/Receive switching
********************************************************************/
public:
void rx();
inline void tx() { tx(txSrc); }
void tx(TxAudioIn src);
/********************************************************************
* General audio setup -- called via begin()
********************************************************************/
protected:
virtual void setupRxAudio();
virtual void setupTxAudio();
/********************************************************************
* Receive audio chain
********************************************************************/
// Basic control of RX audio inputs and outputs.
public:
void setRxInLevel(RxAudioCh ch, float level); // Set the audio input level for a given channel.
void muteRxIn(); // Mute all RX audio input channels.
void muteRxIn(RxAudioCh ch); // Mute a specific RX audio input channel.
void unmuteRxIn(RxAudioCh ch); // Un-mute a specific RX audio input channel.
void setLineOutLevel(float level); // Set the line output level (0.0 - 1.0).
void setUSBOutLevel(float level); // Set the USB output level (0.0 - 1.0).
// Discrete control intended for use with TS-590 CAT.
void setLineOut255(unsigned level); // Set the line output level (0 - 255).
void setLineOut9(unsigned level); // Set the line output level (0 - 9).
void setUSBOut255(unsigned level); // Set the USB output level (0 - 255).
void setUSBOut9(unsigned level); // Set the USB output level (0 - 9).
unsigned getLineOut255() const; // Get the line output level (0 - 255).
unsigned getLineOut9() const; // Get the line output level (0 - 9).
unsigned getUSBOut255() const; // Get the USB output level (0 - 255).
unsigned getUSBOut9() const; // Get the USB output level (0 - 9).
//! Set the line output level based on an integer value.
template<unsigned MAX>
void setLineOutLevel(unsigned level) {
setLineOutLevel(static_cast<float>(level) / static_cast<float>(MAX));
}
//! Set the USB output level based on an integer value.
template<unsigned MAX>
void setUSBOutLevel(unsigned level) {
setUSBOutLevel(static_cast<float>(level) / static_cast<float>(MAX));
}
//! Get the line output level as an integer value.
template<unsigned MAX>
unsigned getLineOutLevel() const {
return static_cast<unsigned>(state.rxOut[LINE_OUT].level * static_cast<float>(MAX));
}
//! Get the USB output level as an integer value.
template<unsigned MAX>
unsigned getUSBOutLevel() const {
return static_cast<unsigned>(state.rxOut[USB_OUT].level * static_cast<float>(MAX));
}
/********************************************************************
* Transmit audio chain
********************************************************************/
// Basic control of TX audio inputs and outputs.
public:
void setTxInLevel(TxAudioCh ch, float level); // Set the audio input level for a given channel.
void muteTxIn(); // Mute all TX audio input channels.
void muteTxIn(TxAudioCh ch); // Mute a specific TX audio input channel.
void unmuteTxIn(TxAudioCh ch); // Un-mute a specific TX audio input channel.
void setTxOutLevel(float level); // Set the TX audio output level.
void muteTxOut(); // Mute the TX audio output.
void unmuteTxOut(); // Un-mute the TX audio output.
void setLineInLevel(float level); // Set the line input level (0.0 - 1.0).
void setUSBInLevel(float level); // Set the USB input level (0.0 - 1.0).
// Discrete control intended for use with TS-590 CAT.
void setLineIn255(unsigned level); // Set the line input level (0 - 255).
void setLineIn9(unsigned level); // Set the line input level (0 - 9).
void setUSBIn255(unsigned level); // Set the USB input level (0 - 255).
void setUSBIn9(unsigned level); // Set the USB input level (0 - 9).
unsigned getLineIn255() const; // Get the line input level (0 - 255).
unsigned getLineIn9() const; // Get the line input level (0 - 9).
unsigned getUSBIn255() const; // Get the USB input level (0 - 255).
unsigned getUSBIn9() const; // Get the USB input level (0 - 9).
//! Set the line input level based on an integer value.
template<unsigned MAX>
void setLineInLevel(unsigned level) {
setLineInLevel(static_cast<float>(level) / static_cast<float>(MAX));
}
//! Set the USB input level based on an integer value.
template<unsigned MAX>
void setUSBInLevel(unsigned level) {
setUSBInLevel(static_cast<float>(level) / static_cast<float>(MAX));
}
//! Get the line input level as an integer value.
template<unsigned MAX>
unsigned getLineInLevel() const {
return static_cast<unsigned>(state.txIn[LINE_OUT].level * static_cast<float>(MAX));
}
//! Get the USB input level as an integer value.
template<unsigned MAX>
unsigned getUSBInLevel() const {
return static_cast<unsigned>(state.txIn[USB_OUT].level * static_cast<float>(MAX));
}
// Transmit audio selection (may be overriden at actual transmit time).
public:
void setTxAudioIn(TxAudioIn src, bool isTemp = false); // Select a specific TX audio input path, and identify it as permanent or temporary.
inline TxAudioIn getTxAudioIn() const { return txSrc; } // Return the current TX audio input.
/********************************************************************
* Receive audio filter (band pass)
********************************************************************/
public:
void bypassRxFilter();
void updateRxFilter();
void setRxFilter(int lo, int hi);
void setRxFilterLo(int lo);
void setRxFilterHi(int hi);
void setRxFilterWidth(int width);
void setRxFilterCenter(int center);
/*!
* Get the current low frequency bound of the RX band pass filter.
* @return The low frequency bound.
*/
inline int getRxFilterLo() { return state.rxFilterLo; }
/*!
* Get the current high frequency bound of the RX band pass filter.
* @return The high frequency bound.
*/
inline int getRxFilterHi() { return state.rxFilterHi; }
/*!
* Get the current width of the RX band pass filter.
* @return The filter width.
*/
inline int getRxFilterWidth() { return state.rxFilterHi - state.rxFilterLo; }
/*!
* Get the current center frequency of the RX band pass filter.
* @return The center frequency.
*/
inline int getRxFilterCenter() { return (state.rxFilterHi + state.rxFilterLo) / 2; }
/********************************************************************
* Transmit Voice-Operated-Switch (VOX)
********************************************************************/
inline bool voxActive() { return isVoxActive; }
inline bool voxInactive() { return !isVoxActive; }
void setLineVOXThresh9(unsigned level);
unsigned getLineVOXThresh9() const;
void setUSBVOXThresh9(unsigned level);
unsigned getUSBVOXThresh9() const;
void setDataVoxDelay(unsigned msec);
unsigned getDataVoxDelay() const;
/********************************************************************
* Private state
********************************************************************/
private:
DSPState state;
bool isTx = false;
TxAudioIn txSrc = MIC_IN;
TxAudioIn txSrcLatched = MIC_IN;
short coefficients[NUM_COEFFICIENTS] = {0};
elapsedMillis sinceLastUpdate = 0;
float usbVol = 0.0;
bool isVoxActive = false;
elapsedMillis sinceVoxActive = 0;
};
extern UBitxDSP& DSP;
#endif
//======================================================================
// EOF
//======================================================================