mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-01-13 03:37:10 +01:00
Added SNR meter
This commit is contained in:
parent
3e79d4dfad
commit
96f83ee55c
@ -32,6 +32,7 @@
|
|||||||
#include <gui/dialogs/loading_screen.h>
|
#include <gui/dialogs/loading_screen.h>
|
||||||
#include <options.h>
|
#include <options.h>
|
||||||
#include <gui/colormaps.h>
|
#include <gui/colormaps.h>
|
||||||
|
#include <gui/widgets/snr_meter.h>
|
||||||
|
|
||||||
int fftSize = 8192 * 8;
|
int fftSize = 8192 * 8;
|
||||||
|
|
||||||
@ -103,6 +104,8 @@ bool centerTuning = false;
|
|||||||
dsp::stream<dsp::complex_t> dummyStream;
|
dsp::stream<dsp::complex_t> dummyStream;
|
||||||
bool demoWindow = false;
|
bool demoWindow = false;
|
||||||
|
|
||||||
|
float testSNR = 50;
|
||||||
|
|
||||||
void windowInit() {
|
void windowInit() {
|
||||||
LoadingScreen::show("Initializing UI");
|
LoadingScreen::show("Initializing UI");
|
||||||
gui::waterfall.init();
|
gui::waterfall.init();
|
||||||
@ -515,6 +518,13 @@ void drawWindow() {
|
|||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - 387);
|
||||||
|
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5);
|
||||||
|
ImGui::SetNextItemWidth(300);
|
||||||
|
ImGui::SNRMeter((vfo != NULL) ? gui::waterfall.selectedVFOSNR : 0);
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
// Logo button
|
// Logo button
|
||||||
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - 48);
|
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - 48);
|
||||||
ImGui::SetCursorPosY(10);
|
ImGui::SetCursorPosY(10);
|
||||||
@ -604,6 +614,8 @@ void drawWindow() {
|
|||||||
firstMenuRender = true;
|
firstMenuRender = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::SliderFloat("Testing SNR meter", &testSNR, 0, 100);
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
core/src/gui/widgets/snr_meter.cpp
Normal file
43
core/src/gui/widgets/snr_meter.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include <gui/widgets/volume_meter.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#endif
|
||||||
|
#include <imgui/imgui_internal.h>
|
||||||
|
|
||||||
|
namespace ImGui {
|
||||||
|
void SNRMeter(float val, const ImVec2& size_arg = ImVec2(0, 0)) {
|
||||||
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
ImGuiStyle& style = GImGui->Style;
|
||||||
|
|
||||||
|
float pad = style.FramePadding.y;
|
||||||
|
|
||||||
|
ImVec2 min = window->DC.CursorPos;
|
||||||
|
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), 26);
|
||||||
|
ImRect bb(min, min + size);
|
||||||
|
|
||||||
|
float lineHeight = size.y;
|
||||||
|
|
||||||
|
ItemSize(size, style.FramePadding.y);
|
||||||
|
if (!ItemAdd(bb, 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = std::clamp<float>(val, 0, 100);
|
||||||
|
float ratio = size.x / 90;
|
||||||
|
float it = size.x / 9;
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
window->DrawList->AddRectFilled(min + ImVec2(0, 1), min + ImVec2(roundf((float)val * ratio), 10), IM_COL32(0, 136, 255, 255));
|
||||||
|
window->DrawList->AddLine(min, min + ImVec2(0, 9), IM_COL32(255, 255, 255, 255));
|
||||||
|
window->DrawList->AddLine(min + ImVec2(0, 9), min + ImVec2(size.x + 1, 9), IM_COL32(255, 255, 255, 255));
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
window->DrawList->AddLine(min + ImVec2(roundf((float)i * it), 9), min + ImVec2(roundf((float)i * it), 14), IM_COL32(255, 255, 255, 255));
|
||||||
|
sprintf(buf, "%d", i * 10);
|
||||||
|
ImVec2 sz = ImGui::CalcTextSize(buf);
|
||||||
|
window->DrawList->AddText(min + ImVec2(roundf(((float)i * it) - (sz.x/2.0)) + 1, 16), IM_COL32(255, 255, 255, 255), buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
core/src/gui/widgets/snr_meter.h
Normal file
6
core/src/gui/widgets/snr_meter.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
|
namespace ImGui {
|
||||||
|
void SNRMeter(float val, const ImVec2& size_arg = ImVec2(0, 0));
|
||||||
|
}
|
@ -288,10 +288,6 @@ namespace ImGui {
|
|||||||
// Next, check if a VFO was selected
|
// Next, check if a VFO was selected
|
||||||
if (!targetFound) {
|
if (!targetFound) {
|
||||||
for (auto const& [name, _vfo] : vfos) {
|
for (auto const& [name, _vfo] : vfos) {
|
||||||
if (name == selectedVFO) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If another VFO is selected, select it and cancel out
|
// If another VFO is selected, select it and cancel out
|
||||||
if (IS_IN_AREA(mousePos, _vfo->rectMin, _vfo->rectMax) || IS_IN_AREA(mousePos, _vfo->wfRectMin, _vfo->wfRectMax)) {
|
if (IS_IN_AREA(mousePos, _vfo->rectMin, _vfo->rectMax) || IS_IN_AREA(mousePos, _vfo->wfRectMin, _vfo->wfRectMax)) {
|
||||||
selectedVFO = name;
|
selectedVFO = name;
|
||||||
@ -436,6 +432,16 @@ namespace ImGui {
|
|||||||
printAndScale(_vfo->bandwidth, buf);
|
printAndScale(_vfo->bandwidth, buf);
|
||||||
ImGui::Text("Bandwidth: %sHz", buf);
|
ImGui::Text("Bandwidth: %sHz", buf);
|
||||||
ImGui::Text("Bandwidth Locked: %s", _vfo->bandwidthLocked ? "Yes" : "No");
|
ImGui::Text("Bandwidth Locked: %s", _vfo->bandwidthLocked ? "Yes" : "No");
|
||||||
|
|
||||||
|
float strength, snr;
|
||||||
|
if (calculateVFOSignalInfo(_vfo, strength, snr)) {
|
||||||
|
ImGui::Text("Strength: %0.1fdBFS", strength);
|
||||||
|
ImGui::Text("SNR: %0.1fdB", snr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ImGui::Text("Strength: ---.-dBFS");
|
||||||
|
ImGui::Text("SNR: ---.-dB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
@ -445,6 +451,50 @@ namespace ImGui {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WaterFall::calculateVFOSignalInfo(WaterfallVFO* _vfo, float& strength, float& snr) {
|
||||||
|
if (rawFFTs == NULL || fftLines <= 0) { return false; }
|
||||||
|
|
||||||
|
// Calculate FFT index data
|
||||||
|
double vfoMinSizeFreq = _vfo->centerOffset - _vfo->bandwidth;
|
||||||
|
double vfoMinFreq = _vfo->centerOffset - (_vfo->bandwidth/2.0);
|
||||||
|
double vfoMaxFreq = _vfo->centerOffset + (_vfo->bandwidth/2.0);
|
||||||
|
double vfoMaxSizeFreq = _vfo->centerOffset + _vfo->bandwidth;
|
||||||
|
int vfoMinSideOffset = std::clamp<int>(((vfoMinSizeFreq / (wholeBandwidth/2.0)) * (double)(rawFFTSize/2)) + (rawFFTSize/2), 0, rawFFTSize);
|
||||||
|
int vfoMinOffset = std::clamp<int>(((vfoMinFreq / (wholeBandwidth/2.0)) * (double)(rawFFTSize/2)) + (rawFFTSize/2), 0, rawFFTSize);
|
||||||
|
int vfoMaxOffset = std::clamp<int>(((vfoMaxFreq / (wholeBandwidth/2.0)) * (double)(rawFFTSize/2)) + (rawFFTSize/2), 0, rawFFTSize);
|
||||||
|
int vfoMaxSideOffset = std::clamp<int>(((vfoMaxSizeFreq / (wholeBandwidth/2.0)) * (double)(rawFFTSize/2)) + (rawFFTSize/2), 0, rawFFTSize);
|
||||||
|
|
||||||
|
float* fftLine = &rawFFTs[currentFFTLine * rawFFTSize];
|
||||||
|
|
||||||
|
double avg = 0;
|
||||||
|
float max = -INFINITY;
|
||||||
|
int avgCount = 0;
|
||||||
|
|
||||||
|
// Calculate Left average
|
||||||
|
for (int i = vfoMinSideOffset; i < vfoMinOffset; i++) {
|
||||||
|
avg += fftLine[i];
|
||||||
|
avgCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate Right average
|
||||||
|
for (int i = vfoMaxOffset + 1; i < vfoMaxSideOffset; i++) {
|
||||||
|
avg += fftLine[i];
|
||||||
|
avgCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
avg /= (double)(avgCount);
|
||||||
|
|
||||||
|
// Calculate max
|
||||||
|
for (int i = vfoMinOffset; i <= vfoMaxOffset; i++) {
|
||||||
|
if (fftLine[i] > max) { max = fftLine[i]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
strength = max;
|
||||||
|
snr = max - avg;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void WaterFall::setFastFFT(bool fastFFT) {
|
void WaterFall::setFastFFT(bool fastFFT) {
|
||||||
std::lock_guard<std::mutex> lck(buf_mtx);
|
std::lock_guard<std::mutex> lck(buf_mtx);
|
||||||
_fastFFT = fastFFT;
|
_fastFFT = fastFFT;
|
||||||
@ -749,6 +799,11 @@ namespace ImGui {
|
|||||||
fftLines = 1;
|
fftLines = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selectedVFO != "" && vfos.size() > 0) {
|
||||||
|
float dummy;
|
||||||
|
calculateVFOSignalInfo(vfos[selectedVFO], dummy, selectedVFOSNR);
|
||||||
|
}
|
||||||
|
|
||||||
buf_mtx.unlock();
|
buf_mtx.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,8 @@ namespace ImGui {
|
|||||||
bool mouseInFFT = false;
|
bool mouseInFFT = false;
|
||||||
bool mouseInWaterfall = false;
|
bool mouseInWaterfall = false;
|
||||||
|
|
||||||
|
float selectedVFOSNR = NAN;
|
||||||
|
|
||||||
std::map<std::string, WaterfallVFO*> vfos;
|
std::map<std::string, WaterfallVFO*> vfos;
|
||||||
std::string selectedVFO = "";
|
std::string selectedVFO = "";
|
||||||
bool selectedVFOChanged = false;
|
bool selectedVFOChanged = false;
|
||||||
@ -162,6 +164,7 @@ namespace ImGui {
|
|||||||
void updateWaterfallFb();
|
void updateWaterfallFb();
|
||||||
void updateWaterfallTexture();
|
void updateWaterfallTexture();
|
||||||
void updateAllVFOs();
|
void updateAllVFOs();
|
||||||
|
bool calculateVFOSignalInfo(WaterfallVFO* vfo, float& strength, float& snr);
|
||||||
|
|
||||||
bool waterfallUpdate = false;
|
bool waterfallUpdate = false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user