void PrimaryGLContext::DrawFreqSelector(float uxPos, RGBA4f color, float w, long long center_freq, long long srate) { DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); long long bw = 0; std::string last_type = wxGetApp().getDemodMgr().getLastDemodulatorType(); if (!demod) { bw = wxGetApp().getDemodMgr().getLastBandwidth(); } else { bw = demod->getBandwidth(); } if (!srate) { srate = wxGetApp().getSampleRate(); } glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glColor4f(color.r, color.g, color.b, 0.6); glBegin(GL_LINES); glVertex3f((uxPos - 0.5) * 2.0, 1.0, 0.0); glVertex3f((uxPos - 0.5) * 2.0, -1.0, 0.0); float ofs; if (w) { ofs = w; } else { ofs = ((float) bw) / (float) srate; } if (last_type != "USB") { glVertex3f((uxPos - 0.5) * 2.0 - ofs, 1.0, 0.0); glVertex3f((uxPos - 0.5) * 2.0 - ofs, -1.0, 0.0); } if (last_type != "LSB") { glVertex3f((uxPos - 0.5) * 2.0 + ofs, 1.0, 0.0); glVertex3f((uxPos - 0.5) * 2.0 + ofs, -1.0, 0.0); } glEnd(); glDisable(GL_BLEND); }
void WaterfallCanvas::OnMouseDown(wxMouseEvent& event) { InteractiveCanvas::OnMouseDown(event); dragState = nextDragState; wxGetApp().getDemodMgr().updateLastState(); if (dragState && dragState != WF_DRAG_RANGE) { DemodulatorInstance *demod = wxGetApp().getDemodMgr().getActiveDemodulator(); if (demod) { dragOfs = (long long) (mouseTracker.getMouseX() * (float) getBandwidth()) + getCenterFrequency() - (getBandwidth() / 2) - demod->getFrequency(); dragBW = demod->getBandwidth(); } wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getActiveDemodulator(), false); } }
void WaterfallCanvas::updateHoverState() { long long freqPos = getFrequencyAt(mouseTracker.getMouseX()); std::vector<DemodulatorInstance *> *demodsHover = wxGetApp().getDemodMgr().getDemodulatorsAt(freqPos, 15000); wxGetApp().getDemodMgr().setActiveDemodulator(NULL); if (altDown) { nextDragState = WF_DRAG_RANGE; mouseTracker.setVertDragLock(true); mouseTracker.setHorizDragLock(false); if (shiftDown) { setStatusText("Click and drag to create a new demodulator by range."); } else { setStatusText("Click and drag to set the current demodulator range."); } } else if (demodsHover->size() && !shiftDown) { long near_dist = getBandwidth(); DemodulatorInstance *activeDemodulator = NULL; for (int i = 0, iMax = demodsHover->size(); i < iMax; i++) { DemodulatorInstance *demod = (*demodsHover)[i]; long long freqDiff = demod->getFrequency() - freqPos; long halfBw = (demod->getBandwidth() / 2); long long currentBw = getBandwidth(); long long globalBw = wxGetApp().getSampleRate(); long dist = abs(freqDiff); double bufferBw = 10000.0 * ((double)currentBw / (double)globalBw); double maxDist = ((double)halfBw + bufferBw); if ((double)dist <= maxDist) { if ((freqDiff > 0 && demod->getDemodulatorType() == "USB") || (freqDiff < 0 && demod->getDemodulatorType() == "LSB")) { continue; } if (dist < near_dist) { activeDemodulator = demod; near_dist = dist; } long edge_dist = abs(halfBw - dist); if (edge_dist < near_dist) { activeDemodulator = demod; near_dist = edge_dist; } } } if (activeDemodulator == NULL) { nextDragState = WF_DRAG_NONE; SetCursor(wxCURSOR_CROSS); return; } wxGetApp().getDemodMgr().setActiveDemodulator(activeDemodulator); long long freqDiff = activeDemodulator->getFrequency() - freqPos; if (abs(freqDiff) > (activeDemodulator->getBandwidth() / 3)) { if (freqDiff > 0) { if (activeDemodulator->getDemodulatorType() != "USB") { nextDragState = WF_DRAG_BANDWIDTH_LEFT; SetCursor(wxCURSOR_SIZEWE); } } else { if (activeDemodulator->getDemodulatorType() != "LSB") { nextDragState = WF_DRAG_BANDWIDTH_RIGHT; SetCursor(wxCURSOR_SIZEWE); } } mouseTracker.setVertDragLock(true); mouseTracker.setHorizDragLock(false); setStatusText("Click and drag to change demodulator bandwidth. SPACE or numeric key for direct frequency input. [, ] to nudge, M for mute, D to delete, C to center."); } else { SetCursor(wxCURSOR_SIZING); nextDragState = WF_DRAG_FREQUENCY; mouseTracker.setVertDragLock(true); mouseTracker.setHorizDragLock(false); setStatusText("Click and drag to change demodulator frequency; SPACE or numeric key for direct input. [, ] to nudge, M for mute, D to delete, C to center."); } } else { SetCursor(wxCURSOR_CROSS); nextDragState = WF_DRAG_NONE; if (shiftDown) { setStatusText("Click to create a new demodulator or hold ALT to drag range, SPACE or numeric key for direct center frequency input."); } else { setStatusText( "Click to set active demodulator frequency or hold ALT to drag range; hold SHIFT to create new. Right drag or wheel to Zoom. Arrow keys to navigate/zoom, C to center."); } } delete demodsHover; }
void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) { InteractiveCanvas::OnMouseMoved(event); DemodulatorInstance *demod = wxGetApp().getDemodMgr().getActiveDemodulator(); if (mouseTracker.mouseDown()) { if (demod == NULL) { return; } if (dragState == WF_DRAG_BANDWIDTH_LEFT || dragState == WF_DRAG_BANDWIDTH_RIGHT) { int bwDiff = (int) (mouseTracker.getDeltaMouseX() * (float) getBandwidth()) * 2; if (dragState == WF_DRAG_BANDWIDTH_LEFT) { bwDiff = -bwDiff; } int currentBW = dragBW; currentBW = currentBW + bwDiff; if (currentBW > CHANNELIZER_RATE_MAX) { currentBW = CHANNELIZER_RATE_MAX; } if (currentBW < MIN_BANDWIDTH) { currentBW = MIN_BANDWIDTH; } demod->setBandwidth(currentBW); dragBW = currentBW; } if (dragState == WF_DRAG_FREQUENCY) { long long bwTarget = getFrequencyAt(mouseTracker.getMouseX()) - dragOfs; long long currentFreq = demod->getFrequency(); long long bwDiff = bwTarget - currentFreq; int snap = wxGetApp().getFrequencySnap(); if (snap > 1) { bwDiff = roundf((float)bwDiff/(float)snap)*snap; } if (bwDiff) { demod->setFrequency(currentFreq + bwDiff); currentFreq = demod->getFrequency(); demod->updateLabel(currentFreq); } } } else if (mouseTracker.mouseRightDown()) { mouseZoom = mouseZoom + ((1.0 - (mouseTracker.getDeltaMouseY() * 4.0)) - mouseZoom) * 0.1; } else { long long freqPos = getFrequencyAt(mouseTracker.getMouseX()); std::vector<DemodulatorInstance *> *demodsHover = wxGetApp().getDemodMgr().getDemodulatorsAt(freqPos, 15000); wxGetApp().getDemodMgr().setActiveDemodulator(NULL); if (altDown) { nextDragState = WF_DRAG_RANGE; mouseTracker.setVertDragLock(true); mouseTracker.setHorizDragLock(false); if (shiftDown) { setStatusText("Click and drag to create a new demodulator by range."); } else { setStatusText("Click and drag to set the current demodulator range."); } } else if (demodsHover->size() && !shiftDown) { long near_dist = getBandwidth(); DemodulatorInstance *activeDemodulator = NULL; for (int i = 0, iMax = demodsHover->size(); i < iMax; i++) { DemodulatorInstance *demod = (*demodsHover)[i]; long long freqDiff = demod->getFrequency() - freqPos; long halfBw = (demod->getBandwidth() / 2); long long currentBw = getBandwidth(); long long globalBw = wxGetApp().getSampleRate(); long dist = abs(freqDiff); double bufferBw = 10000.0 * ((double)currentBw / (double)globalBw); double maxDist = ((double)halfBw + bufferBw); if ((double)dist <= maxDist) { if ((freqDiff > 0 && demod->getDemodulatorType() == "USB") || (freqDiff < 0 && demod->getDemodulatorType() == "LSB")) { continue; } if (dist < near_dist) { activeDemodulator = demod; near_dist = dist; } long edge_dist = abs(halfBw - dist); if (edge_dist < near_dist) { activeDemodulator = demod; near_dist = edge_dist; } } } if (activeDemodulator == NULL) { nextDragState = WF_DRAG_NONE; SetCursor(wxCURSOR_CROSS); return; } wxGetApp().getDemodMgr().setActiveDemodulator(activeDemodulator); long long freqDiff = activeDemodulator->getFrequency() - freqPos; if (abs(freqDiff) > (activeDemodulator->getBandwidth() / 3)) { if (freqDiff > 0) { if (activeDemodulator->getDemodulatorType() != "USB") { nextDragState = WF_DRAG_BANDWIDTH_LEFT; SetCursor(wxCURSOR_SIZEWE); } } else { if (activeDemodulator->getDemodulatorType() != "LSB") { nextDragState = WF_DRAG_BANDWIDTH_RIGHT; SetCursor(wxCURSOR_SIZEWE); } } mouseTracker.setVertDragLock(true); mouseTracker.setHorizDragLock(false); setStatusText("Click and drag to change demodulator bandwidth. SPACE for direct frequency input. M for mute, D to delete, C to center."); } else { SetCursor(wxCURSOR_SIZING); nextDragState = WF_DRAG_FREQUENCY; mouseTracker.setVertDragLock(true); mouseTracker.setHorizDragLock(false); setStatusText("Click and drag to change demodulator frequency; SPACE for direct input. M for mute, D to delete, C to center."); } } else { SetCursor(wxCURSOR_CROSS); nextDragState = WF_DRAG_NONE; if (shiftDown) { setStatusText("Click to create a new demodulator or hold ALT to drag range, SPACE for direct center frequency input."); } else { setStatusText( "Click to move active demodulator frequency or hold ALT to drag range; hold SHIFT to create new. Right drag or wheel to Zoom. Arrow keys to navigate/zoom, C to center."); } } delete demodsHover; } }
void AppFrame::OnIdle(wxIdleEvent& event) { bool work_done = false; //#ifdef __APPLE__ // std::this_thread::sleep_for(std::chrono::milliseconds(4)); // std::this_thread::yield(); //#endif DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); if (demod) { DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); if (demod->isTracking()) { if (spectrumCanvas->getViewState()) { long long diff = abs(demod->getFrequency() - spectrumCanvas->getCenterFrequency()) + (demod->getBandwidth()/2) + (demod->getBandwidth()/4); if (diff > spectrumCanvas->getBandwidth()/2) { if (demod->getBandwidth() > spectrumCanvas->getBandwidth()) { diff = abs(demod->getFrequency() - spectrumCanvas->getCenterFrequency()); } else { diff = diff - spectrumCanvas->getBandwidth()/2; } spectrumCanvas->moveCenterFrequency((demod->getFrequency() < spectrumCanvas->getCenterFrequency())?diff:-diff); demod->setTracking(false); } } else { demod->setTracking(false); } } if (demod != activeDemodulator) { demodSignalMeter->setInputValue(demod->getSquelchLevel()); demodGainMeter->setInputValue(demod->getGain()); int outputDevice = demod->getOutputDevice(); scopeCanvas->setDeviceName(outputDevices[outputDevice].name); outputDeviceMenuItems[outputDevice]->Check(true); int dType = demod->getDemodulatorType(); demodModeSelector->setSelection(dType); } if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) { long long centerFreq = demod->getFrequency(); unsigned int demodBw = (unsigned int) ceil((float) demod->getBandwidth() * 2.25); if (demod->getDemodulatorType() == DEMOD_TYPE_USB) { demodBw /= 2; centerFreq += demod->getBandwidth() / 4; } if (demod->getDemodulatorType() == DEMOD_TYPE_LSB) { demodBw /= 2; centerFreq -= demod->getBandwidth() / 4; } if (demodBw > wxGetApp().getSampleRate() / 2) { demodBw = wxGetApp().getSampleRate() / 2; } if (demodBw < 20000) { demodBw = 20000; } if (centerFreq != demodWaterfallCanvas->getCenterFrequency()) { demodWaterfallCanvas->setCenterFrequency(centerFreq); demodSpectrumCanvas->setCenterFrequency(centerFreq); } int dSelection = demodModeSelector->getSelection(); if (dSelection != -1 && dSelection != demod->getDemodulatorType()) { demod->setDemodulatorType(dSelection); } demodWaterfallCanvas->setBandwidth(demodBw); demodSpectrumCanvas->setBandwidth(demodBw); } demodSignalMeter->setLevel(demod->getSignalLevel()); demodGainMeter->setLevel(demod->getGain()); if (demodSignalMeter->inputChanged()) { demod->setSquelchLevel(demodSignalMeter->getInputValue()); } if (demodGainMeter->inputChanged()) { demod->setGain(demodGainMeter->getInputValue()); demodGainMeter->setLevel(demodGainMeter->getInputValue()); } activeDemodulator = demod; } else { DemodulatorMgr *mgr = &wxGetApp().getDemodMgr(); int dSelection = demodModeSelector->getSelection(); if (dSelection != -1 && dSelection != mgr->getLastDemodulatorType()) { mgr->setLastDemodulatorType(dSelection); } demodGainMeter->setLevel(mgr->getLastGain()); if (demodSignalMeter->inputChanged()) { mgr->setLastSquelchLevel(demodSignalMeter->getInputValue()); } if (demodGainMeter->inputChanged()) { mgr->setLastGain(demodGainMeter->getInputValue()); demodGainMeter->setLevel(demodGainMeter->getInputValue()); } if (wxGetApp().getFrequency() != demodWaterfallCanvas->getCenterFrequency()) { demodWaterfallCanvas->setCenterFrequency(wxGetApp().getFrequency()); demodSpectrumCanvas->setCenterFrequency(wxGetApp().getFrequency()); } if (spectrumCanvas->getViewState() && abs(wxGetApp().getFrequency()-spectrumCanvas->getCenterFrequency()) > (wxGetApp().getSampleRate()/2)) { spectrumCanvas->setCenterFrequency(wxGetApp().getFrequency()); waterfallCanvas->setCenterFrequency(wxGetApp().getFrequency()); } } if (demodTuner->getMouseTracker()->mouseInView()) { if (!demodTuner->HasFocus()) { demodTuner->SetFocus(); } } else if (!waterfallCanvas->HasFocus()) { waterfallCanvas->SetFocus(); } scopeCanvas->setPPMMode(demodTuner->isAltDown()); event.Skip(); }