Now passing IQ data from SDR Thread to AppFrame

This commit is contained in:
Charles J. Cliffe 2014-10-28 21:39:59 -04:00
parent 0e25cbcc1a
commit 23f8c6a197
9 changed files with 168 additions and 35 deletions

View File

@ -73,6 +73,7 @@ endif (DEFINED WIN32)
SET (cubicsdr_sources SET (cubicsdr_sources
src/CubicSDR.cpp src/CubicSDR.cpp
src/SDRThread.cpp src/SDRThread.cpp
src/IQBufferThread.cpp
src/PrimaryGLContext.cpp src/PrimaryGLContext.cpp
src/AppFrame.cpp src/AppFrame.cpp
) )
@ -80,6 +81,7 @@ SET (cubicsdr_sources
SET (cubicsdr_headers SET (cubicsdr_headers
src/CubicSDR.h src/CubicSDR.h
src/SDRThread.h src/SDRThread.h
src/IQBufferThread.h
src/PrimaryGLContext.h src/PrimaryGLContext.h
src/AppFrame.h src/AppFrame.h
) )

View File

@ -10,9 +10,14 @@
#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
#include <vector>
#include "SDRThread.h"
wxBEGIN_EVENT_TABLE(AppFrame, wxFrame) EVT_MENU(wxID_NEW, AppFrame::OnNewWindow) wxBEGIN_EVENT_TABLE(AppFrame, wxFrame)
//EVT_MENU(wxID_NEW, AppFrame::OnNewWindow)
EVT_MENU(wxID_CLOSE, AppFrame::OnClose) EVT_MENU(wxID_CLOSE, AppFrame::OnClose)
EVT_THREAD(EVENT_SDR_INPUT, AppFrame::OnEventInput)
EVT_IDLE(AppFrame::OnIdle)
wxEND_EVENT_TABLE() wxEND_EVENT_TABLE()
AppFrame::AppFrame() : AppFrame::AppFrame() :
@ -50,3 +55,16 @@ void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) {
void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) { void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
new AppFrame(); new AppFrame();
} }
void AppFrame::OnEventInput(wxThreadEvent& event) {
std::vector<unsigned char> *new_buffer = event.GetPayload<std::vector<unsigned char> *>();
std::cout << "Got IQ buffer, length: " << new_buffer->size() << std::endl;
delete new_buffer;
}
void AppFrame::OnIdle(wxIdleEvent& event) {
event.Skip();
}

View File

@ -4,14 +4,15 @@
#include "PrimaryGLContext.h" #include "PrimaryGLContext.h"
// Define a new frame type // Define a new frame type
class AppFrame : public wxFrame class AppFrame: public wxFrame {
{
public: public:
AppFrame(); AppFrame();
void OnEventInput(wxThreadEvent& event);
private: private:
void OnClose(wxCommandEvent& event); void OnClose(wxCommandEvent& event);
void OnNewWindow(wxCommandEvent& event); void OnNewWindow(wxCommandEvent& event);
void OnIdle(wxIdleEvent& event);
wxDECLARE_EVENT_TABLE(); wxDECLARE_EVENT_TABLE();
}; };

View File

@ -10,26 +10,31 @@
#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
#include "CubicSDR.h" #include "CubicSDR.h"
#include "AppFrame.h" #include "AppFrame.h"
IMPLEMENT_APP(CubicSDR) IMPLEMENT_APP(CubicSDR)
bool CubicSDR::OnInit() { bool CubicSDR::OnInit() {
if (!wxApp::OnInit()) if (!wxApp::OnInit())
return false; return false;
new AppFrame(); AppFrame *appframe = new AppFrame();
m_pThread = new SDRThread(this); t_SDR = new SDRThread(appframe);
if (m_pThread->Run() != wxTHREAD_NO_ERROR) { if (t_SDR->Run() != wxTHREAD_NO_ERROR) {
wxLogError wxLogError
("Can't create the thread!"); ("Can't create the thread!");
delete m_pThread; delete t_SDR;
m_pThread = NULL; t_SDR = NULL;
}
t_IQBuffer = new IQBufferThread(this);
if (t_IQBuffer->Run() != wxTHREAD_NO_ERROR) {
wxLogError
("Can't create the thread!");
delete t_IQBuffer;
t_IQBuffer = NULL;
} }
return true; return true;
@ -40,15 +45,27 @@ int CubicSDR::OnExit() {
{ {
wxCriticalSectionLocker enter(m_pThreadCS); wxCriticalSectionLocker enter(m_pThreadCS);
if (m_pThread) { if (t_SDR) {
wxMessageOutputDebug().Printf("CubicSDR: deleting thread"); wxMessageOutputDebug().Printf("CubicSDR: deleting thread");
if (m_pThread->Delete() != wxTHREAD_NO_ERROR) { if (t_SDR->Delete() != wxTHREAD_NO_ERROR) {
wxLogError wxLogError
("Can't delete the thread!"); ("Can't delete the thread!");
} }
} }
} }
{
wxCriticalSectionLocker enter(m_pThreadCS);
if (t_IQBuffer) {
wxMessageOutputDebug().Printf("CubicSDR: deleting thread");
if (t_IQBuffer->Delete() != wxTHREAD_NO_ERROR) {
wxLogError
("Can't delete the thread!");
}
}
}
wxThread::This()->Sleep(1);
// while (1) { // while (1) {
// { wxCriticalSectionLocker enter(m_pThreadCS); // { wxCriticalSectionLocker enter(m_pThreadCS);
// if (!m_pThread) // if (!m_pThread)

View File

@ -4,25 +4,31 @@
//WX_GL_MAJOR_VERSION 3 //WX_GL_MAJOR_VERSION 3
//WX_GL_MINOR_VERSION 2 //WX_GL_MINOR_VERSION 2
#include "SDRThread.h" #include "SDRThread.h"
#include "IQBufferThread.h"
#include "wx/glcanvas.h" #include "wx/glcanvas.h"
#include "PrimaryGLContext.h" #include "PrimaryGLContext.h"
class CubicSDR : public wxApp class CubicSDR: public wxApp {
{
public: public:
CubicSDR() { m_glContext = NULL; m_pThread = NULL; } CubicSDR() {
m_glContext = NULL;
t_SDR = NULL;
}
PrimaryGLContext &GetContext(wxGLCanvas *canvas); PrimaryGLContext &GetContext(wxGLCanvas *canvas);
virtual bool OnInit(); virtual bool OnInit();
virtual int OnExit(); virtual int OnExit();
void OnEventInput(wxEvent& event) {
std::cout << "event !" << std::endl;
}
private: private:
PrimaryGLContext *m_glContext; PrimaryGLContext *m_glContext;
SDRThread *m_pThread; SDRThread *t_SDR;
IQBufferThread *t_IQBuffer;
wxCriticalSection m_pThreadCS; wxCriticalSection m_pThreadCS;
}; };

53
src/IQBufferThread.cpp Normal file
View File

@ -0,0 +1,53 @@
#include "IQBufferThread.h"
#include <cstring>
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#if !wxUSE_GLCANVAS
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
#endif
#define BUF_SIZE (16 * 32 * 512)
IQBufferThread::IQBufferThread(wxApp *app) :
wxThread(wxTHREAD_DETACHED) {
this->handler = handler;
}
IQBufferThread::~IQBufferThread() {
}
wxThread::ExitCode IQBufferThread::Entry() {
unsigned char *buf = (unsigned char*) malloc(BUF_SIZE);
int n_read;
int i = 0;
// std::cout << "Sampling..";
while (!TestDestroy()) {
//
// iq_buffer.push(new_buffer);
//
// if (iq_buffer.size() > 100) {
// for (int i = 0; i < 50; i++) {
// std::vector<__int8> *old_buffer = iq_buffer.front();
// iq_buffer.pop();
// delete old_buffer;
// }
std::cout << "#";
// }
this->Sleep(100);
}
std::cout << std::endl << "Done." << std::endl << std::endl;
free(buf);
return (wxThread::ExitCode) 0;
}

28
src/IQBufferThread.h Normal file
View File

@ -0,0 +1,28 @@
#pragma once
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/thread.h"
#include "SDRThread.h"
#include <queue>
class IQBufferThread: public wxThread {
public:
IQBufferThread(wxApp *app);
~IQBufferThread();
void OnEventInput(wxEvent& event)
{
std::cout << "event !" << std::endl;
}
protected:
virtual ExitCode Entry();
wxApp *handler;
std::queue<std::vector<unsigned char> *> iq_buffer;
};

View File

@ -1,12 +1,15 @@
#include "SDRThread.h" #include "SDRThread.h"
#include <vector>
#define BUF_SIZE (16 * 32 * 512) #define BUF_SIZE (16 * 32 * 512)
SDRThread::SDRThread(wxApp *app) : //wxDEFINE_EVENT(wxEVT_COMMAND_SDRThread_INPUT, wxThreadEvent);
SDRThread::SDRThread(AppFrame *frame) :
wxThread(wxTHREAD_DETACHED) { wxThread(wxTHREAD_DETACHED) {
dev = NULL; dev = NULL;
this->handler = handler; this->frame = frame;
} }
SDRThread::~SDRThread() { SDRThread::~SDRThread() {
@ -91,20 +94,19 @@ wxThread::ExitCode SDRThread::Entry() {
rtlsdr_reset_buffer(dev); rtlsdr_reset_buffer(dev);
int n_read; int n_read;
int i = 0;
std::cout << "Sampling.."; std::cout << "Sampling..";
while (!TestDestroy()) { while (!TestDestroy()) {
rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read); rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read);
if (!TestDestroy()) {
std::vector<unsigned char> *new_buffer = new std::vector<unsigned char>(buf, buf + n_read);
if (i % 50 == 0) { wxThreadEvent event(wxEVT_THREAD, EVENT_SDR_INPUT);
std::cout << std::endl; event.SetPayload(new_buffer);
wxQueueEvent(frame, event.Clone());
} }
this->Sleep(1);
std::cout << ((n_read == BUF_SIZE) ? "." : "!");
i++;
} }
std::cout << std::endl << "Done." << std::endl << std::endl; std::cout << std::endl << "Done." << std::endl << std::endl;

View File

@ -9,21 +9,27 @@
#include "wx/thread.h" #include "wx/thread.h"
// declare a new type of event, to be used by our SDRThread class: #include "AppFrame.h"
wxDECLARE_EVENT(wxEVT_COMMAND_SDRThread_COMPLETED, wxThreadEvent);
wxDECLARE_EVENT(wxEVT_COMMAND_SDRThread_UPDATE, wxThreadEvent);
// declare a new type of event, to be used by our SDRThread class:
//wxDECLARE_EVENT(wxEVT_COMMAND_SDRThread_COMPLETED, wxThreadEvent);
//wxDECLARE_EVENT(wxEVT_COMMAND_SDRThread_UPDATE, wxThreadEvent);
//wxDECLARE_EVENT(wxEVT_COMMAND_SDRThread_INPUT, wxThreadEvent);
enum {
EVENT_SDR_INPUT = wxID_HIGHEST+1
};
class SDRThread: public wxThread { class SDRThread: public wxThread {
public: public:
rtlsdr_dev_t *dev; rtlsdr_dev_t *dev;
SDRThread(wxApp *app); SDRThread(AppFrame *appframe);
~SDRThread(); ~SDRThread();
void enumerate_rtl(); void enumerate_rtl();
protected: protected:
virtual ExitCode Entry(); virtual ExitCode Entry();
wxApp *handler; AppFrame *frame;
}; };