Pick freq/drag in waterfall, show demod bandwidth

This commit is contained in:
Charles J. Cliffe
2014-11-25 22:51:14 -05:00
parent f6966b1824
commit f441546023
11 changed files with 230 additions and 63 deletions
+4 -4
View File
@@ -57,13 +57,13 @@ void ScopeCanvas::OnKeyDown(wxKeyEvent& event) {
freq = wxGetApp().getFrequency();
freq += 100000;
wxGetApp().setFrequency(freq);
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
break;
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
break;
case WXK_LEFT:
freq = wxGetApp().getFrequency();
freq -= 100000;
wxGetApp().setFrequency(freq);
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
break;
case WXK_DOWN:
break;
@@ -81,7 +81,7 @@ void ScopeCanvas::OnIdle(wxIdleEvent &event) {
// timer.update();
// frameTimer += timer.lastUpdateSeconds();
// if (frameTimer > 1.0/30.0) {
Refresh(false);
Refresh(false);
// frameTimer = 0;
// }
}
+1 -1
View File
@@ -29,7 +29,7 @@ private:
ScopeContext *glContext;
Timer timer;
float frameTimer;
float frameTimer;
// event table
wxDECLARE_EVENT_TABLE();
};
+21 -36
View File
@@ -29,7 +29,7 @@ wxEND_EVENT_TABLE()
SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) :
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), isMouseDown(false) {
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0) {
int in_block_size = BUF_SIZE / 2;
int out_block_size = FFT_SIZE;
@@ -44,6 +44,9 @@ SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) :
glContext = new SpectrumContext(this, &wxGetApp().GetContext(this));
timer.start();
mTracker.setTarget(this);
mTracker.setVertDragLock(true);
SetCursor(wxCURSOR_SIZEWE);
}
@@ -72,13 +75,13 @@ void SpectrumCanvas::OnKeyDown(wxKeyEvent& event) {
freq = wxGetApp().getFrequency();
freq += 100000;
wxGetApp().setFrequency(freq);
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
break;
case WXK_LEFT:
freq = wxGetApp().getFrequency();
freq -= 100000;
wxGetApp().setFrequency(freq);
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
break;
case WXK_DOWN:
break;
@@ -167,62 +170,44 @@ void SpectrumCanvas::OnIdle(wxIdleEvent &event) {
// timer.update();
// frameTimer += timer.lastUpdateSeconds();
// if (frameTimer > 1.0/30.0) {
Refresh(false);
Refresh(false);
// frameTimer = 0;
// }
}
void SpectrumCanvas::mouseMoved(wxMouseEvent& event) {
if (isMouseDown) {
const wxSize ClientSize = GetClientSize();
float mouseX = (float)event.m_x/(float)ClientSize.x;
float mouseY = (float)event.m_y/(float)ClientSize.y;
mTracker.OnMouseMoved(event);
if (mTracker.mouseDown()) {
int freqChange = mTracker.getDeltaMouseX() * SRATE;
if (freqChange != 0) {
int freq = wxGetApp().getFrequency();
freq -= freqChange;
wxGetApp().setFrequency(freq);
deltaMouseX = mouseX-lastMouseX;
deltaMouseY = mouseY-lastMouseY;
lastMouseX = mouseX;
// lastMouseY = mouseY;
int freqChange = deltaMouseX*SRATE;
int freq = wxGetApp().getFrequency();
freq -= freqChange;
wxGetApp().setFrequency(freq);
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %s"),wxNumberFormatter::ToString((long)freq,wxNumberFormatter::Style_WithThousandsSep)));
if (mouseY != lastMouseY) {
WarpPointer(event.m_x,lastMouseY*ClientSize.y);
((wxFrame*) parent)->GetStatusBar()->SetStatusText(
wxString::Format(wxT("Set center frequency: %s"),
wxNumberFormatter::ToString((long) freq, wxNumberFormatter::Style_WithThousandsSep)));
}
}
}
void SpectrumCanvas::mouseDown(wxMouseEvent& event) {
const wxSize ClientSize = GetClientSize();
lastMouseX = (float)event.m_x/(float)ClientSize.x;
lastMouseY = (float)event.m_y/(float)ClientSize.y;
isMouseDown = true;
mTracker.OnMouseDown(event);
SetCursor(wxCURSOR_CROSS);
}
void SpectrumCanvas::mouseWheelMoved(wxMouseEvent& event) {
std::cout << "wheel?" << std::endl;
mTracker.OnMouseWheelMoved(event);
}
void SpectrumCanvas::mouseReleased(wxMouseEvent& event) {
isMouseDown = false;
mTracker.OnMouseReleased(event);
SetCursor(wxCURSOR_SIZEWE);
}
void SpectrumCanvas::mouseLeftWindow(wxMouseEvent& event) {
isMouseDown = false;
mTracker.OnMouseLeftWindow(event);
SetCursor(wxCURSOR_SIZEWE);
}
+2 -3
View File
@@ -10,6 +10,7 @@
#include "fftw3.h"
#include "Timer.h"
#include "MouseTracker.h"
class SpectrumCanvas: public wxGLCanvas {
public:
@@ -48,9 +49,7 @@ private:
Timer timer;
float frameTimer;
float lastMouseX, lastMouseY;
float deltaMouseX, deltaMouseY;
bool isMouseDown;
MouseTracker mTracker;
// event table
wxDECLARE_EVENT_TABLE();
};
+75 -3
View File
@@ -15,9 +15,16 @@
#include "AppFrame.h"
#include <algorithm>
#include <wx/numformatter.h>
wxBEGIN_EVENT_TABLE(WaterfallCanvas, wxGLCanvas) EVT_PAINT(WaterfallCanvas::OnPaint)
EVT_KEY_DOWN(WaterfallCanvas::OnKeyDown)
EVT_IDLE(WaterfallCanvas::OnIdle)
EVT_MOTION(WaterfallCanvas::mouseMoved)
EVT_LEFT_DOWN(WaterfallCanvas::mouseDown)
EVT_LEFT_UP(WaterfallCanvas::mouseReleased)
EVT_LEAVE_WINDOW(WaterfallCanvas::mouseLeftWindow)
EVT_ENTER_WINDOW(WaterfallCanvas::mouseEnterWindow)
wxEND_EVENT_TABLE()
WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
@@ -37,6 +44,8 @@ WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
glContext = new WaterfallContext(this, &wxGetApp().GetContext(this));
timer.start();
mTracker.setTarget(this);
SetCursor(wxCURSOR_CROSS);
}
@@ -51,8 +60,14 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
glContext->SetCurrent(*this);
glViewport(0, 0, ClientSize.x, ClientSize.y);
glContext->BeginDraw();
glContext->Draw(spectrum_points);
if (mTracker.mouseInView()) {
glContext->DrawFreqSelector(mTracker.getMouseX());
}
glContext->EndDraw();
SwapBuffers();
}
@@ -65,13 +80,13 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
freq = wxGetApp().getFrequency();
freq += 100000;
wxGetApp().setFrequency(freq);
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
break;
case WXK_LEFT:
freq = wxGetApp().getFrequency();
freq -= 100000;
wxGetApp().setFrequency(freq);
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
break;
case WXK_DOWN:
break;
@@ -158,7 +173,64 @@ void WaterfallCanvas::OnIdle(wxIdleEvent &event) {
// timer.update();
// frameTimer += timer.lastUpdateSeconds();
// if (frameTimer > 1.0/30.0) {
Refresh(false);
Refresh(false);
// frameTimer = 0;
// }
}
void WaterfallCanvas::mouseMoved(wxMouseEvent& event) {
mTracker.OnMouseMoved(event);
if (mTracker.mouseDown()) {
int freqChange = mTracker.getDeltaMouseX() * SRATE;
if (freqChange != 0) {
int freq = wxGetApp().getFrequency();
freq -= freqChange;
wxGetApp().setFrequency(freq);
((wxFrame*) parent)->GetStatusBar()->SetStatusText(
wxString::Format(wxT("Set center frequency: %s"),
wxNumberFormatter::ToString((long) freq, wxNumberFormatter::Style_WithThousandsSep)));
}
}
}
void WaterfallCanvas::mouseDown(wxMouseEvent& event) {
mTracker.OnMouseDown(event);
SetCursor(wxCURSOR_CROSS);
}
void WaterfallCanvas::mouseWheelMoved(wxMouseEvent& event) {
mTracker.OnMouseWheelMoved(event);
}
void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
mTracker.OnMouseReleased(event);
if (mTracker.getOriginDeltaMouseX() == 0 && mTracker.getOriginDeltaMouseX() == 0) {
float pos = mTracker.getMouseX();
int freq = wxGetApp().getFrequency();
freq += (pos - 0.5) * SRATE;
wxGetApp().setFrequency(freq);
((wxFrame*) parent)->GetStatusBar()->SetStatusText(
wxString::Format(wxT("Set center frequency: %s"),
wxNumberFormatter::ToString((long) freq, wxNumberFormatter::Style_WithThousandsSep)));
}
SetCursor(wxCURSOR_SIZEWE);
}
void WaterfallCanvas::mouseLeftWindow(wxMouseEvent& event) {
mTracker.OnMouseLeftWindow(event);
SetCursor(wxCURSOR_SIZEWE);
}
void WaterfallCanvas::mouseEnterWindow(wxMouseEvent& event) {
mTracker.OnMouseEnterWindow(event);
SetCursor(wxCURSOR_SIZEWE);
}
+10
View File
@@ -7,6 +7,7 @@
#include <queue>
#include "WaterfallContext.h"
#include "MouseTracker.h"
#include "fftw3.h"
#include "Timer.h"
@@ -23,6 +24,13 @@ private:
void OnIdle(wxIdleEvent &event);
void mouseMoved(wxMouseEvent& event);
void mouseDown(wxMouseEvent& event);
void mouseWheelMoved(wxMouseEvent& event);
void mouseReleased(wxMouseEvent& event);
void mouseEnterWindow(wxMouseEvent& event);
void mouseLeftWindow(wxMouseEvent& event);
wxWindow *parent;
std::vector<float> spectrum_points;
@@ -39,6 +47,8 @@ private:
WaterfallContext *glContext;
Timer timer;
float frameTimer;
MouseTracker mTracker;
// event table
wxDECLARE_EVENT_TABLE();
};
+38 -5
View File
@@ -1,5 +1,6 @@
#include "WaterfallContext.h"
#include "WaterfallCanvas.h"
#include "CubicSDR.h"
WaterfallContext::WaterfallContext(WaterfallCanvas *canvas, wxGLContext *sharedContext) :
PrimaryGLContext(canvas, sharedContext) {
@@ -36,11 +37,14 @@ WaterfallContext::WaterfallContext(WaterfallCanvas *canvas, wxGLContext *sharedC
glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 256, &(grad.getBlue())[0]);
}
void WaterfallContext::Draw(std::vector<float> &points) {
void WaterfallContext::BeginDraw() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void WaterfallContext::Draw(std::vector<float> &points) {
if (points.size()) {
memmove(waterfall_tex + FFT_SIZE, waterfall_tex, (NUM_WATERFALL_LINES - 1) * FFT_SIZE);
@@ -57,15 +61,13 @@ void WaterfallContext::Draw(std::vector<float> &points) {
}
}
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, waterfall);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, FFT_SIZE, NUM_WATERFALL_LINES, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, (GLvoid *) waterfall_tex);
glDisable(GL_TEXTURE_2D);
glColor3f(1.0, 1.0, 1.0);
glEnable(GL_TEXTURE_2D);
// glEnable(GL_COLOR_TABLE);
glBindTexture(GL_TEXTURE_2D, waterfall);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 1.0);
@@ -78,6 +80,37 @@ void WaterfallContext::Draw(std::vector<float> &points) {
glVertex3f(-1.0, 1.0, 0.0);
glEnd();
}
void WaterfallContext::DrawFreqSelector(float uxPos) {
DemodulatorInstance *demod = wxGetApp().getDemodTest();
if (!demod) {
return;
}
glClear(GL_DEPTH_BUFFER_BIT);
glDisable(GL_TEXTURE_2D);
glColor3f(1.0, 1.0, 1.0);
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 = ((float) demod->params.inputResampleRate) / (float) SRATE;
glVertex3f((uxPos - 0.5) * 2.0 - ofs, 1.0, 0.0);
glVertex3f((uxPos - 0.5) * 2.0 - ofs, -1.0, 0.0);
glVertex3f((uxPos - 0.5) * 2.0 + ofs, 1.0, 0.0);
glVertex3f((uxPos - 0.5) * 2.0 + ofs, -1.0, 0.0);
glEnd();
}
void WaterfallContext::EndDraw() {
glFlush();
CheckGLError();
+3
View File
@@ -11,7 +11,10 @@ class WaterfallContext: public PrimaryGLContext {
public:
WaterfallContext(WaterfallCanvas *canvas, wxGLContext *sharedContext);
void BeginDraw();
void Draw(std::vector<float> &points);
void DrawFreqSelector(float uxPos);
void EndDraw();
private:
Gradient grad;