Insanely, this also compiles.
Numerous changes updating modes, rig, config, everything... don't think this ones gonna work first time through...
This commit is contained in:
parent
2da162f7c2
commit
6581a5f2a4
@ -97,41 +97,39 @@ enum MessageID {
|
||||
* (e.g. USB, LSB, etc.)
|
||||
*/
|
||||
|
||||
enum rig_mode {
|
||||
lsb = 0,
|
||||
usb,
|
||||
enum struct rig_mode {
|
||||
ssb = 0,
|
||||
cw,
|
||||
cwr,
|
||||
dig,
|
||||
digi,
|
||||
// add new items here
|
||||
num_rig_modes
|
||||
count
|
||||
};
|
||||
|
||||
/* Keyer modes.
|
||||
*/
|
||||
|
||||
enum keyer_mode {
|
||||
enum struct keyer_mode {
|
||||
straight = 0,
|
||||
iambic_a,
|
||||
iambic_b,
|
||||
//ultimatic,
|
||||
//bug,
|
||||
// add any new items here
|
||||
num_keyer_modes
|
||||
count
|
||||
};
|
||||
|
||||
enum rx_filter {
|
||||
enum struct rx_filter {
|
||||
wide = 0,
|
||||
medium,
|
||||
narrow,
|
||||
num_rx_filters
|
||||
count
|
||||
};
|
||||
|
||||
enum digi_mode {
|
||||
enum struct digi_submode {
|
||||
rtty = 0,
|
||||
psk31,
|
||||
user_defined,
|
||||
num_digi_modes
|
||||
count
|
||||
};
|
||||
|
||||
//const unsigned char RIG_MODE_LETTER[num_rig_modes] = {'s', 'S', 'c', 'C', 'd', 'D', 't', 'T'};
|
||||
@ -154,67 +152,70 @@ struct IOPMessage {
|
||||
// Interface to a configuration object.
|
||||
//======================================================================
|
||||
|
||||
struct filter_config {
|
||||
float lo;
|
||||
float hi;
|
||||
struct bpf_config {
|
||||
float lo_freq;
|
||||
float hi_freq;
|
||||
float gain;
|
||||
};
|
||||
|
||||
struct mode_config {
|
||||
mode_config(bool usb, rx_filter f, const filter_config *fc) : is_usb(usb), filter(f) {
|
||||
for (int i = 0; i < num_rx_filters; i++) {
|
||||
filtercfg[i] = fc[i];
|
||||
mode_config(bool usb, rx_filter f, const bpf_config *fc) : is_usb(usb), filter(f) {
|
||||
for (int i = 0; i < static_cast<int>(rx_filter::count); i++) {
|
||||
filter_cfg[i] = fc[i];
|
||||
}
|
||||
}
|
||||
bool is_usb;
|
||||
rx_filter filter;
|
||||
filter_config filtercfg[num_rx_filters];
|
||||
bpf_config filter_cfg[static_cast<size_t>(rx_filter::count)];
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// SSB CONFIGURATION
|
||||
//======================================================================
|
||||
|
||||
const filter_config ssb_filter_config[num_rx_filters] =
|
||||
{filter_config{ 300.0, 3100.0, 1.0},
|
||||
filter_config{ 500.0, 2900.0, 1.0},
|
||||
filter_config{ 700.0, 2500.0, 1.0}};
|
||||
const bpf_config ssb_filter_config[] =
|
||||
{bpf_config{ 300.0, 3100.0, 1.0},
|
||||
bpf_config{ 500.0, 2900.0, 1.0},
|
||||
bpf_config{ 700.0, 2500.0, 1.0}};
|
||||
|
||||
struct comp_config {
|
||||
bool enabled = false;
|
||||
float threshold = 0.1;
|
||||
float ratio = 20.0;
|
||||
float gain = 2.0;
|
||||
};
|
||||
|
||||
struct ssb_config : public mode_config {
|
||||
ssb_config() : mode_config(true, wide, ssb_filter_config) {}
|
||||
// speech compressor parameters
|
||||
bool comp_enable = false;
|
||||
float comp_threshold = 0.1;
|
||||
float comp_ratio = 20.0;
|
||||
float comp_gain = 2.0;
|
||||
ssb_config() : mode_config(true, rx_filter::wide, ssb_filter_config) {}
|
||||
comp_config comp;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// DIG CONFIGURATION
|
||||
// DIGI CONFIGURATION
|
||||
//======================================================================
|
||||
|
||||
const filter_config dig_filter_config[num_rx_filters] =
|
||||
{filter_config{ 300.0, 3100.0, 1.0},
|
||||
filter_config{ 500.0, 2900.0, 1.0},
|
||||
filter_config{1250.0, 1750.0, 1.0}};
|
||||
const bpf_config digi_filter_config[] =
|
||||
{bpf_config{ 300.0, 3100.0, 1.0},
|
||||
bpf_config{ 500.0, 2900.0, 1.0},
|
||||
bpf_config{1250.0, 1750.0, 1.0}};
|
||||
|
||||
struct dig_config : public mode_config {
|
||||
dig_config() : mode_config(true, wide, dig_filter_config) {}
|
||||
digi_mode submode = user_defined;
|
||||
struct digi_config : public mode_config {
|
||||
digi_config() : mode_config(true, rx_filter::wide, digi_filter_config) {}
|
||||
digi_submode submode = digi_submode::user_defined;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// CW CONFIGURATION
|
||||
//======================================================================
|
||||
|
||||
const filter_config cw_filter_config[num_rx_filters] =
|
||||
{filter_config{ 300.0, 1300.0, 1.0},
|
||||
filter_config{ 450.0, 950.0, 1.0},
|
||||
filter_config{ 575.0, 825.0, 1.0}};
|
||||
const bpf_config cw_filter_config[] =
|
||||
{bpf_config{ 300.0, 1300.0, 1.0},
|
||||
bpf_config{ 450.0, 950.0, 1.0},
|
||||
bpf_config{ 575.0, 825.0, 1.0}};
|
||||
|
||||
struct cw_config : public mode_config {
|
||||
cw_config() : mode_config(true, wide, cw_filter_config) {}
|
||||
keyer_mode mode = iambic_a;
|
||||
cw_config() : mode_config(true, rx_filter::wide, cw_filter_config) {}
|
||||
keyer_mode mode = keyer_mode::iambic_a;
|
||||
// flags
|
||||
bool reversed = false;
|
||||
// parameters
|
||||
|
@ -7,147 +7,160 @@
|
||||
|
||||
#include "audio.h"
|
||||
|
||||
// Exceptions not active (for Arduino, I assume?).
|
||||
//enum IModeExceptions {
|
||||
// MODE_ALREADY_ACTIVE = -1,
|
||||
// MODE_STILL_TRANSMITTING = -2,
|
||||
// MODE_ALREADY_TRANSMITTING = -3,
|
||||
// MODE_NOT_TRANSMITTING = -4,
|
||||
//};
|
||||
|
||||
//======================================================================
|
||||
// IMode
|
||||
// basic_mode
|
||||
//
|
||||
// Interface to a rig mode (SSB, CW, etc.).
|
||||
// A basic rig mode. It can perform actions on_entry() and on_exit(),
|
||||
// as well as on_tx() and on_rx(). These actions are defined in an
|
||||
// appropriate subclass. In addition, the basic mode support an audio
|
||||
// audio band pass filter with wide, medium, and narrow modes.
|
||||
//======================================================================
|
||||
|
||||
class IMode {
|
||||
class basic_mode {
|
||||
public:
|
||||
|
||||
IMode(mode_config& c, RigAudio& a, IFilter& f):
|
||||
_config(c), _audio(a), _filter(f), _active(false), _transmitting(false)
|
||||
basic_mode(mode_config& c, RigAudio& a, bp_filter& f) :
|
||||
config_(c), audio_(a), filter_(f), active_(false), transmitting_(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~IMode() {}
|
||||
virtual ~basic_mode() {}
|
||||
|
||||
inline mode_config& config() { return _config; }
|
||||
inline mode_config& config() { return config_; }
|
||||
|
||||
inline RigAudio& audio() { return _audio; }
|
||||
inline RigAudio& audio() { return audio_; }
|
||||
|
||||
inline IFilter& filter() { return _filter; }
|
||||
inline bp_filter& filter() { return filter_; }
|
||||
|
||||
// Called upon mode entry. Should assume that the rig's state is
|
||||
// "clean", i.e. that it still needs to enable anything it needs for
|
||||
// use in the mode.
|
||||
virtual void onEntry() = 0;
|
||||
virtual void on_entry() = 0;
|
||||
|
||||
// Called upon mode exit. Should clean everything up that it used,
|
||||
// and not make assumptions about which mode is being entered next.
|
||||
virtual void onExit() = 0;
|
||||
virtual void on_exit() = 0;
|
||||
|
||||
// Called when transmitting.
|
||||
virtual void onTx() = 0;
|
||||
virtual void on_tx() = 0;
|
||||
|
||||
// Called when receiving.
|
||||
virtual void onRx() = 0;
|
||||
virtual void on_rx() = 0;
|
||||
|
||||
inline void enter() {
|
||||
if (_active) {
|
||||
if (active_) {
|
||||
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
||||
//throw MODE_ALREADY_ACTIVE;
|
||||
USBDEBUG("ERROR - tried to enter mode, but it's already active");
|
||||
} else {
|
||||
_active = true;
|
||||
onEntry();
|
||||
active_ = true;
|
||||
on_entry();
|
||||
}
|
||||
}
|
||||
|
||||
inline void exit() {
|
||||
if (_transmitting) {
|
||||
if (transmitting_) {
|
||||
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
||||
//throw MODE_STILL_TRANSMITTING;
|
||||
USBDEBUG("ERROR - tried to exit mode, but it's transmitting");
|
||||
} else {
|
||||
_active = false;
|
||||
onExit();
|
||||
active_ = false;
|
||||
on_exit();
|
||||
}
|
||||
}
|
||||
|
||||
inline bool isActive() { return _active; }
|
||||
inline bool isInactive() { return !_active; }
|
||||
inline bool is_active() { return active_; }
|
||||
inline bool is_inactive() { return !active_; }
|
||||
|
||||
inline void tx() {
|
||||
if (_transmitting) {
|
||||
if (transmitting_) {
|
||||
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
||||
//throw MODE_ALREADY_TRANSMITTING;
|
||||
USBDEBUG("ERROR - tried to start transmitting, but mode already is transmitting");
|
||||
} else {
|
||||
_transmitting = true;
|
||||
onTx();
|
||||
transmitting_ = true;
|
||||
on_tx();
|
||||
}
|
||||
}
|
||||
|
||||
inline void rx() {
|
||||
if (!_transmitting) {
|
||||
if (!transmitting_) {
|
||||
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
||||
//throw MODE_NOT_TRANSMITTING;
|
||||
USBDEBUG("ERROR - tried to start receiving, but mode already is receiving");
|
||||
} else {
|
||||
_transmitting = false;
|
||||
onRx();
|
||||
transmitting_ = false;
|
||||
on_rx();
|
||||
}
|
||||
}
|
||||
|
||||
inline bool isTx() const { return _transmitting; }
|
||||
inline bool isRx() const { return !_transmitting; }
|
||||
inline bool is_tx() const { return transmitting_; }
|
||||
inline bool is_rx() const { return !transmitting_; }
|
||||
|
||||
virtual void setWideRxFilter() = 0;
|
||||
inline void set_rx_filter(rx_filter f) {
|
||||
filter_.disable();
|
||||
config_.filter = f;
|
||||
filter_.init(config_.filter_cfg[static_cast<int>(config_.filter)]);
|
||||
filter_.enable();
|
||||
#if defined(DEBUG)
|
||||
switch(config_.filter) {
|
||||
case rx_filter::wide:
|
||||
USBDEBUG("selected wide filter");
|
||||
break;
|
||||
|
||||
virtual void setMediumRxFilter() = 0;
|
||||
case rx_filter::medium:
|
||||
USBDEBUG("selected medium filter");
|
||||
break;
|
||||
|
||||
virtual void setNarrowRxFilter() = 0;
|
||||
case rx_filter::narrow:
|
||||
USBDEBUG("selected narrow filter");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
mode_config& _config;
|
||||
RigAudio& _audio;
|
||||
IFilter& _filter;
|
||||
bool _active;
|
||||
bool _transmitting;
|
||||
mode_config& config_;
|
||||
RigAudio& audio_;
|
||||
bp_filter& filter_;
|
||||
bool active_;
|
||||
bool transmitting_;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// SSBMode
|
||||
// ssb_mode
|
||||
//======================================================================
|
||||
|
||||
class SSBMode : public IMode
|
||||
class ssb_mode : public basic_mode
|
||||
{
|
||||
public:
|
||||
|
||||
SSBMode(mode_config& c, RigAudio& a, IFilter& f, bool default_mic=true):
|
||||
IMode(c, a, f), _use_mic(default_mic)
|
||||
{
|
||||
}
|
||||
ssb_mode(ssb_config& c, RigAudio& a, bp_filter& f, speech_comp& s, bool default_mic=true) :
|
||||
basic_mode(c, a, f), use_mic_(default_mic), comp_(s) {}
|
||||
|
||||
virtual void onEntry()
|
||||
virtual void on_entry()
|
||||
{
|
||||
setWideRxFilter();
|
||||
set_rx_filter(config().filter);
|
||||
if (comp_.is_enabled()) {
|
||||
enable_comp();
|
||||
}
|
||||
audio().unmuteRx();
|
||||
audio().muteAllTx();
|
||||
USBDEBUG("SSB mode entered");
|
||||
}
|
||||
|
||||
virtual void onExit() {
|
||||
virtual void on_exit() {
|
||||
audio().muteAllTx();
|
||||
audio().muteRx();
|
||||
disable_comp();
|
||||
USBDEBUG("SSB mode exited");
|
||||
}
|
||||
|
||||
virtual void onTx()
|
||||
virtual void on_tx()
|
||||
{
|
||||
audio().muteRx();
|
||||
if (_use_mic) {
|
||||
if (use_mic_) {
|
||||
audio().unmuteMicIn();
|
||||
} else {
|
||||
audio().unmuteLineIn();
|
||||
@ -155,9 +168,9 @@ class SSBMode : public IMode
|
||||
USBDEBUG("SSB mode transmitting");
|
||||
}
|
||||
|
||||
virtual void onRx()
|
||||
virtual void on_rx()
|
||||
{
|
||||
if (_use_mic) {
|
||||
if (use_mic_) {
|
||||
audio().muteMicIn();
|
||||
} else {
|
||||
audio().muteLineIn();
|
||||
@ -166,137 +179,100 @@ class SSBMode : public IMode
|
||||
USBDEBUG("SSB mode receiving");
|
||||
}
|
||||
|
||||
void setMicIn()
|
||||
void set_mic_in()
|
||||
{
|
||||
if (isRx()) {
|
||||
if (is_rx()) {
|
||||
// can't switch inputs while already transmitting
|
||||
_use_mic = true;
|
||||
use_mic_ = true;
|
||||
}
|
||||
USBDEBUG("SSB mode - Mic In set");
|
||||
}
|
||||
|
||||
void setLineIn()
|
||||
void set_line_in()
|
||||
{
|
||||
if (isRx()) {
|
||||
if (is_rx()) {
|
||||
// can't switch inputs while already transmitting
|
||||
_use_mic = false;
|
||||
use_mic_ = false;
|
||||
}
|
||||
USBDEBUG("SSB mode - Line In set");
|
||||
}
|
||||
|
||||
virtual void setWideRxFilter() {
|
||||
((BPFilter&)filter()).setBand(300.0, 3100.0);
|
||||
filter().enable();
|
||||
USBDEBUG("set wide RX SSB filter");
|
||||
}
|
||||
|
||||
virtual void setMediumRxFilter() {
|
||||
((BPFilter&)filter()).setBand(500.0, 2900.0);
|
||||
filter().enable();
|
||||
USBDEBUG("set medium RX SSB filter");
|
||||
}
|
||||
|
||||
virtual void setNarrowRxFilter() {
|
||||
((BPFilter&)filter()).setBand(700.0, 2500.0);
|
||||
filter().enable();
|
||||
USBDEBUG("set narrow RX SSB filter");
|
||||
}
|
||||
inline void enable_comp() { comp_.enable(); }
|
||||
inline void disable_comp() { comp_.disable(); }
|
||||
|
||||
private:
|
||||
|
||||
bool _use_mic;
|
||||
bool use_mic_;
|
||||
speech_comp& comp_;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// DGTMode
|
||||
// digi_mode
|
||||
//======================================================================
|
||||
|
||||
class DGTMode : public IMode
|
||||
class digi_mode : public basic_mode
|
||||
{
|
||||
public:
|
||||
|
||||
DGTMode(mode_config& c, RigAudio& a, IFilter& f):
|
||||
IMode(c, a, f)
|
||||
{
|
||||
}
|
||||
digi_mode(digi_config& c, RigAudio& a, bp_filter& f) :
|
||||
basic_mode(c, a, f) {}
|
||||
|
||||
virtual void onEntry()
|
||||
virtual void on_entry()
|
||||
{
|
||||
setWideRxFilter();
|
||||
set_rx_filter(config().filter);
|
||||
audio().unmuteRx();
|
||||
audio().muteAllTx();
|
||||
USBDEBUG("DGT mode entered");
|
||||
USBDEBUG("Digi mode entered");
|
||||
}
|
||||
|
||||
virtual void onExit() {
|
||||
virtual void on_exit() {
|
||||
audio().muteAllTx();
|
||||
audio().muteRx();
|
||||
USBDEBUG("DGT mode exited");
|
||||
USBDEBUG("Digi mode exited");
|
||||
}
|
||||
|
||||
virtual void onTx()
|
||||
virtual void on_tx()
|
||||
{
|
||||
audio().muteRx();
|
||||
audio().unmuteUSBIn();
|
||||
USBDEBUG("DGT mode transmitting");
|
||||
USBDEBUG("Digi mode transmitting");
|
||||
}
|
||||
|
||||
virtual void onRx()
|
||||
virtual void on_rx()
|
||||
{
|
||||
audio().muteUSBIn();
|
||||
audio().unmuteRx();
|
||||
USBDEBUG("DGT mode receiving");
|
||||
USBDEBUG("Digi mode receiving");
|
||||
}
|
||||
|
||||
virtual void setWideRxFilter(){
|
||||
((BPFilter&)filter()).setBand(300.0, 3100.0);
|
||||
filter().enable();
|
||||
USBDEBUG("set wide RX DGT filter");
|
||||
}
|
||||
|
||||
virtual void setMediumRxFilter(){
|
||||
((BPFilter&)filter()).setBand(500.0, 2900.0);
|
||||
filter().enable();
|
||||
USBDEBUG("set medium RX DGT filter");
|
||||
}
|
||||
|
||||
virtual void setNarrowRxFilter(){
|
||||
((BPFilter&)filter()).setCenterAndWidth(1500.0, 500.0);
|
||||
filter().enable();
|
||||
USBDEBUG("set narrow RX DGT filter");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//======================================================================
|
||||
// CWMode
|
||||
// cw_mode
|
||||
//======================================================================
|
||||
|
||||
class CWMode : public IMode
|
||||
class cw_mode : public basic_mode
|
||||
{
|
||||
public:
|
||||
|
||||
CWMode(mode_config& c, RigAudio& a, IFilter& f):
|
||||
IMode(c, a, f)
|
||||
{
|
||||
}
|
||||
cw_mode(cw_config& c, RigAudio& a, bp_filter& f):
|
||||
basic_mode(c, a, f) {}
|
||||
|
||||
virtual void onEntry()
|
||||
virtual void on_entry()
|
||||
{
|
||||
setWideRxFilter();
|
||||
set_rx_filter(config().filter);
|
||||
audio().unmuteRx();
|
||||
audio().muteAllTx();
|
||||
USBDEBUG("CW mode entered");
|
||||
}
|
||||
|
||||
virtual void onExit() {
|
||||
virtual void on_exit() {
|
||||
audio().muteAllTx();
|
||||
audio().muteRx();
|
||||
USBDEBUG("CW mode exited");
|
||||
}
|
||||
|
||||
virtual void onTx()
|
||||
virtual void on_tx()
|
||||
{
|
||||
// Currently not muting Rx, since the uBITX produces it's own
|
||||
// sidetone... but I'm probably going to replace that with a S/W-
|
||||
@ -304,108 +280,10 @@ class CWMode : public IMode
|
||||
USBDEBUG("CW mode transmitting");
|
||||
}
|
||||
|
||||
virtual void onRx()
|
||||
virtual void on_rx()
|
||||
{
|
||||
USBDEBUG("CW mode receiving");
|
||||
}
|
||||
|
||||
virtual void setWideRxFilter(){
|
||||
float st = float(((cw_config&)config()).sidetone);
|
||||
float width = 1000.0;
|
||||
float low = st - (width * 0.5);
|
||||
if (low < 300.0) {
|
||||
low = 300.0;
|
||||
}
|
||||
((BPFilter&)filter()).setBand(low, low + width);
|
||||
filter().enable();
|
||||
USBDEBUG("set wide RX CW filter");
|
||||
}
|
||||
|
||||
virtual void setMediumRxFilter(){
|
||||
float st = float(((cw_config&)config()).sidetone);
|
||||
float width = 500.0;
|
||||
float low = st - (width * 0.5);
|
||||
if (low < 300.0) {
|
||||
low = 300.0;
|
||||
}
|
||||
((BPFilter&)filter()).setBand(low, low + width);
|
||||
filter().enable();
|
||||
USBDEBUG("set medium RX CW filter");
|
||||
}
|
||||
|
||||
virtual void setNarrowRxFilter(){
|
||||
float st = float(((cw_config&)config()).sidetone);
|
||||
float width = 250.0;
|
||||
float low = st - (width * 0.5);
|
||||
if (low < 300.0) {
|
||||
low = 300.0;
|
||||
}
|
||||
((BPFilter&)filter()).setBand(low, low + width);
|
||||
filter().enable();
|
||||
USBDEBUG("set narrow RX CW filter");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// TTMode
|
||||
//======================================================================
|
||||
|
||||
class TTMode : public IMode
|
||||
{
|
||||
public:
|
||||
|
||||
TTMode(mode_config& c, RigAudio& a, IFilter& f):
|
||||
IMode(c, a, f)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void onEntry()
|
||||
{
|
||||
setWideRxFilter();
|
||||
audio().unmuteRx();
|
||||
audio().muteAllTx();
|
||||
USBDEBUG("Test (Two-Tone) mode entered");
|
||||
}
|
||||
|
||||
virtual void onExit() {
|
||||
audio().muteAllTx();
|
||||
audio().muteRx();
|
||||
USBDEBUG("Test (Two-Tone) mode exited");
|
||||
}
|
||||
|
||||
virtual void onTx()
|
||||
{
|
||||
audio().muteRx();
|
||||
audio().unmuteTTIn();
|
||||
USBDEBUG("Test (Two-Tone) mode transmitting");
|
||||
}
|
||||
|
||||
virtual void onRx()
|
||||
{
|
||||
audio().muteTTIn();
|
||||
audio().unmuteRx();
|
||||
USBDEBUG("Test (Two-Tone) mode receiving");
|
||||
}
|
||||
|
||||
virtual void setWideRxFilter(){
|
||||
((BPFilter&)filter()).setBand(300.0, 3100.0);
|
||||
filter().enable();
|
||||
USBDEBUG("set wide RX TT filter");
|
||||
}
|
||||
|
||||
virtual void setMediumRxFilter(){
|
||||
((BPFilter&)filter()).setBand(500.0, 2900.0);
|
||||
filter().enable();
|
||||
USBDEBUG("set medium RX TT filter");
|
||||
}
|
||||
|
||||
virtual void setNarrowRxFilter(){
|
||||
((BPFilter&)filter()).setBand(700.0, 2500.0);
|
||||
filter().enable();
|
||||
USBDEBUG("set narrow RX TT filter");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -29,12 +29,12 @@ class ITxSwitch
|
||||
virtual ~ITxSwitch() {}
|
||||
|
||||
// Called before beginning transmit; if false, transmit aborts before starting.
|
||||
virtual bool onPress(IMode* m) = 0;
|
||||
virtual bool onPress(basic_mode* m) = 0;
|
||||
|
||||
// Called before stopping tranmit; if false, transmit continues.
|
||||
virtual bool onRelease(IMode* m) = 0;
|
||||
virtual bool onRelease(basic_mode* m) = 0;
|
||||
|
||||
void press(IMode* m, bool output_enable=true) {
|
||||
void press(basic_mode* m, bool output_enable=true) {
|
||||
if (onPress(m)) {
|
||||
USBDEBUG("PTT pressed");
|
||||
m->tx();
|
||||
@ -44,7 +44,7 @@ class ITxSwitch
|
||||
}
|
||||
}
|
||||
|
||||
void release(IMode* m, bool output_enable=true) {
|
||||
void release(basic_mode* m, bool output_enable=true) {
|
||||
if (onRelease(m)) {
|
||||
USBDEBUG("PTT released");
|
||||
if (output_enable) {
|
||||
@ -68,10 +68,10 @@ class CATSwitch : public ITxSwitch
|
||||
public:
|
||||
CATSwitch(): _transmitting(false) {}
|
||||
|
||||
virtual bool onPress(IMode* m) {
|
||||
virtual bool onPress(basic_mode* m) {
|
||||
// If another transmission is already occuring, abort... CAT can't
|
||||
// interrupt transmissions already ongoing.
|
||||
if (m->isRx()) {
|
||||
if (m->is_rx()) {
|
||||
USBDEBUG("CAT PTT pressed");
|
||||
_transmitting = true;
|
||||
return true;
|
||||
@ -80,7 +80,7 @@ class CATSwitch : public ITxSwitch
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool onRelease(IMode* m) {
|
||||
virtual bool onRelease(basic_mode* m) {
|
||||
// If CAT transmission is not occurring, abort... CAT can't stop
|
||||
// transmissions initiated by other sources. We don't check if
|
||||
// the mode is already transmitting, because it could be
|
||||
@ -98,90 +98,6 @@ class CATSwitch : public ITxSwitch
|
||||
bool _transmitting; // CAT-specific transmission
|
||||
};
|
||||
|
||||
/*
|
||||
//----------------------------------------------------------------------
|
||||
// MicSwitch
|
||||
//
|
||||
// Implementation of the ITxSwitch interface for the Mic (front panel)
|
||||
// switch. Features:
|
||||
// - In SSB, it will automatically select the Mic (front panel) input.
|
||||
// - If already transmitting, press will have no effect.
|
||||
// - If already transmitting (any mode, source), release will stop
|
||||
// the transmission... a failsafe.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class MicSwitch : public ITxSwitch
|
||||
{
|
||||
public:
|
||||
MicSwitch(): _ssb_mode(false) {}
|
||||
|
||||
inline void setSSBMode(bool flag) { _ssb_mode = flag; }
|
||||
|
||||
virtual bool onPress(IMode* m) {
|
||||
if (m->isRx()) {
|
||||
if (_ssb_mode) {
|
||||
((SSBMode*)m)->setMicIn();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool onRelease(IMode* m) {
|
||||
if (m->isTx()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool _ssb_mode;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// LineSwitch
|
||||
//
|
||||
// Implementation of the ITxSwitch interface for the Line (rear panel)
|
||||
// switch. Features:
|
||||
// - In SSB, it will automatically select the Line (rear panel) input.
|
||||
// - If already transmitting, press will have no effect.
|
||||
// - If already transmitting (any mode, source), release will stop
|
||||
// the transmission... a failsafe.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class LineSwitch : public ITxSwitch
|
||||
{
|
||||
public:
|
||||
LineSwitch(): _ssb_mode(false) {}
|
||||
|
||||
inline void setSSBMode(bool flag) { _ssb_mode = flag; }
|
||||
|
||||
virtual bool onPress(IMode* m) {
|
||||
if (m->isRx()) {
|
||||
if (_ssb_mode) {
|
||||
((SSBMode*)m)->setLineIn();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool onRelease(IMode* m) {
|
||||
if (m->isTx()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool _ssb_mode;
|
||||
};
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// GPIOSwitch
|
||||
//
|
||||
@ -201,15 +117,15 @@ class GPIOSwitch : public ITxSwitch
|
||||
|
||||
inline void setSSBMode(bool flag) { _ssb_mode = flag; }
|
||||
|
||||
virtual bool onPress(IMode* m) {
|
||||
if (m->isRx()) {
|
||||
virtual bool onPress(basic_mode* m) {
|
||||
if (m->is_rx()) {
|
||||
if (_ssb_mode) {
|
||||
if (_is_mic) {
|
||||
USBDEBUG("Mic PTT pressed");
|
||||
((SSBMode*)m)->setMicIn();
|
||||
((ssb_mode*)m)->set_mic_in();
|
||||
} else {
|
||||
USBDEBUG("Line PTT pressed");
|
||||
((SSBMode*)m)->setLineIn();
|
||||
((ssb_mode*)m)->set_line_in();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -218,15 +134,15 @@ class GPIOSwitch : public ITxSwitch
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool onRelease(IMode* m) {
|
||||
if (m->isTx()) {
|
||||
virtual bool onRelease(basic_mode* m) {
|
||||
if (m->is_tx()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void update(IMode* m, bool output_enable=true) {
|
||||
void update(basic_mode* m, bool output_enable=true) {
|
||||
_bounce.update();
|
||||
|
||||
if (_bounce.fell()) {
|
||||
|
@ -8,6 +8,8 @@
|
||||
#define __iop_audio_h__
|
||||
|
||||
#include <Audio.h>
|
||||
#include <dynamicFilters.h>
|
||||
#include <effect_compressor_fb.h>
|
||||
#include "config.h"
|
||||
|
||||
class RigAudio
|
||||
@ -49,38 +51,57 @@ class RigAudio
|
||||
|
||||
//======================================================================
|
||||
|
||||
class IFilter {
|
||||
public:
|
||||
virtual ~IFilter() {}
|
||||
virtual void enable() = 0;
|
||||
virtual void disable() = 0;
|
||||
};
|
||||
|
||||
class BPFilter : public IFilter {
|
||||
class bp_filter {
|
||||
|
||||
public:
|
||||
|
||||
BPFilter(double f1, double f2, bool use_center, short int window=-1, short int coeff=-1);
|
||||
void init(AudioFilterFIR* filter=NULL, short* coefficients=NULL);
|
||||
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);
|
||||
virtual void enable();
|
||||
virtual void disable();
|
||||
//bp_filter(double f1, double f2, bool use_center, short int window=-1, short int coeff=-1);
|
||||
bp_filter();
|
||||
bp_filter(AudioFilterFIR& f, AudioAmplifier& a);
|
||||
void init(const bpf_config& cfg);
|
||||
//void init(AudioFilterFIR* filter=NULL, short* coefficients=NULL);
|
||||
void set_band(double f1, double f2);
|
||||
void set_freq_lo(double f);
|
||||
void set_freq_hi(double f);
|
||||
void set_center_and_width(double c, double w);
|
||||
void set_center(double c);
|
||||
void set_width(double w);
|
||||
void set_gain(double g);
|
||||
void enable();
|
||||
void disable();
|
||||
|
||||
private:
|
||||
|
||||
double _freq_lo;
|
||||
double _freq_hi;
|
||||
short int _window;
|
||||
short int _coeff;
|
||||
float _recovery; // recovery amplifier value
|
||||
double freq_lo;
|
||||
double freq_hi;
|
||||
short int window;
|
||||
short int coeff;
|
||||
float recovery; // recovery amplifier value
|
||||
|
||||
AudioFilterFIR* _filter; // = &filterRX;
|
||||
short* _coefficients;
|
||||
AudioFilterFIR& filter; // = &filterRX;
|
||||
AudioAmplifier& amp;
|
||||
short coefficients[NUM_COEFFICIENTS];
|
||||
bool setup_complete;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
||||
class speech_comp
|
||||
{
|
||||
public:
|
||||
speech_comp(comp_config* cfg);
|
||||
// speech_comp(AudioEffectCompressor&, AudioAmplifier&, AudioAnalyzeRMS&);
|
||||
void update();
|
||||
void enable();
|
||||
void disable();
|
||||
inline bool is_enabled() const { return config_->enabled; }
|
||||
|
||||
private:
|
||||
comp_config* config_;
|
||||
AudioEffectCompressor& comp_;
|
||||
AudioAmplifier& amp_;
|
||||
AudioAnalyzeRMS& rms_;
|
||||
float env_ = 1.0;
|
||||
float alpha_ = 0.8;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
@ -8,10 +8,7 @@
|
||||
|
||||
#include <dynamicFilters.h>
|
||||
#include <effect_compressor_fb.h>
|
||||
|
||||
|
||||
#include "audio.h"
|
||||
#include "tx_audio_proc.h"
|
||||
|
||||
//short firActive[NUM_COEFFICIENTS];
|
||||
|
||||
@ -266,470 +263,90 @@ TxInput audioTxInput;
|
||||
TxOutput audioTxOutput;
|
||||
*/
|
||||
|
||||
//======================================================================
|
||||
// bp_filter
|
||||
//
|
||||
// Band Pass Filter methods.
|
||||
//======================================================================
|
||||
|
||||
short _internal_coefficients[NUM_COEFFICIENTS];
|
||||
bp_filter::bp_filter(): filter(filterRX), amp(filterAmp) {}
|
||||
|
||||
BPFilter::BPFilter(double f1, double f2, bool use_center=false, short int window, short int coeff):
|
||||
_window(window), _coeff(coeff)
|
||||
bp_filter::bp_filter(AudioFilterFIR& f, AudioAmplifier& a): filter(f), amp(a) {}
|
||||
|
||||
void bp_filter::init(const bpf_config& cfg) {
|
||||
set_band(cfg.lo_freq, cfg.hi_freq);
|
||||
set_gain(cfg.gain);
|
||||
}
|
||||
|
||||
void bp_filter::set_band(double f1, double f2) {
|
||||
freq_lo = f1;
|
||||
freq_hi = f2;
|
||||
}
|
||||
|
||||
void bp_filter::set_freq_lo(double f) { freq_lo = f; }
|
||||
|
||||
void bp_filter::set_freq_hi(double f) { freq_hi = f; }
|
||||
|
||||
void bp_filter::set_center_and_width(double c, double w) {
|
||||
freq_lo = c - (0.5 * w);
|
||||
freq_hi = c + (0.5 * w);
|
||||
}
|
||||
|
||||
void bp_filter::set_center(double c) {
|
||||
double w = freq_hi - freq_lo;
|
||||
set_center_and_width(c, w);
|
||||
}
|
||||
|
||||
void bp_filter::set_width(double w) {
|
||||
double c = (freq_lo + freq_hi) * 0.5;
|
||||
set_center_and_width(c, w);
|
||||
}
|
||||
|
||||
void bp_filter::set_gain(double g) { recovery = g; }
|
||||
|
||||
void bp_filter::enable() {
|
||||
audioFilter(coefficients, NUM_COEFFICIENTS, ID_BANDPASS, W_HAMMING, freq_lo, freq_hi);
|
||||
filter.begin(coefficients, NUM_COEFFICIENTS);
|
||||
amp.gain(recovery);
|
||||
}
|
||||
|
||||
void bp_filter::disable() {
|
||||
filter.begin(FIR_PASSTHRU, NUM_COEFFICIENTS);
|
||||
amp.gain(1.0);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
speech_comp::speech_comp(comp_config* cfg) :
|
||||
config_(cfg), comp_(compTX), amp_(compAmp), rms_(compRMS) {}
|
||||
|
||||
void speech_comp::enable()
|
||||
{
|
||||
if (window == -1) {
|
||||
_window = W_HAMMING;
|
||||
}
|
||||
if (coeff == -1) {
|
||||
_coeff = NUM_COEFFICIENTS;
|
||||
}
|
||||
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;
|
||||
}
|
||||
config_->enabled = true;
|
||||
comp_.begin(1, config_->threshold, config_->ratio); // Need to make configurable
|
||||
amp_.gain(config_->gain);
|
||||
}
|
||||
|
||||
void BPFilter::init(AudioFilterFIR* filter, short* coefficients) {
|
||||
if (filter == NULL) {
|
||||
_filter = &filterRX;
|
||||
} else {
|
||||
_filter = filter;
|
||||
}
|
||||
if (coefficients == NULL) {
|
||||
_coefficients = _internal_coefficients;
|
||||
} else {
|
||||
_coefficients = coefficients;
|
||||
}
|
||||
//audioFilter(coefficients, NUM_COEFFICIENTS, ID_BANDPASS, _window, _freq_lo, _freq_hi);
|
||||
//filter->begin(coefficients, NUM_COEFFICIENTS);
|
||||
}
|
||||
|
||||
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::enable() {
|
||||
audioFilter(_coefficients, NUM_COEFFICIENTS, ID_BANDPASS, _window, _freq_lo, _freq_hi);
|
||||
_filter->begin(_coefficients, NUM_COEFFICIENTS);
|
||||
}
|
||||
|
||||
void BPFilter::disable() {
|
||||
_filter->begin(FIR_PASSTHRU, NUM_COEFFICIENTS);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
SpeechCompressor speechCompressor(compTX, compAmp, compRMS);
|
||||
|
||||
//======================================================================
|
||||
|
||||
/*
|
||||
// array based on mode right now
|
||||
BPFilter *rxFilter[NUM_RIG_MODES][NUM_RX_FILTERS];
|
||||
|
||||
//======================================================================
|
||||
|
||||
void audioSetupFilters()
|
||||
void speech_comp::disable()
|
||||
{
|
||||
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);
|
||||
config_->enabled = false;
|
||||
comp_.disable();
|
||||
amp_.gain(1.0);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Speech compressor code based on post by 'hyperdyne': https://forum.pjrc.com/threads/36245-Changing-Pitch-of-Voice
|
||||
|
||||
SpeechCompressor speechCompressor(compTX, compAmp, compRMS);
|
||||
|
||||
//======================================================================
|
||||
|
||||
// audioInit()
|
||||
// Setup the audio subsystem.
|
||||
void audioInit()
|
||||
void speech_comp::update()
|
||||
{
|
||||
audioCtrl.enable();
|
||||
audioCtrl.muteHeadphone(); // not using the headphone output
|
||||
audioCtrl.volume(0.0); // not using the headphone output
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN); // required for RX audio
|
||||
audioCtrl.unmuteLineout(); // required for RX audio
|
||||
audioCtrl.lineInLevel(rigConfig.rxRigInLevel, rigConfig.txLineInLevel); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||||
audioCtrl.lineOutLevel(rigConfig.rxLineOutLevel, rigConfig.txRigOutLevel); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||||
audioCtrl.micGain(rigConfig.txMicInGain); // superfluous, as I have to do this anytime I switch to mic for some reason
|
||||
//audioCtrl.dacVolumeRamp(); // if this seems too slow, might try dacVolumeRampLinear().
|
||||
//audioCtrl.dacVolume(1.0, 0.0); // we're going to mute TX audio via the DAC unless we're transmitting
|
||||
|
||||
updateRxRigIn();
|
||||
updateRxSpkrOut();
|
||||
updateRxLineOut();
|
||||
updateRxUSBOut();
|
||||
|
||||
// Note - these really just need to be init functions; keep things muted while setting them up.
|
||||
updateTxMicIn();
|
||||
updateTxLineIn();
|
||||
updateTxUSBIn();
|
||||
updateTxTwoToneIn();
|
||||
|
||||
updateTxRigOut();
|
||||
|
||||
audioSelectRxInput(RX_RIG_IN);
|
||||
audioSelectTxInput(TX_MIC_IN); // superfluous I think
|
||||
|
||||
//audioCtrl.adcHighPassFilterDisable();
|
||||
//audioCtrl.audioPreProcessorEnable();
|
||||
|
||||
// setup the two-tone generator
|
||||
sine1.frequency(700);
|
||||
sine2.frequency(1900);
|
||||
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);
|
||||
filterAmp.gain(1.0);
|
||||
|
||||
// for now, just pass through the compressor
|
||||
//compTX.disable();
|
||||
//compAmp.gain(1.0);
|
||||
speechCompressor.enable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//======================================================================
|
||||
|
||||
|
||||
//======================================================================
|
||||
|
||||
void audioCalibrate(AudioConfig* c, char cmd, char subcmd, char parm, float value, bool set_value=true)
|
||||
{
|
||||
switch(cmd) {
|
||||
case 'r':
|
||||
case 'R':
|
||||
// RX audio parameters
|
||||
switch(subcmd) {
|
||||
case 'r':
|
||||
case 'R':
|
||||
// Rig input
|
||||
switch(parm) {
|
||||
case 'l':
|
||||
case 'L':
|
||||
// level
|
||||
if (set_value) {
|
||||
c->rxRigInLevel = int(value);
|
||||
updateRxRigIn();
|
||||
float rms_cur;
|
||||
if (config_->enabled && rms_.available()) {
|
||||
rms_cur = rms_.read();
|
||||
env_ = rms_cur + (alpha_ * (env_ - rms_cur));
|
||||
comp_.update_pwr(env_);
|
||||
}
|
||||
USBSERIAL.print("rxRigInLevel: ");
|
||||
USBSERIAL.println(c->rxRigInLevel);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
// volume
|
||||
if (set_value) {
|
||||
c->rxRigInVol = value;
|
||||
updateRxRigIn();
|
||||
}
|
||||
USBSERIAL.print("rxRigInVol: ");
|
||||
USBSERIAL.println(c->rxRigInVol);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
// calibration
|
||||
if (set_value) {
|
||||
c->rxRigInCal = value;
|
||||
updateRxRigIn();
|
||||
}
|
||||
USBSERIAL.print("rxRigInCal: ");
|
||||
USBSERIAL.println(c->rxRigInCal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'S':
|
||||
// Speaker output
|
||||
switch(parm) {
|
||||
case 'c':
|
||||
case 'C':
|
||||
// calibration
|
||||
if (set_value) {
|
||||
c->rxSpkrOutCal = value;
|
||||
updateRxSpkrOut();
|
||||
}
|
||||
USBSERIAL.print("rxSpkrOutCal: ");
|
||||
USBSERIAL.println(c->rxSpkrOutCal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
case 'L':
|
||||
// Line output
|
||||
switch(parm) {
|
||||
case 'l':
|
||||
case 'L':
|
||||
// level
|
||||
if (set_value) {
|
||||
c->rxLineOutLevel = int(value);
|
||||
updateRxLineOut();
|
||||
}
|
||||
USBSERIAL.print("rxLineOutLevel: ");
|
||||
USBSERIAL.println(c->rxLineOutLevel);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
// calibration
|
||||
if (set_value) {
|
||||
c->rxLineOutCal = value;
|
||||
updateRxLineOut();
|
||||
}
|
||||
USBSERIAL.print("rxLineOutCal: ");
|
||||
USBSERIAL.println(c->rxLineOutCal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
case 'U':
|
||||
// USB output
|
||||
switch(parm) {
|
||||
case 'c':
|
||||
case 'C':
|
||||
// calibration
|
||||
if (set_value) {
|
||||
c->rxUSBOutCal = value;
|
||||
updateRxUSBOut();
|
||||
}
|
||||
USBSERIAL.print("rxUSBOutCal: ");
|
||||
USBSERIAL.println(c->rxUSBOutCal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
//TX audio parameters
|
||||
switch(subcmd) {
|
||||
case 'm':
|
||||
case 'M':
|
||||
// Mic input
|
||||
switch(parm) {
|
||||
case 'g':
|
||||
case 'G':
|
||||
// mic gain
|
||||
if (set_value) {
|
||||
c->txMicInGain = int(value);
|
||||
updateTxMicIn();
|
||||
}
|
||||
USBSERIAL.print("txMicInGain: ");
|
||||
USBSERIAL.println(c->txMicInGain);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
// volume
|
||||
if (set_value) {
|
||||
c->txMicInVol = value;
|
||||
updateTxMicIn();
|
||||
}
|
||||
USBSERIAL.print("txMicInVol: ");
|
||||
USBSERIAL.println(c->txMicInVol);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
// calibration
|
||||
if (set_value) {
|
||||
c->txMicInCal = value;
|
||||
updateTxMicIn();
|
||||
}
|
||||
USBSERIAL.print("txMicInCal: ");
|
||||
USBSERIAL.println(c->txMicInCal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
case 'L':
|
||||
// Line input
|
||||
switch(parm) {
|
||||
case 'l':
|
||||
case 'L':
|
||||
// level
|
||||
if (set_value) {
|
||||
c->txLineInLevel = int(value);
|
||||
updateTxLineIn();
|
||||
}
|
||||
USBSERIAL.print("txLineInLevel: ");
|
||||
USBSERIAL.println(c->txLineInLevel);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
// volume
|
||||
if (set_value) {
|
||||
c->txLineInVol = value;
|
||||
updateTxLineIn();
|
||||
}
|
||||
USBSERIAL.print("txLineInVol: ");
|
||||
USBSERIAL.println(c->txLineInVol);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
// calibration
|
||||
if (set_value) {
|
||||
c->txLineInCal = value;
|
||||
updateTxLineIn();
|
||||
}
|
||||
USBSERIAL.print("txLineInCal: ");
|
||||
USBSERIAL.println(c->txLineInCal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
case 'U':
|
||||
// USB input
|
||||
switch(parm) {
|
||||
case 'v':
|
||||
case 'V':
|
||||
// volume
|
||||
if (set_value) {
|
||||
c->txUSBInVol = value;
|
||||
updateTxUSBIn();
|
||||
}
|
||||
USBSERIAL.print("txUSBInVol: ");
|
||||
USBSERIAL.println(c->txUSBInVol);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
// calibration
|
||||
if (set_value) {
|
||||
c->txUSBInCal = value;
|
||||
updateTxUSBIn();
|
||||
}
|
||||
USBSERIAL.print("txUSBInCal: ");
|
||||
USBSERIAL.println(c->txUSBInCal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
case 'R':
|
||||
// Rig output
|
||||
switch(parm) {
|
||||
case 'l':
|
||||
case 'L':
|
||||
// level
|
||||
if (set_value) {
|
||||
c->txRigOutLevel = int(value);
|
||||
updateTxRigOut();
|
||||
}
|
||||
USBSERIAL.print("txRigOutLevel: ");
|
||||
USBSERIAL.println(c->txRigOutLevel);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
// calibration
|
||||
if (set_value) {
|
||||
c->txRigOutCal = value;
|
||||
updateTxRigOut();
|
||||
}
|
||||
USBSERIAL.print("txRigOutCal: ");
|
||||
USBSERIAL.println(c->txRigOutCal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int lpFilter[5];
|
||||
int hpFilter[5];
|
||||
|
||||
void audioSSBFilter()
|
||||
{
|
||||
// calcBiquad(FilterType,FrequencyC,dBgain,Q,QuantizationUnit,SampleRate,int*);
|
||||
calcBiquad(FILTER_LOPASS, 3300, 0, 0.707, 524288, 44100, lpFilter);
|
||||
calcBiquad(FILTER_HIPASS, 100, 0, 0.707, 524288, 44100, hpFilter);
|
||||
audioCtrl.eqFilter(0, lpFilter);
|
||||
audioCtrl.eqFilter(1, hpFilter);
|
||||
audioCtrl.eqFilter(2, lpFilter);
|
||||
audioCtrl.eqFilter(3, hpFilter);
|
||||
audioCtrl.eqFilter(4, lpFilter);
|
||||
audioCtrl.eqFilter(5, hpFilter);
|
||||
}
|
||||
|
||||
void audioCWFilter()
|
||||
{
|
||||
// calcBiquad(FilterType,FrequencyC,dBgain,Q,QuantizationUnit,SampleRate,int*);
|
||||
calcBiquad(FILTER_LOPASS, 1300, 0, 0.707, 524288, 44100, lpFilter);
|
||||
calcBiquad(FILTER_HIPASS, 100, 0, 0.707, 524288, 44100, hpFilter);
|
||||
audioCtrl.eqFilter(0, lpFilter);
|
||||
audioCtrl.eqFilter(1, hpFilter);
|
||||
audioCtrl.eqFilter(2, lpFilter);
|
||||
audioCtrl.eqFilter(3, hpFilter);
|
||||
audioCtrl.eqFilter(4, lpFilter);
|
||||
audioCtrl.eqFilter(5, hpFilter);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// audioDigiFilter()
|
||||
// Create a very wide filter for digital modes... wider than the uBITX
|
||||
// needs, but just want to make sure we leave the full audio bandwidth
|
||||
// open for digimodes, while ensuring we've cut down any extraneous
|
||||
// noise outside the normal band.
|
||||
//======================================================================
|
||||
|
||||
void audioDigiFilter()
|
||||
{
|
||||
// calcBiquad(FilterType,FrequencyC,dBgain,Q,QuantizationUnit,SampleRate,int*);
|
||||
calcBiquad(FILTER_LOPASS, 5000, 0, 0.707, 524288, 44100, lpFilter);
|
||||
calcBiquad(FILTER_HIPASS, 100, 0, 0.707, 524288, 44100, hpFilter);
|
||||
audioCtrl.eqFilter(0, lpFilter);
|
||||
audioCtrl.eqFilter(1, hpFilter);
|
||||
audioCtrl.eqFilter(2, lpFilter);
|
||||
audioCtrl.eqFilter(3, hpFilter);
|
||||
audioCtrl.eqFilter(4, lpFilter);
|
||||
audioCtrl.eqFilter(5, hpFilter);
|
||||
}
|
||||
*/
|
||||
|
||||
int eqFilter1[5];
|
||||
|
||||
|
@ -10,7 +10,7 @@ IOPMessage inBuf; // input message buffer
|
||||
IOPMessage outBuf; // output message buffer
|
||||
|
||||
extern CATSwitch catPTT;
|
||||
extern Rig rig;
|
||||
extern basic_rig rig;
|
||||
|
||||
int received_mode = 0;
|
||||
|
||||
@ -57,27 +57,21 @@ void processIOPCommand(IOPMessage const& m)
|
||||
if (m.len < 1) {
|
||||
return;
|
||||
} else {
|
||||
rig.switchMode(rig_mode(m.data[0]));
|
||||
rig.set_rig_mode(static_cast<rig_mode>(m.data[0]));
|
||||
#if defined(DEBUG)
|
||||
switch(rig.modeNum()) {
|
||||
case cwr:
|
||||
USBDEBUG("new mode - CWR");
|
||||
break;
|
||||
case cw:
|
||||
switch(rig.get_rig_mode()) {
|
||||
case rig_mode::cw:
|
||||
USBDEBUG("new mode - CW");
|
||||
break;
|
||||
case lsb:
|
||||
USBDEBUG("new mode - LSB");
|
||||
case rig_mode::ssb:
|
||||
USBDEBUG("new mode - SSB");
|
||||
break;
|
||||
case usb:
|
||||
USBDEBUG("new mode - USB");
|
||||
break;
|
||||
case dig:
|
||||
case rig_mode::digi:
|
||||
USBDEBUG("new mode - DIG");
|
||||
break;
|
||||
default:
|
||||
char errormessage[32];
|
||||
sprintf(errormessage, "unknown mode command - %3d", rig.modeNum());
|
||||
sprintf(errormessage, "unknown mode command - %3d", rig.get_rig_mode());
|
||||
USBDEBUG("mode command not recognized");
|
||||
}
|
||||
#endif
|
||||
|
@ -121,12 +121,11 @@ class RigConfig {
|
||||
|
||||
// mode configuration
|
||||
ssb_config ssb;
|
||||
dig_config dig;
|
||||
digi_config digi;
|
||||
cw_config cw;
|
||||
|
||||
// General rig configuration entries.
|
||||
rig_mode numModes = num_rig_modes;
|
||||
rig_mode startMode = lsb;
|
||||
rig_mode mode = rig_mode::ssb;
|
||||
};
|
||||
|
||||
extern RigConfig rigConfig;
|
||||
|
101
ubitx_iop/menu.h
101
ubitx_iop/menu.h
@ -13,9 +13,6 @@
|
||||
//#include <vector>
|
||||
#include <initializer_list>
|
||||
#include "rig.h"
|
||||
#include "tx_audio_proc.h"
|
||||
|
||||
extern SpeechCompressor speechCompressor; // This should be somewhere else.
|
||||
|
||||
// 16 characters on display
|
||||
const int MAX_TEXT_LEN = 16;
|
||||
@ -211,11 +208,9 @@ class Parm_float : public Config_parm<float> {
|
||||
//======================================================================
|
||||
|
||||
const char modeID[] = {'s', 'S', 'c', 'C', 'd', 'D', 't', 'T'};
|
||||
const char* const filterID[num_rig_modes][num_rx_filters] = {
|
||||
{"2.8", "2.4", "1.8"}, // LSB
|
||||
{"2.8", "2.4", "1.8"}, // USB
|
||||
const char* const filterID[static_cast<int>(rig_mode::count)][static_cast<int>(rx_filter::count)] = {
|
||||
{"2.8", "2.4", "1.8"}, // SSB
|
||||
{"1.0", "500", "250"}, // CW
|
||||
{"1.0", "500", "250"}, // CWR
|
||||
{"2.8", "2.4", "500"}, // DIG
|
||||
};
|
||||
|
||||
@ -226,7 +221,7 @@ const char* const filterID[num_rig_modes][num_rx_filters] = {
|
||||
|
||||
class Main_menu : public Menu_item {
|
||||
public:
|
||||
Main_menu(Rig& rig): menu_title("Main Menu"), rig(rig), adjust_tx(false), comp_on(false) {}
|
||||
Main_menu(basic_rig& rig): menu_title("Main Menu"), rig_(rig), adjust_tx(false) {}
|
||||
|
||||
virtual const Menu_string& title() const {
|
||||
return menu_title;
|
||||
@ -240,33 +235,12 @@ class Main_menu : public Menu_item {
|
||||
char text[max_text_len+1];
|
||||
sprintf(text, "%1cR:%3s %1cT:%3s ",
|
||||
adjust_tx ? ' ' : menu_selection_char,
|
||||
filterID[rig.modeNum()][rig.filterNum()],
|
||||
filterID[static_cast<size_t>(rig_.get_rig_mode())][static_cast<size_t>(rig_.get_rx_filter())],
|
||||
adjust_tx ? menu_selection_char : ' ',
|
||||
rig.isSSBMode() && comp_on ? "CMP" : " ");
|
||||
rig_.is_ssb_mode() && rig_.config().ssb.comp.enabled ? "CMP" : " ");
|
||||
outstr.assign(text);
|
||||
}
|
||||
|
||||
/*
|
||||
virtual void update() {
|
||||
sprintf(_text0, "%1cR:%3s %1cT:%3s ",
|
||||
_adjust_tx ? ' ' : MENU_SELECTED_CHAR,
|
||||
filterID[_rig.modeNum()][_rig.filterNum()],
|
||||
_adjust_tx ? MENU_SELECTED_CHAR : ' ',
|
||||
_rig.isSSBMode() && _comp_on ? "CMP" : " ");
|
||||
if ((strcmp(_text0, _text1) != 0) || _dirty) {
|
||||
if (_visible) {
|
||||
sendIOPMenuDisplay(_text0);
|
||||
USBDEBUG("updating menu:");
|
||||
USBDEBUG(_text0);
|
||||
} else {
|
||||
sendIOPMenuInactive();
|
||||
USBDEBUG("deactivating menu");
|
||||
}
|
||||
_dirty = false;
|
||||
strncpy(_text1, _text0, MAX_TEXT_LEN);
|
||||
}
|
||||
}
|
||||
*/
|
||||
virtual Menu_item* select() {
|
||||
adjust_tx = !adjust_tx;
|
||||
return this;
|
||||
@ -282,79 +256,40 @@ class Main_menu : public Menu_item {
|
||||
|
||||
virtual Menu_item* prev() {
|
||||
if (adjust_tx) {
|
||||
if (rig.isSSBMode()) {
|
||||
comp_on = !comp_on;
|
||||
if (comp_on)
|
||||
speechCompressor.enable();
|
||||
if (rig_.is_ssb_mode()) {
|
||||
rig_.config().ssb.comp.enabled = !rig_.config().ssb.comp.enabled;
|
||||
if (rig_.config().ssb.comp.enabled)
|
||||
rig_.enable_comp();
|
||||
else
|
||||
speechCompressor.disable();
|
||||
rig_.disable_comp();
|
||||
}
|
||||
} else {
|
||||
rig.switchRxFilter(true);
|
||||
rig_.prev_rx_filter();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual Menu_item* next() {
|
||||
if (adjust_tx) {
|
||||
if (rig.isSSBMode()) {
|
||||
comp_on = !comp_on;
|
||||
if (comp_on)
|
||||
speechCompressor.enable();
|
||||
if (rig_.is_ssb_mode()) {
|
||||
rig_.config().ssb.comp.enabled = !rig_.config().ssb.comp.enabled;
|
||||
if (rig_.config().ssb.comp.enabled)
|
||||
rig_.enable_comp();
|
||||
else
|
||||
speechCompressor.disable();
|
||||
rig_.disable_comp();
|
||||
}
|
||||
} else {
|
||||
rig.switchRxFilter();
|
||||
rig_.next_rx_filter();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private:
|
||||
Menu_string menu_title;
|
||||
Rig& rig;
|
||||
basic_rig& rig_;
|
||||
bool adjust_tx;
|
||||
bool comp_on;
|
||||
};
|
||||
|
||||
/*
|
||||
public class MenuItem {
|
||||
public:
|
||||
MenuItem(bool active = true, int timeout = 0): _active(active), _timeout(timeout), _elapsed(0) {}
|
||||
void update() {
|
||||
if ((_timeout > 0) && (_elapsed > _timeout)) {
|
||||
_active = false;
|
||||
}
|
||||
}
|
||||
inline void activate() { _active = true; _elapsed = 0; }
|
||||
inline void deactivate() { _active = false; }
|
||||
virtual MenuItem* accept();
|
||||
virtual MenuItem* reject();
|
||||
virtual MenuItem* next();
|
||||
virtual MenuItem* prev();
|
||||
|
||||
private:
|
||||
bool _active;
|
||||
int _timeout;
|
||||
elapsedMillis _elapsed;
|
||||
};
|
||||
|
||||
public class SSBMenu {
|
||||
public:
|
||||
private:
|
||||
};
|
||||
|
||||
public class DigiMenu {
|
||||
public:
|
||||
private:
|
||||
}
|
||||
|
||||
public class CWMenu {
|
||||
public:
|
||||
private:
|
||||
};
|
||||
*/
|
||||
|
||||
extern const Menu_item* audio_config_menu;
|
||||
|
||||
#endif
|
||||
|
293
ubitx_iop/rig.h
293
ubitx_iop/rig.h
@ -8,143 +8,80 @@
|
||||
#include <iopcomm.h>
|
||||
#include "audio.h"
|
||||
#include "RigMode.h"
|
||||
//#include "menu.h"
|
||||
|
||||
//======================================================================
|
||||
// Rig class
|
||||
// basic_rig
|
||||
//======================================================================
|
||||
|
||||
class Rig {
|
||||
class basic_rig {
|
||||
public:
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Constructor/destructor.
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
Rig(RigConfig& c, RigAudio& a): _config(c), _audio(a), _filter(wide)
|
||||
{
|
||||
_modes = new IMode*[c.numModes];
|
||||
_modesLen = c.numModes;
|
||||
_modesIndex = c.startMode;
|
||||
basic_rig(RigConfig& c, RigAudio& a) :
|
||||
config_(c), audio_(a),
|
||||
bpf_(),
|
||||
comp_(&config_.ssb.comp),
|
||||
ssb_ (config_.ssb, audio_, bpf_, comp_),
|
||||
cw_ (config_.cw, audio_, bpf_),
|
||||
digi_(config_.digi, audio_, bpf_) { set_rig_mode(config_.mode); }
|
||||
|
||||
// for (int i = 0; i < 16; i++) { _modeText[i] = ' '; }
|
||||
// _modeText[16] = '\0';
|
||||
/* _modes[RIG_MODE_LSB] = new SSBMode(c.lsb, a);
|
||||
_modes[RIG_MODE_USB] = new SSBMode(c.usb, a);
|
||||
_modes[RIG_MODE_CWL] = new CWMode(c.cwl, a);
|
||||
_modes[RIG_MODE_CWU] = new CWMode(c.cwu, a);
|
||||
_modes[RIG_MODE_DGL] = new DGTMode(c.dgl, a);
|
||||
_modes[RIG_MODE_DGU] = new DGTMode(c.dgu, a);
|
||||
_modes[RIG_MODE_TTL] = new TTMode(c.ttl, a);
|
||||
_modes[RIG_MODE_TTU] = new TTMode(c.ttu, a);*/
|
||||
/*
|
||||
_rxFilters = new (IFilter*)[num_rx_filters];
|
||||
_rxFiltersLen = num_rx_filters;
|
||||
_rxFiltersIndex = 0; // need to get default filter from current mode...
|
||||
_rxFilters[wide] = mode()->filterWide();
|
||||
_rxFilters[medium] = mode()->filterMedium();
|
||||
_rxFilters[narrow] = mode()->filterNarrow();
|
||||
*/
|
||||
}
|
||||
void init() {}
|
||||
|
||||
~Rig()
|
||||
{
|
||||
for (unsigned i = 0; i < _modesLen; i++) {
|
||||
delete _modes[i];
|
||||
}
|
||||
delete _modes;
|
||||
}
|
||||
|
||||
void init() {
|
||||
switchRxFilter(_filter);
|
||||
}
|
||||
RigConfig& config() { return config_; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Mode control.
|
||||
//--------------------------------------------------------------------
|
||||
/*
|
||||
const char* modeText() {
|
||||
sprintf(_modeText, "%1c- %6s %6s", modeID[_modesIndex],
|
||||
mode()->rxInfo(), mode()->txInfo());
|
||||
return _modeText;
|
||||
}
|
||||
*/
|
||||
inline bool isSSBMode() const { return (_modesIndex == usb || _modesIndex == lsb); }
|
||||
// inline bool isUSBMode() const { return (_modesIndex == usb); }
|
||||
// inline bool isLSBMode() const { return (_modesIndex == lsb); }
|
||||
inline bool isDIGMode() const { return (_modesIndex == dig); }
|
||||
inline bool isCWMode() const { return (_modesIndex == cw || _modesIndex == cwr); }
|
||||
// inline bool isCWUMode() const { return (_modesIndex == RIG_MODE_CWU); }
|
||||
// inline bool isCWLMode() const { return (_modesIndex == RIG_MODE_CWL); }
|
||||
|
||||
// Assign a pointer to a mode object. Returns true if successful, false otherwise.
|
||||
bool addNewMode(rig_mode i, IMode* mode) {
|
||||
if (i > _modesLen) {
|
||||
return false;
|
||||
} else {
|
||||
_modes[i] = mode;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
inline bool is_ssb_mode() const { return (config_.mode == rig_mode::ssb ); }
|
||||
inline bool is_digi_mode() const { return (config_.mode == rig_mode::digi); }
|
||||
inline bool is_cw_mode() const { return (config_.mode == rig_mode::cw ); }
|
||||
|
||||
// Returns a pointer to the current mode.
|
||||
inline IMode* mode() const {
|
||||
return _modes[_modesIndex];
|
||||
}
|
||||
|
||||
// Returns the array index of the current mode.
|
||||
inline rig_mode modeNum() const {
|
||||
return _modesIndex;
|
||||
}
|
||||
|
||||
/* // Returns a pointer to the specified mode.
|
||||
inline IMode* mode(RigMode m) const {
|
||||
return _modes[m];
|
||||
}*/
|
||||
|
||||
// Switch to the mode specified by the provided index. Returns a
|
||||
// pointer to the new mode.
|
||||
IMode* switchMode(rig_mode i) {
|
||||
// Switch to the specified mode. Returns a pointer to the new mode.
|
||||
basic_mode* set_rig_mode(rig_mode m) {
|
||||
// exit the previous mode
|
||||
mode()->exit(); // NOTE: This could currently occur during TX, which is NOT desirable.
|
||||
current_mode_->exit(); // NOTE: This could currently occur during TX, which is NOT desirable.
|
||||
|
||||
// select the new mode
|
||||
_modesIndex = rig_mode(i % _modesLen);
|
||||
config_.mode = m;
|
||||
|
||||
switch(config_.mode) {
|
||||
case rig_mode::ssb:
|
||||
current_mode_ = &ssb_;
|
||||
break;
|
||||
|
||||
case rig_mode::cw:
|
||||
current_mode_ = &cw_;
|
||||
break;
|
||||
|
||||
case rig_mode::digi:
|
||||
current_mode_ = &digi_;
|
||||
break;
|
||||
}
|
||||
|
||||
//enter the new mode
|
||||
mode()->enter();
|
||||
current_mode_->enter();
|
||||
|
||||
// return a pointer to the new mode
|
||||
return mode();
|
||||
return current_mode_;
|
||||
}
|
||||
|
||||
// Advance to the next (or previous) mode. Returns a pointer to the
|
||||
// new mode.
|
||||
IMode* switchMode(bool prev=false) {
|
||||
// Returns the rig_mode (enum) of the current mode object.
|
||||
inline rig_mode get_rig_mode() const { return config_.mode; }
|
||||
|
||||
// exit the previous mode
|
||||
mode()->exit();
|
||||
|
||||
// select the new mode
|
||||
if (prev) {
|
||||
_modesIndex = rig_mode(_modesIndex > 0 ? _modesIndex - 1 : _modesLen - 1);
|
||||
} else {
|
||||
_modesIndex = rig_mode((_modesIndex + 1) % _modesLen);
|
||||
}
|
||||
|
||||
// enter the new mode
|
||||
mode()->enter();
|
||||
|
||||
// return a pointer to the new mode
|
||||
return mode();
|
||||
}
|
||||
// Returns a pointer to the current mode object.
|
||||
inline basic_mode* mode() const { return current_mode_; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Transmit/Receive (T/R) control.
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
inline bool isTx() const { return mode()->isTx(); }
|
||||
inline bool isRx() const { return mode()->isRx(); }
|
||||
inline bool is_tx() const { return mode()->is_tx(); }
|
||||
inline bool is_rx() const { return mode()->is_rx(); }
|
||||
|
||||
// Enter the transmit state. This is delegated to the mode.
|
||||
inline void tx() { mode()->tx(); }
|
||||
@ -156,178 +93,144 @@ class Rig {
|
||||
// Transmit processor control.
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void switchProcessor(bool prev=false) {
|
||||
inline void enable_comp() {
|
||||
if (is_ssb_mode()) ((ssb_mode*)mode())->enable_comp();
|
||||
}
|
||||
|
||||
inline void disable_comp() {
|
||||
if (is_ssb_mode()) ((ssb_mode*)mode())->disable_comp();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// RX filter control.
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
inline void setWideRxFilter() {
|
||||
_filter = wide;
|
||||
mode()->setWideRxFilter();
|
||||
USBDEBUG("selected wide RX filter");
|
||||
}
|
||||
// Set the RX filter. This is delegated to the mode.
|
||||
inline void set_rx_filter(rx_filter f) { mode()->set_rx_filter(f); }
|
||||
|
||||
inline void setMediumRxFilter() {
|
||||
_filter = medium;
|
||||
mode()->setMediumRxFilter();
|
||||
USBDEBUG("selected medium RX filter");
|
||||
}
|
||||
// Returns the rx_filter (enum) of the RX filter currently being used.
|
||||
inline rx_filter get_rx_filter() const { return mode()->config().filter; }
|
||||
|
||||
inline void setNarrowRxFilter() {
|
||||
_filter = narrow;
|
||||
mode()->setNarrowRxFilter();
|
||||
USBDEBUG("selected narrow RX filter");
|
||||
}
|
||||
|
||||
void switchRxFilter(rx_filter f) {
|
||||
switch(f) {
|
||||
case wide:
|
||||
setWideRxFilter();
|
||||
void next_rx_filter() {
|
||||
switch(mode()->config().filter) {
|
||||
case rx_filter::wide:
|
||||
set_rx_filter(rx_filter::medium);
|
||||
break;
|
||||
|
||||
case medium:
|
||||
setMediumRxFilter();
|
||||
case rx_filter::medium:
|
||||
set_rx_filter(rx_filter::narrow);
|
||||
break;
|
||||
|
||||
case narrow:
|
||||
setNarrowRxFilter();
|
||||
case rx_filter::narrow:
|
||||
set_rx_filter(rx_filter::wide);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void switchRxFilter(bool prev=false) {
|
||||
rx_filter f;
|
||||
if (prev) {
|
||||
f = rx_filter(_filter > 0 ? _filter - 1 : num_rx_filters - 1);
|
||||
} else {
|
||||
f = rx_filter((_filter + 1) % num_rx_filters);
|
||||
void prev_rx_filter() {
|
||||
switch(mode()->config().filter) {
|
||||
case rx_filter::wide:
|
||||
set_rx_filter(rx_filter::narrow);
|
||||
break;
|
||||
|
||||
case rx_filter::medium:
|
||||
set_rx_filter(rx_filter::wide);
|
||||
break;
|
||||
|
||||
case rx_filter::narrow:
|
||||
set_rx_filter(rx_filter::medium);
|
||||
break;
|
||||
}
|
||||
switchRxFilter(f);
|
||||
}
|
||||
|
||||
// Returns the array index of the current mode.
|
||||
inline rx_filter filterNum() const {
|
||||
return _filter;
|
||||
}
|
||||
|
||||
/*
|
||||
// Returns a pointer to the current RX filter.
|
||||
IFilter* rxFilter() {
|
||||
return _rxFilters[_rxFiltersIndex];
|
||||
}
|
||||
|
||||
IFilter* switchRxFilter(bool prev=false) {
|
||||
if (prev) {
|
||||
_rxFiltersIndex--;
|
||||
} else {
|
||||
_rxFiltersIndex++;
|
||||
}
|
||||
_rxFiltersIndex %= _rxFiltersLen;
|
||||
return _rxFiltersList[_rxFiltersIndex];
|
||||
}
|
||||
|
||||
IFilter* switchRxFilterWide() {
|
||||
}
|
||||
|
||||
IFilter* switchFilterMedium() {
|
||||
|
||||
}
|
||||
|
||||
IFilter* switchFilterNarrow() {
|
||||
|
||||
}
|
||||
*/
|
||||
//--------------------------------------------------------------------
|
||||
// Audio output control.
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
inline void muteSpkrOut() const {
|
||||
_audio.muteSpkrOut();
|
||||
audio_.muteSpkrOut();
|
||||
}
|
||||
|
||||
inline void unmuteSpkrOut() const {
|
||||
_audio.unmuteSpkrOut();
|
||||
audio_.unmuteSpkrOut();
|
||||
}
|
||||
|
||||
inline void muteLineOut() const {
|
||||
_audio.muteLineOut();
|
||||
audio_.muteLineOut();
|
||||
}
|
||||
|
||||
inline void unmuteLineOut() const {
|
||||
_audio.unmuteLineOut();
|
||||
audio_.unmuteLineOut();
|
||||
}
|
||||
|
||||
inline void muteUSBOut() const {
|
||||
_audio.muteUSBOut();
|
||||
audio_.muteUSBOut();
|
||||
}
|
||||
|
||||
inline void unmuteUSBOut() const {
|
||||
_audio.unmuteUSBOut();
|
||||
audio_.unmuteUSBOut();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Audio input control.
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
inline void muteAllTx() const {
|
||||
_audio.muteAllTx();
|
||||
audio_.muteAllTx();
|
||||
}
|
||||
|
||||
inline void muteMicIn() const {
|
||||
_audio.muteMicIn();
|
||||
audio_.muteMicIn();
|
||||
}
|
||||
|
||||
inline void unmuteMicIn() const {
|
||||
_audio.unmuteMicIn();
|
||||
audio_.unmuteMicIn();
|
||||
}
|
||||
|
||||
inline void muteLineIn() const {
|
||||
_audio.muteLineIn();
|
||||
audio_.muteLineIn();
|
||||
}
|
||||
|
||||
inline void unmuteLineIn() const {
|
||||
_audio.unmuteLineIn();
|
||||
audio_.unmuteLineIn();
|
||||
}
|
||||
|
||||
inline void muteUSBIn() const {
|
||||
_audio.muteUSBIn();
|
||||
audio_.muteUSBIn();
|
||||
}
|
||||
|
||||
inline void unmuteUSBIn() const {
|
||||
_audio.unmuteUSBOut();
|
||||
audio_.unmuteUSBOut();
|
||||
}
|
||||
|
||||
inline void muteTTIn() const {
|
||||
_audio.muteTTIn();
|
||||
audio_.muteTTIn();
|
||||
}
|
||||
|
||||
inline void unmuteTTIn() const {
|
||||
_audio.unmuteTTIn();
|
||||
audio_.unmuteTTIn();
|
||||
}
|
||||
|
||||
// Update the rig state. This should be called once each time through
|
||||
// the main loop.
|
||||
void update()
|
||||
{
|
||||
comp_.update(); // It checks if it's enabled on its own.
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
RigConfig& _config;
|
||||
RigAudio& _audio;
|
||||
RigConfig& config_;
|
||||
RigAudio& audio_;
|
||||
|
||||
IMode** _modes;
|
||||
rig_mode _modesLen;
|
||||
rig_mode _modesIndex;
|
||||
bp_filter bpf_;
|
||||
speech_comp comp_;
|
||||
|
||||
rx_filter _filter;
|
||||
ssb_mode ssb_;
|
||||
cw_mode cw_;
|
||||
digi_mode digi_;
|
||||
|
||||
// char _modeText[17];
|
||||
|
||||
/*
|
||||
IFilter** _rxFilters;
|
||||
uint8_t _rxFiltersLen;
|
||||
uint8_t _rxFiltersIndex;
|
||||
*/
|
||||
basic_mode* current_mode_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,46 +0,0 @@
|
||||
//======================================================================
|
||||
// tx_audio_proc.h
|
||||
//
|
||||
// Classes/functions for processing transmit audio.
|
||||
//======================================================================
|
||||
|
||||
#ifndef __tx_audio_proc_h__
|
||||
#define __tx_audio_proc_h__
|
||||
|
||||
#include <Audio.h>
|
||||
#include <effect_compressor_fb.h>
|
||||
|
||||
class IAudioProcessor
|
||||
{
|
||||
public:
|
||||
virtual ~IAudioProcessor() {}
|
||||
virtual bool isEnabled() const = 0;
|
||||
virtual void enable() = 0;
|
||||
virtual void disable() = 0;
|
||||
virtual void update() = 0;
|
||||
};
|
||||
|
||||
class SpeechCompressor : public IAudioProcessor
|
||||
{
|
||||
public:
|
||||
SpeechCompressor(AudioEffectCompressor&, AudioAmplifier&, AudioAnalyzeRMS&);
|
||||
//void config(AudioEffectCompressor*, AudioAnalyzeRMS*);
|
||||
virtual bool isEnabled() const;
|
||||
virtual void enable();
|
||||
virtual void disable();
|
||||
virtual void update();
|
||||
|
||||
private:
|
||||
AudioEffectCompressor& _compress;
|
||||
AudioAmplifier& _amp;
|
||||
AudioAnalyzeRMS& _rms;
|
||||
float _env = 0.0;
|
||||
float _alpha = 0.8;
|
||||
bool _enabled = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
@ -1,53 +0,0 @@
|
||||
//======================================================================
|
||||
// tx_audio_proc.ino
|
||||
//
|
||||
// Classes/functions for processing transmit audio.
|
||||
//======================================================================
|
||||
|
||||
#include "tx_audio_proc.h"
|
||||
|
||||
SpeechCompressor::SpeechCompressor(AudioEffectCompressor& comp, AudioAmplifier& amp, AudioAnalyzeRMS& rms):
|
||||
_compress(comp), _amp(amp), _rms(rms)
|
||||
{
|
||||
}
|
||||
|
||||
//void SpeechCompressor::config(AudioEffectCompressor* comp, AudioAnalyzeRMS* rms)
|
||||
//{
|
||||
// _compress = comp;
|
||||
// _rms = rms;
|
||||
//}
|
||||
|
||||
bool SpeechCompressor::isEnabled() const
|
||||
{
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
void SpeechCompressor::enable()
|
||||
{
|
||||
_enabled = true;
|
||||
_compress.begin(1, 0.1, 20); // Need to make configurable
|
||||
_amp.gain(2.0);
|
||||
}
|
||||
|
||||
void SpeechCompressor::disable()
|
||||
{
|
||||
_enabled = false;
|
||||
_compress.disable();
|
||||
_amp.gain(1.0);
|
||||
}
|
||||
|
||||
// Speech compressor code based on post by 'hyperdyne': https://forum.pjrc.com/threads/36245-Changing-Pitch-of-Voice
|
||||
|
||||
void SpeechCompressor::update()
|
||||
{
|
||||
float rms_cur;
|
||||
if (_enabled && _rms.available()) {
|
||||
rms_cur = _rms.read();
|
||||
_env = rms_cur + (_alpha * (_env - rms_cur));
|
||||
_compress.update_pwr(_env);
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
@ -16,13 +16,7 @@ Keyer keyer{15, 3.0}; // NOTE: make configurable
|
||||
|
||||
RigConfig rigConfig;
|
||||
RigAudio rigAudio{rigConfig.audio};
|
||||
Rig rig{rigConfig, rigAudio};
|
||||
|
||||
BPFilter rxFilter{300, 3100, false};
|
||||
|
||||
SSBMode ssbMode{rigConfig.ssb, rigAudio, rxFilter};
|
||||
DGTMode digMode{rigConfig.dig, rigAudio, rxFilter};
|
||||
CWMode cwMode {rigConfig.cw, rigAudio, rxFilter};
|
||||
basic_rig rig{rigConfig, rigAudio};
|
||||
|
||||
CATSwitch catPTT;
|
||||
//MicSwitch micPTTHelper;
|
||||
@ -54,16 +48,6 @@ void setup() {
|
||||
|
||||
AudioMemory(16); // NOTE: Need to fine tune this. Have had errors due to this being too low.
|
||||
|
||||
// initialize the filter(s)
|
||||
rxFilter.init();
|
||||
|
||||
// adding all of the modes to the rig
|
||||
rig.addNewMode(lsb, &ssbMode);
|
||||
rig.addNewMode(usb, &ssbMode);
|
||||
rig.addNewMode(cw, &cwMode);
|
||||
rig.addNewMode(cwr, &cwMode);
|
||||
rig.addNewMode(dig, &digMode);
|
||||
|
||||
initKeyLine();
|
||||
rigAudio.init();
|
||||
|
||||
@ -78,14 +62,6 @@ void setup() {
|
||||
rig.init();
|
||||
|
||||
USBDEBUG("setup completed");
|
||||
// audioInit();
|
||||
/*
|
||||
#if defined(FACTORY_CALIBRATION)
|
||||
setRigMode(RIG_MODE_TEST);
|
||||
#else
|
||||
setRigMode(RIG_MODE_SSB);
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
@ -118,13 +94,13 @@ void loop()
|
||||
|
||||
frameCounter++;
|
||||
|
||||
if (rig.isCWMode()) {
|
||||
if (rig.is_cw_mode()) {
|
||||
if (keyer.do_paddles()) {
|
||||
|
||||
// Checking for T/R separately from the paddle loop, because it's
|
||||
// possible we're already transmitting (PTT/Key being held), and
|
||||
// we don't want to run the tx() actions if we're already in TX.
|
||||
if (rig.isRx()) {
|
||||
if (rig.is_rx()) {
|
||||
USBDEBUG("entered TX via paddles");
|
||||
rig.tx();
|
||||
}
|
||||
@ -154,21 +130,21 @@ void loop()
|
||||
|
||||
rig.update();
|
||||
|
||||
oldRigMode = rig.modeNum();
|
||||
oldRigMode = rig.get_rig_mode();
|
||||
|
||||
// Update the mic PTT. We need to tell it if we're in SSB mode, so that
|
||||
// it knows if it should switch to the mic input if pressed. We also
|
||||
// need to make it inactive if we're in DGT mode, since only CAT will be
|
||||
// used to start transmitting in that case.
|
||||
micPTT.setSSBMode(rig.isSSBMode());
|
||||
micPTT.update(rig.mode(), !rig.isDIGMode());
|
||||
micPTT.setSSBMode(rig.is_ssb_mode());
|
||||
micPTT.update(rig.mode(), !rig.is_digi_mode());
|
||||
|
||||
// Update the line PTT. We need to tell it if we're in SSB mode, so that
|
||||
// it knows if it should switch to the line input if pressed. We also
|
||||
// need to make it inactive if we're in DGT mode, since only CAT will be
|
||||
// used to start transmitting in that case.
|
||||
linePTT.setSSBMode(rig.isSSBMode());
|
||||
linePTT.update(rig.mode(), !rig.isDIGMode());
|
||||
linePTT.setSSBMode(rig.is_ssb_mode());
|
||||
linePTT.update(rig.mode(), !rig.is_digi_mode());
|
||||
|
||||
serviceCAT();
|
||||
|
||||
@ -237,9 +213,7 @@ void loop()
|
||||
USBDEBUG("updated main menu");
|
||||
}
|
||||
|
||||
// update the speech compressor. Really should do this elsewhere.
|
||||
if (speechCompressor.isEnabled())
|
||||
speechCompressor.update();
|
||||
rig.update();
|
||||
|
||||
if (frameMillis > 5000) {
|
||||
#if defined(DEBUG)
|
||||
|
Loading…
Reference in New Issue
Block a user