Bugfixed + performance improvements to the waterfall

pull/40/head
Ryzerth 2020-12-12 05:34:58 +01:00
rodzic 774663d70d
commit e3db19b16a
20 zmienionych plików z 122 dodań i 67 usunięć

3
.gitignore vendored
Wyświetl plik

@ -6,4 +6,5 @@ build/
*.zip
*.wav
.DS_Store
sdrpp_v0.2.5_beta_x64
sdrpp_v0.2.5_beta_x64
sdrpp_v0.2.5_beta_x64_new_wf

Wyświetl plik

@ -16,7 +16,7 @@ add_subdirectory("plutosdr_source")
#add_subdirectory("demo")
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17")
endif (MSVC)

Wyświetl plik

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)
project(audio_sink)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)

Wyświetl plik

@ -3,7 +3,7 @@ project(sdrpp_core)
# Set compiler options
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
else()
set(CMAKE_CXX_FLAGS "-g -O3 -std=c++17 -fpermissive")

Wyświetl plik

@ -8,11 +8,8 @@ using nlohmann::json;
#define DEV_BUILD
#define SDRPP_RESOURCE_DIR "/usr/local/"
#ifndef ROOT_DIR
#ifdef DEV_BUILD
#define ROOT_DIR "../root_dev"

Wyświetl plik

@ -79,7 +79,7 @@ int sdrpp_main() {
defConfig["bandColors"]["military"] = "#FFFF00FF";
defConfig["bandPlan"] = "General";
defConfig["bandPlanEnabled"] = true;
defConfig["centerTuning"] = true;
defConfig["centerTuning"] = false;
defConfig["fftHeight"] = 300;
defConfig["frequency"] = 100000000.0;
defConfig["max"] = 0.0;

Wyświetl plik

@ -35,12 +35,12 @@ std::thread worker;
std::mutex fft_mtx;
fftwf_complex *fft_in, *fft_out;
fftwf_plan p;
float* tempFFT;
float* FFTdata;
char buf[1024];
int fftSize = 8192 * 8;
std::vector<float> _data;
std::vector<float> fftTaps;
void fftHandler(dsp::complex_t* samples, int count, void* ctx) {
if (count < fftSize) {
return;
@ -49,19 +49,24 @@ void fftHandler(dsp::complex_t* samples, int count, void* ctx) {
fftwf_execute(p);
int half = fftSize / 2;
for (int i = 0; i < half; i++) {
_data.push_back(log10(std::abs(std::complex<float>(fft_out[half + i][0], fft_out[half + i][1])) / (float)fftSize) * 10.0);
}
for (int i = 0; i < half; i++) {
_data.push_back(log10(std::abs(std::complex<float>(fft_out[i][0], fft_out[i][1])) / (float)fftSize) * 10.0);
}
volk_32fc_s32f_power_spectrum_32f(tempFFT, (lv_32fc_t*)fft_out, fftSize, fftSize);
volk_32f_s32f_multiply_32f(FFTdata, tempFFT, 0.5f, fftSize);
for (int i = 5; i < fftSize; i++) {
_data[i] = (_data[i - 4] + _data[i - 3] + _data[i - 2] + _data[i - 1] + _data[i]) / 5.0;
}
memcpy(tempFFT, &FFTdata[half], half * sizeof(float));
memmove(&FFTdata[half], FFTdata, half * sizeof(float));
memcpy(FFTdata, tempFFT, half * sizeof(float));
gui::waterfall.pushFFT(_data, fftSize);
_data.clear();
float* fftBuf = gui::waterfall.getFFTBuffer();
if (fftBuf == NULL) {
gui::waterfall.pushFFT();
return;
}
float last = FFTdata[0];
for (int i = 0; i < fftSize; i++) {
last = (FFTdata[i] * 0.1f) + (last * 0.9f);
fftBuf[i] = last;
}
gui::waterfall.pushFFT();
}
watcher<uint64_t> freq((uint64_t)90500000);
@ -87,6 +92,10 @@ bool demoWindow = false;
void windowInit() {
LoadingScreen::show("Initializing UI");
gui::waterfall.init();
gui::waterfall.setRawFFTSize(fftSize);
tempFFT = new float[fftSize];
FFTdata = new float[fftSize];
credits::init();
@ -167,7 +176,6 @@ void windowInit() {
// TODO for 0.2.6
// Add a module add/remove/change order menu
// Change the way fft samples are stored to make it less CPU intensive
// Update UI settings
LoadingScreen::show("Loading configuration");

Wyświetl plik

@ -23,7 +23,7 @@ float COLOR_MAP[][3] = {
{0x4A, 0x00, 0x00}
};
void doZoom(int offset, int width, int outWidth, std::vector<float> data, float* out) {
void doZoom(int offset, int width, int outWidth, float* data, float* out) {
// NOTE: REMOVE THAT SHIT, IT'S JUST A HACKY FIX
if (offset < 0) {
offset = 0;
@ -34,7 +34,7 @@ void doZoom(int offset, int width, int outWidth, std::vector<float> data, float*
float factor = (float)width / (float)outWidth;
for (int i = 0; i < outWidth; i++) {
out[i] = data[offset + ((float)i * factor)];
out[i] = data[(int)(offset + ((float)i * factor))];
}
}
@ -281,7 +281,11 @@ namespace ImGui {
lowerFreq = (centerFreq + viewOffset) - (viewBandwidth / 2.0);
upperFreq = (centerFreq + viewOffset) + (viewBandwidth / 2.0);
updateWaterfallFb();
if (viewBandwidth != wholeBandwidth) {
updateAllVFOs();
updateWaterfallFb();
}
}
else {
lastDrag = 0;
@ -289,25 +293,26 @@ namespace ImGui {
}
void WaterFall::updateWaterfallFb() {
if (!waterfallVisible) {
if (!waterfallVisible || rawFFTs == NULL) {
return;
}
double offsetRatio = viewOffset / (wholeBandwidth / 2.0);
int drawDataSize;
int drawDataStart;
int count = std::min<int>(waterfallHeight, rawFFTs.size());
// TODO: Maybe put on the stack for faster alloc?
float* tempData = new float[dataWidth];
float pixel;
float dataRange = waterfallMax - waterfallMin;
int size;
for (int i = 0; i < count; i++) {
size = rawFFTs[i].size();
drawDataSize = (viewBandwidth / wholeBandwidth) * size;
drawDataStart = (((double)size / 2.0) * (offsetRatio + 1)) - (drawDataSize / 2);
doZoom(drawDataStart, drawDataSize, dataWidth, rawFFTs[i], tempData);
for (int j = 0; j < dataWidth; j++) {
pixel = (std::clamp<float>(tempData[j], waterfallMin, waterfallMax) - waterfallMin) / dataRange;
waterfallFb[(i * dataWidth) + j] = waterfallPallet[(int)(pixel * (WATERFALL_RESOLUTION - 1))];
int count = std::min<float>(waterfallHeight, fftLines);
if (rawFFTs != NULL) {
for (int i = 0; i < count; i++) {
drawDataSize = (viewBandwidth / wholeBandwidth) * rawFFTSize;
drawDataStart = (((double)rawFFTSize / 2.0) * (offsetRatio + 1)) - (drawDataSize / 2);
doZoom(drawDataStart, drawDataSize, dataWidth, &rawFFTs[((i + currentFFTLine) % waterfallHeight) * rawFFTSize], tempData);
for (int j = 0; j < dataWidth; j++) {
pixel = (std::clamp<float>(tempData[j], waterfallMin, waterfallMax) - waterfallMin) / dataRange;
waterfallFb[(i * dataWidth) + j] = waterfallPallet[(int)(pixel * (WATERFALL_RESOLUTION - 1))];
}
}
}
delete[] tempData;
@ -391,6 +396,8 @@ namespace ImGui {
return;
}
int lastWaterfallHeight = waterfallHeight;
if (waterfallVisible) {
FFTAreaHeight = std::min<int>(FFTAreaHeight, widgetSize.y - 50);
fftHeight = FFTAreaHeight - 50;
@ -402,12 +409,28 @@ namespace ImGui {
dataWidth = widgetSize.x - 60.0;
delete[] latestFFT;
if (waterfallVisible) {
delete[] waterfallFb;
// Raw FFT resize
fftLines = std::min<int>(fftLines, waterfallHeight);
if (rawFFTs != NULL) {
if (currentFFTLine != 0) {
float* tempWF = new float[currentFFTLine * rawFFTSize];
int moveCount = lastWaterfallHeight - currentFFTLine;
memcpy(tempWF, rawFFTs, currentFFTLine * rawFFTSize * sizeof(float));
memmove(rawFFTs, &rawFFTs[currentFFTLine * rawFFTSize], moveCount * rawFFTSize * sizeof(float));
memcpy(&rawFFTs[moveCount * rawFFTSize], tempWF, currentFFTLine * rawFFTSize * sizeof(float));
delete[] tempWF;
}
currentFFTLine = 0;
rawFFTs = (float*)realloc(rawFFTs, waterfallHeight * rawFFTSize * sizeof(float));
}
else {
rawFFTs = (float*)malloc(waterfallHeight * rawFFTSize * sizeof(float));
}
// ==============
latestFFT = new float[dataWidth];
if (waterfallVisible) {
delete[] waterfallFb;
waterfallFb = new uint32_t[dataWidth * waterfallHeight];
memset(waterfallFb, 0, dataWidth * waterfallHeight * sizeof(uint32_t));
}
@ -504,17 +527,23 @@ namespace ImGui {
buf_mtx.unlock();
}
void WaterFall::pushFFT(std::vector<float> data, int n) {
float* WaterFall::getFFTBuffer() {
if (rawFFTs == NULL) { return NULL; }
buf_mtx.lock();
currentFFTLine--;
fftLines++;
currentFFTLine = ((currentFFTLine + waterfallHeight) % waterfallHeight);
fftLines = std::min<float>(fftLines, waterfallHeight);
return &rawFFTs[currentFFTLine * rawFFTSize];
}
void WaterFall::pushFFT() {
if (rawFFTs == NULL) { return; }
double offsetRatio = viewOffset / (wholeBandwidth / 2.0);
int drawDataSize = (viewBandwidth / wholeBandwidth) * data.size();
int drawDataStart = (((double)data.size() / 2.0) * (offsetRatio + 1)) - (drawDataSize / 2);
int drawDataSize = (viewBandwidth / wholeBandwidth) * rawFFTSize;
int drawDataStart = (((double)rawFFTSize / 2.0) * (offsetRatio + 1)) - (drawDataSize / 2);
doZoom(drawDataStart, drawDataSize, dataWidth, data, latestFFT);
rawFFTs.insert(rawFFTs.begin(), data);
if (rawFFTs.size() > waterfallHeight + 300) {
rawFFTs.resize(waterfallHeight);
}
doZoom(drawDataStart, drawDataSize, dataWidth, &rawFFTs[currentFFTLine * rawFFTSize], latestFFT);
if (waterfallVisible) {
memmove(&waterfallFb[dataWidth], waterfallFb, dataWidth * (waterfallHeight - 1) * sizeof(uint32_t));
@ -683,6 +712,19 @@ namespace ImGui {
}
}
void WaterFall::setRawFFTSize(int size, bool lock) {
if (lock) { buf_mtx.lock(); }
rawFFTSize = size;
if (rawFFTs != NULL) {
rawFFTs = (float*)realloc(rawFFTs, rawFFTSize * waterfallHeight * sizeof(float));
}
else {
rawFFTs = (float*)malloc(rawFFTSize * waterfallHeight * sizeof(float));
}
memset(rawFFTs, 0, rawFFTSize * waterfallHeight * sizeof(float));
if (lock) { buf_mtx.unlock(); }
}
void WaterfallVFO::setOffset(double offset) {
generalOffset = offset;
if (reference == REF_CENTER) {

Wyświetl plik

@ -53,7 +53,8 @@ namespace ImGui {
void init();
void draw();
void pushFFT(std::vector<float> data, int n);
float* getFFTBuffer();
void pushFFT();
void updatePallette(float colors[][3], int colorCount);
@ -97,6 +98,8 @@ namespace ImGui {
void setFFTHeight(int height);
int getFFTHeight();
void setRawFFTSize(int size, bool lock = true);
bool centerFreqMoved = false;
bool vfoFreqChanged = false;
bool bandplanEnabled = false;
@ -155,9 +158,9 @@ namespace ImGui {
int maxVSteps;
int maxHSteps;
int dataWidth; // Width of the FFT and waterfall
int fftHeight; // Height of the fft graph
int waterfallHeight; // Height of the waterfall
int dataWidth; // Width of the FFT and waterfall
int fftHeight; // Height of the fft graph
int waterfallHeight = 0; // Height of the waterfall
double viewBandwidth;
double viewOffset;
@ -180,8 +183,12 @@ namespace ImGui {
float waterfallMin;
float waterfallMax;
std::vector<std::vector<float>> rawFFTs;
//std::vector<std::vector<float>> rawFFTs;
int rawFFTSize;
float* rawFFTs = NULL;
float* latestFFT;
int currentFFTLine = 0;
int fftLines = 0;
uint32_t* waterfallFb;

Wyświetl plik

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)
project(demo)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)

Wyświetl plik

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)
project(file_source)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)

Wyświetl plik

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)
project(plutosdr_source)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)

Wyświetl plik

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)
project(radio)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)

Wyświetl plik

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)
project(recorder)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)

Wyświetl plik

@ -3,7 +3,7 @@
"bandPlanEnabled": true,
"centerTuning": false,
"fftHeight": 300,
"frequency": 103600000,
"frequency": 99000000,
"max": 0.0,
"maximized": false,
"menuOrder": [
@ -17,7 +17,7 @@
"Display"
],
"menuWidth": 300,
"min": -66.17647552490234,
"min": -55.147056579589844,
"moduleInstances": {
"Audio Sink": "audio_sink",
"PlutoSDR Source": "plutosdr_source",
@ -36,12 +36,12 @@
],
"offset": 0.0,
"showWaterfall": true,
"source": "PlutoSDR",
"source": "SoapySDR",
"streams": {
"Radio": {
"muted": false,
"sink": "Audio",
"volume": 0.6785714030265808
"volume": 0.545918345451355
},
"Radio 1": {
"muted": false,

Wyświetl plik

@ -1,5 +1,5 @@
{
"device": "AirSpy HF+ [c852435de0224af7]",
"device": "HackRF One #0 901868dc282c8f8b",
"devices": {
"": {
"agc": false,
@ -32,10 +32,10 @@
"HackRF One #0 901868dc282c8f8b": {
"gains": {
"AMP": 0.0,
"LNA": 23.415000915527344,
"LNA": 24.503000259399414,
"VGA": 16.332000732421875
},
"sampleRate": 8000000.0
"sampleRate": 2000000.0
},
"Microphone (Realtek High Definition Audio)": {
"sampleRate": 96000.0

Wyświetl plik

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)
project(rtl_tcp_source)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)

Wyświetl plik

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)
project(rx888_source)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)

Wyświetl plik

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)
project(soapy_source)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)

Wyświetl plik

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)
project(soapy)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)