mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-26 13:48:38 -05:00
commit
6f5f97d26f
@ -79,6 +79,7 @@ AppFrame::AppFrame() :
|
||||
demodWaterfallCanvas->Setup(1024, 256);
|
||||
demodWaterfallCanvas->SetView(DEFAULT_FREQ, 300000);
|
||||
demodWaterfallCanvas->attachSpectrumCanvas(demodSpectrumCanvas);
|
||||
demodSpectrumCanvas->attachWaterfallCanvas(demodWaterfallCanvas);
|
||||
demodVisuals->Add(demodWaterfallCanvas, 3, wxEXPAND | wxALL, 0);
|
||||
|
||||
demodTray->Add(demodVisuals, 30, wxEXPAND | wxALL, 0);
|
||||
@ -103,6 +104,7 @@ AppFrame::AppFrame() :
|
||||
waterfallCanvas = new WaterfallCanvas(this, NULL);
|
||||
waterfallCanvas->Setup(2048, 512);
|
||||
waterfallCanvas->attachSpectrumCanvas(spectrumCanvas);
|
||||
spectrumCanvas->attachWaterfallCanvas(waterfallCanvas);
|
||||
vbox->Add(waterfallCanvas, 4, wxEXPAND | wxALL, 0);
|
||||
|
||||
this->SetSizer(vbox);
|
||||
|
@ -119,7 +119,7 @@ void DemodulatorThread::threadMain() {
|
||||
freqdem_reset(fdem);
|
||||
}
|
||||
|
||||
int out_size = ceil((double) (bufSize) * inp->resample_ratio) + 32;
|
||||
int out_size = ceil((double) (bufSize) * inp->resample_ratio) + 512;
|
||||
|
||||
if (agc_data.size() != out_size) {
|
||||
if (agc_data.capacity() < out_size) {
|
||||
@ -144,7 +144,7 @@ void DemodulatorThread::threadMain() {
|
||||
demod_output.resize(num_written);
|
||||
}
|
||||
|
||||
int audio_out_size = ceil((double) (num_written) * audio_resample_ratio) + 32;
|
||||
int audio_out_size = ceil((double) (num_written) * audio_resample_ratio) + 512;
|
||||
|
||||
agc_crcf_execute_block(agc, &resampled_data[0], num_written, &agc_data[0]);
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "AppFrame.h"
|
||||
#include <algorithm>
|
||||
#include <wx/numformatter.h>
|
||||
#include "WaterfallCanvas.h"
|
||||
|
||||
wxBEGIN_EVENT_TABLE(SpectrumCanvas, wxGLCanvas) EVT_PAINT(SpectrumCanvas::OnPaint)
|
||||
EVT_IDLE(SpectrumCanvas::OnIdle)
|
||||
@ -27,7 +28,8 @@ wxEND_EVENT_TABLE()
|
||||
|
||||
SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) :
|
||||
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
|
||||
wxFULL_REPAINT_ON_RESIZE), parent(parent), fft_size(0), in(NULL), out(NULL), plan(NULL), center_freq(0), bandwidth(0), isView(0) {
|
||||
wxFULL_REPAINT_ON_RESIZE), parent(parent), fft_size(0), in(NULL), out(NULL), plan(NULL), waterfallCanvas(NULL), center_freq(0), bandwidth(0), isView(
|
||||
0) {
|
||||
|
||||
glContext = new SpectrumContext(this, &wxGetApp().GetContext(this));
|
||||
|
||||
@ -57,7 +59,6 @@ void SpectrumCanvas::Setup(int fft_size_in) {
|
||||
}
|
||||
plan = fftw_plan_dft_1d(fft_size, in, out, FFTW_FORWARD, FFTW_MEASURE);
|
||||
|
||||
|
||||
fft_ceil_ma = fft_ceil_maa = 100.0;
|
||||
fft_floor_ma = fft_floor_maa = 0.0;
|
||||
}
|
||||
@ -171,8 +172,6 @@ void SpectrumCanvas::setData(DemodulatorThreadIQData *input) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SpectrumCanvas::SetView(int center_freq_in, int bandwidth_in) {
|
||||
isView = true;
|
||||
center_freq = center_freq_in;
|
||||
@ -181,7 +180,10 @@ void SpectrumCanvas::SetView(int center_freq_in, int bandwidth_in) {
|
||||
|
||||
void SpectrumCanvas::DisableView() {
|
||||
isView = false;
|
||||
center_freq = wxGetApp().getFrequency();
|
||||
bandwidth = SRATE;
|
||||
}
|
||||
|
||||
void SpectrumCanvas::SetCenterFrequency(unsigned int center_freq_in) {
|
||||
center_freq = center_freq_in;
|
||||
}
|
||||
@ -217,12 +219,32 @@ void SpectrumCanvas::mouseMoved(wxMouseEvent& event) {
|
||||
|
||||
if (freqChange != 0) {
|
||||
int freq = wxGetApp().getFrequency();
|
||||
freq -= freqChange;
|
||||
wxGetApp().setFrequency(freq);
|
||||
|
||||
((wxFrame*) parent)->GetStatusBar()->SetStatusText(
|
||||
wxString::Format(wxT("Set center frequency: %s"),
|
||||
wxNumberFormatter::ToString((long) freq, wxNumberFormatter::Style_WithThousandsSep)));
|
||||
if (isView) {
|
||||
center_freq = center_freq - freqChange;
|
||||
if (waterfallCanvas) {
|
||||
waterfallCanvas->SetCenterFrequency(center_freq);
|
||||
}
|
||||
|
||||
int bw = (int)bandwidth;
|
||||
int bwOfs = ((int)center_freq>freq)?((int)bandwidth/2):(-(int)bandwidth/2);
|
||||
int freqEdge = ((int)center_freq+bwOfs);
|
||||
|
||||
if (abs(freq-freqEdge) > (SRATE/2)) {
|
||||
freqChange = -(((int)center_freq>freq)?(freqEdge-freq-(SRATE/2)):(freqEdge-freq+(SRATE/2)));
|
||||
} else {
|
||||
freqChange = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (freqChange) {
|
||||
freq -= freqChange;
|
||||
wxGetApp().setFrequency(freq);
|
||||
((wxFrame*) parent)->GetStatusBar()->SetStatusText(
|
||||
wxString::Format(wxT("Set center frequency: %s"),
|
||||
wxNumberFormatter::ToString((long) freq, wxNumberFormatter::Style_WithThousandsSep)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -246,6 +268,9 @@ void SpectrumCanvas::mouseLeftWindow(wxMouseEvent& event) {
|
||||
SetCursor(wxCURSOR_SIZEWE);
|
||||
}
|
||||
|
||||
void SpectrumCanvas::attachWaterfallCanvas(WaterfallCanvas* canvas_in) {
|
||||
waterfallCanvas = canvas_in;
|
||||
}
|
||||
//void SpectrumCanvas::rightClick(wxMouseEvent& event) {}
|
||||
//void SpectrumCanvas::keyPressed(wxKeyEvent& event) {}
|
||||
//void SpectrumCanvas::keyReleased(wxKeyEvent& event) {}
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "fftw3.h"
|
||||
#include "MouseTracker.h"
|
||||
|
||||
class WaterfallCanvas;
|
||||
|
||||
class SpectrumCanvas: public wxGLCanvas {
|
||||
public:
|
||||
std::vector<float> spectrum_points;
|
||||
@ -30,6 +32,8 @@ public:
|
||||
void SetBandwidth(unsigned int bandwidth_in);
|
||||
unsigned int GetBandwidth();
|
||||
|
||||
void attachWaterfallCanvas(WaterfallCanvas *canvas_in);
|
||||
|
||||
private:
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
|
||||
@ -56,6 +60,7 @@ private:
|
||||
std::vector<double> fft_result_maa;
|
||||
|
||||
SpectrumContext *glContext;
|
||||
WaterfallCanvas *waterfallCanvas;
|
||||
int fft_size;
|
||||
|
||||
unsigned int center_freq;
|
||||
|
@ -35,7 +35,7 @@ WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
|
||||
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(
|
||||
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), zoom(0) {
|
||||
|
||||
glContext = new WaterfallContext(this, &wxGetApp().GetContext(this));
|
||||
|
||||
@ -62,6 +62,9 @@ void WaterfallCanvas::SetView(int center_freq_in, int bandwidth_in) {
|
||||
|
||||
void WaterfallCanvas::DisableView() {
|
||||
isView = false;
|
||||
center_freq = wxGetApp().getFrequency();
|
||||
bandwidth = SRATE;
|
||||
last_bandwidth = 0;
|
||||
}
|
||||
|
||||
void WaterfallCanvas::Setup(int fft_size_in, int waterfall_lines_in) {
|
||||
@ -221,8 +224,14 @@ void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) {
|
||||
shiftDown = event.ShiftDown();
|
||||
altDown = event.AltDown();
|
||||
ctrlDown = event.ControlDown();
|
||||
// switch (event.GetKeyCode()) {
|
||||
// }
|
||||
switch (event.GetKeyCode()) {
|
||||
case 'A':
|
||||
zoom = 0;
|
||||
break;
|
||||
case 'Z':
|
||||
zoom = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
|
||||
@ -235,60 +244,65 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
|
||||
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
|
||||
|
||||
unsigned int freq;
|
||||
if (!isView) {
|
||||
switch (event.GetKeyCode()) {
|
||||
case WXK_RIGHT:
|
||||
freq = wxGetApp().getFrequency();
|
||||
if (shiftDown) {
|
||||
freq += SRATE * 10;
|
||||
} else {
|
||||
freq += SRATE / 2;
|
||||
}
|
||||
wxGetApp().setFrequency(freq);
|
||||
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||
break;
|
||||
case WXK_LEFT:
|
||||
freq = wxGetApp().getFrequency();
|
||||
if (shiftDown) {
|
||||
freq -= SRATE * 10;
|
||||
} else {
|
||||
freq -= SRATE / 2;
|
||||
}
|
||||
wxGetApp().setFrequency(freq);
|
||||
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||
break;
|
||||
case 'D':
|
||||
case WXK_DELETE:
|
||||
if (!activeDemod) {
|
||||
break;
|
||||
}
|
||||
wxGetApp().removeDemodulator(activeDemod);
|
||||
wxGetApp().getDemodMgr().deleteThread(activeDemod);
|
||||
break;
|
||||
case 'S':
|
||||
if (!activeDemod) {
|
||||
break;
|
||||
}
|
||||
if (activeDemod->isSquelchEnabled()) {
|
||||
activeDemod->setSquelchEnabled(false);
|
||||
} else {
|
||||
activeDemod->squelchAuto();
|
||||
}
|
||||
break;
|
||||
case WXK_SPACE:
|
||||
if (!activeDemod) {
|
||||
break;
|
||||
}
|
||||
if (activeDemod->isStereo()) {
|
||||
activeDemod->setStereo(false);
|
||||
} else {
|
||||
activeDemod->setStereo(true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
event.Skip();
|
||||
return;
|
||||
unsigned int bw;
|
||||
switch (event.GetKeyCode()) {
|
||||
case 'A':
|
||||
zoom = 1;
|
||||
break;
|
||||
case 'Z':
|
||||
zoom = -1;
|
||||
break;
|
||||
case WXK_RIGHT:
|
||||
freq = wxGetApp().getFrequency();
|
||||
if (shiftDown) {
|
||||
freq += SRATE * 10;
|
||||
} else {
|
||||
freq += SRATE / 2;
|
||||
}
|
||||
wxGetApp().setFrequency(freq);
|
||||
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||
break;
|
||||
case WXK_LEFT:
|
||||
freq = wxGetApp().getFrequency();
|
||||
if (shiftDown) {
|
||||
freq -= SRATE * 10;
|
||||
} else {
|
||||
freq -= SRATE / 2;
|
||||
}
|
||||
wxGetApp().setFrequency(freq);
|
||||
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||
break;
|
||||
case 'D':
|
||||
case WXK_DELETE:
|
||||
if (!activeDemod) {
|
||||
break;
|
||||
}
|
||||
wxGetApp().removeDemodulator(activeDemod);
|
||||
wxGetApp().getDemodMgr().deleteThread(activeDemod);
|
||||
break;
|
||||
case 'S':
|
||||
if (!activeDemod) {
|
||||
break;
|
||||
}
|
||||
if (activeDemod->isSquelchEnabled()) {
|
||||
activeDemod->setSquelchEnabled(false);
|
||||
} else {
|
||||
activeDemod->squelchAuto();
|
||||
}
|
||||
break;
|
||||
case WXK_SPACE:
|
||||
if (!activeDemod) {
|
||||
break;
|
||||
}
|
||||
if (activeDemod->isStereo()) {
|
||||
activeDemod->setStereo(false);
|
||||
} else {
|
||||
activeDemod->setStereo(true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,16 +311,72 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int bw;
|
||||
if (zoom) {
|
||||
int freq = wxGetApp().getFrequency();
|
||||
|
||||
if (zoom > 0) {
|
||||
center_freq = GetCenterFrequency();
|
||||
bw = GetBandwidth();
|
||||
bw = (unsigned int) ceil((float) bw * 0.95);
|
||||
if (bw < 80000) {
|
||||
bw = 80000;
|
||||
}
|
||||
if (mTracker.mouseInView()) {
|
||||
int mfreqA = GetFrequencyAt(mTracker.getMouseX());
|
||||
SetBandwidth(bw);
|
||||
int mfreqB = GetFrequencyAt(mTracker.getMouseX());
|
||||
center_freq += mfreqA - mfreqB;
|
||||
}
|
||||
|
||||
SetView(center_freq, bw);
|
||||
if (spectrumCanvas) {
|
||||
spectrumCanvas->SetView(center_freq, bw);
|
||||
}
|
||||
} else {
|
||||
if (isView) {
|
||||
bw = GetBandwidth();
|
||||
bw = (unsigned int) ceil((float) bw * 1.05);
|
||||
if ((int) bw >= SRATE) {
|
||||
bw = (unsigned int) SRATE;
|
||||
DisableView();
|
||||
if (spectrumCanvas) {
|
||||
spectrumCanvas->DisableView();
|
||||
}
|
||||
} else {
|
||||
if (mTracker.mouseInView()) {
|
||||
int freq = wxGetApp().getFrequency();
|
||||
int mfreqA = GetFrequencyAt(mTracker.getMouseX());
|
||||
SetBandwidth(bw);
|
||||
int mfreqB = GetFrequencyAt(mTracker.getMouseX());
|
||||
center_freq += mfreqA - mfreqB;
|
||||
}
|
||||
|
||||
SetView(GetCenterFrequency(), bw);
|
||||
if (spectrumCanvas) {
|
||||
spectrumCanvas->SetView(center_freq, bw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (center_freq < freq && (center_freq - bandwidth / 2) < (freq - SRATE / 2)) {
|
||||
center_freq = (freq - SRATE / 2) + bandwidth / 2;
|
||||
}
|
||||
if (center_freq > freq && (center_freq + bandwidth / 2) > (freq + SRATE / 2)) {
|
||||
center_freq = (freq + SRATE / 2) - bandwidth / 2;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<liquid_float_complex> *data = &input->data;
|
||||
|
||||
if (data && data->size()) {
|
||||
if (fft_size != data->size() && !isView) {
|
||||
Setup(data->size(), waterfall_lines);
|
||||
}
|
||||
// if (fft_size != data->size() && !isView) {
|
||||
// Setup(data->size(), waterfall_lines);
|
||||
// }
|
||||
|
||||
if (last_bandwidth != bandwidth && !isView) {
|
||||
Setup(bandwidth, waterfall_lines);
|
||||
}
|
||||
// if (last_bandwidth != bandwidth && !isView) {
|
||||
// Setup(bandwidth, waterfall_lines);
|
||||
// }
|
||||
|
||||
if (spectrum_points.size() < fft_size * 2) {
|
||||
spectrum_points.resize(fft_size * 2);
|
||||
@ -356,7 +426,7 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
|
||||
last_input_bandwidth = input->bandwidth;
|
||||
}
|
||||
|
||||
int out_size = ceil((double) (input->data.size()) * resample_ratio) + 32;
|
||||
int out_size = ceil((double) (input->data.size()) * resample_ratio) + 512;
|
||||
|
||||
if (resampler_buffer.size() != out_size) {
|
||||
if (resampler_buffer.capacity() < out_size) {
|
||||
@ -648,6 +718,10 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
|
||||
|
||||
if (DemodulatorInstance *last = wxGetApp().getDemodMgr().getLastActiveDemodulator()) {
|
||||
demod->getParams().bandwidth = last->getParams().bandwidth;
|
||||
demod->setDemodulatorType(last->getDemodulatorType());
|
||||
demod->setSquelchLevel(last->getSquelchLevel());
|
||||
demod->setSquelchEnabled(last->isSquelchEnabled());
|
||||
demod->setStereo(last->isStereo());
|
||||
}
|
||||
|
||||
demod->run();
|
||||
@ -708,7 +782,12 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
|
||||
demod = wxGetApp().getDemodMgr().newThread();
|
||||
demod->getParams().frequency = freq;
|
||||
demod->getParams().bandwidth = bw;
|
||||
|
||||
if (DemodulatorInstance *last = wxGetApp().getDemodMgr().getLastActiveDemodulator()) {
|
||||
demod->setDemodulatorType(last->getDemodulatorType());
|
||||
demod->setSquelchLevel(last->getSquelchLevel());
|
||||
demod->setSquelchEnabled(last->isSquelchEnabled());
|
||||
demod->setStereo(last->isStereo());
|
||||
}
|
||||
demod->run();
|
||||
|
||||
wxGetApp().bindDemodulator(demod);
|
||||
|
@ -95,6 +95,8 @@ private:
|
||||
int last_input_bandwidth;
|
||||
int last_bandwidth;
|
||||
|
||||
int zoom;
|
||||
|
||||
std::vector<liquid_float_complex> shift_buffer;
|
||||
std::vector<liquid_float_complex> resampler_buffer;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user