Add delta lock -- lock modem relative to center frequency

This commit is contained in:
Charles J. Cliffe 2016-02-15 17:43:10 -05:00
parent 7bf0ad47c5
commit 93d2c73fb9
11 changed files with 141 additions and 8 deletions

View File

@ -53,6 +53,7 @@ AppFrame::AppFrame() :
wxBoxSizer *demodVisuals = new wxBoxSizer(wxVERTICAL);
demodTray = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *demodScopeTray = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *demodTunerTray = new wxBoxSizer(wxHORIZONTAL);
int attribList[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
@ -156,10 +157,23 @@ AppFrame::AppFrame() :
demodScopeTray->AddSpacer(1);
deltaLockButton = new ModeSelectorCanvas(demodPanel, attribList);
deltaLockButton->addChoice(1, "V");
deltaLockButton->setPadding(-1,-1);
deltaLockButton->setHighlightColor(RGBA4f(0.8,0.8,0.2));
deltaLockButton->setHelpTip("Delta Lock Toggle (V) - Enable to lock modem relative to center frequency.");
deltaLockButton->setToggleMode(true);
deltaLockButton->setSelection(-1);
deltaLockButton->SetMinSize(wxSize(20,28));
demodTunerTray->Add(deltaLockButton, 0, wxEXPAND | wxALL, 0);
demodTunerTray->AddSpacer(1);
demodTuner = new TuningCanvas(demodPanel, attribList);
demodTuner->setHelpTip("Testing tuner");
demodTuner->SetMinClientSize(wxSize(200,28));
demodScopeTray->Add(demodTuner, 1, wxEXPAND | wxALL, 0);
demodTunerTray->Add(demodTuner, 1, wxEXPAND | wxALL, 0);
demodScopeTray->Add(demodTunerTray, 1, wxEXPAND | wxALL, 0);
demodTray->Add(demodScopeTray, 30, wxEXPAND | wxALL, 0);
@ -1078,6 +1092,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
#ifdef ENABLE_DIGITAL_LAB
demodModeSelectorAdv->setSelection(dType);
#endif
deltaLockButton->setSelection(demod->isDeltaLock()?1:-1);
demodMuteButton->setSelection(demod->isMuted()?1:-1);
modemPropertiesUpdated.store(true);
demodTuner->setHalfBand(dType=="USB" || dType=="LSB");
@ -1144,11 +1159,34 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
if (demod->isMuted() && muteMode == -1) {
demodMuteButton->setSelection(1);
wxGetApp().getDemodMgr().setLastMuted(demod->isMuted());
demodMuteButton->Refresh();
} else if (!demod->isMuted() && muteMode == 1) {
demodMuteButton->setSelection(-1);
wxGetApp().getDemodMgr().setLastMuted(demod->isMuted());
demodMuteButton->Refresh();
}
}
int deltaMode = deltaLockButton->getSelection();
if (deltaLockButton->modeChanged()) {
if (demod->isDeltaLock() && deltaMode == -1) {
demod->setDeltaLock(false);
} else if (!demod->isDeltaLock() && deltaMode == 1) {
demod->setDeltaLockOfs(demod->getFrequency()-wxGetApp().getFrequency());
demod->setDeltaLock(true);
}
wxGetApp().getDemodMgr().setLastDeltaLock(demod->isDeltaLock());
deltaLockButton->clearModeChanged();
} else {
if (demod->isDeltaLock() && deltaMode == -1) {
deltaLockButton->setSelection(1);
wxGetApp().getDemodMgr().setLastDeltaLock(true);
deltaLockButton->Refresh();
} else if (!demod->isDeltaLock() && deltaMode == 1) {
deltaLockButton->setSelection(-1);
wxGetApp().getDemodMgr().setLastDeltaLock(false);
deltaLockButton->Refresh();
}
demodMuteButton->Refresh();
}
int soloMode = soloModeButton->getSelection();
@ -1377,6 +1415,10 @@ void AppFrame::saveSession(std::string fileName) {
*demod->newChild("output_device") = outputDevices[(*instance_i)->getOutputDevice()].name;
*demod->newChild("gain") = (*instance_i)->getGain();
*demod->newChild("muted") = (*instance_i)->isMuted() ? 1 : 0;
if ((*instance_i)->isDeltaLock()) {
*demod->newChild("delta_lock") = (*instance_i)->isDeltaLock() ? 1 : 0;
*demod->newChild("delta_ofs") = (*instance_i)->getDeltaLockOfs();
}
if ((*instance_i) == wxGetApp().getDemodMgr().getLastActiveDemodulator()) {
*demod->newChild("active") = 1;
}
@ -1450,9 +1492,11 @@ bool AppFrame::loadSession(std::string fileName) {
float squelch_level = demod->hasAnother("squelch_level") ? (float) *demod->getNext("squelch_level") : 0;
int squelch_enabled = demod->hasAnother("squelch_enabled") ? (int) *demod->getNext("squelch_enabled") : 0;
int muted = demod->hasAnother("muted") ? (int) *demod->getNext("muted") : 0;
int delta_locked = demod->hasAnother("delta_lock") ? (int) *demod->getNext("delta_lock") : 0;
int delta_ofs = demod->hasAnother("delta_ofs") ? (int) *demod->getNext("delta_ofs") : 0;
std::string output_device = demod->hasAnother("output_device") ? string(*(demod->getNext("output_device"))) : "";
float gain = demod->hasAnother("gain") ? (float) *demod->getNext("gain") : 1.0;
std::string type = "FM";
DataNode *demodTypeNode = demod->hasAnother("type")?demod->getNext("type"):nullptr;
@ -1512,6 +1556,10 @@ bool AppFrame::loadSession(std::string fileName) {
newDemod->setGain(gain);
newDemod->updateLabel(freq);
newDemod->setMuted(muted?true:false);
if (delta_locked) {
newDemod->setDeltaLock(true);
newDemod->setDeltaLockOfs(delta_ofs);
}
if (squelch_enabled) {
newDemod->setSquelchEnabled(true);
newDemod->setSquelchLevel(squelch_level);
@ -1645,6 +1693,8 @@ int AppFrame::OnGlobalKeyDown(wxKeyEvent &event) {
case WXK_NUMPAD_RIGHT:
waterfallCanvas->OnKeyDown(event); // TODO: Move the stuff from there to here
return 1;
case 'V':
return 1;
case ']':
if (lastDemod) {
lastDemod->setFrequency(lastDemod->getFrequency()+snap);
@ -1709,6 +1759,8 @@ int AppFrame::OnGlobalKeyUp(wxKeyEvent &event) {
return -1;
}
DemodulatorInstance *lastDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
switch (event.GetKeyCode()) {
case WXK_SPACE:
if (!demodTuner->getMouseTracker()->mouseInView()) {
@ -1726,6 +1778,14 @@ int AppFrame::OnGlobalKeyUp(wxKeyEvent &event) {
case WXK_NUMPAD_RIGHT:
waterfallCanvas->OnKeyUp(event);
return 1;
case 'V':
if (lastDemod && lastDemod->isDeltaLock()) {
lastDemod->setDeltaLock(false);
} else if (lastDemod) {
lastDemod->setDeltaLockOfs(lastDemod->getFrequency() - wxGetApp().getFrequency());
lastDemod->setDeltaLock(true);
}
break;
case 'A':
demodModeSelector->setSelection("AM");
return 1;

View File

@ -110,7 +110,7 @@ private:
// UITestCanvas *testCanvas;
MeterCanvas *spectrumAvgMeter;
MeterCanvas *waterfallSpeedMeter;
ModeSelectorCanvas *demodMuteButton, *peakHoldButton, *soloModeButton;
ModeSelectorCanvas *demodMuteButton, *peakHoldButton, *soloModeButton, *deltaLockButton;
GainCanvas *gainCanvas;
wxSizerItem *gainSizerItem, *gainSpacerItem;
wxSplitterWindow *mainVisSplitter, *mainSplitter;

View File

@ -373,6 +373,22 @@ void DemodulatorInstance::setTracking(bool tracking) {
this->tracking = tracking;
}
bool DemodulatorInstance::isDeltaLock() {
return deltaLock.load();
}
void DemodulatorInstance::setDeltaLock(bool lock) {
deltaLock.store(lock);
}
void DemodulatorInstance::setDeltaLockOfs(int lockOfs) {
deltaLockOfs.store(lockOfs);
}
int DemodulatorInstance::getDeltaLockOfs() {
return deltaLockOfs.load();
}
bool DemodulatorInstance::isMuted() {
return demodulatorThread->isMuted();
}

View File

@ -80,7 +80,12 @@ public:
bool isTracking();
void setTracking(bool tracking);
bool isDeltaLock();
void setDeltaLock(bool lock);
void setDeltaLockOfs(int lockOfs);
int getDeltaLockOfs();
bool isMuted();
void setMuted(bool muted);
@ -122,6 +127,8 @@ private:
std::atomic_bool active;
std::atomic_bool squelch;
std::atomic_bool muted;
std::atomic_bool deltaLock;
std::atomic_int deltaLockOfs;
std::atomic_int currentOutputDevice;
std::atomic<float> currentAudioGain;

View File

@ -11,7 +11,7 @@ bool inactiveCompare (DemodulatorInstance *i, DemodulatorInstance *j) { return (
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) {
DEFAULT_DEMOD_TYPE), lastSquelchEnabled(false), lastSquelch(-100), lastGain(1.0), lastMuted(false), lastDeltaLock(false) {
}
DemodulatorMgr::~DemodulatorMgr() {
@ -284,6 +284,15 @@ void DemodulatorMgr::setLastGain(float lastGain) {
this->lastGain = lastGain;
}
bool DemodulatorMgr::getLastDeltaLock() const {
return lastDeltaLock;
}
void DemodulatorMgr::setLastDeltaLock(bool lock) {
lastDeltaLock = lock;
}
float DemodulatorMgr::getLastSquelchLevel() const {
return lastSquelch;
}

View File

@ -37,6 +37,9 @@ public:
float getLastGain() const;
void setLastGain(float lastGain);
bool getLastDeltaLock() const;
void setLastDeltaLock(bool lock);
float getLastSquelchLevel() const;
void setLastSquelchLevel(float lastSquelch);
@ -67,6 +70,7 @@ private:
float lastSquelch;
float lastGain;
bool lastMuted;
bool lastDeltaLock;
std::map<std::string, ModemSettings> lastModemSettings;
};

View File

@ -69,11 +69,22 @@ void SDRPostThread::updateActiveDemodulators() {
nRunDemods = 0;
long long centerFreq = wxGetApp().getFrequency();
for (demod_i = demodulators.begin(); demod_i != demodulators.end(); demod_i++) {
DemodulatorInstance *demod = *demod_i;
DemodulatorThreadInputQueue *demodQueue = demod->getIQInputDataPipe();
// not in range?
if (demod->isDeltaLock()) {
if (demod->getFrequency() != centerFreq + demod->getDeltaLockOfs()) {
demod->setFrequency(centerFreq + demod->getDeltaLockOfs());
demod->updateLabel(demod->getFrequency());
demod->setFollow(false);
demod->setTracking(false);
}
}
if (abs(frequency - demod->getFrequency()) > (sampleRate / 2)) {
// deactivate if active
if (demod->isActive() && !demod->isFollow() && !demod->isTracking()) {
@ -85,7 +96,7 @@ void SDRPostThread::updateActiveDemodulators() {
}
// follow if follow mode
if (demod->isFollow() && wxGetApp().getFrequency() != demod->getFrequency()) {
if (demod->isFollow() && centerFreq != demod->getFrequency()) {
wxGetApp().setFrequency(demod->getFrequency());
demod->setFollow(false);
}

View File

@ -183,6 +183,7 @@ void ModeSelectorCanvas::setSelection(int value) {
for (int i = 0; i < numChoices; i++) {
if (selections[i].value == value) {
currentSelection = i;
Refresh();
return;
}
}

View File

@ -148,6 +148,10 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, RGBA4f color, l
demodLabel = std::string("[S] ") + demodLabel;
}
if (demod->isDeltaLock()) {
demodLabel.append(" [V]");
}
if (demod->getDemodulatorType() == "USB") {
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodLabel, uxPos, hPos, 16, GLFont::GLFONT_ALIGN_LEFT, GLFont::GLFONT_ALIGN_CENTER);
} else if (demod->getDemodulatorType() == "LSB") {

View File

@ -186,6 +186,9 @@ void TuningCanvas::StepTuner(ActiveState state, int exponent, bool up) {
activeDemod->setTracking(true);
activeDemod->setFollow(true);
activeDemod->setFrequency(freq);
if (activeDemod->isDeltaLock()) {
activeDemod->setDeltaLockOfs(activeDemod->getFrequency() - wxGetApp().getFrequency());
}
activeDemod->updateLabel(freq);
}

View File

@ -612,6 +612,9 @@ void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
if (bwDiff) {
demod->setFrequency(currentFreq + bwDiff);
if (demod->isDeltaLock()) {
demod->setDeltaLockOfs(demod->getFrequency() - wxGetApp().getFrequency());
}
currentFreq = demod->getFrequency();
demod->updateLabel(currentFreq);
}
@ -699,6 +702,12 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
demod->setSquelchEnabled(mgr->isLastSquelchEnabled());
demod->setGain(mgr->getLastGain());
demod->setMuted(mgr->isLastMuted());
if (mgr->getLastDeltaLock()) {
demod->setDeltaLock(true);
demod->setDeltaLockOfs(wxGetApp().getFrequency()-freq);
} else {
demod->setDeltaLock(false);
}
demod->writeModemSettings(mgr->getLastModemSettings(mgr->getLastDemodulatorType()));
demod->run();
@ -712,6 +721,9 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
demod->updateLabel(freq);
demod->setFrequency(freq);
if (demod->isDeltaLock()) {
demod->setDeltaLockOfs(demod->getFrequency() - wxGetApp().getFrequency());
}
if (isNew) {
setStatusText("New demodulator at frequency: %s", freq);
@ -788,6 +800,12 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) {
demod->setSquelchEnabled(mgr->isLastSquelchEnabled());
demod->setGain(mgr->getLastGain());
demod->setMuted(mgr->isLastMuted());
if (mgr->getLastDeltaLock()) {
demod->setDeltaLock(true);
demod->setDeltaLockOfs(wxGetApp().getFrequency()-freq);
} else {
demod->setDeltaLock(false);
}
demod->writeModemSettings(mgr->getLastModemSettings(mgr->getLastDemodulatorType()));
demod->run();