diff --git a/CMakeLists.txt b/CMakeLists.txt index b65373c..8abf717 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,6 @@ endif (DEFINED WIN32) SET (cubicsdr_sources src/CubicSDR.cpp src/SDRThread.cpp - src/IQBufferThread.cpp src/PrimaryGLContext.cpp src/AppFrame.cpp src/SDRThreadQueue.cpp @@ -109,7 +108,6 @@ SET (cubicsdr_sources SET (cubicsdr_headers src/CubicSDR.h src/SDRThread.h - src/IQBufferThread.h src/PrimaryGLContext.h src/AppFrame.h src/CubicSDRDefs.h diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 075d2dd..5a06c78 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -19,9 +19,7 @@ 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_THREAD(EVENT_DEMOD_INPUT, AppFrame::OnDemodInput) -EVT_THREAD(EVENT_AUDIO_INPUT, AppFrame::OnAudioInput) +EVT_COMMAND(wxID_ANY, wxEVT_THREAD, AppFrame::OnThread) EVT_IDLE(AppFrame::OnIdle) wxEND_EVENT_TABLE() @@ -85,14 +83,6 @@ AppFrame::AppFrame() : t_Audio = 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; -// } - // static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 }; // wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not"); // ShowFullScreen(true); @@ -110,19 +100,7 @@ AppFrame::~AppFrame() { } } -// { -// 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!"); -// } -// } -// } - // delete t_SDR; -// delete t_IQBuffer; delete threadQueueAudio; delete threadQueueDemod; delete threadQueueSDR; @@ -138,66 +116,64 @@ void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) { new AppFrame(); } -// SDR IQ -> Demodulator -void AppFrame::OnEventInput(wxThreadEvent& event) { - std::vector *new_buffer = event.GetPayload *>(); -// std::cout << new_buffer->size() << std::endl; - if (new_buffer->size()) { - DemodulatorThreadTask task = DemodulatorThreadTask(DemodulatorThreadTask::DEMOD_THREAD_DATA); - task.setData(*new_buffer); - threadQueueDemod->addTask(task, DemodulatorThreadQueue::DEMOD_PRIORITY_HIGHEST); +void AppFrame::OnThread(wxCommandEvent& event) { + SDRThreadIQData *iqData; + DemodulatorThreadAudioData *demodAudioData; -// test_demod.writeBuffer(new_buffer); -// scopeCanvas->setWaveformPoints(test_demod.waveform_points); - spectrumCanvas->setData(new_buffer); - waterfallCanvas->setData(new_buffer); - } else { - std::cout << "Incoming IQ data empty?" << std::endl; - } - delete new_buffer; -} + std::vector *new_uc_buffer; + std::vector *new_float_buffer; -// Demodulator -> Audio -void AppFrame::OnDemodInput(wxThreadEvent& event) { - std::vector *new_buffer = event.GetPayload *>(); + switch (event.GetId()) { - if (new_buffer->size()) { - AudioThreadTask task = AudioThreadTask(AudioThreadTask::AUDIO_THREAD_DATA); - task.setData(*new_buffer); - threadQueueAudio->addTask(task, AudioThreadQueue::AUDIO_PRIORITY_HIGHEST); + // SDR IQ -> Demodulator + case SDRThreadTask::SDR_THREAD_DATA: + iqData = (SDRThreadIQData *) event.GetClientData(); + new_uc_buffer = &(iqData->data); + if (new_uc_buffer->size()) { + DemodulatorThreadTask task = DemodulatorThreadTask(DemodulatorThreadTask::DEMOD_THREAD_DATA); + task.data = new DemodulatorThreadIQData(iqData->bandwidth, iqData->frequency, iqData->data); + threadQueueDemod->addTask(task, DemodulatorThreadQueue::DEMOD_PRIORITY_HIGHEST); - if (scopeCanvas->waveform_points.size() != new_buffer->size() * 2) { - scopeCanvas->waveform_points.resize(new_buffer->size() * 2); + spectrumCanvas->setData(new_uc_buffer); + waterfallCanvas->setData(new_uc_buffer); + } else { + std::cout << "Incoming IQ data empty?" << std::endl; } + delete iqData; - for (int i = 0, iMax = new_buffer->size(); i < iMax; i++) { - scopeCanvas->waveform_points[i * 2 + 1] = (*new_buffer)[i] * 0.5f; - scopeCanvas->waveform_points[i * 2] = ((double) i / (double) iMax); + break; // thread wants to exit: disable controls and destroy main window + + // Demodulator -> Audio + case DemodulatorThreadTask::DEMOD_THREAD_AUDIO_DATA: + demodAudioData = (DemodulatorThreadAudioData *) event.GetClientData(); + new_float_buffer = &(demodAudioData->data); + if (new_float_buffer->size()) { + AudioThreadTask task = AudioThreadTask(AudioThreadTask::AUDIO_THREAD_DATA); + task.data = new AudioThreadData(demodAudioData->frequency, demodAudioData->sampleRate, demodAudioData->data); + threadQueueAudio->addTask(task, AudioThreadQueue::AUDIO_PRIORITY_HIGHEST); + + if (scopeCanvas->waveform_points.size() != new_float_buffer->size() * 2) { + scopeCanvas->waveform_points.resize(new_float_buffer->size() * 2); + } + + for (int i = 0, iMax = new_float_buffer->size(); i < iMax; i++) { + scopeCanvas->waveform_points[i * 2 + 1] = (*new_float_buffer)[i] * 0.5f; + scopeCanvas->waveform_points[i * 2] = ((double) i / (double) iMax); + } + + } else { + std::cout << "Incoming Demodulator data empty?" << std::endl; } + delete demodAudioData; - } else { - std::cout << "Incoming Demod data empty?" << std::endl; + break; + default: + event.Skip(); } - delete new_buffer; -} - -// Audio -> Visual -void AppFrame::OnAudioInput(wxThreadEvent& event) { -// std::vector *new_buffer = event.GetPayload *>(); -// -// if (new_buffer->size()) { -// AudioThreadTask task = AudioThreadTask(AudioThreadTask::AUDIO_THREAD_DATA); -// task.setData(*new_buffer); -// threadQueueAudio->addTask(task, AudioThreadQueue::AUDIO_PRIORITY_HIGHEST); -// } else { -// std::cout << "Incoming Demod data empty?" << std::endl; -// } -// delete new_buffer; } void AppFrame::OnIdle(wxIdleEvent& event) { - wxGetApp().Yield(); event.Skip(); } diff --git a/src/AppFrame.h b/src/AppFrame.h index a460349..c25431b 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -15,9 +15,8 @@ class AppFrame: public wxFrame { public: AppFrame(); ~AppFrame(); + void OnThread (wxCommandEvent& event); void OnEventInput(wxThreadEvent& event); - void OnDemodInput(wxThreadEvent& event); - void OnAudioInput(wxThreadEvent& event); void setFrequency(unsigned int freq); @@ -39,7 +38,6 @@ private: DemodulatorThread *t_Demod; DemodulatorThreadQueue* threadQueueDemod; - // IQBufferThread *t_IQBuffer; wxCriticalSection m_pThreadCS; unsigned int frequency; diff --git a/src/AudioThread.cpp b/src/AudioThread.cpp index 66a5691..df0e476 100644 --- a/src/AudioThread.cpp +++ b/src/AudioThread.cpp @@ -5,7 +5,7 @@ //wxDEFINE_EVENT(wxEVT_COMMAND_AudioThread_INPUT, wxThreadEvent); AudioThread::AudioThread(AudioThreadQueue* pQueue, int id) : - wxThread(wxTHREAD_DETACHED), m_pQueue(pQueue), m_ID(id), audio_queue_ptr(0) { + wxThread(wxTHREAD_DETACHED), m_pQueue(pQueue), m_ID(id), audio_queue_ptr(0), stream(NULL) { } AudioThread::~AudioThread() { @@ -107,7 +107,10 @@ wxThread::ExitCode AudioThread::Entry() { AudioThreadTask task = m_pQueue->pop(); // pop a task from the queue. this will block the worker thread if queue is empty switch (task.m_cmd) { case AudioThreadTask::AUDIO_THREAD_DATA: - audio_queue.push(task.getData()); + if (!TestDestroy()) { + audio_queue.push(task.data->data); + } + delete task.data; break; } } diff --git a/src/AudioThreadTask.cpp b/src/AudioThreadTask.cpp index 173bee3..9de3985 100644 --- a/src/AudioThreadTask.cpp +++ b/src/AudioThreadTask.cpp @@ -1,9 +1,2 @@ #include "AudioThreadTask.h" - -void AudioThreadTask::setData(std::vector &data_in) { - data = data_in; -} -std::vector &AudioThreadTask::getData() { - return data; -} diff --git a/src/AudioThreadTask.h b/src/AudioThreadTask.h index 563f67a..fc1a56b 100644 --- a/src/AudioThreadTask.h +++ b/src/AudioThreadTask.h @@ -4,25 +4,45 @@ #include "wx/defs.h" #include "wx/string.h" +#include "wx/object.h" + +class AudioThreadData: public wxObject { +public: + unsigned int frequency; + unsigned int sampleRate; + unsigned short channels; + + std::vector data; + + AudioThreadData(unsigned int frequency, unsigned int sampleRate, std::vector data) : + data(data), sampleRate(sampleRate), frequency(frequency) { + channels = 1; + } + + ~AudioThreadData() { + + } +}; class AudioThreadTask { public: enum AUDIO_THREAD_COMMAND { - AUDIO_THREAD_EXIT = wxID_EXIT, AUDIO_THREAD_NULL = wxID_HIGHEST + 1, AUDIO_THREAD_STARTED, AUDIO_THREAD_PROCESS, AUDIO_THREAD_ERROR, AUDIO_THREAD_DATA + AUDIO_THREAD_EXIT = wxID_EXIT, + AUDIO_THREAD_NULL = wxID_HIGHEST + 200, + AUDIO_THREAD_STARTED, + AUDIO_THREAD_PROCESS, + AUDIO_THREAD_ERROR, + AUDIO_THREAD_DATA }; AudioThreadTask() : - m_cmd(AUDIO_THREAD_NULL) { + m_cmd(AUDIO_THREAD_NULL), data(NULL) { } AudioThreadTask(AUDIO_THREAD_COMMAND cmd) : - m_cmd(cmd) { + m_cmd(cmd), data(NULL) { } - void setData(std::vector &data_in); - std::vector &getData(); - - - std::vector data; + AudioThreadData *data; AUDIO_THREAD_COMMAND m_cmd; }; diff --git a/src/DemodulatorThread.cpp b/src/DemodulatorThread.cpp index a3944fd..d1d0250 100644 --- a/src/DemodulatorThread.cpp +++ b/src/DemodulatorThread.cpp @@ -2,7 +2,6 @@ #include "CubicSDRDefs.h" #include -//wxDEFINE_EVENT(wxEVT_COMMAND_DemodulatorThread_INPUT, wxThreadEvent); DemodulatorThread::DemodulatorThread(DemodulatorThreadQueue* pQueue, int id) : wxThread(wxTHREAD_DETACHED), m_pQueue(pQueue), m_ID(id) { @@ -61,7 +60,7 @@ wxThread::ExitCode DemodulatorThread::Entry() { DemodulatorThreadTask task = m_pQueue->pop(); // pop a task from the queue. this will block the worker thread if queue is empty switch (task.m_cmd) { case DemodulatorThreadTask::DEMOD_THREAD_DATA: - std::vector *data = &task.getData(); + std::vector *data = &task.data->data; if (data->size()) { liquid_float_complex filtered_input[BUF_SIZE / 2]; @@ -122,43 +121,24 @@ wxThread::ExitCode DemodulatorThread::Entry() { unsigned int num_audio_written; msresamp_crcf_execute(audio_resampler, resampled_wbfm_output, num_wbfm_written, resampled_audio_output, &num_audio_written); - std::vector *newBuffer = new std::vector; - newBuffer->resize(num_audio_written * 2); + std::vector newBuffer; + newBuffer.resize(num_audio_written * 2); for (int i = 0; i < num_audio_written; i++) { liquid_float_complex y = resampled_audio_output[i]; - (*newBuffer)[i * 2] = y.real; - (*newBuffer)[i * 2 + 1] = y.real; + newBuffer[i * 2] = y.real; + newBuffer[i * 2 + 1] = y.real; } if (!TestDestroy()) { - wxThreadEvent event(wxEVT_THREAD, EVENT_DEMOD_INPUT); - event.SetPayload(newBuffer); - wxQueueEvent(m_pQueue->getHandler(), event.Clone()); - } else { - delete newBuffer; + DemodulatorThreadAudioData *audioOut = new DemodulatorThreadAudioData(task.data->frequency,audio_frequency,newBuffer); + + m_pQueue->sendAudioData(DemodulatorThreadTask::DEMOD_THREAD_AUDIO_DATA,audioOut); } - // std::vector *newBuffer = new std::vector; - // newBuffer->resize(num_audio_written * 2); - // for (int i = 0; i < num_audio_written; i++) { - // liquid_float_complex y = resampled_audio_output[i]; - // - // (*newBuffer)[i * 2] = y.real; - // (*newBuffer)[i * 2 + 1] = y.real; - // } - -// if (waveform_points.size() != num_audio_written * 2) { -// waveform_points.resize(num_audio_written * 2); -// } -// -// for (int i = 0, iMax = waveform_points.size() / 2; i < iMax; i++) { -// waveform_points[i * 2 + 1] = resampled_audio_output[i].real * 0.5f; -// waveform_points[i * 2] = ((double) i / (double) iMax); -// } + delete task.data; } - // audio_queue.push(newBuffer); break; } } diff --git a/src/DemodulatorThread.h b/src/DemodulatorThread.h index aff1531..6f2ee2b 100644 --- a/src/DemodulatorThread.h +++ b/src/DemodulatorThread.h @@ -11,13 +11,8 @@ #include "wx/thread.h" #include "DemodulatorThreadQueue.h" - #include "liquid/liquid.h" -// declare a new type of event, to be used by our DemodulatorThread class: -//wxDECLARE_EVENT(wxEVT_COMMAND_DemodulatorThread_COMPLETED, wxThreadEvent); -//wxDECLARE_EVENT(wxEVT_COMMAND_DemodulatorThread_UPDATE, wxThreadEvent); -//wxDECLARE_EVENT(wxEVT_COMMAND_DemodulatorThread_INPUT, wxThreadEvent); enum { EVENT_DEMOD_INPUT = wxID_HIGHEST + 2 @@ -25,9 +20,6 @@ enum { class DemodulatorThread: public wxThread { public: - std::queue *> audio_queue; - unsigned int audio_queue_ptr; - DemodulatorThread(DemodulatorThreadQueue* pQueue, int id = 0); ~DemodulatorThread(); @@ -40,18 +32,16 @@ protected: firfilt_crcf fir_audio_filter; unsigned int bandwidth; - msresamp_crcf resampler; float resample_ratio; + unsigned int wbfm_frequency; msresamp_crcf wbfm_resampler; float wbfm_resample_ratio; - unsigned int wbfm_frequency; + unsigned int audio_frequency; msresamp_crcf audio_resampler; float audio_resample_ratio; - unsigned int audio_frequency; - freqdem fdem; }; diff --git a/src/DemodulatorThreadQueue.cpp b/src/DemodulatorThreadQueue.cpp index a6f6f5b..b72db67 100644 --- a/src/DemodulatorThreadQueue.cpp +++ b/src/DemodulatorThreadQueue.cpp @@ -26,10 +26,11 @@ DemodulatorThreadTask DemodulatorThreadQueue::pop() { return element; } -void DemodulatorThreadQueue::report(const DemodulatorThreadTask::DEMOD_THREAD_COMMAND& cmd, const wxString& sArg, int iArg) { +void DemodulatorThreadQueue::sendAudioData(const DemodulatorThreadTask::DEMOD_THREAD_COMMAND& cmd, DemodulatorThreadAudioData *data) { wxCommandEvent evt(wxEVT_THREAD, cmd); - evt.SetString(sArg); - evt.SetInt(iArg); + + evt.SetClientData(data); + m_pParent->AddPendingEvent(evt); } diff --git a/src/DemodulatorThreadQueue.h b/src/DemodulatorThreadQueue.h index 3920c11..61f1e04 100644 --- a/src/DemodulatorThreadQueue.h +++ b/src/DemodulatorThreadQueue.h @@ -13,7 +13,7 @@ public: DemodulatorThreadQueue(wxEvtHandler* pParent); void addTask(const DemodulatorThreadTask& task, const DEMOD_PRIORITY& priority = DEMOD_PRIORITY_NORMAL); - void report(const DemodulatorThreadTask::DEMOD_THREAD_COMMAND& cmd, const wxString& sArg = wxEmptyString, int iArg = 0); + void sendAudioData(const DemodulatorThreadTask::DEMOD_THREAD_COMMAND& cmd, DemodulatorThreadAudioData *data); DemodulatorThreadTask pop(); size_t stackSize(); diff --git a/src/DemodulatorThreadTask.cpp b/src/DemodulatorThreadTask.cpp index c64d239..311d859 100644 --- a/src/DemodulatorThreadTask.cpp +++ b/src/DemodulatorThreadTask.cpp @@ -1,8 +1,2 @@ #include "DemodulatorThreadTask.h" -void DemodulatorThreadTask::setData(std::vector &data_in) { - data = data_in; -} -std::vector &DemodulatorThreadTask::getData() { - return data; -} diff --git a/src/DemodulatorThreadTask.h b/src/DemodulatorThreadTask.h index 07341ce..757bdb2 100644 --- a/src/DemodulatorThreadTask.h +++ b/src/DemodulatorThreadTask.h @@ -3,24 +3,62 @@ #include #include "wx/defs.h" #include "wx/string.h" +#include "wx/object.h" + +class DemodulatorThreadIQData: public wxObject { +public: + unsigned int frequency; + unsigned int bandwidth; + std::vector data; + + DemodulatorThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector data) : + data(data), frequency(frequency), bandwidth(bandwidth) { + + } + + ~DemodulatorThreadIQData() { + + } +}; + +class DemodulatorThreadAudioData: public wxObject { +public: + unsigned int frequency; + unsigned int sampleRate; + unsigned char channels; + + std::vector data; + + DemodulatorThreadAudioData(unsigned int frequency, unsigned int sampleRate, std::vector data) : + data(data), sampleRate(sampleRate), frequency(frequency), channels(1) { + + } + + ~DemodulatorThreadAudioData() { + + } +}; class DemodulatorThreadTask { public: enum DEMOD_THREAD_COMMAND { - DEMOD_THREAD_EXIT = wxID_EXIT, DEMOD_THREAD_NULL = wxID_HIGHEST + 1, DEMOD_THREAD_STARTED, DEMOD_THREAD_PROCESS, DEMOD_THREAD_ERROR, DEMOD_THREAD_DATA + DEMOD_THREAD_EXIT = wxID_EXIT, + DEMOD_THREAD_NULL = wxID_HIGHEST + 100, + DEMOD_THREAD_STARTED, + DEMOD_THREAD_PROCESS, + DEMOD_THREAD_ERROR, + DEMOD_THREAD_DATA, + DEMOD_THREAD_AUDIO_DATA }; DemodulatorThreadTask() : - m_cmd(DEMOD_THREAD_NULL) { + m_cmd(DEMOD_THREAD_NULL), data(NULL) { } DemodulatorThreadTask(DEMOD_THREAD_COMMAND cmd) : - m_cmd(cmd) { + m_cmd(cmd), data(NULL) { } - void setData(std::vector &data_in); - std::vector &getData(); - DEMOD_THREAD_COMMAND m_cmd; - std::vector data; + DemodulatorThreadIQData *data; }; diff --git a/src/IQBufferThread.cpp b/src/IQBufferThread.cpp deleted file mode 100644 index 38389b0..0000000 --- a/src/IQBufferThread.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#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 - -#include "CubicSDRDefs.h" - -IQBufferThread::IQBufferThread(wxApp *app) : - wxThread(wxTHREAD_DETACHED) { - this->handler = handler; -} -IQBufferThread::~IQBufferThread() { - -} -wxThread::ExitCode IQBufferThread::Entry() { - signed char *buf = (signed 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 deleted file mode 100644 index 432ef95..0000000 --- a/src/IQBufferThread.h +++ /dev/null @@ -1,26 +0,0 @@ -#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 d5f0824..8fd5a50 100644 --- a/src/SDRThread.cpp +++ b/src/SDRThread.cpp @@ -103,9 +103,12 @@ wxThread::ExitCode SDRThread::Entry() { signed char *buf = (signed char *) malloc(BUF_SIZE); + unsigned int frequency = DEFAULT_FREQ; + unsigned int bandwidth = SRATE; + rtlsdr_open(&dev, first_available); - rtlsdr_set_sample_rate(dev, SRATE); - rtlsdr_set_center_freq(dev, DEFAULT_FREQ); + rtlsdr_set_sample_rate(dev, bandwidth); + rtlsdr_set_center_freq(dev, frequency); rtlsdr_set_agc_mode(dev, 1); rtlsdr_set_offset_tuning(dev, 1); rtlsdr_reset_buffer(dev); @@ -136,17 +139,18 @@ wxThread::ExitCode SDRThread::Entry() { } if (freq_changed) { - rtlsdr_set_center_freq(dev, new_freq); + frequency = new_freq; + rtlsdr_set_center_freq(dev, frequency); } } rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read); if (!TestDestroy()) { - std::vector *new_buffer = new std::vector(); + std::vector new_buffer; for (int i = 0; i < n_read; i++) { - new_buffer->push_back(buf[i] - 127); + new_buffer.push_back(buf[i] - 127); } double time_slice = (double) n_read / (double) sample_rate; @@ -154,11 +158,8 @@ wxThread::ExitCode SDRThread::Entry() { // std::cout << "Time Slice: " << time_slice << std::endl; if (!TestDestroy()) { - wxThreadEvent event(wxEVT_THREAD, EVENT_SDR_INPUT); - event.SetPayload(new_buffer); - wxQueueEvent(m_pQueue->getHandler(), event.Clone()); - } else { - delete new_buffer; + SDRThreadIQData *iqData = new SDRThreadIQData(bandwidth,frequency,new_buffer); + m_pQueue->sendIQData(SDRThreadTask::SDR_THREAD_DATA, iqData); } } else { this->Yield(); diff --git a/src/SDRThread.h b/src/SDRThread.h index f3bc521..c52afa5 100644 --- a/src/SDRThread.h +++ b/src/SDRThread.h @@ -9,18 +9,8 @@ #include "wx/thread.h" -#include "IQBufferThread.h" #include "SDRThreadQueue.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; diff --git a/src/SDRThreadQueue.cpp b/src/SDRThreadQueue.cpp index 6f75c42..ecdd4ce 100644 --- a/src/SDRThreadQueue.cpp +++ b/src/SDRThreadQueue.cpp @@ -26,10 +26,11 @@ SDRThreadTask SDRThreadQueue::pop() { return element; } -void SDRThreadQueue::report(const SDRThreadTask::SDR_COMMAND& cmd, const wxString& sArg, int iArg) { +void SDRThreadQueue::sendIQData(const SDRThreadTask::SDR_COMMAND& cmd, SDRThreadIQData *data) { wxCommandEvent evt(wxEVT_THREAD, cmd); - evt.SetString(sArg); - evt.SetInt(iArg); + + evt.SetClientData(data); + m_pParent->AddPendingEvent(evt); } diff --git a/src/SDRThreadQueue.h b/src/SDRThreadQueue.h index dc9cc3e..ada1d84 100644 --- a/src/SDRThreadQueue.h +++ b/src/SDRThreadQueue.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "SDRThreadTask.h" #include "wx/event.h" @@ -13,7 +14,7 @@ public: SDRThreadQueue(wxEvtHandler* pParent); void addTask(const SDRThreadTask& task, const SDR_PRIORITY& priority = SDR_PRIORITY_NORMAL); - void report(const SDRThreadTask::SDR_COMMAND& cmd, const wxString& sArg = wxEmptyString, int iArg = 0); + void sendIQData(const SDRThreadTask::SDR_COMMAND& cmd, SDRThreadIQData *data); SDRThreadTask pop(); size_t stackSize(); diff --git a/src/SDRThreadTask.h b/src/SDRThreadTask.h index ea6b72b..8f17f50 100644 --- a/src/SDRThreadTask.h +++ b/src/SDRThreadTask.h @@ -1,12 +1,36 @@ #pragma once +#include #include "wx/defs.h" #include "wx/string.h" +#include "wx/object.h" + +class SDRThreadIQData: public wxObject { +public: + unsigned int frequency; + unsigned int bandwidth; + std::vector data; + + SDRThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector data) : + data(data), frequency(frequency), bandwidth(bandwidth) { + + } + + ~SDRThreadIQData() { + + } +}; class SDRThreadTask { public: enum SDR_COMMAND { - SDR_THREAD_EXIT = wxID_EXIT, SDR_THREAD_NULL = wxID_HIGHEST + 1, SDR_THREAD_STARTED, SDR_THREAD_PROCESS, SDR_THREAD_ERROR, SDR_THREAD_TUNING + SDR_THREAD_EXIT = wxID_EXIT, + SDR_THREAD_NULL = wxID_HIGHEST + 1, + SDR_THREAD_STARTED, + SDR_THREAD_PROCESS, + SDR_THREAD_ERROR, + SDR_THREAD_TUNING, + SDR_THREAD_DATA }; SDRThreadTask() : diff --git a/src/Timer.cpp b/src/Timer.cpp index 3c97c7c..4237d42 100644 --- a/src/Timer.cpp +++ b/src/Timer.cpp @@ -1,25 +1,3 @@ -/* - This file is part of CubicVR. - - CubicVR is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - CubicVR is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with CubicVR; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - - Source (c) 2003 by Charles J. Cliffe unless otherwise specified - To contact me, e-mail or MSN to cj@cubicproductions.com or by ICQ#7188044 - http://www.cubicproductions.com -*/ #include "Timer.h" @@ -27,7 +5,7 @@ #include #endif -Timer::Timer(void) : time_elapsed(0), system_milliseconds(0), start_time(0), end_time(0), last_update(0), paused_time(0), offset(0), paused_state(false) +Timer::Timer(void) : time_elapsed(0), system_milliseconds(0), start_time(0), end_time(0), last_update(0), paused_time(0), offset(0), paused_state(false), num_updates(0), lock_state(0), lock_rate(0) { } diff --git a/src/Timer.h b/src/Timer.h index 914a470..7c95f8c 100644 --- a/src/Timer.h +++ b/src/Timer.h @@ -1,25 +1,3 @@ -/* - This file is part of CubicVR. - - CubicVR is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - CubicVR is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with CubicVR; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - - Source (c) 2003 by Charles J. Cliffe unless otherwise specified - To contact me, e-mail or MSN to cj@cubicproductions.com or by ICQ#7188044 - http://www.cubicproductions.com -*/ #ifndef TIMER_H #define TIMER_H