diff --git a/CMakeLists.txt b/CMakeLists.txt index f98307e..06c8840 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,7 +90,6 @@ SET (cubicsdr_sources src/AppFrame.cpp src/SDRThreadQueue.cpp src/SDRThreadTask.cpp - src/Demodulator.cpp src/DemodulatorThread.cpp src/DemodulatorThreadQueue.cpp src/DemodulatorThreadTask.cpp @@ -115,7 +114,6 @@ SET (cubicsdr_headers src/CubicSDRDefs.h src/SDRThreadQueue.h src/SDRThreadTask.h - src/Demodulator.h src/DemodulatorThread.h src/DemodulatorThreadQueue.h src/DemodulatorThreadTask.h diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index a725433..754dece 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -142,8 +142,12 @@ void AppFrame::OnEventInput(wxThreadEvent& event) { std::vector *new_buffer = event.GetPayload *>(); // std::cout << new_buffer->size() << std::endl; if (new_buffer->size()) { - test_demod.writeBuffer(new_buffer); - scopeCanvas->setWaveformPoints(test_demod.waveform_points); + DemodulatorThreadTask task = DemodulatorThreadTask(DemodulatorThreadTask::DEMOD_THREAD_DATA); + task.setData(*new_buffer); + threadQueueDemod->addTask(task, DemodulatorThreadQueue::DEMOD_PRIORITY_HIGHEST); + +// test_demod.writeBuffer(new_buffer); +// scopeCanvas->setWaveformPoints(test_demod.waveform_points); spectrumCanvas->setData(new_buffer); waterfallCanvas->setData(new_buffer); } else { @@ -152,7 +156,6 @@ void AppFrame::OnEventInput(wxThreadEvent& event) { delete new_buffer; } - // Demodulator -> Audio void AppFrame::OnDemodInput(wxThreadEvent& event) { std::vector *new_buffer = event.GetPayload *>(); diff --git a/src/AppFrame.h b/src/AppFrame.h index 765bcaa..a460349 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -9,7 +9,6 @@ #include "ScopeCanvas.h" #include "SpectrumCanvas.h" #include "WaterfallCanvas.h" -#include "Demodulator.h" // Define a new frame type class AppFrame: public wxFrame { @@ -44,8 +43,6 @@ private: wxCriticalSection m_pThreadCS; unsigned int frequency; - Demodulator test_demod; - // event table wxDECLARE_EVENT_TABLE(); }; diff --git a/src/AudioThread.cpp b/src/AudioThread.cpp index 7a414bd..c20b481 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) { + wxThread(wxTHREAD_DETACHED), m_pQueue(pQueue), m_ID(id), audio_queue_ptr(0) { } AudioThread::~AudioThread() { @@ -30,16 +30,15 @@ static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned return paContinue; } - std::vector *nextBuffer = src->audio_queue.front(); + std::vector nextBuffer = src->audio_queue.front(); for (int i = 0; i < framesPerBuffer * 2; i++) { - out[i] = (*nextBuffer)[src->audio_queue_ptr]; + out[i] = nextBuffer[src->audio_queue_ptr]; src->audio_queue_ptr++; - if (src->audio_queue_ptr == nextBuffer->size()) { + if (src->audio_queue_ptr == nextBuffer.size()) { src->audio_queue.pop(); - delete nextBuffer; src->audio_queue_ptr = 0; if (!src->audio_queue.size()) { break; @@ -107,10 +106,9 @@ wxThread::ExitCode AudioThread::Entry() { while (m_pQueue->stackSize()) { 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_TUNING: - // - // audio_queue.push(newBuffer); - + case AudioThreadTask::AUDIO_THREAD_DATA: + audio_queue.push(task.getData()); + break; } } } diff --git a/src/AudioThread.h b/src/AudioThread.h index 8d99c10..344953c 100644 --- a/src/AudioThread.h +++ b/src/AudioThread.h @@ -26,12 +26,12 @@ static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned //wxDECLARE_EVENT(wxEVT_COMMAND_AudioThread_INPUT, wxThreadEvent); enum { - EVENT_AUDIO_INPUT = wxID_HIGHEST + 1 + EVENT_AUDIO_INPUT = wxID_HIGHEST + 3 }; class AudioThread: public wxThread { public: - std::queue *> audio_queue; + std::queue > audio_queue; unsigned int audio_queue_ptr; AudioThread(AudioThreadQueue* pQueue, int id = 0); diff --git a/src/Demodulator.cpp b/src/Demodulator.cpp deleted file mode 100644 index 1b586d6..0000000 --- a/src/Demodulator.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include "Demodulator.h" - -#ifdef WIN32 -#include -#endif - - -Demodulator::Demodulator() { - - bandwidth = 200000; - resample_ratio = (float) (bandwidth) / (float) SRATE; - wbfm_frequency = 100000; - wbfm_resample_ratio = (float) (wbfm_frequency) / (float) bandwidth; - audio_frequency = AUDIO_FREQUENCY; - audio_resample_ratio = (float) (audio_frequency) / (float) wbfm_frequency; - - - float fc = 0.5f * ((float)bandwidth / (float)SRATE) * 0.75; // filter cutoff frequency - float ft = 0.05f; // filter transition - float As = 60.0f; // stop-band attenuation [dB] - float mu = 0.0f; // fractional timing offset - - // estimate required filter length and generate filter - unsigned int h_len = estimate_req_filter_len(ft, As); - float h[h_len]; - liquid_firdes_kaiser(h_len, fc, As, mu, h); - - fir_filter = firfilt_crcf_create(h, h_len); - - h_len = estimate_req_filter_len(ft, As); - liquid_firdes_kaiser(h_len, 32000.0/(float)wbfm_frequency, As, mu, h); - - fir_audio_filter = firfilt_crcf_create(h, h_len); - - // create multi-stage arbitrary resampler object - resampler = msresamp_crcf_create(resample_ratio, As); - msresamp_crcf_print(resampler); - - wbfm_resampler = msresamp_crcf_create(wbfm_resample_ratio, As); - msresamp_crcf_print(wbfm_resampler); - - audio_resampler = msresamp_crcf_create(audio_resample_ratio, As); - msresamp_crcf_print(audio_resampler); - - float kf = 0.75; // modulation factor - - fdem = freqdem_create(kf); - freqdem_print(fdem); -} - -Demodulator::~Demodulator() { - -} - -void Demodulator::writeBuffer(std::vector *data) { - if (data->size()) { - liquid_float_complex filtered_input[BUF_SIZE / 2]; - - for (int i = 0; i < BUF_SIZE / 2; i++) { - - liquid_float_complex x; - liquid_float_complex y; - - x.real = (float) (*data)[i * 2] / 127.0f; - x.imag = (float) (*data)[i * 2 + 1] / 127.0f; - - firfilt_crcf_push(fir_filter, x); // push input sample - firfilt_crcf_execute(fir_filter, &y); // compute output - - filtered_input[i] = y; - } - - int out_size = ceil((float) (BUF_SIZE / 2) * resample_ratio); - - liquid_float_complex resampled_output[out_size]; - - unsigned int num_written; // number of values written to buffer - msresamp_crcf_execute(resampler, filtered_input, (BUF_SIZE / 2), resampled_output, &num_written); - - float waveform_ceil = 0, waveform_floor = 0; - - float pcm = 0; - - for (int i = 0; i < num_written; i++) { - freqdem_demodulate(fdem, resampled_output[i], &pcm); - - resampled_output[i].real = (float) pcm; - resampled_output[i].imag = 0; - - if (waveform_ceil < resampled_output[i].real) { - waveform_ceil = resampled_output[i].real; - } - - if (waveform_floor > resampled_output[i].real) { - waveform_floor = resampled_output[i].real; - } - } - - - int wbfm_out_size = ceil((float) (num_written) * wbfm_resample_ratio); - liquid_float_complex resampled_wbfm_output[wbfm_out_size]; - - unsigned int num_wbfm_written; - msresamp_crcf_execute(wbfm_resampler, resampled_output, num_written, resampled_wbfm_output, &num_wbfm_written); - - - for (int i = 0; i < num_wbfm_written; i++) { - firfilt_crcf_push(fir_audio_filter, resampled_wbfm_output[i]); - firfilt_crcf_execute(fir_audio_filter, &resampled_wbfm_output[i]); - } - - int audio_out_size = ceil((float) (num_wbfm_written) * audio_resample_ratio); - liquid_float_complex resampled_audio_output[audio_out_size]; - - 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); -// 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); - } - } -} diff --git a/src/Demodulator.h b/src/Demodulator.h deleted file mode 100644 index 46efb02..0000000 --- a/src/Demodulator.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "CubicSDRDefs.h" -#include "liquid/liquid.h" - - - -class Demodulator { -public: - std::vector waveform_points; - - Demodulator(); - ~Demodulator(); - - void writeBuffer(std::vector *data); - -private: - firfilt_crcf fir_filter; - firfilt_crcf fir_audio_filter; - - unsigned int bandwidth; - - msresamp_crcf resampler; - float resample_ratio; - - msresamp_crcf wbfm_resampler; - float wbfm_resample_ratio; - unsigned int wbfm_frequency; - - msresamp_crcf audio_resampler; - float audio_resample_ratio; - - unsigned int audio_frequency; - - freqdem fdem; -}; diff --git a/src/DemodulatorThread.cpp b/src/DemodulatorThread.cpp index 43decdc..917e0b5 100644 --- a/src/DemodulatorThread.cpp +++ b/src/DemodulatorThread.cpp @@ -61,7 +61,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.getData(); if (data->size()) { liquid_float_complex filtered_input[BUF_SIZE / 2]; diff --git a/src/DemodulatorThread.h b/src/DemodulatorThread.h index bff7638..aff1531 100644 --- a/src/DemodulatorThread.h +++ b/src/DemodulatorThread.h @@ -20,7 +20,7 @@ //wxDECLARE_EVENT(wxEVT_COMMAND_DemodulatorThread_INPUT, wxThreadEvent); enum { - EVENT_DEMOD_INPUT = wxID_HIGHEST + 1 + EVENT_DEMOD_INPUT = wxID_HIGHEST + 2 }; class DemodulatorThread: public wxThread { diff --git a/src/DemodulatorThreadTask.cpp b/src/DemodulatorThreadTask.cpp index 4728df0..c64d239 100644 --- a/src/DemodulatorThreadTask.cpp +++ b/src/DemodulatorThreadTask.cpp @@ -1,8 +1,8 @@ #include "DemodulatorThreadTask.h" -void DemodulatorThreadTask::setData(std::vector &data_in) { +void DemodulatorThreadTask::setData(std::vector &data_in) { data = data_in; } -std::vector &DemodulatorThreadTask::getData() { +std::vector &DemodulatorThreadTask::getData() { return data; } diff --git a/src/DemodulatorThreadTask.h b/src/DemodulatorThreadTask.h index 03f2efd..07341ce 100644 --- a/src/DemodulatorThreadTask.h +++ b/src/DemodulatorThreadTask.h @@ -17,10 +17,10 @@ public: m_cmd(cmd) { } - void setData(std::vector &data_in); - std::vector &getData(); + void setData(std::vector &data_in); + std::vector &getData(); DEMOD_THREAD_COMMAND m_cmd; - std::vector data; + std::vector data; }; diff --git a/src/visual/SpectrumCanvas.h b/src/visual/SpectrumCanvas.h index 649e8ed..29c748b 100644 --- a/src/visual/SpectrumCanvas.h +++ b/src/visual/SpectrumCanvas.h @@ -9,7 +9,6 @@ #include "SpectrumContext.h" #include "fftw3.h" -#include "Demodulator.h" class SpectrumCanvas: public wxGLCanvas { public: