mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-02-03 09:44:26 -05:00
Rendering rtl-sdr I/Q data to the GL canvas
This commit is contained in:
parent
23f8c6a197
commit
2ef8010438
@ -23,7 +23,7 @@ wxEND_EVENT_TABLE()
|
|||||||
AppFrame::AppFrame() :
|
AppFrame::AppFrame() :
|
||||||
wxFrame(NULL, wxID_ANY, wxT("CubicSDR")) {
|
wxFrame(NULL, wxID_ANY, wxT("CubicSDR")) {
|
||||||
|
|
||||||
new TestGLCanvas(this, NULL);
|
canvas = new TestGLCanvas(this, NULL);
|
||||||
|
|
||||||
// SetIcon(wxICON(sample));
|
// SetIcon(wxICON(sample));
|
||||||
|
|
||||||
@ -57,9 +57,11 @@ void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AppFrame::OnEventInput(wxThreadEvent& event) {
|
void AppFrame::OnEventInput(wxThreadEvent& event) {
|
||||||
std::vector<unsigned char> *new_buffer = event.GetPayload<std::vector<unsigned char> *>();
|
std::vector<signed char> *new_buffer = event.GetPayload<std::vector<signed char> *>();
|
||||||
|
|
||||||
std::cout << "Got IQ buffer, length: " << new_buffer->size() << std::endl;
|
// std::cout << "Got IQ buffer, length: " << new_buffer->size() << std::endl;
|
||||||
|
|
||||||
|
canvas->setData(new_buffer);
|
||||||
|
|
||||||
delete new_buffer;
|
delete new_buffer;
|
||||||
}
|
}
|
||||||
|
@ -14,5 +14,7 @@ private:
|
|||||||
void OnNewWindow(wxCommandEvent& event);
|
void OnNewWindow(wxCommandEvent& event);
|
||||||
void OnIdle(wxIdleEvent& event);
|
void OnIdle(wxIdleEvent& event);
|
||||||
|
|
||||||
|
TestGLCanvas *canvas;
|
||||||
|
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include "IQBufferThread.h"
|
#include "IQBufferThread.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
#include "wx/wxprec.h"
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
@ -12,8 +11,6 @@
|
|||||||
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
|
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define BUF_SIZE (16 * 32 * 512)
|
#define BUF_SIZE (16 * 32 * 512)
|
||||||
|
|
||||||
IQBufferThread::IQBufferThread(wxApp *app) :
|
IQBufferThread::IQBufferThread(wxApp *app) :
|
||||||
@ -24,7 +21,7 @@ IQBufferThread::~IQBufferThread() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
wxThread::ExitCode IQBufferThread::Entry() {
|
wxThread::ExitCode IQBufferThread::Entry() {
|
||||||
unsigned char *buf = (unsigned char*) malloc(BUF_SIZE);
|
signed char *buf = (signed char*) malloc(BUF_SIZE);
|
||||||
|
|
||||||
int n_read;
|
int n_read;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -40,7 +37,7 @@ wxThread::ExitCode IQBufferThread::Entry() {
|
|||||||
// iq_buffer.pop();
|
// iq_buffer.pop();
|
||||||
// delete old_buffer;
|
// delete old_buffer;
|
||||||
// }
|
// }
|
||||||
std::cout << "#";
|
// std::cout << "#";
|
||||||
// }
|
// }
|
||||||
this->Sleep(100);
|
this->Sleep(100);
|
||||||
}
|
}
|
||||||
|
@ -10,19 +10,17 @@
|
|||||||
#include "SDRThread.h"
|
#include "SDRThread.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
|
||||||
class IQBufferThread: public wxThread {
|
class IQBufferThread: public wxThread {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
IQBufferThread(wxApp *app);
|
IQBufferThread(wxApp *app);
|
||||||
~IQBufferThread();
|
~IQBufferThread();
|
||||||
|
|
||||||
void OnEventInput(wxEvent& event)
|
void OnEventInput(wxEvent& event) {
|
||||||
{
|
std::cout << "event !" << std::endl;
|
||||||
std::cout << "event !" << std::endl;
|
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
virtual ExitCode Entry();
|
virtual ExitCode Entry();
|
||||||
wxApp *handler;
|
wxApp *handler;
|
||||||
std::queue<std::vector<unsigned char> *> iq_buffer;
|
std::queue<std::vector<signed char> *> iq_buffer;
|
||||||
};
|
};
|
||||||
|
@ -59,23 +59,45 @@ PrimaryGLContext::PrimaryGLContext(wxGLCanvas *canvas) :
|
|||||||
CheckGLError();
|
CheckGLError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimaryGLContext::PlotIQ() {
|
void PrimaryGLContext::PlotIQ(std::vector<float> &i_points, std::vector<float> &q_points) {
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
glBegin(GL_LINE_STRIP);
|
glPushMatrix();
|
||||||
glColor3f(1.0f, 1.0f, 1.0f);
|
glTranslatef(0.0f, 0.5f, 0.0f);
|
||||||
glVertex3f(-1.0f, -0.5f, 0.0f);
|
if (q_points.size()) {
|
||||||
glVertex3f(1.0f, -0.5f, 0.0f);
|
glScalef(10.0f, 1.0f, 1.0f);
|
||||||
glEnd();
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, 0, &q_points[0]);
|
||||||
|
glDrawArrays(GL_LINE_STRIP, 0, q_points.size() / 2);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
} else {
|
||||||
|
glBegin(GL_LINE_STRIP);
|
||||||
|
glColor3f(1.0f, 1.0f, 1.0f);
|
||||||
|
glVertex3f(-1.0f, 0.0f, 0.0f);
|
||||||
|
glVertex3f(1.0f, 0.0f, 0.0f);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
glBegin(GL_LINE_STRIP);
|
glPushMatrix();
|
||||||
glColor3f(1.0f, 1.0f, 1.0f);
|
glTranslatef(0.0f, -0.5f, 0.0f);
|
||||||
glVertex3f(-1.0f, 0.5f, 0.0f);
|
if (i_points.size()) {
|
||||||
glVertex3f(1.0f, 0.5f, 0.0f);
|
glScalef(10.0f, 1.0f, 1.0f);
|
||||||
glEnd();
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, 0, &i_points[0]);
|
||||||
|
glDrawArrays(GL_LINE_STRIP, 0, i_points.size() / 2);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
} else {
|
||||||
|
glBegin(GL_LINE_STRIP);
|
||||||
|
glColor3f(1.0f, 1.0f, 1.0f);
|
||||||
|
glVertex3f(-1.0f, 0.0f, 0.0f);
|
||||||
|
glVertex3f(1.0f, 0.0f, 0.0f);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
|
|
||||||
@ -84,6 +106,7 @@ void PrimaryGLContext::PlotIQ() {
|
|||||||
|
|
||||||
wxBEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas) EVT_PAINT(TestGLCanvas::OnPaint)
|
wxBEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas) EVT_PAINT(TestGLCanvas::OnPaint)
|
||||||
EVT_KEY_DOWN(TestGLCanvas::OnKeyDown)
|
EVT_KEY_DOWN(TestGLCanvas::OnKeyDown)
|
||||||
|
EVT_IDLE(TestGLCanvas::OnIdle)
|
||||||
wxEND_EVENT_TABLE()
|
wxEND_EVENT_TABLE()
|
||||||
|
|
||||||
TestGLCanvas::TestGLCanvas(wxWindow *parent, int *attribList) :
|
TestGLCanvas::TestGLCanvas(wxWindow *parent, int *attribList) :
|
||||||
@ -99,7 +122,7 @@ void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
|||||||
PrimaryGLContext& canvas = wxGetApp().GetContext(this);
|
PrimaryGLContext& canvas = wxGetApp().GetContext(this);
|
||||||
glViewport(0, 0, ClientSize.x, ClientSize.y);
|
glViewport(0, 0, ClientSize.x, ClientSize.y);
|
||||||
|
|
||||||
canvas.PlotIQ();
|
canvas.PlotIQ(i_points, q_points);
|
||||||
|
|
||||||
SwapBuffers();
|
SwapBuffers();
|
||||||
}
|
}
|
||||||
@ -124,3 +147,24 @@ void TestGLCanvas::OnKeyDown(wxKeyEvent& event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestGLCanvas::setData(std::vector<signed char> *data) {
|
||||||
|
if (data && data->size()) {
|
||||||
|
if (i_points.size() < data->size()) {
|
||||||
|
i_points.resize(data->size());
|
||||||
|
}
|
||||||
|
if (q_points.size() < data->size()) {
|
||||||
|
q_points.resize(data->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iMax = data->size() / 2; i < iMax; i++) {
|
||||||
|
i_points[i * 2 + 1] = (float) (*data)[i * 2] / 127.0f;
|
||||||
|
q_points[i * 2 + 1] = (float) (*data)[i * 2 + 1] / 127.0f;
|
||||||
|
i_points[i * 2] = q_points[i * 2] = 2.0f * ((float) i / (float) iMax) - 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestGLCanvas::OnIdle(wxIdleEvent &event) {
|
||||||
|
Refresh(false);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
@ -3,12 +3,14 @@
|
|||||||
#include "wx/glcanvas.h"
|
#include "wx/glcanvas.h"
|
||||||
#include "wx/timer.h"
|
#include "wx/timer.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class PrimaryGLContext : public wxGLContext
|
class PrimaryGLContext : public wxGLContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrimaryGLContext(wxGLCanvas *canvas);
|
PrimaryGLContext(wxGLCanvas *canvas);
|
||||||
|
|
||||||
void PlotIQ();
|
void PlotIQ(std::vector<float> &i_points, std::vector<float> &q_points);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// textures for the cube faces
|
// textures for the cube faces
|
||||||
@ -20,9 +22,16 @@ class TestGLCanvas : public wxGLCanvas
|
|||||||
public:
|
public:
|
||||||
TestGLCanvas(wxWindow *parent, int *attribList = NULL);
|
TestGLCanvas(wxWindow *parent, int *attribList = NULL);
|
||||||
|
|
||||||
|
void setData(std::vector<signed char> *data);
|
||||||
|
|
||||||
|
std::vector<float> i_points;
|
||||||
|
std::vector<float> q_points;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnPaint(wxPaintEvent& event);
|
void OnPaint(wxPaintEvent& event);
|
||||||
void OnKeyDown(wxKeyEvent& event);
|
void OnKeyDown(wxKeyEvent& event);
|
||||||
|
|
||||||
|
void OnIdle(wxIdleEvent &event);
|
||||||
|
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#define BUF_SIZE (16 * 32 * 512)
|
#define BUF_SIZE (16 * 32 * 512)
|
||||||
|
|
||||||
|
|
||||||
//wxDEFINE_EVENT(wxEVT_COMMAND_SDRThread_INPUT, wxThreadEvent);
|
//wxDEFINE_EVENT(wxEVT_COMMAND_SDRThread_INPUT, wxThreadEvent);
|
||||||
|
|
||||||
SDRThread::SDRThread(AppFrame *frame) :
|
SDRThread::SDRThread(AppFrame *frame) :
|
||||||
@ -91,6 +90,8 @@ wxThread::ExitCode SDRThread::Entry() {
|
|||||||
rtlsdr_open(&dev, 0);
|
rtlsdr_open(&dev, 0);
|
||||||
rtlsdr_set_sample_rate(dev, 2500000);
|
rtlsdr_set_sample_rate(dev, 2500000);
|
||||||
rtlsdr_set_center_freq(dev, 105700000);
|
rtlsdr_set_center_freq(dev, 105700000);
|
||||||
|
rtlsdr_set_agc_mode(dev, 1);
|
||||||
|
rtlsdr_set_offset_tuning(dev, 1);
|
||||||
rtlsdr_reset_buffer(dev);
|
rtlsdr_reset_buffer(dev);
|
||||||
|
|
||||||
int n_read;
|
int n_read;
|
||||||
@ -100,7 +101,11 @@ wxThread::ExitCode SDRThread::Entry() {
|
|||||||
|
|
||||||
rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read);
|
rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read);
|
||||||
if (!TestDestroy()) {
|
if (!TestDestroy()) {
|
||||||
std::vector<unsigned char> *new_buffer = new std::vector<unsigned char>(buf, buf + n_read);
|
std::vector<signed char> *new_buffer = new std::vector<signed char>();
|
||||||
|
|
||||||
|
for (int i = 0; i < n_read; i++) {
|
||||||
|
new_buffer->push_back(buf[i] - 127);
|
||||||
|
}
|
||||||
|
|
||||||
wxThreadEvent event(wxEVT_THREAD, EVENT_SDR_INPUT);
|
wxThreadEvent event(wxEVT_THREAD, EVENT_SDR_INPUT);
|
||||||
event.SetPayload(new_buffer);
|
event.SetPayload(new_buffer);
|
||||||
|
Loading…
Reference in New Issue
Block a user