mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2026-06-04 06:54:41 -04:00
Demodulator now has it's own spectrum view
This commit is contained in:
@@ -21,7 +21,7 @@ wxEND_EVENT_TABLE()
|
||||
|
||||
ScopeCanvas::ScopeCanvas(wxWindow *parent, int *attribList) :
|
||||
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
|
||||
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), divider(false) {
|
||||
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), stereo(false) {
|
||||
|
||||
glContext = new ScopeContext(this, &wxGetApp().GetContext(this));
|
||||
timer.start();
|
||||
@@ -35,8 +35,8 @@ void ScopeCanvas::setWaveformPoints(std::vector<float> &waveform_points_in) {
|
||||
waveform_points = waveform_points_in;
|
||||
}
|
||||
|
||||
void ScopeCanvas::setDivider(bool state) {
|
||||
divider = state;
|
||||
void ScopeCanvas::setStereo(bool state) {
|
||||
stereo = state;
|
||||
}
|
||||
|
||||
void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
@@ -47,10 +47,7 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
glViewport(0, 0, ClientSize.x, ClientSize.y);
|
||||
|
||||
glContext->DrawBegin();
|
||||
glContext->Plot(waveform_points);
|
||||
if (divider) {
|
||||
glContext->DrawDivider();
|
||||
}
|
||||
glContext->Plot(waveform_points, stereo);
|
||||
glContext->DrawEnd();
|
||||
|
||||
SwapBuffers();
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
~ScopeCanvas();
|
||||
|
||||
void setWaveformPoints(std::vector<float> &waveform_points_in);
|
||||
void setDivider(bool state);
|
||||
void setStereo(bool state);
|
||||
private:
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
|
||||
@@ -30,7 +30,7 @@ private:
|
||||
ScopeContext *glContext;
|
||||
Timer timer;
|
||||
float frameTimer;
|
||||
bool divider;
|
||||
bool stereo;
|
||||
// event table
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
@@ -20,18 +20,57 @@ void ScopeContext::DrawBegin() {
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void ScopeContext::Plot(std::vector<float> &points) {
|
||||
void ScopeContext::Plot(std::vector<float> &points, bool stereo) {
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
|
||||
if (stereo) {
|
||||
glColor3f(0.7, 0.7, 0.7);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f(-1.0,0.0);
|
||||
glVertex2f(1.0,0.0);
|
||||
glEnd();
|
||||
glColor3f(0.3, 0.3, 0.3);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f(-1.0,0.5);
|
||||
glVertex2f(1.0,0.5);
|
||||
glVertex2f(-1.0,-0.5);
|
||||
glVertex2f(1.0,-0.5);
|
||||
glEnd();
|
||||
} else {
|
||||
glColor3f(0.3, 0.3, 0.3);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f(-1.0,0.0);
|
||||
glVertex2f(1.0,0.0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glColor3f(0.9, 0.9, 0.9);
|
||||
if (points.size()) {
|
||||
glPushMatrix();
|
||||
glTranslatef(-1.0f, 0.0f, 0.0f);
|
||||
glScalef(2.0f, 2.0f, 1.0f);
|
||||
glEnableClientState (GL_VERTEX_ARRAY);
|
||||
glVertexPointer(2, GL_FLOAT, 0, &points[0]);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, points.size() / 2);
|
||||
if (stereo) {
|
||||
glPushMatrix();
|
||||
glTranslatef(-1.0f, 0.5f, 0.0f);
|
||||
glScalef(4.0f, 0.92f, 1.0f);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, points.size() / 4);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.0f, -0.5f, 0.0f);
|
||||
glPushMatrix();
|
||||
glScalef(4.0f, 0.92f, 1.0f);
|
||||
glDrawArrays(GL_LINE_STRIP, points.size() / 4, points.size() / 4);
|
||||
glPopMatrix();
|
||||
glPopMatrix();
|
||||
} else {
|
||||
glPushMatrix();
|
||||
glTranslatef(-1.0f, 0.0f, 0.0f);
|
||||
glScalef(2.0f, 2.0f, 1.0f);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, points.size() / 2);
|
||||
glPopMatrix();
|
||||
}
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glPopMatrix();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ public:
|
||||
ScopeContext(ScopeCanvas *canvas, wxGLContext *sharedContext);
|
||||
|
||||
void DrawBegin();
|
||||
void Plot(std::vector<float> &points);
|
||||
void Plot(std::vector<float> &points, bool stereo=false);
|
||||
void DrawDivider();
|
||||
void DrawEnd();
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ wxEND_EVENT_TABLE()
|
||||
|
||||
SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) :
|
||||
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
|
||||
wxFULL_REPAINT_ON_RESIZE), parent(parent), fft_size(0), in(NULL), out(NULL), plan(NULL) {
|
||||
wxFULL_REPAINT_ON_RESIZE), parent(parent), fft_size(0), in(NULL), out(NULL), plan(NULL), center_freq(0), bandwidth(0), isView(0) {
|
||||
|
||||
glContext = new SpectrumContext(this, &wxGetApp().GetContext(this));
|
||||
|
||||
@@ -74,12 +74,12 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
glViewport(0, 0, ClientSize.x, ClientSize.y);
|
||||
|
||||
glContext->BeginDraw();
|
||||
glContext->Draw(spectrum_points);
|
||||
glContext->Draw(spectrum_points, GetCenterFrequency(), GetBandwidth());
|
||||
|
||||
std::vector<DemodulatorInstance *> &demods = wxGetApp().getDemodMgr().getDemodulators();
|
||||
|
||||
for (int i = 0, iMax = demods.size(); i < iMax; i++) {
|
||||
glContext->DrawDemodInfo(demods[i]);
|
||||
glContext->DrawDemodInfo(demods[i], 1, 1, 1, GetCenterFrequency(), GetBandwidth());
|
||||
}
|
||||
|
||||
glContext->EndDraw();
|
||||
@@ -171,6 +171,41 @@ void SpectrumCanvas::setData(DemodulatorThreadIQData *input) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SpectrumCanvas::SetView(int center_freq_in, int bandwidth_in) {
|
||||
isView = true;
|
||||
center_freq = center_freq_in;
|
||||
bandwidth = bandwidth_in;
|
||||
}
|
||||
|
||||
void SpectrumCanvas::DisableView() {
|
||||
isView = false;
|
||||
}
|
||||
void SpectrumCanvas::SetCenterFrequency(unsigned int center_freq_in) {
|
||||
center_freq = center_freq_in;
|
||||
}
|
||||
|
||||
unsigned int SpectrumCanvas::GetCenterFrequency() {
|
||||
if (isView) {
|
||||
return center_freq;
|
||||
} else {
|
||||
return (unsigned int) wxGetApp().getFrequency();
|
||||
}
|
||||
}
|
||||
|
||||
void SpectrumCanvas::SetBandwidth(unsigned int bandwidth_in) {
|
||||
bandwidth = bandwidth_in;
|
||||
}
|
||||
|
||||
unsigned int SpectrumCanvas::GetBandwidth() {
|
||||
if (isView) {
|
||||
return bandwidth;
|
||||
} else {
|
||||
return SRATE;
|
||||
}
|
||||
}
|
||||
|
||||
void SpectrumCanvas::OnIdle(wxIdleEvent &event) {
|
||||
// timer.update();
|
||||
// frameTimer += timer.lastUpdateSeconds();
|
||||
@@ -183,7 +218,7 @@ void SpectrumCanvas::OnIdle(wxIdleEvent &event) {
|
||||
void SpectrumCanvas::mouseMoved(wxMouseEvent& event) {
|
||||
mTracker.OnMouseMoved(event);
|
||||
if (mTracker.mouseDown()) {
|
||||
int freqChange = mTracker.getDeltaMouseX() * SRATE;
|
||||
int freqChange = mTracker.getDeltaMouseX() * GetBandwidth();
|
||||
|
||||
if (freqChange != 0) {
|
||||
int freq = wxGetApp().getFrequency();
|
||||
|
||||
@@ -14,11 +14,23 @@
|
||||
|
||||
class SpectrumCanvas: public wxGLCanvas {
|
||||
public:
|
||||
std::vector<float> spectrum_points;
|
||||
|
||||
SpectrumCanvas(wxWindow *parent, int *attribList = NULL);
|
||||
void Setup(int fft_size_in);
|
||||
~SpectrumCanvas();
|
||||
|
||||
void setData(DemodulatorThreadIQData *input);
|
||||
|
||||
void SetView(int center_freq_in, int bandwidth_in);
|
||||
void DisableView();
|
||||
|
||||
void SetCenterFrequency(unsigned int center_freq_in);
|
||||
unsigned int GetCenterFrequency();
|
||||
|
||||
void SetBandwidth(unsigned int bandwidth_in);
|
||||
unsigned int GetBandwidth();
|
||||
|
||||
private:
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
|
||||
@@ -33,7 +45,6 @@ private:
|
||||
void mouseLeftWindow(wxMouseEvent& event);
|
||||
|
||||
wxWindow *parent;
|
||||
std::vector<float> spectrum_points;
|
||||
|
||||
fftw_complex *in, *out;
|
||||
fftw_plan plan;
|
||||
@@ -48,6 +59,11 @@ private:
|
||||
SpectrumContext *glContext;
|
||||
int fft_size;
|
||||
|
||||
unsigned int center_freq;
|
||||
unsigned int bandwidth;
|
||||
|
||||
bool isView;
|
||||
|
||||
MouseTracker mTracker;
|
||||
// event table
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <iostream>
|
||||
|
||||
SpectrumContext::SpectrumContext(SpectrumCanvas *canvas, wxGLContext *sharedContext) :
|
||||
PrimaryGLContext(canvas, sharedContext) {
|
||||
PrimaryGLContext(canvas, sharedContext), fft_size(0) {
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
@@ -15,7 +15,7 @@ SpectrumContext::SpectrumContext(SpectrumCanvas *canvas, wxGLContext *sharedCont
|
||||
|
||||
}
|
||||
|
||||
void SpectrumContext::Draw(std::vector<float> &points) {
|
||||
void SpectrumContext::Draw(std::vector<float> &points, int freq, int bandwidth) {
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
@@ -35,9 +35,10 @@ void SpectrumContext::Draw(std::vector<float> &points) {
|
||||
glGetIntegerv( GL_VIEWPORT, vp);
|
||||
|
||||
float viewHeight = (float) vp[3];
|
||||
float viewWidth = (float) vp[2];
|
||||
|
||||
float leftFreq = (float) wxGetApp().getFrequency() - ((float) SRATE / 2.0);
|
||||
float rightFreq = leftFreq + (float) SRATE;
|
||||
float leftFreq = (float) freq - ((float) bandwidth / 2.0);
|
||||
float rightFreq = leftFreq + (float) bandwidth;
|
||||
|
||||
float firstMhz = floor(leftFreq / 1000000.0) * 1000000.0;
|
||||
float mhzStart = ((firstMhz - leftFreq) / (rightFreq - leftFreq)) * 2.0;
|
||||
|
||||
@@ -11,7 +11,7 @@ class SpectrumContext: public PrimaryGLContext {
|
||||
public:
|
||||
SpectrumContext(SpectrumCanvas *canvas, wxGLContext *sharedContext);
|
||||
|
||||
void Draw(std::vector<float> &points);
|
||||
void Draw(std::vector<float> &points, int freq, int bandwidth);
|
||||
|
||||
private:
|
||||
int fft_size;
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <wx/numformatter.h>
|
||||
|
||||
#define MIN_FM_BANDWIDTH 10000
|
||||
|
||||
wxBEGIN_EVENT_TABLE(WaterfallCanvas, wxGLCanvas) EVT_PAINT(WaterfallCanvas::OnPaint)
|
||||
EVT_KEY_DOWN(WaterfallCanvas::OnKeyDown)
|
||||
EVT_KEY_UP(WaterfallCanvas::OnKeyUp)
|
||||
@@ -30,7 +32,7 @@ wxEND_EVENT_TABLE()
|
||||
|
||||
WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
|
||||
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
|
||||
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState(
|
||||
wxFULL_REPAINT_ON_RESIZE), parent(parent), spectrumCanvas(NULL), frameTimer(0), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState(
|
||||
WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(false), altDown(false), ctrlDown(false), fft_size(0), waterfall_lines(0), plan(
|
||||
NULL), in(NULL), out(NULL), center_freq(0), bandwidth(0), isView(false), resampler(NULL), resample_ratio(0), last_bandwidth(0), last_input_bandwidth(
|
||||
0) {
|
||||
@@ -126,6 +128,11 @@ WaterfallCanvas::DragState WaterfallCanvas::getNextDragState() {
|
||||
return nextDragState;
|
||||
}
|
||||
|
||||
void WaterfallCanvas::attachSpectrumCanvas(SpectrumCanvas *canvas_in) {
|
||||
spectrumCanvas = canvas_in;
|
||||
}
|
||||
|
||||
|
||||
void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
wxPaintDC dc(this);
|
||||
const wxSize ClientSize = GetClientSize();
|
||||
@@ -427,6 +434,10 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
|
||||
spectrum_points[i * 2] = ((float) i / (float) iMax);
|
||||
spectrum_points[i * 2 + 1] = v;
|
||||
}
|
||||
|
||||
if (spectrumCanvas) {
|
||||
spectrumCanvas->spectrum_points.assign(spectrum_points.begin(),spectrum_points.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,11 +478,11 @@ void WaterfallCanvas::mouseMoved(wxMouseEvent& event) {
|
||||
DemodulatorThreadCommand command;
|
||||
command.cmd = DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_BANDWIDTH;
|
||||
activeDemodulatorBandwidth = activeDemodulatorBandwidth + bwDiff;
|
||||
if (activeDemodulatorBandwidth < 2000) {
|
||||
activeDemodulatorBandwidth = 2000;
|
||||
if (activeDemodulatorBandwidth > SRATE) {
|
||||
activeDemodulatorBandwidth = SRATE;
|
||||
}
|
||||
if (activeDemodulatorBandwidth > GetBandwidth()) {
|
||||
activeDemodulatorBandwidth = GetBandwidth();
|
||||
if (activeDemodulatorBandwidth < MIN_FM_BANDWIDTH) {
|
||||
activeDemodulatorBandwidth = MIN_FM_BANDWIDTH;
|
||||
}
|
||||
|
||||
command.int_value = activeDemodulatorBandwidth;
|
||||
@@ -661,8 +672,8 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
|
||||
unsigned int freq = input_center_freq - (int) (0.5 * (float) GetBandwidth()) + (int) ((float) pos * (float) GetBandwidth());
|
||||
unsigned int bw = (unsigned int) (fabs(width) * (float) GetBandwidth());
|
||||
|
||||
if (bw < 2000) {
|
||||
bw = 2000;
|
||||
if (bw < MIN_FM_BANDWIDTH) {
|
||||
bw = MIN_FM_BANDWIDTH;
|
||||
}
|
||||
|
||||
if (!bw) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "WaterfallContext.h"
|
||||
#include "MouseTracker.h"
|
||||
#include "SpectrumCanvas.h"
|
||||
|
||||
#include "fftw3.h"
|
||||
#include "Timer.h"
|
||||
@@ -37,6 +38,8 @@ public:
|
||||
DragState getDragState();
|
||||
DragState getNextDragState();
|
||||
|
||||
void attachSpectrumCanvas(SpectrumCanvas *canvas_in);
|
||||
|
||||
private:
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnKeyDown(wxKeyEvent& event);
|
||||
@@ -52,6 +55,7 @@ private:
|
||||
void mouseLeftWindow(wxMouseEvent& event);
|
||||
|
||||
wxWindow *parent;
|
||||
SpectrumCanvas *spectrumCanvas;
|
||||
std::vector<float> spectrum_points;
|
||||
|
||||
fftw_complex *in, *out;
|
||||
|
||||
Reference in New Issue
Block a user