FFTW->FFTWF better CPU usage

This commit is contained in:
Charles J. Cliffe 2015-01-06 19:15:27 -05:00
parent 0806e47116
commit 7d5d638666
11 changed files with 1101 additions and 63 deletions

View File

@ -61,7 +61,7 @@ IF (WIN32)
set(wxWidgets_USE_STATIC ON)
include_directories ( ${PROJECT_SOURCE_DIR}/external/fftw-3.3.4-dll64 ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release )
link_directories ( ${PROJECT_SOURCE_DIR}/external/fftw-3.3.4-dll64 ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/x64 )
set(FFTW_LIB fftw3-3)
set(FFTW_LIB fftw3f-3)
link_directories ( ${PROJECT_SOURCE_DIR}/external/liquid-dsp/lib/64 )
include_directories ( ${PROJECT_SOURCE_DIR}/external/liquid-dsp/include )

BIN
external/fftw-3.3.4-dll64/libfftw3f-3.a vendored Normal file

Binary file not shown.

1013
external/fftw-3.3.4-dll64/libfftw3f-3.def vendored Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -53,16 +53,16 @@ AppFrame::AppFrame() :
demodSpectrumCanvas = new SpectrumCanvas(this, NULL);
demodSpectrumCanvas->setup(1024);
demodSpectrumCanvas->setView(DEFAULT_FREQ, 300000);
demodVisuals->Add(demodSpectrumCanvas, 1, wxEXPAND | wxALL, 0);
demodVisuals->Add(demodSpectrumCanvas, 3, wxEXPAND | wxALL, 0);
demodVisuals->AddSpacer(1);
demodWaterfallCanvas = new WaterfallCanvas(this, NULL);
demodWaterfallCanvas->setup(1024, 256);
demodWaterfallCanvas->setup(1024, 128);
demodWaterfallCanvas->setView(DEFAULT_FREQ, 300000);
demodWaterfallCanvas->attachSpectrumCanvas(demodSpectrumCanvas);
demodSpectrumCanvas->attachWaterfallCanvas(demodWaterfallCanvas);
demodVisuals->Add(demodWaterfallCanvas, 3, wxEXPAND | wxALL, 0);
demodVisuals->Add(demodWaterfallCanvas, 6, wxEXPAND | wxALL, 0);
demodTray->Add(demodVisuals, 30, wxEXPAND | wxALL, 0);
@ -86,17 +86,17 @@ AppFrame::AppFrame() :
demodTray->Add(demodScopeTray, 30, wxEXPAND | wxALL, 0);
vbox->Add(demodTray, 2, wxEXPAND | wxALL, 0);
vbox->Add(demodTray, 12, wxEXPAND | wxALL, 0);
vbox->AddSpacer(2);
spectrumCanvas = new SpectrumCanvas(this, NULL);
spectrumCanvas->setup(2048);
vbox->Add(spectrumCanvas, 1, wxEXPAND | wxALL, 0);
vbox->Add(spectrumCanvas, 5, wxEXPAND | wxALL, 0);
vbox->AddSpacer(2);
waterfallCanvas = new WaterfallCanvas(this, NULL);
waterfallCanvas->setup(2048, 512);
waterfallCanvas->attachSpectrumCanvas(spectrumCanvas);
spectrumCanvas->attachWaterfallCanvas(waterfallCanvas);
vbox->Add(waterfallCanvas, 4, wxEXPAND | wxALL, 0);
vbox->Add(waterfallCanvas, 20, wxEXPAND | wxALL, 0);
this->SetSizer(vbox);
@ -171,8 +171,10 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
activeDemodulator = NULL;
}
} else if (event.GetId() == wxID_SET_FREQ_OFFSET) {
long ofs = wxGetNumberFromUser ("Shift the displayed frequency by this amount.\ni.e. -125000000 for -125 MHz", "Frequency (Hz)", "Frequency Offset", 0, -2000000000, 2000000000, this);
wxGetApp().setOffset(ofs);
long ofs = wxGetNumberFromUser ("Shift the displayed frequency by this amount.\ni.e. -125000000 for -125 MHz", "Frequency (Hz)", "Frequency Offset", wxGetApp().getOffset(), -2000000000, 2000000000, this);
if (ofs != -1) {
wxGetApp().setOffset(ofs);
}
}
}

View File

@ -250,8 +250,8 @@ int DemodulatorInstance::getBandwidth() {
}
void DemodulatorInstance::setFrequency(long long freq) {
if ((freq - getBandwidth()/2) < SRATE/2) {
freq = SRATE/2 - getBandwidth()/2;
if ((freq - getBandwidth()/2) <= 0) {
freq = getBandwidth()/2;
}
if (demodulatorPreThread && threadQueueCommand) {
DemodulatorThreadCommand command;

View File

@ -118,7 +118,23 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, float r, float
float ofs = ((float) demod->getBandwidth()) / (float) srate;
float labelHeight = 20.0 / viewHeight;
float hPos = -1.0 + labelHeight;
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0, 0, 0, 0.35);
glBegin(GL_QUADS);
glVertex3f(uxPos - ofs, hPos + labelHeight, 0.0);
glVertex3f(uxPos - ofs, -1.0, 0.0);
glVertex3f(uxPos + ofs, -1.0, 0.0);
glVertex3f(uxPos + ofs, hPos + labelHeight, 0.0);
glEnd();
glBlendFunc(GL_SRC_ALPHA, GL_DST_COLOR);
glColor4f(r, g, b, 0.2);
glBegin(GL_QUADS);
glVertex3f(uxPos - ofs, 1.0, 0.0);
@ -128,9 +144,7 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, float r, float
glVertex3f(uxPos + ofs, 1.0, 0.0);
glEnd();
float labelHeight = 20.0 / viewHeight;
float hPos = -1.0 + labelHeight;
if (ofs * 2.0 < 16.0 / viewWidth) {
ofs = 16.0 / viewWidth;

View File

@ -47,15 +47,15 @@ void SpectrumCanvas::setup(int fft_size_in) {
if (in) {
free(in);
}
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fft_size);
in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fft_size);
if (out) {
free(out);
}
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fft_size);
out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fft_size);
if (plan) {
fftw_destroy_plan(plan);
fftwf_destroy_plan(plan);
}
plan = fftw_plan_dft_1d(fft_size, in, out, FFTW_FORWARD, FFTW_MEASURE);
plan = fftwf_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;
@ -107,9 +107,9 @@ void SpectrumCanvas::setData(DemodulatorThreadIQData *input) {
in[i][1] = (*data)[i].imag;
}
fftw_execute(plan);
fftwf_execute(plan);
double fft_ceil = 0, fft_floor = 1;
float fft_ceil = 0, fft_floor = 1;
if (fft_result.size() != fft_size) {
if (fft_result.capacity() < fft_size) {
@ -125,13 +125,13 @@ void SpectrumCanvas::setData(DemodulatorThreadIQData *input) {
int n;
for (int i = 0, iMax = fft_size / 2; i < iMax; i++) {
n = (i == 0) ? 1 : i;
double a = out[n][0];
double b = out[n][1];
double c = sqrt(a * a + b * b);
float a = out[n][0];
float b = out[n][1];
float c = sqrt(a * a + b * b);
double x = out[fft_size / 2 + n][0];
double y = out[fft_size / 2 + n][1];
double z = sqrt(x * x + y * y);
float x = out[fft_size / 2 + n][0];
float y = out[fft_size / 2 + n][1];
float z = sqrt(x * x + y * y);
fft_result[i] = (z);
fft_result[fft_size / 2 + i] = (c);
@ -158,7 +158,7 @@ void SpectrumCanvas::setData(DemodulatorThreadIQData *input) {
fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.01;
fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.01;
// fftw_execute(plan[1]);
// fftwf_execute(plan[1]);
for (int i = 0, iMax = fft_size; i < iMax; i++) {
float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa));
@ -182,7 +182,13 @@ void SpectrumCanvas::OnMouseMoved(wxMouseEvent& event) {
long long freq = wxGetApp().getFrequency();
if (isView) {
centerFreq = centerFreq - freqChange;
if (isView) {
if (centerFreq - freqChange < bandwidth/2) {
centerFreq = bandwidth/2;
} else {
centerFreq -= freqChange;
}
}
if (waterfallCanvas) {
waterfallCanvas->setCenterFrequency(centerFreq);
}

View File

@ -36,15 +36,15 @@ private:
void OnMouseReleased(wxMouseEvent& event);
void OnMouseLeftWindow(wxMouseEvent& event);
fftw_complex *in, *out;
fftw_plan plan;
fftwf_complex *in, *out;
fftwf_plan plan;
double fft_ceil_ma, fft_ceil_maa;
double fft_floor_ma, fft_floor_maa;
float fft_ceil_ma, fft_ceil_maa;
float fft_floor_ma, fft_floor_maa;
std::vector<double> fft_result;
std::vector<double> fft_result_ma;
std::vector<double> fft_result_maa;
std::vector<float> fft_result;
std::vector<float> fft_result_ma;
std::vector<float> fft_result_maa;
SpectrumContext *glContext;
WaterfallCanvas *waterfallCanvas;

View File

@ -62,15 +62,15 @@ void WaterfallCanvas::setup(int fft_size_in, int waterfall_lines_in) {
if (in) {
free(in);
}
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fft_size);
in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fft_size);
if (out) {
free(out);
}
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fft_size);
out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fft_size);
if (plan) {
fftw_destroy_plan(plan);
fftwf_destroy_plan(plan);
}
plan = fftw_plan_dft_1d(fft_size, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
plan = fftwf_plan_dft_1d(fft_size, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
glContext->Setup(fft_size, waterfall_lines);
}
@ -195,6 +195,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
long long freq;
long long originalFreq;
unsigned int bw;
switch (event.GetKeyCode()) {
case 'A':
@ -205,10 +206,11 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
break;
case WXK_RIGHT:
freq = wxGetApp().getFrequency();
originalFreq = freq;
if (shiftDown) {
freq += SRATE * 10;
if (isView) {
setView(centerFreq + SRATE * 10, getBandwidth());
setView(centerFreq + (freq - originalFreq), getBandwidth());
if (spectrumCanvas) {
spectrumCanvas->setView(getCenterFrequency(), getBandwidth());
}
@ -216,7 +218,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
} else {
freq += SRATE / 2;
if (isView) {
setView(centerFreq + SRATE / 2, getBandwidth());
setView(centerFreq + (freq - originalFreq), getBandwidth());
if (spectrumCanvas) {
spectrumCanvas->setView(getCenterFrequency(), getBandwidth());
}
@ -227,6 +229,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
break;
case WXK_LEFT:
freq = wxGetApp().getFrequency();
originalFreq = freq;
if (shiftDown) {
if ((freq - SRATE * 10) < SRATE / 2) {
freq = SRATE / 2;
@ -234,7 +237,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
freq -= SRATE * 10;
}
if (isView) {
setView(centerFreq - SRATE * 10, getBandwidth());
setView(centerFreq + (freq - originalFreq), getBandwidth());
if (spectrumCanvas) {
spectrumCanvas->setView(getCenterFrequency(), getBandwidth());
}
@ -246,7 +249,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
freq -= SRATE / 2;
}
if (isView) {
setView(centerFreq - SRATE / 2, getBandwidth());
setView(centerFreq + (freq - originalFreq), getBandwidth());
if (spectrumCanvas) {
spectrumCanvas->setView(getCenterFrequency(), getBandwidth());
}
@ -309,8 +312,8 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
centerFreq = getCenterFrequency();
bw = getBandwidth();
bw = (long long) ceil((long double) bw * currentZoom);
if (bw < 80000) {
bw = 80000;
if (bw < 100000) {
bw = 100000;
}
if (mouseTracker.mouseInView()) {
long long mfreqA = getFrequencyAt(mouseTracker.getMouseX());
@ -464,9 +467,9 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
}
}
fftw_execute(plan);
fftwf_execute(plan);
double fft_ceil = 0, fft_floor = 1;
float fft_ceil = 0, fft_floor = 1;
if (fft_result.size() < fft_size) {
fft_result.resize(fft_size);
@ -477,13 +480,13 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
int n;
for (int i = 0, iMax = fft_size / 2; i < iMax; i++) {
n = (i == 0) ? 1 : i;
double a = out[n][0];
double b = out[n][1];
double c = sqrt(a * a + b * b);
float a = out[n][0];
float b = out[n][1];
float c = sqrt(a * a + b * b);
double x = out[fft_size / 2 + n][0];
double y = out[fft_size / 2 + n][1];
double z = sqrt(x * x + y * y);
float x = out[fft_size / 2 + n][0];
float y = out[fft_size / 2 + n][1];
float z = sqrt(x * x + y * y);
fft_result[i] = (z);
fft_result[fft_size / 2 + i] = (c);
@ -491,8 +494,8 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
for (int i = 0, iMax = fft_size; i < iMax; i++) {
if (isView) {
fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.85;
fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.55;
fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65;
fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65;
} else {
fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65;
fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65;
@ -506,7 +509,7 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
}
}
fft_ceil += 1;
fft_ceil += 0.25;
fft_floor -= 1;
fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.05;
@ -516,7 +519,7 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.05;
for (int i = 0, iMax = fft_size; i < iMax; i++) {
double v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa));
float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa));
spectrum_points[i * 2] = ((float) i / (float) iMax);
spectrum_points[i * 2 + 1] = v;
}

View File

@ -49,15 +49,15 @@ private:
SpectrumCanvas *spectrumCanvas;
std::vector<float> spectrum_points;
fftw_complex *in, *out;
fftw_plan plan;
fftwf_complex *in, *out;
fftwf_plan plan;
double fft_ceil_ma, fft_ceil_maa;
double fft_floor_ma, fft_floor_maa;
float fft_ceil_ma, fft_ceil_maa;
float fft_floor_ma, fft_floor_maa;
std::vector<double> fft_result;
std::vector<double> fft_result_ma;
std::vector<double> fft_result_maa;
std::vector<float> fft_result;
std::vector<float> fft_result_ma;
std::vector<float> fft_result_maa;
WaterfallContext *glContext;