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.)
|
* (e.g. USB, LSB, etc.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum rig_mode {
|
enum struct rig_mode {
|
||||||
lsb = 0,
|
ssb = 0,
|
||||||
usb,
|
|
||||||
cw,
|
cw,
|
||||||
cwr,
|
digi,
|
||||||
dig,
|
|
||||||
// add new items here
|
// add new items here
|
||||||
num_rig_modes
|
count
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Keyer modes.
|
/* Keyer modes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum keyer_mode {
|
enum struct keyer_mode {
|
||||||
straight = 0,
|
straight = 0,
|
||||||
iambic_a,
|
iambic_a,
|
||||||
iambic_b,
|
iambic_b,
|
||||||
//ultimatic,
|
//ultimatic,
|
||||||
//bug,
|
//bug,
|
||||||
// add any new items here
|
// add any new items here
|
||||||
num_keyer_modes
|
count
|
||||||
};
|
};
|
||||||
|
|
||||||
enum rx_filter {
|
enum struct rx_filter {
|
||||||
wide = 0,
|
wide = 0,
|
||||||
medium,
|
medium,
|
||||||
narrow,
|
narrow,
|
||||||
num_rx_filters
|
count
|
||||||
};
|
};
|
||||||
|
|
||||||
enum digi_mode {
|
enum struct digi_submode {
|
||||||
rtty = 0,
|
rtty = 0,
|
||||||
psk31,
|
psk31,
|
||||||
user_defined,
|
user_defined,
|
||||||
num_digi_modes
|
count
|
||||||
};
|
};
|
||||||
|
|
||||||
//const unsigned char RIG_MODE_LETTER[num_rig_modes] = {'s', 'S', 'c', 'C', 'd', 'D', 't', 'T'};
|
//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.
|
// Interface to a configuration object.
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
struct filter_config {
|
struct bpf_config {
|
||||||
float lo;
|
float lo_freq;
|
||||||
float hi;
|
float hi_freq;
|
||||||
float gain;
|
float gain;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mode_config {
|
struct mode_config {
|
||||||
mode_config(bool usb, rx_filter f, const filter_config *fc) : is_usb(usb), filter(f) {
|
mode_config(bool usb, rx_filter f, const bpf_config *fc) : is_usb(usb), filter(f) {
|
||||||
for (int i = 0; i < num_rx_filters; i++) {
|
for (int i = 0; i < static_cast<int>(rx_filter::count); i++) {
|
||||||
filtercfg[i] = fc[i];
|
filter_cfg[i] = fc[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool is_usb;
|
bool is_usb;
|
||||||
rx_filter filter;
|
rx_filter filter;
|
||||||
filter_config filtercfg[num_rx_filters];
|
bpf_config filter_cfg[static_cast<size_t>(rx_filter::count)];
|
||||||
};
|
};
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// SSB CONFIGURATION
|
// SSB CONFIGURATION
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
const filter_config ssb_filter_config[num_rx_filters] =
|
const bpf_config ssb_filter_config[] =
|
||||||
{filter_config{ 300.0, 3100.0, 1.0},
|
{bpf_config{ 300.0, 3100.0, 1.0},
|
||||||
filter_config{ 500.0, 2900.0, 1.0},
|
bpf_config{ 500.0, 2900.0, 1.0},
|
||||||
filter_config{ 700.0, 2500.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 {
|
struct ssb_config : public mode_config {
|
||||||
ssb_config() : mode_config(true, wide, ssb_filter_config) {}
|
ssb_config() : mode_config(true, rx_filter::wide, ssb_filter_config) {}
|
||||||
// speech compressor parameters
|
comp_config comp;
|
||||||
bool comp_enable = false;
|
|
||||||
float comp_threshold = 0.1;
|
|
||||||
float comp_ratio = 20.0;
|
|
||||||
float comp_gain = 2.0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// DIG CONFIGURATION
|
// DIGI CONFIGURATION
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
const filter_config dig_filter_config[num_rx_filters] =
|
const bpf_config digi_filter_config[] =
|
||||||
{filter_config{ 300.0, 3100.0, 1.0},
|
{bpf_config{ 300.0, 3100.0, 1.0},
|
||||||
filter_config{ 500.0, 2900.0, 1.0},
|
bpf_config{ 500.0, 2900.0, 1.0},
|
||||||
filter_config{1250.0, 1750.0, 1.0}};
|
bpf_config{1250.0, 1750.0, 1.0}};
|
||||||
|
|
||||||
struct dig_config : public mode_config {
|
struct digi_config : public mode_config {
|
||||||
dig_config() : mode_config(true, wide, dig_filter_config) {}
|
digi_config() : mode_config(true, rx_filter::wide, digi_filter_config) {}
|
||||||
digi_mode submode = user_defined;
|
digi_submode submode = digi_submode::user_defined;
|
||||||
};
|
};
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// CW CONFIGURATION
|
// CW CONFIGURATION
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
const filter_config cw_filter_config[num_rx_filters] =
|
const bpf_config cw_filter_config[] =
|
||||||
{filter_config{ 300.0, 1300.0, 1.0},
|
{bpf_config{ 300.0, 1300.0, 1.0},
|
||||||
filter_config{ 450.0, 950.0, 1.0},
|
bpf_config{ 450.0, 950.0, 1.0},
|
||||||
filter_config{ 575.0, 825.0, 1.0}};
|
bpf_config{ 575.0, 825.0, 1.0}};
|
||||||
|
|
||||||
struct cw_config : public mode_config {
|
struct cw_config : public mode_config {
|
||||||
cw_config() : mode_config(true, wide, cw_filter_config) {}
|
cw_config() : mode_config(true, rx_filter::wide, cw_filter_config) {}
|
||||||
keyer_mode mode = iambic_a;
|
keyer_mode mode = keyer_mode::iambic_a;
|
||||||
// flags
|
// flags
|
||||||
bool reversed = false;
|
bool reversed = false;
|
||||||
// parameters
|
// parameters
|
||||||
|
|
|
@ -7,147 +7,160 @@
|
||||||
|
|
||||||
#include "audio.h"
|
#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:
|
public:
|
||||||
|
|
||||||
IMode(mode_config& c, RigAudio& a, IFilter& f):
|
basic_mode(mode_config& c, RigAudio& a, bp_filter& f) :
|
||||||
_config(c), _audio(a), _filter(f), _active(false), _transmitting(false)
|
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
|
// 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
|
// "clean", i.e. that it still needs to enable anything it needs for
|
||||||
// use in the mode.
|
// use in the mode.
|
||||||
virtual void onEntry() = 0;
|
virtual void on_entry() = 0;
|
||||||
|
|
||||||
// Called upon mode exit. Should clean everything up that it used,
|
// Called upon mode exit. Should clean everything up that it used,
|
||||||
// and not make assumptions about which mode is being entered next.
|
// and not make assumptions about which mode is being entered next.
|
||||||
virtual void onExit() = 0;
|
virtual void on_exit() = 0;
|
||||||
|
|
||||||
// Called when transmitting.
|
// Called when transmitting.
|
||||||
virtual void onTx() = 0;
|
virtual void on_tx() = 0;
|
||||||
|
|
||||||
// Called when receiving.
|
// Called when receiving.
|
||||||
virtual void onRx() = 0;
|
virtual void on_rx() = 0;
|
||||||
|
|
||||||
inline void enter() {
|
inline void enter() {
|
||||||
if (_active) {
|
if (active_) {
|
||||||
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
||||||
//throw MODE_ALREADY_ACTIVE;
|
//throw MODE_ALREADY_ACTIVE;
|
||||||
USBDEBUG("ERROR - tried to enter mode, but it's already active");
|
USBDEBUG("ERROR - tried to enter mode, but it's already active");
|
||||||
} else {
|
} else {
|
||||||
_active = true;
|
active_ = true;
|
||||||
onEntry();
|
on_entry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void exit() {
|
inline void exit() {
|
||||||
if (_transmitting) {
|
if (transmitting_) {
|
||||||
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
||||||
//throw MODE_STILL_TRANSMITTING;
|
//throw MODE_STILL_TRANSMITTING;
|
||||||
USBDEBUG("ERROR - tried to exit mode, but it's transmitting");
|
USBDEBUG("ERROR - tried to exit mode, but it's transmitting");
|
||||||
} else {
|
} else {
|
||||||
_active = false;
|
active_ = false;
|
||||||
onExit();
|
on_exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isActive() { return _active; }
|
inline bool is_active() { return active_; }
|
||||||
inline bool isInactive() { return !_active; }
|
inline bool is_inactive() { return !active_; }
|
||||||
|
|
||||||
inline void tx() {
|
inline void tx() {
|
||||||
if (_transmitting) {
|
if (transmitting_) {
|
||||||
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
||||||
//throw MODE_ALREADY_TRANSMITTING;
|
//throw MODE_ALREADY_TRANSMITTING;
|
||||||
USBDEBUG("ERROR - tried to start transmitting, but mode already is transmitting");
|
USBDEBUG("ERROR - tried to start transmitting, but mode already is transmitting");
|
||||||
} else {
|
} else {
|
||||||
_transmitting = true;
|
transmitting_ = true;
|
||||||
onTx();
|
on_tx();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void rx() {
|
inline void rx() {
|
||||||
if (!_transmitting) {
|
if (!transmitting_) {
|
||||||
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
// Do nothing. Exceptions not active (for Arduino, I assume?).
|
||||||
//throw MODE_NOT_TRANSMITTING;
|
//throw MODE_NOT_TRANSMITTING;
|
||||||
USBDEBUG("ERROR - tried to start receiving, but mode already is receiving");
|
USBDEBUG("ERROR - tried to start receiving, but mode already is receiving");
|
||||||
} else {
|
} else {
|
||||||
_transmitting = false;
|
transmitting_ = false;
|
||||||
onRx();
|
on_rx();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isTx() const { return _transmitting; }
|
inline bool is_tx() const { return transmitting_; }
|
||||||
inline bool isRx() 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:
|
private:
|
||||||
|
|
||||||
mode_config& _config;
|
mode_config& config_;
|
||||||
RigAudio& _audio;
|
RigAudio& audio_;
|
||||||
IFilter& _filter;
|
bp_filter& filter_;
|
||||||
bool _active;
|
bool active_;
|
||||||
bool _transmitting;
|
bool transmitting_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// SSBMode
|
// ssb_mode
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
class SSBMode : public IMode
|
class ssb_mode : public basic_mode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SSBMode(mode_config& c, RigAudio& a, IFilter& f, bool default_mic=true):
|
ssb_mode(ssb_config& c, RigAudio& a, bp_filter& f, speech_comp& s, bool default_mic=true) :
|
||||||
IMode(c, a, f), _use_mic(default_mic)
|
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().unmuteRx();
|
||||||
audio().muteAllTx();
|
audio().muteAllTx();
|
||||||
USBDEBUG("SSB mode entered");
|
USBDEBUG("SSB mode entered");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onExit() {
|
virtual void on_exit() {
|
||||||
audio().muteAllTx();
|
audio().muteAllTx();
|
||||||
audio().muteRx();
|
audio().muteRx();
|
||||||
|
disable_comp();
|
||||||
USBDEBUG("SSB mode exited");
|
USBDEBUG("SSB mode exited");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onTx()
|
virtual void on_tx()
|
||||||
{
|
{
|
||||||
audio().muteRx();
|
audio().muteRx();
|
||||||
if (_use_mic) {
|
if (use_mic_) {
|
||||||
audio().unmuteMicIn();
|
audio().unmuteMicIn();
|
||||||
} else {
|
} else {
|
||||||
audio().unmuteLineIn();
|
audio().unmuteLineIn();
|
||||||
|
@ -155,9 +168,9 @@ class SSBMode : public IMode
|
||||||
USBDEBUG("SSB mode transmitting");
|
USBDEBUG("SSB mode transmitting");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onRx()
|
virtual void on_rx()
|
||||||
{
|
{
|
||||||
if (_use_mic) {
|
if (use_mic_) {
|
||||||
audio().muteMicIn();
|
audio().muteMicIn();
|
||||||
} else {
|
} else {
|
||||||
audio().muteLineIn();
|
audio().muteLineIn();
|
||||||
|
@ -166,137 +179,100 @@ class SSBMode : public IMode
|
||||||
USBDEBUG("SSB mode receiving");
|
USBDEBUG("SSB mode receiving");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMicIn()
|
void set_mic_in()
|
||||||
{
|
{
|
||||||
if (isRx()) {
|
if (is_rx()) {
|
||||||
// can't switch inputs while already transmitting
|
// can't switch inputs while already transmitting
|
||||||
_use_mic = true;
|
use_mic_ = true;
|
||||||
}
|
}
|
||||||
USBDEBUG("SSB mode - Mic In set");
|
USBDEBUG("SSB mode - Mic In set");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLineIn()
|
void set_line_in()
|
||||||
{
|
{
|
||||||
if (isRx()) {
|
if (is_rx()) {
|
||||||
// can't switch inputs while already transmitting
|
// can't switch inputs while already transmitting
|
||||||
_use_mic = false;
|
use_mic_ = false;
|
||||||
}
|
}
|
||||||
USBDEBUG("SSB mode - Line In set");
|
USBDEBUG("SSB mode - Line In set");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setWideRxFilter() {
|
inline void enable_comp() { comp_.enable(); }
|
||||||
((BPFilter&)filter()).setBand(300.0, 3100.0);
|
inline void disable_comp() { comp_.disable(); }
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool _use_mic;
|
bool use_mic_;
|
||||||
|
speech_comp& comp_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// DGTMode
|
// digi_mode
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
class DGTMode : public IMode
|
class digi_mode : public basic_mode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DGTMode(mode_config& c, RigAudio& a, IFilter& f):
|
digi_mode(digi_config& c, RigAudio& a, bp_filter& f) :
|
||||||
IMode(c, a, f)
|
basic_mode(c, a, f) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onEntry()
|
virtual void on_entry()
|
||||||
{
|
{
|
||||||
setWideRxFilter();
|
set_rx_filter(config().filter);
|
||||||
audio().unmuteRx();
|
audio().unmuteRx();
|
||||||
audio().muteAllTx();
|
audio().muteAllTx();
|
||||||
USBDEBUG("DGT mode entered");
|
USBDEBUG("Digi mode entered");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onExit() {
|
virtual void on_exit() {
|
||||||
audio().muteAllTx();
|
audio().muteAllTx();
|
||||||
audio().muteRx();
|
audio().muteRx();
|
||||||
USBDEBUG("DGT mode exited");
|
USBDEBUG("Digi mode exited");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onTx()
|
virtual void on_tx()
|
||||||
{
|
{
|
||||||
audio().muteRx();
|
audio().muteRx();
|
||||||
audio().unmuteUSBIn();
|
audio().unmuteUSBIn();
|
||||||
USBDEBUG("DGT mode transmitting");
|
USBDEBUG("Digi mode transmitting");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onRx()
|
virtual void on_rx()
|
||||||
{
|
{
|
||||||
audio().muteUSBIn();
|
audio().muteUSBIn();
|
||||||
audio().unmuteRx();
|
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:
|
public:
|
||||||
|
|
||||||
CWMode(mode_config& c, RigAudio& a, IFilter& f):
|
cw_mode(cw_config& c, RigAudio& a, bp_filter& f):
|
||||||
IMode(c, a, f)
|
basic_mode(c, a, f) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onEntry()
|
virtual void on_entry()
|
||||||
{
|
{
|
||||||
setWideRxFilter();
|
set_rx_filter(config().filter);
|
||||||
audio().unmuteRx();
|
audio().unmuteRx();
|
||||||
audio().muteAllTx();
|
audio().muteAllTx();
|
||||||
USBDEBUG("CW mode entered");
|
USBDEBUG("CW mode entered");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onExit() {
|
virtual void on_exit() {
|
||||||
audio().muteAllTx();
|
audio().muteAllTx();
|
||||||
audio().muteRx();
|
audio().muteRx();
|
||||||
USBDEBUG("CW mode exited");
|
USBDEBUG("CW mode exited");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onTx()
|
virtual void on_tx()
|
||||||
{
|
{
|
||||||
// Currently not muting Rx, since the uBITX produces it's own
|
// Currently not muting Rx, since the uBITX produces it's own
|
||||||
// sidetone... but I'm probably going to replace that with a S/W-
|
// 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");
|
USBDEBUG("CW mode transmitting");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onRx()
|
virtual void on_rx()
|
||||||
{
|
{
|
||||||
USBDEBUG("CW mode receiving");
|
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
|
#endif
|
||||||
|
|
|
@ -29,12 +29,12 @@ class ITxSwitch
|
||||||
virtual ~ITxSwitch() {}
|
virtual ~ITxSwitch() {}
|
||||||
|
|
||||||
// Called before beginning transmit; if false, transmit aborts before starting.
|
// 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.
|
// 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)) {
|
if (onPress(m)) {
|
||||||
USBDEBUG("PTT pressed");
|
USBDEBUG("PTT pressed");
|
||||||
m->tx();
|
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)) {
|
if (onRelease(m)) {
|
||||||
USBDEBUG("PTT released");
|
USBDEBUG("PTT released");
|
||||||
if (output_enable) {
|
if (output_enable) {
|
||||||
|
@ -68,10 +68,10 @@ class CATSwitch : public ITxSwitch
|
||||||
public:
|
public:
|
||||||
CATSwitch(): _transmitting(false) {}
|
CATSwitch(): _transmitting(false) {}
|
||||||
|
|
||||||
virtual bool onPress(IMode* m) {
|
virtual bool onPress(basic_mode* m) {
|
||||||
// If another transmission is already occuring, abort... CAT can't
|
// If another transmission is already occuring, abort... CAT can't
|
||||||
// interrupt transmissions already ongoing.
|
// interrupt transmissions already ongoing.
|
||||||
if (m->isRx()) {
|
if (m->is_rx()) {
|
||||||
USBDEBUG("CAT PTT pressed");
|
USBDEBUG("CAT PTT pressed");
|
||||||
_transmitting = true;
|
_transmitting = true;
|
||||||
return 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
|
// If CAT transmission is not occurring, abort... CAT can't stop
|
||||||
// transmissions initiated by other sources. We don't check if
|
// transmissions initiated by other sources. We don't check if
|
||||||
// the mode is already transmitting, because it could be
|
// the mode is already transmitting, because it could be
|
||||||
|
@ -98,90 +98,6 @@ class CATSwitch : public ITxSwitch
|
||||||
bool _transmitting; // CAT-specific transmission
|
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
|
// GPIOSwitch
|
||||||
//
|
//
|
||||||
|
@ -201,15 +117,15 @@ class GPIOSwitch : public ITxSwitch
|
||||||
|
|
||||||
inline void setSSBMode(bool flag) { _ssb_mode = flag; }
|
inline void setSSBMode(bool flag) { _ssb_mode = flag; }
|
||||||
|
|
||||||
virtual bool onPress(IMode* m) {
|
virtual bool onPress(basic_mode* m) {
|
||||||
if (m->isRx()) {
|
if (m->is_rx()) {
|
||||||
if (_ssb_mode) {
|
if (_ssb_mode) {
|
||||||
if (_is_mic) {
|
if (_is_mic) {
|
||||||
USBDEBUG("Mic PTT pressed");
|
USBDEBUG("Mic PTT pressed");
|
||||||
((SSBMode*)m)->setMicIn();
|
((ssb_mode*)m)->set_mic_in();
|
||||||
} else {
|
} else {
|
||||||
USBDEBUG("Line PTT pressed");
|
USBDEBUG("Line PTT pressed");
|
||||||
((SSBMode*)m)->setLineIn();
|
((ssb_mode*)m)->set_line_in();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -218,15 +134,15 @@ class GPIOSwitch : public ITxSwitch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool onRelease(IMode* m) {
|
virtual bool onRelease(basic_mode* m) {
|
||||||
if (m->isTx()) {
|
if (m->is_tx()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(IMode* m, bool output_enable=true) {
|
void update(basic_mode* m, bool output_enable=true) {
|
||||||
_bounce.update();
|
_bounce.update();
|
||||||
|
|
||||||
if (_bounce.fell()) {
|
if (_bounce.fell()) {
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#define __iop_audio_h__
|
#define __iop_audio_h__
|
||||||
|
|
||||||
#include <Audio.h>
|
#include <Audio.h>
|
||||||
|
#include <dynamicFilters.h>
|
||||||
|
#include <effect_compressor_fb.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
class RigAudio
|
class RigAudio
|
||||||
|
@ -49,38 +51,57 @@ class RigAudio
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
class IFilter {
|
class bp_filter {
|
||||||
public:
|
|
||||||
virtual ~IFilter() {}
|
|
||||||
virtual void enable() = 0;
|
|
||||||
virtual void disable() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BPFilter : public IFilter {
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
//bp_filter(double f1, double f2, bool use_center, short int window=-1, short int coeff=-1);
|
||||||
BPFilter(double f1, double f2, bool use_center, short int window=-1, short int coeff=-1);
|
bp_filter();
|
||||||
void init(AudioFilterFIR* filter=NULL, short* coefficients=NULL);
|
bp_filter(AudioFilterFIR& f, AudioAmplifier& a);
|
||||||
void setFreqLo(double f);
|
void init(const bpf_config& cfg);
|
||||||
void setFreqHi(double f);
|
//void init(AudioFilterFIR* filter=NULL, short* coefficients=NULL);
|
||||||
void setBand(double f1, double f2);
|
void set_band(double f1, double f2);
|
||||||
void setCenter(double c);
|
void set_freq_lo(double f);
|
||||||
void setWidth(double w);
|
void set_freq_hi(double f);
|
||||||
void setCenterAndWidth(double c, double w);
|
void set_center_and_width(double c, double w);
|
||||||
virtual void enable();
|
void set_center(double c);
|
||||||
virtual void disable();
|
void set_width(double w);
|
||||||
|
void set_gain(double g);
|
||||||
|
void enable();
|
||||||
|
void disable();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
double _freq_lo;
|
double freq_lo;
|
||||||
double _freq_hi;
|
double freq_hi;
|
||||||
short int _window;
|
short int window;
|
||||||
short int _coeff;
|
short int coeff;
|
||||||
float _recovery; // recovery amplifier value
|
float recovery; // recovery amplifier value
|
||||||
|
|
||||||
AudioFilterFIR* _filter; // = &filterRX;
|
AudioFilterFIR& filter; // = &filterRX;
|
||||||
short* _coefficients;
|
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 <dynamicFilters.h>
|
||||||
#include <effect_compressor_fb.h>
|
#include <effect_compressor_fb.h>
|
||||||
|
|
||||||
|
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "tx_audio_proc.h"
|
|
||||||
|
|
||||||
//short firActive[NUM_COEFFICIENTS];
|
//short firActive[NUM_COEFFICIENTS];
|
||||||
|
|
||||||
|
@ -266,470 +263,90 @@ TxInput audioTxInput;
|
||||||
TxOutput audioTxOutput;
|
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):
|
bp_filter::bp_filter(AudioFilterFIR& f, AudioAmplifier& a): filter(f), amp(a) {}
|
||||||
_window(window), _coeff(coeff)
|
|
||||||
|
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) {
|
config_->enabled = true;
|
||||||
_window = W_HAMMING;
|
comp_.begin(1, config_->threshold, config_->ratio); // Need to make configurable
|
||||||
}
|
amp_.gain(config_->gain);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPFilter::init(AudioFilterFIR* filter, short* coefficients) {
|
void speech_comp::disable()
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
rxFilter[RIG_MODE_SSB][FILTER_WIDE] = new BPFilter( 300.0, 3100.0);
|
config_->enabled = false;
|
||||||
rxFilter[RIG_MODE_SSB][FILTER_NORMAL] = new BPFilter( 500.0, 2900.0);
|
comp_.disable();
|
||||||
rxFilter[RIG_MODE_SSB][FILTER_NARROW] = new BPFilter( 700.0, 2500.0);
|
amp_.gain(1.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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================================================================
|
// Speech compressor code based on post by 'hyperdyne': https://forum.pjrc.com/threads/36245-Changing-Pitch-of-Voice
|
||||||
|
|
||||||
SpeechCompressor speechCompressor(compTX, compAmp, compRMS);
|
void speech_comp::update()
|
||||||
|
|
||||||
//======================================================================
|
|
||||||
|
|
||||||
// audioInit()
|
|
||||||
// Setup the audio subsystem.
|
|
||||||
void audioInit()
|
|
||||||
{
|
{
|
||||||
audioCtrl.enable();
|
float rms_cur;
|
||||||
audioCtrl.muteHeadphone(); // not using the headphone output
|
if (config_->enabled && rms_.available()) {
|
||||||
audioCtrl.volume(0.0); // not using the headphone output
|
rms_cur = rms_.read();
|
||||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN); // required for RX audio
|
env_ = rms_cur + (alpha_ * (env_ - rms_cur));
|
||||||
audioCtrl.unmuteLineout(); // required for RX audio
|
comp_.update_pwr(env_);
|
||||||
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();
|
|
||||||
}
|
|
||||||
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];
|
int eqFilter1[5];
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ IOPMessage inBuf; // input message buffer
|
||||||
IOPMessage outBuf; // output message buffer
|
IOPMessage outBuf; // output message buffer
|
||||||
|
|
||||||
extern CATSwitch catPTT;
|
extern CATSwitch catPTT;
|
||||||
extern Rig rig;
|
extern basic_rig rig;
|
||||||
|
|
||||||
int received_mode = 0;
|
int received_mode = 0;
|
||||||
|
|
||||||
|
@ -57,27 +57,21 @@ void processIOPCommand(IOPMessage const& m)
|
||||||
if (m.len < 1) {
|
if (m.len < 1) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
rig.switchMode(rig_mode(m.data[0]));
|
rig.set_rig_mode(static_cast<rig_mode>(m.data[0]));
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
switch(rig.modeNum()) {
|
switch(rig.get_rig_mode()) {
|
||||||
case cwr:
|
case rig_mode::cw:
|
||||||
USBDEBUG("new mode - CWR");
|
|
||||||
break;
|
|
||||||
case cw:
|
|
||||||
USBDEBUG("new mode - CW");
|
USBDEBUG("new mode - CW");
|
||||||
break;
|
break;
|
||||||
case lsb:
|
case rig_mode::ssb:
|
||||||
USBDEBUG("new mode - LSB");
|
USBDEBUG("new mode - SSB");
|
||||||
break;
|
break;
|
||||||
case usb:
|
case rig_mode::digi:
|
||||||
USBDEBUG("new mode - USB");
|
|
||||||
break;
|
|
||||||
case dig:
|
|
||||||
USBDEBUG("new mode - DIG");
|
USBDEBUG("new mode - DIG");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
char errormessage[32];
|
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");
|
USBDEBUG("mode command not recognized");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -121,12 +121,11 @@ class RigConfig {
|
||||||
|
|
||||||
// mode configuration
|
// mode configuration
|
||||||
ssb_config ssb;
|
ssb_config ssb;
|
||||||
dig_config dig;
|
digi_config digi;
|
||||||
cw_config cw;
|
cw_config cw;
|
||||||
|
|
||||||
// General rig configuration entries.
|
// General rig configuration entries.
|
||||||
rig_mode numModes = num_rig_modes;
|
rig_mode mode = rig_mode::ssb;
|
||||||
rig_mode startMode = lsb;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RigConfig rigConfig;
|
extern RigConfig rigConfig;
|
||||||
|
|
101
ubitx_iop/menu.h
101
ubitx_iop/menu.h
|
@ -13,9 +13,6 @@
|
||||||
//#include <vector>
|
//#include <vector>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include "rig.h"
|
#include "rig.h"
|
||||||
#include "tx_audio_proc.h"
|
|
||||||
|
|
||||||
extern SpeechCompressor speechCompressor; // This should be somewhere else.
|
|
||||||
|
|
||||||
// 16 characters on display
|
// 16 characters on display
|
||||||
const int MAX_TEXT_LEN = 16;
|
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 modeID[] = {'s', 'S', 'c', 'C', 'd', 'D', 't', 'T'};
|
||||||
const char* const filterID[num_rig_modes][num_rx_filters] = {
|
const char* const filterID[static_cast<int>(rig_mode::count)][static_cast<int>(rx_filter::count)] = {
|
||||||
{"2.8", "2.4", "1.8"}, // LSB
|
{"2.8", "2.4", "1.8"}, // SSB
|
||||||
{"2.8", "2.4", "1.8"}, // USB
|
|
||||||
{"1.0", "500", "250"}, // CW
|
{"1.0", "500", "250"}, // CW
|
||||||
{"1.0", "500", "250"}, // CWR
|
|
||||||
{"2.8", "2.4", "500"}, // DIG
|
{"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 {
|
class Main_menu : public Menu_item {
|
||||||
public:
|
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 {
|
virtual const Menu_string& title() const {
|
||||||
return menu_title;
|
return menu_title;
|
||||||
|
@ -240,33 +235,12 @@ class Main_menu : public Menu_item {
|
||||||
char text[max_text_len+1];
|
char text[max_text_len+1];
|
||||||
sprintf(text, "%1cR:%3s %1cT:%3s ",
|
sprintf(text, "%1cR:%3s %1cT:%3s ",
|
||||||
adjust_tx ? ' ' : menu_selection_char,
|
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 : ' ',
|
adjust_tx ? menu_selection_char : ' ',
|
||||||
rig.isSSBMode() && comp_on ? "CMP" : " ");
|
rig_.is_ssb_mode() && rig_.config().ssb.comp.enabled ? "CMP" : " ");
|
||||||
outstr.assign(text);
|
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() {
|
virtual Menu_item* select() {
|
||||||
adjust_tx = !adjust_tx;
|
adjust_tx = !adjust_tx;
|
||||||
return this;
|
return this;
|
||||||
|
@ -282,79 +256,40 @@ class Main_menu : public Menu_item {
|
||||||
|
|
||||||
virtual Menu_item* prev() {
|
virtual Menu_item* prev() {
|
||||||
if (adjust_tx) {
|
if (adjust_tx) {
|
||||||
if (rig.isSSBMode()) {
|
if (rig_.is_ssb_mode()) {
|
||||||
comp_on = !comp_on;
|
rig_.config().ssb.comp.enabled = !rig_.config().ssb.comp.enabled;
|
||||||
if (comp_on)
|
if (rig_.config().ssb.comp.enabled)
|
||||||
speechCompressor.enable();
|
rig_.enable_comp();
|
||||||
else
|
else
|
||||||
speechCompressor.disable();
|
rig_.disable_comp();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rig.switchRxFilter(true);
|
rig_.prev_rx_filter();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Menu_item* next() {
|
virtual Menu_item* next() {
|
||||||
if (adjust_tx) {
|
if (adjust_tx) {
|
||||||
if (rig.isSSBMode()) {
|
if (rig_.is_ssb_mode()) {
|
||||||
comp_on = !comp_on;
|
rig_.config().ssb.comp.enabled = !rig_.config().ssb.comp.enabled;
|
||||||
if (comp_on)
|
if (rig_.config().ssb.comp.enabled)
|
||||||
speechCompressor.enable();
|
rig_.enable_comp();
|
||||||
else
|
else
|
||||||
speechCompressor.disable();
|
rig_.disable_comp();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rig.switchRxFilter();
|
rig_.next_rx_filter();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Menu_string menu_title;
|
Menu_string menu_title;
|
||||||
Rig& rig;
|
basic_rig& rig_;
|
||||||
bool adjust_tx;
|
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;
|
extern const Menu_item* audio_config_menu;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
291
ubitx_iop/rig.h
291
ubitx_iop/rig.h
|
@ -8,143 +8,80 @@
|
||||||
#include <iopcomm.h>
|
#include <iopcomm.h>
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "RigMode.h"
|
#include "RigMode.h"
|
||||||
//#include "menu.h"
|
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Rig class
|
// basic_rig
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
class Rig {
|
class basic_rig {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Constructor/destructor.
|
// Constructor/destructor.
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
Rig(RigConfig& c, RigAudio& a): _config(c), _audio(a), _filter(wide)
|
basic_rig(RigConfig& c, RigAudio& a) :
|
||||||
{
|
config_(c), audio_(a),
|
||||||
_modes = new IMode*[c.numModes];
|
bpf_(),
|
||||||
_modesLen = c.numModes;
|
comp_(&config_.ssb.comp),
|
||||||
_modesIndex = c.startMode;
|
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] = ' '; }
|
void init() {}
|
||||||
// _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();
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
~Rig()
|
RigConfig& config() { return config_; }
|
||||||
{
|
|
||||||
for (unsigned i = 0; i < _modesLen; i++) {
|
|
||||||
delete _modes[i];
|
|
||||||
}
|
|
||||||
delete _modes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init() {
|
|
||||||
switchRxFilter(_filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Mode control.
|
// 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.
|
inline bool is_ssb_mode() const { return (config_.mode == rig_mode::ssb ); }
|
||||||
bool addNewMode(rig_mode i, IMode* mode) {
|
inline bool is_digi_mode() const { return (config_.mode == rig_mode::digi); }
|
||||||
if (i > _modesLen) {
|
inline bool is_cw_mode() const { return (config_.mode == rig_mode::cw ); }
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
_modes[i] = mode;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a pointer to the current mode.
|
// Switch to the specified mode. Returns a pointer to the new mode.
|
||||||
inline IMode* mode() const {
|
basic_mode* set_rig_mode(rig_mode m) {
|
||||||
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) {
|
|
||||||
// exit the previous mode
|
// 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
|
// select the new mode
|
||||||
_modesIndex = rig_mode(i % _modesLen);
|
config_.mode = m;
|
||||||
|
|
||||||
//enter the new mode
|
switch(config_.mode) {
|
||||||
mode()->enter();
|
case rig_mode::ssb:
|
||||||
|
current_mode_ = &ssb_;
|
||||||
|
break;
|
||||||
|
|
||||||
// return a pointer to the new mode
|
case rig_mode::cw:
|
||||||
return mode();
|
current_mode_ = &cw_;
|
||||||
}
|
break;
|
||||||
|
|
||||||
// Advance to the next (or previous) mode. Returns a pointer to the
|
case rig_mode::digi:
|
||||||
// new mode.
|
current_mode_ = &digi_;
|
||||||
IMode* switchMode(bool prev=false) {
|
break;
|
||||||
|
|
||||||
// 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
|
//enter the new mode
|
||||||
mode()->enter();
|
current_mode_->enter();
|
||||||
|
|
||||||
// return a pointer to the new mode
|
// return a pointer to the new mode
|
||||||
return mode();
|
return current_mode_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the rig_mode (enum) of the current mode object.
|
||||||
|
inline rig_mode get_rig_mode() const { return config_.mode; }
|
||||||
|
|
||||||
|
|
||||||
|
// Returns a pointer to the current mode object.
|
||||||
|
inline basic_mode* mode() const { return current_mode_; }
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Transmit/Receive (T/R) control.
|
// Transmit/Receive (T/R) control.
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
inline bool isTx() const { return mode()->isTx(); }
|
inline bool is_tx() const { return mode()->is_tx(); }
|
||||||
inline bool isRx() const { return mode()->isRx(); }
|
inline bool is_rx() const { return mode()->is_rx(); }
|
||||||
|
|
||||||
// Enter the transmit state. This is delegated to the mode.
|
// Enter the transmit state. This is delegated to the mode.
|
||||||
inline void tx() { mode()->tx(); }
|
inline void tx() { mode()->tx(); }
|
||||||
|
@ -156,178 +93,144 @@ class Rig {
|
||||||
// Transmit processor control.
|
// 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.
|
// RX filter control.
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
inline void setWideRxFilter() {
|
// Set the RX filter. This is delegated to the mode.
|
||||||
_filter = wide;
|
inline void set_rx_filter(rx_filter f) { mode()->set_rx_filter(f); }
|
||||||
mode()->setWideRxFilter();
|
|
||||||
USBDEBUG("selected wide RX filter");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setMediumRxFilter() {
|
// Returns the rx_filter (enum) of the RX filter currently being used.
|
||||||
_filter = medium;
|
inline rx_filter get_rx_filter() const { return mode()->config().filter; }
|
||||||
mode()->setMediumRxFilter();
|
|
||||||
USBDEBUG("selected medium RX filter");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setNarrowRxFilter() {
|
void next_rx_filter() {
|
||||||
_filter = narrow;
|
switch(mode()->config().filter) {
|
||||||
mode()->setNarrowRxFilter();
|
case rx_filter::wide:
|
||||||
USBDEBUG("selected narrow RX filter");
|
set_rx_filter(rx_filter::medium);
|
||||||
}
|
|
||||||
|
|
||||||
void switchRxFilter(rx_filter f) {
|
|
||||||
switch(f) {
|
|
||||||
case wide:
|
|
||||||
setWideRxFilter();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case medium:
|
case rx_filter::medium:
|
||||||
setMediumRxFilter();
|
set_rx_filter(rx_filter::narrow);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case narrow:
|
case rx_filter::narrow:
|
||||||
setNarrowRxFilter();
|
set_rx_filter(rx_filter::wide);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void switchRxFilter(bool prev=false) {
|
void prev_rx_filter() {
|
||||||
rx_filter f;
|
switch(mode()->config().filter) {
|
||||||
if (prev) {
|
case rx_filter::wide:
|
||||||
f = rx_filter(_filter > 0 ? _filter - 1 : num_rx_filters - 1);
|
set_rx_filter(rx_filter::narrow);
|
||||||
} else {
|
break;
|
||||||
f = rx_filter((_filter + 1) % num_rx_filters);
|
|
||||||
|
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.
|
// Audio output control.
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
inline void muteSpkrOut() const {
|
inline void muteSpkrOut() const {
|
||||||
_audio.muteSpkrOut();
|
audio_.muteSpkrOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unmuteSpkrOut() const {
|
inline void unmuteSpkrOut() const {
|
||||||
_audio.unmuteSpkrOut();
|
audio_.unmuteSpkrOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void muteLineOut() const {
|
inline void muteLineOut() const {
|
||||||
_audio.muteLineOut();
|
audio_.muteLineOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unmuteLineOut() const {
|
inline void unmuteLineOut() const {
|
||||||
_audio.unmuteLineOut();
|
audio_.unmuteLineOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void muteUSBOut() const {
|
inline void muteUSBOut() const {
|
||||||
_audio.muteUSBOut();
|
audio_.muteUSBOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unmuteUSBOut() const {
|
inline void unmuteUSBOut() const {
|
||||||
_audio.unmuteUSBOut();
|
audio_.unmuteUSBOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
// Audio input control.
|
// Audio input control.
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
inline void muteAllTx() const {
|
inline void muteAllTx() const {
|
||||||
_audio.muteAllTx();
|
audio_.muteAllTx();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void muteMicIn() const {
|
inline void muteMicIn() const {
|
||||||
_audio.muteMicIn();
|
audio_.muteMicIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unmuteMicIn() const {
|
inline void unmuteMicIn() const {
|
||||||
_audio.unmuteMicIn();
|
audio_.unmuteMicIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void muteLineIn() const {
|
inline void muteLineIn() const {
|
||||||
_audio.muteLineIn();
|
audio_.muteLineIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unmuteLineIn() const {
|
inline void unmuteLineIn() const {
|
||||||
_audio.unmuteLineIn();
|
audio_.unmuteLineIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void muteUSBIn() const {
|
inline void muteUSBIn() const {
|
||||||
_audio.muteUSBIn();
|
audio_.muteUSBIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unmuteUSBIn() const {
|
inline void unmuteUSBIn() const {
|
||||||
_audio.unmuteUSBOut();
|
audio_.unmuteUSBOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void muteTTIn() const {
|
inline void muteTTIn() const {
|
||||||
_audio.muteTTIn();
|
audio_.muteTTIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unmuteTTIn() const {
|
inline void unmuteTTIn() const {
|
||||||
_audio.unmuteTTIn();
|
audio_.unmuteTTIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the rig state. This should be called once each time through
|
// Update the rig state. This should be called once each time through
|
||||||
// the main loop.
|
// the main loop.
|
||||||
void update()
|
void update()
|
||||||
{
|
{
|
||||||
|
comp_.update(); // It checks if it's enabled on its own.
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
RigConfig& _config;
|
RigConfig& config_;
|
||||||
RigAudio& _audio;
|
RigAudio& audio_;
|
||||||
|
|
||||||
IMode** _modes;
|
bp_filter bpf_;
|
||||||
rig_mode _modesLen;
|
speech_comp comp_;
|
||||||
rig_mode _modesIndex;
|
|
||||||
|
|
||||||
rx_filter _filter;
|
ssb_mode ssb_;
|
||||||
|
cw_mode cw_;
|
||||||
|
digi_mode digi_;
|
||||||
|
|
||||||
// char _modeText[17];
|
basic_mode* current_mode_;
|
||||||
|
|
||||||
/*
|
|
||||||
IFilter** _rxFilters;
|
|
||||||
uint8_t _rxFiltersLen;
|
|
||||||
uint8_t _rxFiltersIndex;
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#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;
|
RigConfig rigConfig;
|
||||||
RigAudio rigAudio{rigConfig.audio};
|
RigAudio rigAudio{rigConfig.audio};
|
||||||
Rig rig{rigConfig, rigAudio};
|
basic_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};
|
|
||||||
|
|
||||||
CATSwitch catPTT;
|
CATSwitch catPTT;
|
||||||
//MicSwitch micPTTHelper;
|
//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.
|
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();
|
initKeyLine();
|
||||||
rigAudio.init();
|
rigAudio.init();
|
||||||
|
|
||||||
|
@ -78,14 +62,6 @@ void setup() {
|
||||||
rig.init();
|
rig.init();
|
||||||
|
|
||||||
USBDEBUG("setup completed");
|
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++;
|
frameCounter++;
|
||||||
|
|
||||||
if (rig.isCWMode()) {
|
if (rig.is_cw_mode()) {
|
||||||
if (keyer.do_paddles()) {
|
if (keyer.do_paddles()) {
|
||||||
|
|
||||||
// Checking for T/R separately from the paddle loop, because it's
|
// Checking for T/R separately from the paddle loop, because it's
|
||||||
// possible we're already transmitting (PTT/Key being held), and
|
// 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.
|
// 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");
|
USBDEBUG("entered TX via paddles");
|
||||||
rig.tx();
|
rig.tx();
|
||||||
}
|
}
|
||||||
|
@ -154,21 +130,21 @@ void loop()
|
||||||
|
|
||||||
rig.update();
|
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
|
// 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
|
// 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
|
// need to make it inactive if we're in DGT mode, since only CAT will be
|
||||||
// used to start transmitting in that case.
|
// used to start transmitting in that case.
|
||||||
micPTT.setSSBMode(rig.isSSBMode());
|
micPTT.setSSBMode(rig.is_ssb_mode());
|
||||||
micPTT.update(rig.mode(), !rig.isDIGMode());
|
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
|
// 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
|
// 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
|
// need to make it inactive if we're in DGT mode, since only CAT will be
|
||||||
// used to start transmitting in that case.
|
// used to start transmitting in that case.
|
||||||
linePTT.setSSBMode(rig.isSSBMode());
|
linePTT.setSSBMode(rig.is_ssb_mode());
|
||||||
linePTT.update(rig.mode(), !rig.isDIGMode());
|
linePTT.update(rig.mode(), !rig.is_digi_mode());
|
||||||
|
|
||||||
serviceCAT();
|
serviceCAT();
|
||||||
|
|
||||||
|
@ -237,9 +213,7 @@ void loop()
|
||||||
USBDEBUG("updated main menu");
|
USBDEBUG("updated main menu");
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the speech compressor. Really should do this elsewhere.
|
rig.update();
|
||||||
if (speechCompressor.isEnabled())
|
|
||||||
speechCompressor.update();
|
|
||||||
|
|
||||||
if (frameMillis > 5000) {
|
if (frameMillis > 5000) {
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user