diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 7d5fb54..fce7a96 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -277,3 +277,13 @@ void CubicSDR::showFrequencyInput() { fdialog.ShowModal(); } +void CubicSDR::setFrequencySnap(int snap) { + if (snap > 1000000) { + snap = 1000000; + } + this->snap = snap; +} + +int CubicSDR::getFrequencySnap() { + return snap; +} diff --git a/src/CubicSDR.h b/src/CubicSDR.h index dfc7e33..2d84af1 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -22,7 +22,7 @@ class CubicSDR: public wxApp { public: CubicSDR() : - m_glContext(NULL), frequency(DEFAULT_FREQ), sdrThread(NULL), sdrPostThread(NULL), threadCmdQueueSDR(NULL), iqVisualQueue(NULL), iqPostDataQueue(NULL), audioVisualQueue(NULL), t_SDR(NULL), t_PostSDR(NULL), sampleRate(DEFAULT_SAMPLE_RATE), offset(0) { + m_glContext(NULL), frequency(DEFAULT_FREQ), sdrThread(NULL), sdrPostThread(NULL), threadCmdQueueSDR(NULL), iqVisualQueue(NULL), iqPostDataQueue(NULL), audioVisualQueue(NULL), t_SDR(NULL), t_PostSDR(NULL), sampleRate(DEFAULT_SAMPLE_RATE), offset(0), snap(1) { } @@ -51,6 +51,9 @@ public: void bindDemodulator(DemodulatorInstance *demod); void removeDemodulator(DemodulatorInstance *demod); + void setFrequencySnap(int snap); + int getFrequencySnap(); + AppConfig *getConfig(); void saveConfig(); @@ -69,7 +72,7 @@ private: long long frequency; long long offset; - int ppm; + int ppm, snap; long long sampleRate; SDRThread *sdrThread; diff --git a/src/visual/TuningCanvas.cpp b/src/visual/TuningCanvas.cpp index e6322d7..d7e4a6b 100644 --- a/src/visual/TuningCanvas.cpp +++ b/src/visual/TuningCanvas.cpp @@ -20,6 +20,9 @@ EVT_IDLE(TuningCanvas::OnIdle) EVT_MOTION(TuningCanvas::OnMouseMoved) EVT_LEFT_DOWN(TuningCanvas::OnMouseDown) EVT_LEFT_UP(TuningCanvas::OnMouseReleased) +EVT_RIGHT_DOWN(TuningCanvas::OnMouseRightDown) +EVT_RIGHT_UP(TuningCanvas::OnMouseRightReleased) + EVT_LEAVE_WINDOW(TuningCanvas::OnMouseLeftWindow) EVT_ENTER_WINDOW(TuningCanvas::OnMouseEnterWindow) EVT_MOUSEWHEEL(TuningCanvas::OnMouseWheelMoved) @@ -124,6 +127,10 @@ void TuningCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { glContext->DrawTuner(currentPPM, 11, freqDP, freqW); } else { glContext->DrawTuner(freq, 11, freqDP, freqW); + int snap = wxGetApp().getFrequencySnap(); + if (snap != 1) { + glContext->DrawTunerDigitBox((int)log10(snap), 11, freqDP, freqW, RGBColor(1.0,0.0,0.0)); + } } glContext->DrawTuner(bw, 7, bwDP, bwW); glContext->DrawTuner(center, 11, centerDP, centerW); @@ -341,6 +348,27 @@ void TuningCanvas::OnMouseReleased(wxMouseEvent& event) { SetCursor(wxCURSOR_ARROW); } +void TuningCanvas::OnMouseRightDown(wxMouseEvent& event) { + InteractiveCanvas::OnMouseRightDown(event); +} + +void TuningCanvas::OnMouseRightReleased(wxMouseEvent& event) { + InteractiveCanvas::OnMouseRightReleased(event); + + if (hoverState == TUNING_HOVER_FREQ) { + if (hoverIndex == 1) { + wxGetApp().setFrequencySnap(1); + } else if (hoverIndex > 1 && hoverIndex < 8) { + int exp = pow(10, hoverIndex-1); + if (wxGetApp().getFrequencySnap() == exp) { + wxGetApp().setFrequencySnap(1); + } else { + wxGetApp().setFrequencySnap(exp); + } + } + } +} + void TuningCanvas::OnMouseLeftWindow(wxMouseEvent& event) { InteractiveCanvas::OnMouseLeftWindow(event); SetCursor(wxCURSOR_CROSS); diff --git a/src/visual/TuningCanvas.h b/src/visual/TuningCanvas.h index d6e2cee..1fea2e2 100644 --- a/src/visual/TuningCanvas.h +++ b/src/visual/TuningCanvas.h @@ -35,6 +35,8 @@ private: void OnMouseLeftWindow(wxMouseEvent& event); void OnKeyDown(wxKeyEvent& event); void OnKeyUp(wxKeyEvent& event); + void OnMouseRightDown(wxMouseEvent& event); + void OnMouseRightReleased(wxMouseEvent& event); void StepTuner(ActiveState state, int factor, bool up = true); diff --git a/src/visual/TuningContext.cpp b/src/visual/TuningContext.cpp index 9a4dd4c..16d49ac 100644 --- a/src/visual/TuningContext.cpp +++ b/src/visual/TuningContext.cpp @@ -112,6 +112,34 @@ void TuningContext::DrawTuner(long long freq, int count, float displayPos, float glDisable(GL_BLEND); } + +void TuningContext::DrawTunerDigitBox(int index, int count, float displayPos, float displayWidth, RGBColor c) { + GLint vp[4]; + glGetIntegerv( GL_VIEWPORT, vp); + + float viewHeight = (float) vp[3]; + float viewWidth = (float) vp[2]; + + float pixelHeight = 2.0/viewHeight; + + glColor4f(1.0, 0,0,1); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + float xpos = displayPos + (displayWidth / (float) count) * (float) (count-index); + float xpos2 = displayPos + (displayWidth / (float) count) * (float) ((count-1)-index); + glBegin(GL_LINE_STRIP); + glVertex2f(xpos, 1.0-pixelHeight); + glVertex2f(xpos, -1.0+pixelHeight); + glVertex2f(xpos2, -1.0+pixelHeight); + glVertex2f(xpos2, 1.0-pixelHeight); + glVertex2f(xpos, 1.0-pixelHeight); + glEnd(); + glDisable(GL_BLEND); +} + + + + int TuningContext::GetTunerDigitIndex(float mPos, int count, float displayPos, float displayWidth) { mPos -= 0.5; mPos *= 2.0; diff --git a/src/visual/TuningContext.h b/src/visual/TuningContext.h index dd4c77b..436a1f1 100644 --- a/src/visual/TuningContext.h +++ b/src/visual/TuningContext.h @@ -14,6 +14,7 @@ public: void DrawBegin(); void Draw(float r, float g, float b, float a, float p1, float p2); void DrawTuner(long long freq, int count, float displayPos, float displayWidth); + void DrawTunerDigitBox(int index, int count, float displayPos, float displayWidth, RGBColor c); int GetTunerDigitIndex(float mPos, int count, float displayPos, float displayWidth); void DrawTunerBarIndexed(int start, int end, int count, float displayPos, float displayWidth, RGBColor color, float alpha, bool top, bool bottom); diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index b00fb84..5485bc2 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -633,12 +633,20 @@ void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) { } if (dragState == WF_DRAG_FREQUENCY) { - long long bwDiff = (long long) (mouseTracker.getDeltaMouseX() * (float) getBandwidth()); + long long bwTarget = (long long) (mouseTracker.getMouseX() * (float) getBandwidth()) + getCenterFrequency() - (getBandwidth() / 2); long long currentFreq = demod->getFrequency(); + long long bwDiff = bwTarget - currentFreq; + int snap = wxGetApp().getFrequencySnap(); - demod->setFrequency(currentFreq + bwDiff); - currentFreq = demod->getFrequency(); - demod->updateLabel(currentFreq); + if (snap > 1) { + bwDiff = roundf((float)bwDiff/(float)snap)*snap; + } + + if (bwDiff) { + demod->setFrequency(currentFreq + bwDiff); + currentFreq = demod->getFrequency(); + demod->updateLabel(currentFreq); + } setStatusText("Set demodulator frequency: %s", demod->getFrequency()); } @@ -765,13 +773,30 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) { mouseTracker.setVertDragLock(false); mouseTracker.setHorizDragLock(false); - DemodulatorInstance *demod; + DemodulatorInstance *demod = isNew?NULL:wxGetApp().getDemodMgr().getLastActiveDemodulator(); DemodulatorMgr *mgr = &wxGetApp().getDemodMgr(); if (mouseTracker.getOriginDeltaMouseX() == 0 && mouseTracker.getOriginDeltaMouseY() == 0) { float pos = mouseTracker.getMouseX(); long long input_center_freq = getCenterFrequency(); - long long freq = input_center_freq - (long long) (0.5 * (float) getBandwidth()) + (long long) ((float) pos * (float) getBandwidth()); + long long freqTarget = input_center_freq - (long long) (0.5 * (float) getBandwidth()) + (long long) ((float) pos * (float) getBandwidth()); + long long demodFreq = demod?demod->getFrequency():freqTarget; + long long bwDiff = freqTarget - demodFreq; + long long freq = demodFreq; + + int snap = wxGetApp().getFrequencySnap(); + + if (snap > 1) { + if (demod) { + bwDiff = roundf((double)bwDiff/(double)snap)*snap; + freq += bwDiff; + } else { + freq = roundl((long double)freq/(double)snap)*snap; + } + } else { + freq += bwDiff; + } + if (dragState == WF_DRAG_NONE) { if (!isNew && wxGetApp().getDemodMgr().getDemodulators().size()) {