Persist modem settings on new instances

This commit is contained in:
Charles J. Cliffe 2015-11-26 01:54:54 -05:00
parent 1fb5dc4236
commit 4fa0cb7c67
13 changed files with 185 additions and 48 deletions

View File

@ -826,7 +826,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
if (demod) {
if (demod && demod->isModemInitialized()) {
if (demod->isTracking()) {
if (spectrumCanvas->getViewState()) {
long long diff = abs(demod->getFrequency() - spectrumCanvas->getCenterFrequency()) + (demod->getBandwidth()/2) + (demod->getBandwidth()/4);
@ -844,6 +844,10 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
demod->setTracking(false);
}
}
if (demod->getBandwidth() != wxGetApp().getDemodMgr().getLastBandwidth()) {
wxGetApp().getDemodMgr().setLastBandwidth(demod->getBandwidth());
}
if (demod != activeDemodulator) {
demodSignalMeter->setInputValue(demod->getSquelchLevel());
@ -857,7 +861,6 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
demodModeSelectorAdv->setSelection(dType);
#endif
demodMuteButton->setSelection(demod->isMuted()?1:-1);
newModemArgs = demod->getModemArgs();
modemPropertiesUpdated.store(true);
}
if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) {
@ -893,16 +896,25 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
if (dSelection != "" && dSelection != demod->getDemodulatorType()) {
demod->setDemodulatorType(dSelection);
demodModeSelectorAdv->setSelection(-1);
if (int lastDemodBw = wxGetApp().getDemodMgr().getLastBandwidth(dSelection)) {
demod->setBandwidth(lastDemodBw);
}
}
// advanced demodulators
else if (dSelectionadv != "" && dSelectionadv != demod->getDemodulatorType()) {
demod->setDemodulatorType(dSelectionadv);
demodModeSelector->setSelection(-1);
if (int lastDemodBw = wxGetApp().getDemodMgr().getLastBandwidth(dSelection)) {
demod->setBandwidth(lastDemodBw);
}
}
#else
// basic demodulators
if (dSelection != "" && dSelection != demod->getDemodulatorType()) {
demod->setDemodulatorType(dSelection);
if (int lastDemodBw = wxGetApp().getDemodMgr().getLastBandwidth(dSelection)) {
demod->setBandwidth(lastDemodBw);
}
}
#endif
@ -1050,8 +1062,10 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
wproc->setCenterFrequency(waterfallCanvas->getCenterFrequency());
wxGetApp().getSDRPostThread()->setIQVisualRange(waterfallCanvas->getCenterFrequency(), waterfallCanvas->getBandwidth());
demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
if (modemPropertiesUpdated.load()) {
modemProps->initProperties(newModemArgs);
modemProps->initProperties(demod->getModemArgs());
modemPropertiesUpdated.store(false);
demodTray->Layout();
}

View File

@ -126,7 +126,6 @@ public:
void setDeviceSelectorClosed();
bool isDeviceSelectorOpen();
void closeDeviceSelector();
void setAGCMode(bool mode);
bool getAGCMode();

View File

@ -1,4 +1,5 @@
#include "DemodulatorInstance.h"
#include "CubicSDR.h"
DemodulatorInstance::DemodulatorInstance() :
t_PreDemod(NULL), t_Demod(NULL), t_Audio(NULL) {
@ -20,6 +21,8 @@ DemodulatorInstance::DemodulatorInstance() :
pipeIQDemodData = new DemodulatorThreadPostInputQueue;
pipeDemodNotify = new DemodulatorThreadCommandQueue;
audioThread = new AudioThread();
demodulatorPreThread = new DemodulatorPreThread(this);
demodulatorPreThread->setInputQueue("IQDataInput",pipeIQInputData);
demodulatorPreThread->setOutputQueue("IQDataOutput",pipeIQDemodData);
@ -34,7 +37,6 @@ DemodulatorInstance::DemodulatorInstance() :
demodulatorThread->setOutputQueue("NotifyQueue",pipeDemodNotify);
demodulatorThread->setOutputQueue("AudioDataOutput", pipeAudioData);
audioThread = new AudioThread();
audioThread->setInputQueue("AudioDataInput", pipeAudioData);
audioThread->setOutputQueue("NotifyQueue", pipeDemodNotify);
}
@ -204,6 +206,8 @@ float DemodulatorInstance::getSignalLevel() {
void DemodulatorInstance::setSquelchLevel(float signal_level_in) {
demodulatorThread->setSquelchLevel(signal_level_in);
wxGetApp().getDemodMgr().setLastSquelchLevel(signal_level_in);
wxGetApp().getDemodMgr().setLastSquelchEnabled(true);
}
float DemodulatorInstance::getSquelchLevel() {
@ -263,6 +267,7 @@ int DemodulatorInstance::getDemodulatorLock() {
void DemodulatorInstance::setBandwidth(int bw) {
demodulatorPreThread->setBandwidth(bw);
wxGetApp().getDemodMgr().setLastBandwidth(bw);
}
int DemodulatorInstance::getBandwidth() {
@ -296,6 +301,7 @@ int DemodulatorInstance::getAudioSampleRate() {
void DemodulatorInstance::setGain(float gain_in) {
currentAudioGain = gain_in;
audioThread->setGain(gain_in);
wxGetApp().getDemodMgr().setLastGain(gain_in);
}
float DemodulatorInstance::getGain() {
@ -325,6 +331,7 @@ bool DemodulatorInstance::isMuted() {
void DemodulatorInstance::setMuted(bool muted) {
this->muted = muted;
demodulatorThread->setMuted(muted);
wxGetApp().getDemodMgr().setLastMuted(muted);
}
DemodulatorThreadInputQueue *DemodulatorInstance::getIQInputDataPipe() {
@ -342,18 +349,21 @@ ModemArgInfoList DemodulatorInstance::getModemArgs() {
}
std::string DemodulatorInstance::readModemSetting(std::string setting) {
Modem *m = demodulatorPreThread->getModem();
if (m) {
return m->readSetting(setting);
}
return "";
return demodulatorPreThread->readModemSetting(setting);
}
void DemodulatorInstance::writeModemSetting(std::string setting, std::string value) {
Modem *m = demodulatorPreThread->getModem();
if (m) {
m->writeSetting(setting, value);
}
demodulatorPreThread->writeModemSetting(setting, value);
}
ModemSettings DemodulatorInstance::readModemSettings() {
return demodulatorPreThread->readModemSettings();
}
void DemodulatorInstance::writeModemSettings(ModemSettings settings) {
demodulatorPreThread->writeModemSettings(settings);
}
bool DemodulatorInstance::isModemInitialized() {
return demodulatorPreThread->isInitialized();
}

View File

@ -84,8 +84,12 @@ public:
ModemArgInfoList getModemArgs();
std::string readModemSetting(std::string setting);
ModemSettings readModemSettings();
void writeModemSetting(std::string setting, std::string value);
void writeModemSettings(ModemSettings settings);
bool isModemInitialized();
protected:
DemodulatorThreadInputQueue* pipeIQInputData;
DemodulatorThreadPostInputQueue* pipeIQDemodData;

View File

@ -8,7 +8,13 @@
DemodulatorMgr::DemodulatorMgr() :
activeDemodulator(NULL), lastActiveDemodulator(NULL), activeVisualDemodulator(NULL), lastBandwidth(DEFAULT_DEMOD_BW), lastDemodType(
DEFAULT_DEMOD_TYPE), lastSquelchEnabled(false), lastSquelch(-100), lastGain(1.0), lastMuted(false) {
setLastBandwidth("FM",200000);
setLastBandwidth("FMS",200000);
setLastBandwidth("AM",6000);
setLastBandwidth("USB",5400);
setLastBandwidth("LSB",5400);
setLastBandwidth("DSB",5400);
setLastBandwidth("IQ",48000);
}
DemodulatorMgr::~DemodulatorMgr() {
@ -88,6 +94,7 @@ void DemodulatorMgr::setActiveDemodulator(DemodulatorInstance *demod, bool tempo
if (!temporary) {
if (activeDemodulator != NULL) {
lastActiveDemodulator = activeDemodulator;
updateLastState();
} else {
lastActiveDemodulator = demod;
}
@ -121,8 +128,6 @@ DemodulatorInstance *DemodulatorMgr::getActiveDemodulator() {
}
DemodulatorInstance *DemodulatorMgr::getLastActiveDemodulator() {
updateLastState();
return lastActiveDemodulator;
}
@ -165,6 +170,8 @@ void DemodulatorMgr::updateLastState() {
lastSquelchEnabled = lastActiveDemodulator->isSquelchEnabled();
lastSquelch = lastActiveDemodulator->getSquelchLevel();
lastGain = lastActiveDemodulator->getGain();
lastModemSettings[lastDemodType] = lastActiveDemodulator->readModemSettings();
lastBandwidthNamed[lastDemodType] = lastBandwidth;
}
}
@ -222,3 +229,17 @@ void DemodulatorMgr::setLastMuted(bool lastMuted) {
this->lastMuted = lastMuted;
}
ModemSettings DemodulatorMgr::getLastModemSettings(std::string modemType) {
return lastModemSettings[modemType];
}
void DemodulatorMgr::setLastModemSettings(std::string modemType, ModemSettings settings) {
lastModemSettings[modemType] = settings;
}
int DemodulatorMgr::getLastBandwidth(std::string modemType) {
return lastBandwidthNamed[modemType];
}
void DemodulatorMgr::setLastBandwidth(std::string modemType, int lastBandwidth_in) {
lastBandwidthNamed[modemType] = lastBandwidth_in;
}

View File

@ -25,6 +25,9 @@ public:
int getLastBandwidth() const;
void setLastBandwidth(int lastBandwidth);
int getLastBandwidth(std::string modemType);
void setLastBandwidth(std::string modemType, int lastBandwidth);
std::string getLastDemodulatorType() const;
void setLastDemodulatorType(std::string lastDemodType);
@ -40,9 +43,13 @@ public:
bool isLastMuted() const;
void setLastMuted(bool lastMuted);
ModemSettings getLastModemSettings(std::string);
void setLastModemSettings(std::string, ModemSettings);
void updateLastState();
private:
void garbageCollect();
void updateLastState();
std::vector<DemodulatorInstance *> demods;
std::vector<DemodulatorInstance *> demods_deleted;
@ -50,6 +57,7 @@ private:
DemodulatorInstance *lastActiveDemodulator;
DemodulatorInstance *activeVisualDemodulator;
std::map<std::string, int> lastBandwidthNamed;
int lastBandwidth;
std::string lastDemodType;
bool lastDemodLock;
@ -57,4 +65,6 @@ private:
float lastSquelch;
float lastGain;
bool lastMuted;
std::map<std::string, ModemSettings> lastModemSettings;
};

View File

@ -33,10 +33,11 @@ DemodulatorPreThread::DemodulatorPreThread(DemodulatorInstance *parent) : IOThre
frequencyChanged.store(false);
bandwidthChanged.store(false);
audioSampleRateChanged.store(false);
modemSettingsChanged.store(false);
}
void DemodulatorPreThread::initialize() {
initialized.store(true);
bool DemodulatorPreThread::isInitialized() {
return initialized.load();
}
DemodulatorPreThread::~DemodulatorPreThread() {
@ -50,10 +51,6 @@ void DemodulatorPreThread::run() {
pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif
if (!initialized) {
initialize();
}
std::cout << "Demodulator preprocessor thread started.." << std::endl;
ReBuffer<DemodulatorThreadPostIQData> buffers;
@ -103,10 +100,17 @@ void DemodulatorPreThread::run() {
command.demodType = newDemodType;
command.bandwidth = newBandwidth;
command.audioSampleRate = newAudioSampleRate;
workerQueue->push(command);
demodType = newDemodType;
sampleRateChanged.store(false);
audioSampleRateChanged.store(false);
if (modemSettingsBuffered.size()) {
command.settings = modemSettingsBuffered;
}
modemSettingsBuffered.clear();
modemSettingsChanged.store(false);
workerQueue->push(command);
cModem = nullptr;
cModemKit = nullptr;
demodTypeChanged.store(false);
}
else if (
@ -122,14 +126,10 @@ void DemodulatorPreThread::run() {
bandwidthChanged.store(false);
sampleRateChanged.store(false);
audioSampleRateChanged.store(false);
modemSettingsBuffered.clear();
workerQueue->push(command);
}
if (!initialized) {
inp->decRefCount();
continue;
}
// Requested frequency is not center, shift it into the center!
if ((currentFrequency - inp->frequency) != shiftFrequency) {
shiftFrequency = currentFrequency - inp->frequency;
@ -239,12 +239,19 @@ void DemodulatorPreThread::run() {
}
shiftFrequency = inp->frequency-1;
initialized.store(cModem != nullptr);
break;
default:
break;
}
}
}
if ((cModem != nullptr) && modemSettingsChanged.load()) {
cModem->writeSettings(modemSettingsBuffered);
modemSettingsBuffered.clear();
modemSettingsChanged.store(false);
}
}
buffers.purge();
@ -296,11 +303,7 @@ void DemodulatorPreThread::setBandwidth(int bandwidth) {
newBandwidth = bandwidth;
}
int DemodulatorPreThread::getBandwidth() {
// if (bandwidthChanged.load()) {
// return newBandwidth;
// }
int DemodulatorPreThread::getBandwidth() {
return currentBandwidth;
}
@ -337,3 +340,31 @@ Modem *DemodulatorPreThread::getModem() {
ModemKit *DemodulatorPreThread::getModemKit() {
return cModemKit;
}
std::string DemodulatorPreThread::readModemSetting(std::string setting) {
if (cModem) {
return cModem->readSetting(setting);
} else if (modemSettingsBuffered.find(setting) != modemSettingsBuffered.end()) {
return modemSettingsBuffered[setting];
}
return "";
}
void DemodulatorPreThread::writeModemSetting(std::string setting, std::string value) {
modemSettingsBuffered[setting] = value;
modemSettingsChanged.store(true);
}
ModemSettings DemodulatorPreThread::readModemSettings() {
if (cModem) {
return cModem->readSettings();
} else {
return modemSettingsBuffered;
}
}
void DemodulatorPreThread::writeModemSettings(ModemSettings settings) {
modemSettingsBuffered = settings;
modemSettingsChanged.store(true);
}

View File

@ -32,12 +32,18 @@ public:
void setAudioSampleRate(int rate);
int getAudioSampleRate();
void initialize();
bool isInitialized();
void terminate();
Modem *getModem();
ModemKit *getModemKit();
std::string readModemSetting(std::string setting);
void writeModemSetting(std::string setting, std::string value);
ModemSettings readModemSettings();
void writeModemSettings(ModemSettings settings);
protected:
DemodulatorInstance *parent;
msresamp_crcf iqResampler;
@ -53,6 +59,9 @@ protected:
int currentAudioSampleRate, newAudioSampleRate;
std::atomic_bool sampleRateChanged, frequencyChanged, bandwidthChanged, audioSampleRateChanged;
ModemSettings modemSettingsBuffered;
std::atomic_bool modemSettingsChanged;
nco_crcf freqShifter;
int shiftFrequency;

View File

@ -52,6 +52,9 @@ void DemodulatorWorkerThread::run() {
if (makeDemod) {
cModem = Modem::makeModem(demodCommand.demodType);
cModemType = demodCommand.demodType;
if (demodCommand.settings.size()) {
cModem->writeSettings(demodCommand.settings);
}
result.sampleRate = demodCommand.sampleRate;
wxGetApp().getAppFrame()->updateModemProperties(cModem->getSettings());
}

View File

@ -62,6 +62,7 @@ public:
unsigned int bandwidth;
unsigned int audioSampleRate;
std::string demodType;
ModemSettings settings;
};
typedef ThreadQueue<DemodulatorWorkerThreadCommand> DemodulatorThreadWorkerCommandQueue;

View File

@ -28,6 +28,14 @@ ModemArgInfo::ModemArgInfo(void) {
}
Modem::Modem() {
}
Modem::~Modem() {
}
void Modem::addModemFactory(Modem *factorySingle) {
modemFactories[factorySingle->getName()] = factorySingle;
}
@ -58,12 +66,19 @@ std::string Modem::readSetting(std::string setting) {
return "";
}
Modem::Modem() {
void Modem::writeSettings(ModemSettings settings) {
for (ModemSettings::const_iterator i = settings.begin(); i != settings.end(); i++) {
writeSetting(i->first, i->second);
}
}
Modem::~Modem() {
ModemSettings Modem::readSettings() {
ModemArgInfoList args = getSettings();
ModemSettings rs;
for (ModemArgInfoList::const_iterator i = args.begin(); i != args.end(); i++) {
rs[i->key] = readSetting(i->key);
}
return rs;
}
bool Modem::shouldRebuildKit() {

View File

@ -105,6 +105,8 @@ typedef std::vector<ModemArgInfo> ModemArgInfoList;
class Modem;
typedef std::map<std::string,Modem *> ModemFactoryList;
typedef std::map<std::string, std::string> ModemSettings;
class Modem {
public:
static void addModemFactory(Modem *factorySingle);
@ -122,7 +124,9 @@ public:
virtual ModemArgInfoList getSettings();
virtual void writeSetting(std::string setting, std::string value);
virtual void writeSettings(ModemSettings settings);
virtual std::string readSetting(std::string setting);
virtual ModemSettings readSettings();
virtual int checkSampleRate(long long sampleRate, int audioSampleRate) = 0;

View File

@ -597,6 +597,7 @@ void WaterfallCanvas::OnMouseDown(wxMouseEvent& event) {
InteractiveCanvas::OnMouseDown(event);
dragState = nextDragState;
wxGetApp().getDemodMgr().updateLastState();
if (dragState && dragState != WF_DRAG_RANGE) {
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getActiveDemodulator();
@ -617,6 +618,7 @@ void WaterfallCanvas::OnMouseWheelMoved(wxMouseEvent& event) {
void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
InteractiveCanvas::OnMouseReleased(event);
wxGetApp().getDemodMgr().updateLastState();
bool isNew = shiftDown || (wxGetApp().getDemodMgr().getLastActiveDemodulator() == NULL)
|| (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive());
@ -653,6 +655,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
if (dragState == WF_DRAG_NONE) {
if (!isNew && wxGetApp().getDemodMgr().getDemodulators().size()) {
mgr->updateLastState();
demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
} else {
isNew = true;
@ -660,12 +663,16 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
demod->setFrequency(freq);
demod->setDemodulatorType(mgr->getLastDemodulatorType());
demod->setBandwidth(mgr->getLastBandwidth());
if (int lastDemodBw = mgr->getLastBandwidth(mgr->getLastDemodulatorType())) {
demod->setBandwidth(lastDemodBw);
} else {
demod->setBandwidth(mgr->getLastBandwidth());
}
demod->setSquelchLevel(mgr->getLastSquelchLevel());
demod->setSquelchEnabled(mgr->isLastSquelchEnabled());
demod->setGain(mgr->getLastGain());
demod->setMuted(mgr->isLastMuted());
demod->writeModemSettings(mgr->getLastModemSettings(mgr->getLastDemodulatorType()));
demod->run();
wxGetApp().bindDemodulator(demod);
@ -678,7 +685,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
demod->updateLabel(freq);
demod->setFrequency(freq);
if (isNew) {
setStatusText("New demodulator at frequency: %s", freq);
} else {
@ -686,13 +693,14 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
}
wxGetApp().getDemodMgr().setActiveDemodulator(demod, false);
SetCursor(wxCURSOR_SIZING);
SetCursor(wxCURSOR_SIZING);
nextDragState = WF_DRAG_FREQUENCY;
mouseTracker.setVertDragLock(true);
mouseTracker.setHorizDragLock(false);
} else {
if (activeDemod) {
wxGetApp().getDemodMgr().setActiveDemodulator(activeDemod, false);
mgr->updateLastState();
activeDemod->setTracking(true);
nextDragState = WF_DRAG_FREQUENCY;
} else {
@ -742,15 +750,22 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
if (!isNew && wxGetApp().getDemodMgr().getDemodulators().size()) {
mgr->updateLastState();
demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
} else {
demod = wxGetApp().getDemodMgr().newThread();
demod->setFrequency(freq);
demod->setDemodulatorType(mgr->getLastDemodulatorType());
demod->setBandwidth(bw);
if (int lastDemodBw = mgr->getLastBandwidth(mgr->getLastDemodulatorType())) {
demod->setBandwidth(lastDemodBw);
} else {
demod->setBandwidth(mgr->getLastBandwidth());
}
demod->setSquelchLevel(mgr->getLastSquelchLevel());
demod->setSquelchEnabled(mgr->isLastSquelchEnabled());
demod->setGain(mgr->getLastGain());
demod->setMuted(mgr->isLastMuted());
demod->writeModemSettings(mgr->getLastModemSettings(mgr->getLastDemodulatorType()));
demod->run();
@ -767,7 +782,8 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
demod->updateLabel(freq);
demod->setFrequency(freq);
demod->setBandwidth(bw);
wxGetApp().getDemodMgr().setActiveDemodulator(demod, false);
mgr->setActiveDemodulator(demod, false);
mgr->updateLastState();
}
dragState = WF_DRAG_NONE;