diff --git a/CMakeLists.txt b/CMakeLists.txt index 6aaa249..89638ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,7 @@ endif (DEFINED WIN32) SET (cubicsdr_sources src/CubicSDR.cpp src/SDRThread.cpp + src/IQBufferThread.cpp src/PrimaryGLContext.cpp src/AppFrame.cpp ) @@ -80,6 +81,7 @@ SET (cubicsdr_sources SET (cubicsdr_headers src/CubicSDR.h src/SDRThread.h + src/IQBufferThread.h src/PrimaryGLContext.h src/AppFrame.h ) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 493ce88..28f0e7e 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -10,9 +10,14 @@ #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library" #endif +#include +#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_THREAD(EVENT_SDR_INPUT, AppFrame::OnEventInput) +EVT_IDLE(AppFrame::OnIdle) wxEND_EVENT_TABLE() AppFrame::AppFrame() : @@ -22,7 +27,7 @@ AppFrame::AppFrame() : // SetIcon(wxICON(sample)); - // Make a menubar +// Make a menubar wxMenu *menu = new wxMenu; // menu->Append(wxID_NEW); // menu->AppendSeparator(); @@ -50,3 +55,16 @@ void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) { void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) { new AppFrame(); } + +void AppFrame::OnEventInput(wxThreadEvent& event) { + std::vector *new_buffer = event.GetPayload *>(); + + std::cout << "Got IQ buffer, length: " << new_buffer->size() << std::endl; + + delete new_buffer; +} + +void AppFrame::OnIdle(wxIdleEvent& event) { + + event.Skip(); +} diff --git a/src/AppFrame.h b/src/AppFrame.h index 0abdac7..db1ca26 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -4,14 +4,15 @@ #include "PrimaryGLContext.h" // Define a new frame type -class AppFrame : public wxFrame -{ +class AppFrame: public wxFrame { public: AppFrame(); + void OnEventInput(wxThreadEvent& event); private: void OnClose(wxCommandEvent& event); void OnNewWindow(wxCommandEvent& event); + void OnIdle(wxIdleEvent& event); - wxDECLARE_EVENT_TABLE(); +wxDECLARE_EVENT_TABLE(); }; diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index d4b905e..af726dc 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -10,26 +10,31 @@ #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library" #endif - #include "CubicSDR.h" #include "AppFrame.h" - IMPLEMENT_APP(CubicSDR) - bool CubicSDR::OnInit() { if (!wxApp::OnInit()) return false; - new AppFrame(); + AppFrame *appframe = new AppFrame(); - m_pThread = new SDRThread(this); - if (m_pThread->Run() != wxTHREAD_NO_ERROR) { + t_SDR = new SDRThread(appframe); + if (t_SDR->Run() != wxTHREAD_NO_ERROR) { wxLogError ("Can't create the thread!"); - delete m_pThread; - m_pThread = NULL; + delete t_SDR; + 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; @@ -40,15 +45,27 @@ int CubicSDR::OnExit() { { wxCriticalSectionLocker enter(m_pThreadCS); - if (m_pThread) { + if (t_SDR) { wxMessageOutputDebug().Printf("CubicSDR: deleting thread"); - if (m_pThread->Delete() != wxTHREAD_NO_ERROR) { + if (t_SDR->Delete() != wxTHREAD_NO_ERROR) { wxLogError ("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) { // { wxCriticalSectionLocker enter(m_pThreadCS); // if (!m_pThread) diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 49e3d4b..f73e5e7 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -4,25 +4,31 @@ //WX_GL_MAJOR_VERSION 3 //WX_GL_MINOR_VERSION 2 - - #include "SDRThread.h" +#include "IQBufferThread.h" #include "wx/glcanvas.h" #include "PrimaryGLContext.h" -class CubicSDR : public wxApp -{ +class CubicSDR: public wxApp { public: - CubicSDR() { m_glContext = NULL; m_pThread = NULL; } + CubicSDR() { + m_glContext = NULL; + t_SDR = NULL; + } PrimaryGLContext &GetContext(wxGLCanvas *canvas); virtual bool OnInit(); virtual int OnExit(); + void OnEventInput(wxEvent& event) { + std::cout << "event !" << std::endl; + } + private: PrimaryGLContext *m_glContext; - SDRThread *m_pThread; + SDRThread *t_SDR; + IQBufferThread *t_IQBuffer; wxCriticalSection m_pThreadCS; }; diff --git a/src/IQBufferThread.cpp b/src/IQBufferThread.cpp new file mode 100644 index 0000000..e97e04f --- /dev/null +++ b/src/IQBufferThread.cpp @@ -0,0 +1,53 @@ +#include "IQBufferThread.h" +#include + + +#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; +} + diff --git a/src/IQBufferThread.h b/src/IQBufferThread.h new file mode 100644 index 0000000..01e7af6 --- /dev/null +++ b/src/IQBufferThread.h @@ -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 + + +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 *> iq_buffer; +}; diff --git a/src/SDRThread.cpp b/src/SDRThread.cpp index 2d021c1..43c5eec 100644 --- a/src/SDRThread.cpp +++ b/src/SDRThread.cpp @@ -1,12 +1,15 @@ #include "SDRThread.h" +#include #define BUF_SIZE (16 * 32 * 512) -SDRThread::SDRThread(wxApp *app) : +//wxDEFINE_EVENT(wxEVT_COMMAND_SDRThread_INPUT, wxThreadEvent); + +SDRThread::SDRThread(AppFrame *frame) : wxThread(wxTHREAD_DETACHED) { dev = NULL; - this->handler = handler; + this->frame = frame; } SDRThread::~SDRThread() { @@ -91,20 +94,19 @@ wxThread::ExitCode SDRThread::Entry() { rtlsdr_reset_buffer(dev); int n_read; - int i = 0; std::cout << "Sampling.."; while (!TestDestroy()) { rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read); + if (!TestDestroy()) { + std::vector *new_buffer = new std::vector(buf, buf + n_read); - if (i % 50 == 0) { - std::cout << std::endl; + wxThreadEvent event(wxEVT_THREAD, EVENT_SDR_INPUT); + event.SetPayload(new_buffer); + wxQueueEvent(frame, event.Clone()); } - - std::cout << ((n_read == BUF_SIZE) ? "." : "!"); - - i++; + this->Sleep(1); } std::cout << std::endl << "Done." << std::endl << std::endl; diff --git a/src/SDRThread.h b/src/SDRThread.h index c2a1f8b..88198c8 100644 --- a/src/SDRThread.h +++ b/src/SDRThread.h @@ -9,21 +9,27 @@ #include "wx/thread.h" -// 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); +#include "AppFrame.h" +// 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 { public: rtlsdr_dev_t *dev; - SDRThread(wxApp *app); + SDRThread(AppFrame *appframe); ~SDRThread(); void enumerate_rtl(); protected: virtual ExitCode Entry(); - wxApp *handler; + AppFrame *frame; };