Can now choose demodulator output devices

This commit is contained in:
Charles J. Cliffe 2014-12-31 21:31:37 -05:00
parent b7793ef905
commit 6679b20fbb
15 changed files with 136 additions and 71 deletions

View File

@ -22,13 +22,15 @@
wxBEGIN_EVENT_TABLE(AppFrame, wxFrame) wxBEGIN_EVENT_TABLE(AppFrame, wxFrame)
//EVT_MENU(wxID_NEW, AppFrame::OnNewWindow) //EVT_MENU(wxID_NEW, AppFrame::OnNewWindow)
EVT_MENU(wxID_CLOSE, AppFrame::OnClose) //EVT_MENU(wxID_CLOSE, AppFrame::OnClose)
EVT_MENU(wxID_ANY, AppFrame::OnMenu)
EVT_COMMAND(wxID_ANY, wxEVT_THREAD, AppFrame::OnThread) EVT_COMMAND(wxID_ANY, wxEVT_THREAD, AppFrame::OnThread)
EVT_IDLE(AppFrame::OnIdle) EVT_IDLE(AppFrame::OnIdle)
wxEND_EVENT_TABLE() wxEND_EVENT_TABLE()
AppFrame::AppFrame() : AppFrame::AppFrame() :
wxFrame(NULL, wxID_ANY, wxT("CubicSDR")) { wxFrame(NULL, wxID_ANY, wxT("CubicSDR")), activeDemodulator(NULL) {
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *demodOpts = new wxBoxSizer(wxVERTICAL); wxBoxSizer *demodOpts = new wxBoxSizer(wxVERTICAL);
@ -137,12 +139,14 @@ AppFrame::AppFrame() :
i++; i++;
} }
i = 0;
for (mdevices_i = output_devices.begin(); mdevices_i != output_devices.end(); mdevices_i++) { for (mdevices_i = output_devices.begin(); mdevices_i != output_devices.end(); mdevices_i++) {
wxMenuItem *itm = menu->AppendRadioItem(wxID_RT_AUDIO_DEVICE+i,mdevices_i->second.name,wxT("Description?")); wxMenuItem *itm = menu->AppendRadioItem(wxID_RT_AUDIO_DEVICE+mdevices_i->first,mdevices_i->second.name,wxT("Description?"));
if (mdevices_i->second.isDefaultOutput) { if (mdevices_i->second.isDefaultOutput) {
itm->Check(true); itm->Check(true);
} }
output_device_menuitems[mdevices_i->first] = itm;
} }
wxMenuBar *menuBar = new wxMenuBar; wxMenuBar *menuBar = new wxMenuBar;
@ -166,10 +170,13 @@ AppFrame::~AppFrame() {
} }
void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) { void AppFrame::OnMenu(wxCommandEvent& event) {
if (event.GetId() >= wxID_RT_AUDIO_DEVICE && event.GetId() < wxID_RT_AUDIO_DEVICE+output_devices.size()) {
// true is to force the frame to close if (activeDemodulator) {
Close(true); activeDemodulator->setOutputDevice(event.GetId()-wxID_RT_AUDIO_DEVICE);
activeDemodulator = NULL;
}
}
} }
void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) { void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
@ -193,6 +200,9 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
if (demod) { if (demod) {
if (demod != activeDemodulator) { if (demod != activeDemodulator) {
demodSignalMeter->setInputValue(demod->getSquelchLevel()); demodSignalMeter->setInputValue(demod->getSquelchLevel());
int outputDevice = demod->getOutputDevice();
scopeCanvas->setDeviceName(output_devices[outputDevice].name);
output_device_menuitems[outputDevice]->Check(true);
} }
if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) { if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) {
if (demod->getParams().frequency != demodWaterfallCanvas->GetCenterFrequency()) { if (demod->getParams().frequency != demodWaterfallCanvas->GetCenterFrequency()) {

View File

@ -21,7 +21,7 @@ public:
void OnEventInput(wxThreadEvent& event); void OnEventInput(wxThreadEvent& event);
private: private:
void OnClose(wxCommandEvent& event); void OnMenu(wxCommandEvent& event);
void OnNewWindow(wxCommandEvent& event); void OnNewWindow(wxCommandEvent& event);
void OnIdle(wxIdleEvent& event); void OnIdle(wxIdleEvent& event);
@ -37,6 +37,7 @@ private:
std::map<int,RtAudio::DeviceInfo> input_devices; std::map<int,RtAudio::DeviceInfo> input_devices;
std::map<int,RtAudio::DeviceInfo> output_devices; std::map<int,RtAudio::DeviceInfo> output_devices;
std::map<int,wxMenuItem *> output_device_menuitems;
wxDECLARE_EVENT_TABLE(); wxDECLARE_EVENT_TABLE();
}; };

View File

@ -10,7 +10,7 @@ std::map<int, std::thread *> AudioThread::deviceThread;
#endif #endif
AudioThread::AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify) : AudioThread::AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify) :
currentInput(NULL), inputQueue(inputQueue), audio_queue_ptr(0), underflow_count(0), terminated(false), active(false), gain(1.0), threadQueueNotify( currentInput(NULL), inputQueue(inputQueue), audio_queue_ptr(0), underflow_count(0), terminated(false), active(false), output_device(-1), gain(1.0), threadQueueNotify(
threadQueueNotify) { threadQueueNotify) {
#ifdef __APPLE__ #ifdef __APPLE__
boundThreads = new std::vector<AudioThread *>; boundThreads = new std::vector<AudioThread *>;
@ -25,7 +25,9 @@ AudioThread::~AudioThread() {
#ifdef __APPLE__ #ifdef __APPLE__
void AudioThread::bindThread(AudioThread *other) { void AudioThread::bindThread(AudioThread *other) {
boundThreads.load()->push_back(other); if (boundThreads.find(other) == boundThreads.end()) {
boundThreads.load()->push_back(other);
}
} }
void AudioThread::removeThread(AudioThread *other) { void AudioThread::removeThread(AudioThread *other) {
@ -263,22 +265,8 @@ void AudioThread::enumerateDevices(std::vector<RtAudio::DeviceInfo> &devs) {
} }
} }
void AudioThread::threadMain() { void AudioThread::setupDevice(int deviceId) {
#ifdef __APPLE__ parameters.deviceId = deviceId;
pthread_t tID = pthread_self(); // ID of this thread
int priority = sched_get_priority_max( SCHED_RR) - 1;
sched_param prio = {priority}; // scheduling priority of thread
pthread_setschedparam(tID, SCHED_RR, &prio);
#endif
std::cout << "Audio thread initializing.." << std::endl;
if (dac.getDeviceCount() < 1) {
std::cout << "No audio devices found!" << std::endl;
return;
}
parameters.deviceId = dac.getDefaultOutputDevice();
parameters.nChannels = 2; parameters.nChannels = 2;
parameters.firstChannel = 0; parameters.firstChannel = 0;
unsigned int sampleRate = AUDIO_FREQUENCY; unsigned int sampleRate = AUDIO_FREQUENCY;
@ -287,9 +275,15 @@ void AudioThread::threadMain() {
RtAudio::StreamOptions opts; RtAudio::StreamOptions opts;
opts.streamName = "CubicSDR Audio Output"; opts.streamName = "CubicSDR Audio Output";
output_device = deviceId;
try { try {
#ifdef __APPLE__ #ifdef __APPLE__
if (active && deviceController.find(parameters.deviceId) != deviceController.end()) {
deviceController[parameters.deviceId]->removeThread(this);
}
opts.priority = sched_get_priority_max(SCHED_FIFO); opts.priority = sched_get_priority_max(SCHED_FIFO);
// opts.flags = RTAUDIO_MINIMIZE_LATENCY; // opts.flags = RTAUDIO_MINIMIZE_LATENCY;
opts.flags = RTAUDIO_SCHEDULE_REALTIME; opts.flags = RTAUDIO_SCHEDULE_REALTIME;
@ -306,6 +300,13 @@ void AudioThread::threadMain() {
} }
active = true; active = true;
#else #else
if (dac.isStreamOpen()) {
if (dac.isStreamRunning()) {
dac.stopStream();
}
dac.closeStream();
}
dac.openStream(&parameters, NULL, RTAUDIO_FLOAT32, sampleRate, &bufferFrames, &audioCallback, (void *) this, &opts); dac.openStream(&parameters, NULL, RTAUDIO_FLOAT32, sampleRate, &bufferFrames, &audioCallback, (void *) this, &opts);
dac.startStream(); dac.startStream();
@ -314,10 +315,39 @@ void AudioThread::threadMain() {
e.printMessage(); e.printMessage();
return; return;
} }
}
int AudioThread::getOutputDevice() {
if (output_device == -1) {
return dac.getDefaultOutputDevice();
}
return output_device;
}
void AudioThread::threadMain() {
#ifdef __APPLE__
pthread_t tID = pthread_self(); // ID of this thread
int priority = sched_get_priority_max( SCHED_RR) - 1;
sched_param prio = {priority}; // scheduling priority of thread
pthread_setschedparam(tID, SCHED_RR, &prio);
#endif
std::cout << "Audio thread initializing.." << std::endl;
if (dac.getDeviceCount() < 1) {
std::cout << "No audio devices found!" << std::endl;
return;
}
setupDevice(dac.getDefaultOutputDevice());
while (!terminated) { while (!terminated) {
AudioThreadCommand command; AudioThreadCommand command;
cmdQueue.pop(command); cmdQueue.pop(command);
if (command.cmd == AudioThreadCommand::AUDIO_THREAD_CMD_SET_DEVICE) {
setupDevice(command.int_value);
}
} }
#ifdef __APPLE__ #ifdef __APPLE__
@ -387,3 +417,8 @@ void AudioThread::setActive(bool state) {
#endif #endif
active = state; active = state;
} }
AudioThreadCommandQueue *AudioThread::getCommandQueue() {
return &cmdQueue;
}

View File

@ -61,6 +61,7 @@ public:
std::atomic<unsigned int> underflow_count; std::atomic<unsigned int> underflow_count;
std::atomic<bool> terminated; std::atomic<bool> terminated;
std::atomic<bool> active; std::atomic<bool> active;
std::atomic<int> output_device;
float gain; float gain;
AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify); AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify);
@ -68,12 +69,16 @@ public:
static void enumerateDevices(std::vector<RtAudio::DeviceInfo> &devs); static void enumerateDevices(std::vector<RtAudio::DeviceInfo> &devs);
void setupDevice(int deviceId);
int getOutputDevice();
void threadMain(); void threadMain();
void terminate(); void terminate();
bool isActive(); bool isActive();
void setActive(bool state); void setActive(bool state);
AudioThreadCommandQueue *getCommandQueue();
private: private:
RtAudio dac; RtAudio dac;
RtAudio::StreamParameters parameters; RtAudio::StreamParameters parameters;

View File

@ -194,3 +194,16 @@ float DemodulatorInstance::getSquelchLevel() {
return demodulatorThread->getSquelchLevel(); return demodulatorThread->getSquelchLevel();
} }
void DemodulatorInstance::setOutputDevice(int device_id) {
if (audioThread) {
AudioThreadCommand command;
command.cmd = AudioThreadCommand::AUDIO_THREAD_CMD_SET_DEVICE;
command.int_value = device_id;
audioThread->getCommandQueue()->push(command);
}
}
int DemodulatorInstance::getOutputDevice() {
return audioThread->getOutputDevice();
}

View File

@ -60,6 +60,9 @@ public:
void setSquelchLevel(float signal_level_in); void setSquelchLevel(float signal_level_in);
float getSquelchLevel(); float getSquelchLevel();
void setOutputDevice(int device_id);
int getOutputDevice();
private: private:
std::atomic<std::string *> label; // std::atomic<std::string *> label; //
bool terminated; // bool terminated; //

View File

@ -382,7 +382,7 @@ void GLFont::drawString(std::string str, float xpos, float ypos, int pxHeight, A
glPushMatrix(); glPushMatrix();
glTranslatef(xpos, ypos, 0.0f); glTranslatef(xpos, ypos, 0.0f);
switch (hAlign) { switch (vAlign) {
case GLFONT_ALIGN_TOP: case GLFONT_ALIGN_TOP:
glTranslatef(0.0, -size, 0.0); glTranslatef(0.0, -size, 0.0);
break; break;
@ -393,7 +393,7 @@ void GLFont::drawString(std::string str, float xpos, float ypos, int pxHeight, A
break; break;
} }
switch (vAlign) { switch (hAlign) {
case GLFONT_ALIGN_RIGHT: case GLFONT_ALIGN_RIGHT:
glTranslatef(-msgWidth, 0.0, 0.0); glTranslatef(-msgWidth, 0.0, 0.0);
break; break;
@ -445,5 +445,6 @@ void GLFont::drawString(std::string str, float xpos, float ypos, int pxHeight, A
glPopMatrix(); glPopMatrix();
glDisable(GL_BLEND); glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
} }

View File

@ -21,10 +21,9 @@ wxEND_EVENT_TABLE()
ScopeCanvas::ScopeCanvas(wxWindow *parent, int *attribList) : ScopeCanvas::ScopeCanvas(wxWindow *parent, int *attribList) :
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), stereo(false) { wxFULL_REPAINT_ON_RESIZE), parent(parent), stereo(false) {
glContext = new ScopeContext(this, &wxGetApp().GetContext(this)); glContext = new ScopeContext(this, &wxGetApp().GetContext(this));
timer.start();
} }
ScopeCanvas::~ScopeCanvas() { ScopeCanvas::~ScopeCanvas() {
@ -39,6 +38,11 @@ void ScopeCanvas::setStereo(bool state) {
stereo = state; stereo = state;
} }
void ScopeCanvas::setDeviceName(std::string device_name) {
deviceName = device_name;
deviceName.append(" ");
}
void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
wxPaintDC dc(this); wxPaintDC dc(this);
const wxSize ClientSize = GetClientSize(); const wxSize ClientSize = GetClientSize();
@ -47,17 +51,16 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
glViewport(0, 0, ClientSize.x, ClientSize.y); glViewport(0, 0, ClientSize.x, ClientSize.y);
glContext->DrawBegin(); glContext->DrawBegin();
if (!deviceName.empty()) {
glContext->DrawDeviceName(deviceName);
}
glContext->Plot(waveform_points, stereo); glContext->Plot(waveform_points, stereo);
glContext->DrawEnd(); glContext->DrawEnd();
SwapBuffers(); SwapBuffers();
} }
void ScopeCanvas::OnIdle(wxIdleEvent &event) { void ScopeCanvas::OnIdle(wxIdleEvent &event) {
// timer.update();
// frameTimer += timer.lastUpdateSeconds();
// if (frameTimer > 1.0/30.0) {
Refresh(false); Refresh(false);
// frameTimer = 0;
// }
} }

View File

@ -7,9 +7,7 @@
#include <queue> #include <queue>
#include "ScopeContext.h" #include "ScopeContext.h"
#include "fftw3.h" #include "fftw3.h"
#include "Timer.h"
class ScopeCanvas: public wxGLCanvas { class ScopeCanvas: public wxGLCanvas {
public: public:
@ -20,6 +18,7 @@ public:
void setWaveformPoints(std::vector<float> &waveform_points_in); void setWaveformPoints(std::vector<float> &waveform_points_in);
void setStereo(bool state); void setStereo(bool state);
void setDeviceName(std::string device_name);
private: private:
void OnPaint(wxPaintEvent& event); void OnPaint(wxPaintEvent& event);
@ -28,8 +27,7 @@ private:
wxWindow *parent; wxWindow *parent;
ScopeContext *glContext; ScopeContext *glContext;
Timer timer; std::string deviceName;
float frameTimer;
bool stereo; bool stereo;
// event table // event table
wxDECLARE_EVENT_TABLE(); wxDECLARE_EVENT_TABLE();

View File

@ -4,20 +4,20 @@
ScopeContext::ScopeContext(ScopeCanvas *canvas, wxGLContext *sharedContext) : ScopeContext::ScopeContext(ScopeCanvas *canvas, wxGLContext *sharedContext) :
PrimaryGLContext(canvas, sharedContext) { PrimaryGLContext(canvas, sharedContext) {
glDisable (GL_CULL_FACE); glDisable(GL_CULL_FACE);
glDisable (GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glMatrixMode (GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
} }
void ScopeContext::DrawBegin() { void ScopeContext::DrawBegin() {
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();
glDisable (GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} }
void ScopeContext::Plot(std::vector<float> &points, bool stereo) { void ScopeContext::Plot(std::vector<float> &points, bool stereo) {
@ -26,27 +26,27 @@ void ScopeContext::Plot(std::vector<float> &points, bool stereo) {
if (stereo) { if (stereo) {
glColor3f(0.7, 0.7, 0.7); glColor3f(0.7, 0.7, 0.7);
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex2f(-1.0,0.0); glVertex2f(-1.0, 0.0);
glVertex2f(1.0,0.0); glVertex2f(1.0, 0.0);
glEnd(); glEnd();
glColor3f(0.3, 0.3, 0.3); glColor3f(0.3, 0.3, 0.3);
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex2f(-1.0,0.5); glVertex2f(-1.0, 0.5);
glVertex2f(1.0,0.5); glVertex2f(1.0, 0.5);
glVertex2f(-1.0,-0.5); glVertex2f(-1.0, -0.5);
glVertex2f(1.0,-0.5); glVertex2f(1.0, -0.5);
glEnd(); glEnd();
} else { } else {
glColor3f(0.3, 0.3, 0.3); glColor3f(0.3, 0.3, 0.3);
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex2f(-1.0,0.0); glVertex2f(-1.0, 0.0);
glVertex2f(1.0,0.0); glVertex2f(1.0, 0.0);
glEnd(); glEnd();
} }
glColor3f(0.9, 0.9, 0.9); glColor3f(0.9, 0.9, 0.9);
if (points.size()) { if (points.size()) {
glEnableClientState (GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, &points[0]); glVertexPointer(2, GL_FLOAT, 0, &points[0]);
if (stereo) { if (stereo) {
glPushMatrix(); glPushMatrix();
@ -74,6 +74,16 @@ void ScopeContext::Plot(std::vector<float> &points, bool stereo) {
} }
} }
void ScopeContext::DrawDeviceName(std::string deviceName) {
GLint vp[4];
glGetIntegerv( GL_VIEWPORT, vp);
float viewHeight = (float) vp[3];
float hPos = (float) (viewHeight - 20) / viewHeight;
glColor3f(0.65,0.65,0.65);
getFont(PrimaryGLContext::GLFONT_SIZE12).drawString(deviceName.c_str(), 1.0, hPos, 12, GLFont::GLFONT_ALIGN_RIGHT, GLFont::GLFONT_ALIGN_CENTER);
}
void ScopeContext::DrawEnd() { void ScopeContext::DrawEnd() {
glFlush(); glFlush();
@ -83,7 +93,7 @@ void ScopeContext::DrawEnd() {
void ScopeContext::DrawDivider() { void ScopeContext::DrawDivider() {
glColor3f(1.0, 1.0, 1.0); glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex2f(0.0,-1.0); glVertex2f(0.0, -1.0);
glVertex2f(0.0,1.0); glVertex2f(0.0, 1.0);
glEnd(); glEnd();
} }

View File

@ -13,6 +13,7 @@ public:
void DrawBegin(); void DrawBegin();
void Plot(std::vector<float> &points, bool stereo=false); void Plot(std::vector<float> &points, bool stereo=false);
void DrawDeviceName(std::string deviceName);
void DrawDivider(); void DrawDivider();
void DrawEnd(); void DrawEnd();

View File

@ -207,12 +207,7 @@ unsigned int SpectrumCanvas::GetBandwidth() {
} }
void SpectrumCanvas::OnIdle(wxIdleEvent &event) { void SpectrumCanvas::OnIdle(wxIdleEvent &event) {
// timer.update();
// frameTimer += timer.lastUpdateSeconds();
// if (frameTimer > 1.0/30.0) {
Refresh(false); Refresh(false);
// frameTimer = 0;
// }
} }
void SpectrumCanvas::mouseMoved(wxMouseEvent& event) { void SpectrumCanvas::mouseMoved(wxMouseEvent& event) {

View File

@ -9,7 +9,6 @@
#include "SpectrumContext.h" #include "SpectrumContext.h"
#include "fftw3.h" #include "fftw3.h"
#include "Timer.h"
#include "MouseTracker.h" #include "MouseTracker.h"
class SpectrumCanvas: public wxGLCanvas { class SpectrumCanvas: public wxGLCanvas {

View File

@ -32,7 +32,7 @@ wxEND_EVENT_TABLE()
WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) : WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
wxFULL_REPAINT_ON_RESIZE), parent(parent), spectrumCanvas(NULL), frameTimer(0), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState( wxFULL_REPAINT_ON_RESIZE), parent(parent), spectrumCanvas(NULL), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState(
WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(false), altDown(false), ctrlDown(false), fft_size(0), waterfall_lines(0), plan( WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(false), altDown(false), ctrlDown(false), fft_size(0), waterfall_lines(0), plan(
NULL), in(NULL), out(NULL), center_freq(0), bandwidth(0), isView(false), resampler(NULL), resample_ratio(0), last_bandwidth(0), last_input_bandwidth( NULL), in(NULL), out(NULL), center_freq(0), bandwidth(0), isView(false), resampler(NULL), resample_ratio(0), last_bandwidth(0), last_input_bandwidth(
0) { 0) {
@ -85,7 +85,6 @@ void WaterfallCanvas::Setup(int fft_size_in, int waterfall_lines_in) {
plan = fftw_plan_dft_1d(fft_size, in, out, FFTW_FORWARD, FFTW_MEASURE); plan = fftw_plan_dft_1d(fft_size, in, out, FFTW_FORWARD, FFTW_MEASURE);
glContext->Setup(fft_size, waterfall_lines); glContext->Setup(fft_size, waterfall_lines);
timer.start();
} }
int WaterfallCanvas::GetFrequencyAt(float x) { int WaterfallCanvas::GetFrequencyAt(float x) {
@ -447,12 +446,7 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
} }
void WaterfallCanvas::OnIdle(wxIdleEvent &event) { void WaterfallCanvas::OnIdle(wxIdleEvent &event) {
// timer.update();
// frameTimer += timer.lastUpdateSeconds();
// if (frameTimer > 1.0/30.0) {
Refresh(false); Refresh(false);
// frameTimer = 0;
// }
} }
void WaterfallCanvas::mouseMoved(wxMouseEvent& event) { void WaterfallCanvas::mouseMoved(wxMouseEvent& event) {

View File

@ -11,7 +11,6 @@
#include "SpectrumCanvas.h" #include "SpectrumCanvas.h"
#include "fftw3.h" #include "fftw3.h"
#include "Timer.h"
class WaterfallCanvas: public wxGLCanvas { class WaterfallCanvas: public wxGLCanvas {
public: public:
@ -69,8 +68,6 @@ private:
std::vector<float> fft_result_maa; std::vector<float> fft_result_maa;
WaterfallContext *glContext; WaterfallContext *glContext;
Timer timer;
float frameTimer;
MouseTracker mTracker; MouseTracker mTracker;
int activeDemodulatorBandwidth; int activeDemodulatorBandwidth;