commit no. 7
This commit is contained in:
@@ -13,16 +13,44 @@ static double binToFreqHelper(int bin, double sampleRate, bool isIQ, int fftSize
|
||||
}
|
||||
}
|
||||
|
||||
void Cursors::pushAvg(AvgState& st, float dB, int bin) const {
|
||||
// Reset if cursor moved to a different bin or averaging was reduced.
|
||||
if (bin != st.lastBin) {
|
||||
st.samples.clear();
|
||||
st.sum = 0.0;
|
||||
st.lastBin = bin;
|
||||
}
|
||||
st.samples.push_back(dB);
|
||||
st.sum += dB;
|
||||
int maxN = std::max(1, avgCount);
|
||||
while (static_cast<int>(st.samples.size()) > maxN) {
|
||||
st.sum -= st.samples.front();
|
||||
st.samples.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
float Cursors::avgDBA() const {
|
||||
return avgA_.samples.empty() ? cursorA.dB
|
||||
: static_cast<float>(avgA_.sum / avgA_.samples.size());
|
||||
}
|
||||
|
||||
float Cursors::avgDBB() const {
|
||||
return avgB_.samples.empty() ? cursorB.dB
|
||||
: static_cast<float>(avgB_.sum / avgB_.samples.size());
|
||||
}
|
||||
|
||||
void Cursors::update(const std::vector<float>& spectrumDB,
|
||||
double sampleRate, bool isIQ, int fftSize) {
|
||||
// Update dB values at cursor bin positions
|
||||
if (cursorA.active && cursorA.bin >= 0 &&
|
||||
cursorA.bin < static_cast<int>(spectrumDB.size())) {
|
||||
cursorA.dB = spectrumDB[cursorA.bin];
|
||||
pushAvg(avgA_, cursorA.dB, cursorA.bin);
|
||||
}
|
||||
if (cursorB.active && cursorB.bin >= 0 &&
|
||||
cursorB.bin < static_cast<int>(spectrumDB.size())) {
|
||||
cursorB.dB = spectrumDB[cursorB.bin];
|
||||
pushAvg(avgB_, cursorB.dB, cursorB.bin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,12 +61,12 @@ void Cursors::draw(const SpectrumDisplay& specDisplay,
|
||||
float viewLo, float viewHi) const {
|
||||
ImDrawList* dl = ImGui::GetWindowDrawList();
|
||||
|
||||
auto drawCursor = [&](const CursorInfo& c, ImU32 color, const char* label) {
|
||||
auto drawCursor = [&](const CursorInfo& c, float dispDB, ImU32 color, const char* label) {
|
||||
if (!c.active) return;
|
||||
float x = specDisplay.freqToScreenX(c.freq, posX, sizeX,
|
||||
sampleRate, isIQ, freqScale,
|
||||
viewLo, viewHi);
|
||||
float dbNorm = (c.dB - minDB) / (maxDB - minDB);
|
||||
float dbNorm = (dispDB - minDB) / (maxDB - minDB);
|
||||
dbNorm = std::clamp(dbNorm, 0.0f, 1.0f);
|
||||
float y = posY + sizeY * (1.0f - dbNorm);
|
||||
|
||||
@@ -53,13 +81,13 @@ void Cursors::draw(const SpectrumDisplay& specDisplay,
|
||||
char buf[128];
|
||||
if (std::abs(c.freq) >= 1e6)
|
||||
std::snprintf(buf, sizeof(buf), "%s: %.6f MHz %.1f dB",
|
||||
label, c.freq / 1e6, c.dB);
|
||||
label, c.freq / 1e6, dispDB);
|
||||
else if (std::abs(c.freq) >= 1e3)
|
||||
std::snprintf(buf, sizeof(buf), "%s: %.3f kHz %.1f dB",
|
||||
label, c.freq / 1e3, c.dB);
|
||||
label, c.freq / 1e3, dispDB);
|
||||
else
|
||||
std::snprintf(buf, sizeof(buf), "%s: %.1f Hz %.1f dB",
|
||||
label, c.freq, c.dB);
|
||||
label, c.freq, dispDB);
|
||||
|
||||
ImVec2 textSize = ImGui::CalcTextSize(buf);
|
||||
float tx = std::min(x + 8, posX + sizeX - textSize.x - 4);
|
||||
@@ -69,76 +97,86 @@ void Cursors::draw(const SpectrumDisplay& specDisplay,
|
||||
dl->AddText({tx, ty}, color, buf);
|
||||
};
|
||||
|
||||
drawCursor(cursorA, IM_COL32(255, 255, 0, 220), "A");
|
||||
drawCursor(cursorB, IM_COL32(0, 200, 255, 220), "B");
|
||||
float aDB = avgDBA(), bDB = avgDBB();
|
||||
drawCursor(cursorA, aDB, IM_COL32(255, 255, 0, 220), "A");
|
||||
drawCursor(cursorB, bDB, IM_COL32(0, 200, 255, 220), "B");
|
||||
|
||||
// Delta display
|
||||
// Delta display (two lines, column-aligned on '=')
|
||||
if (showDelta && cursorA.active && cursorB.active) {
|
||||
double dFreq = cursorB.freq - cursorA.freq;
|
||||
float dDB = cursorB.dB - cursorA.dB;
|
||||
char buf[128];
|
||||
float dDB = bDB - aDB;
|
||||
char val1[48], val2[48];
|
||||
if (std::abs(dFreq) >= 1e6)
|
||||
std::snprintf(buf, sizeof(buf), "dF=%.6f MHz dA=%.1f dB",
|
||||
dFreq / 1e6, dDB);
|
||||
std::snprintf(val1, sizeof(val1), "%.6f MHz", dFreq / 1e6);
|
||||
else if (std::abs(dFreq) >= 1e3)
|
||||
std::snprintf(buf, sizeof(buf), "dF=%.3f kHz dA=%.1f dB",
|
||||
dFreq / 1e3, dDB);
|
||||
std::snprintf(val1, sizeof(val1), "%.3f kHz", dFreq / 1e3);
|
||||
else
|
||||
std::snprintf(buf, sizeof(buf), "dF=%.1f Hz dA=%.1f dB",
|
||||
dFreq, dDB);
|
||||
std::snprintf(val1, sizeof(val1), "%.1f Hz", dFreq);
|
||||
std::snprintf(val2, sizeof(val2), "%.1f dB", dDB);
|
||||
|
||||
ImVec2 textSize = ImGui::CalcTextSize(buf);
|
||||
float tx = posX + sizeX - textSize.x - 8;
|
||||
ImVec2 labelSz = ImGui::CalcTextSize("dF = ");
|
||||
ImVec2 v1Sz = ImGui::CalcTextSize(val1);
|
||||
ImVec2 v2Sz = ImGui::CalcTextSize(val2);
|
||||
float valW = std::max(v1Sz.x, v2Sz.x);
|
||||
float lineH = labelSz.y;
|
||||
float totalW = labelSz.x + valW;
|
||||
float tx = posX + sizeX - totalW - 8;
|
||||
float ty = posY + 4;
|
||||
dl->AddRectFilled({tx - 4, ty - 2}, {tx + textSize.x + 4, ty + textSize.y + 2},
|
||||
IM_COL32(0, 0, 0, 200));
|
||||
dl->AddText({tx, ty}, IM_COL32(255, 200, 100, 255), buf);
|
||||
ImU32 col = IM_COL32(255, 200, 100, 255);
|
||||
float eqX = tx + labelSz.x; // values start here (right of '= ')
|
||||
|
||||
dl->AddText({tx, ty}, col, "dF =");
|
||||
dl->AddText({eqX + valW - v1Sz.x, ty}, col, val1);
|
||||
dl->AddText({tx, ty + lineH + 2}, col, "dA =");
|
||||
dl->AddText({eqX + valW - v2Sz.x, ty + lineH + 2}, col, val2);
|
||||
}
|
||||
|
||||
// (Hover cursor line is drawn cross-panel by Application.)
|
||||
}
|
||||
|
||||
void Cursors::drawPanel() const {
|
||||
ImGui::Text("Cursors:");
|
||||
ImGui::Separator();
|
||||
|
||||
auto showCursor = [](const char* label, const CursorInfo& c) {
|
||||
void Cursors::drawPanel() {
|
||||
auto showCursor = [](const char* label, const CursorInfo& c, float dispDB) {
|
||||
if (!c.active) {
|
||||
ImGui::Text("%s: (inactive)", label);
|
||||
ImGui::TextDisabled("%s: --", label);
|
||||
return;
|
||||
}
|
||||
if (std::abs(c.freq) >= 1e6)
|
||||
ImGui::Text("%s: %.6f MHz, %.1f dB", label, c.freq / 1e6, c.dB);
|
||||
ImGui::Text("%s: %.6f MHz, %.1f dB", label, c.freq / 1e6, dispDB);
|
||||
else if (std::abs(c.freq) >= 1e3)
|
||||
ImGui::Text("%s: %.3f kHz, %.1f dB", label, c.freq / 1e3, c.dB);
|
||||
ImGui::Text("%s: %.3f kHz, %.1f dB", label, c.freq / 1e3, dispDB);
|
||||
else
|
||||
ImGui::Text("%s: %.1f Hz, %.1f dB", label, c.freq, c.dB);
|
||||
ImGui::Text("%s: %.1f Hz, %.1f dB", label, c.freq, dispDB);
|
||||
};
|
||||
|
||||
showCursor("A", cursorA);
|
||||
showCursor("B", cursorB);
|
||||
float aDB = avgDBA(), bDB = avgDBB();
|
||||
showCursor("A", cursorA, aDB);
|
||||
showCursor("B", cursorB, bDB);
|
||||
|
||||
if (cursorA.active && cursorB.active) {
|
||||
double dF = cursorB.freq - cursorA.freq;
|
||||
float dA = cursorB.dB - cursorA.dB;
|
||||
ImGui::Separator();
|
||||
float dA = bDB - aDB;
|
||||
if (std::abs(dF) >= 1e6)
|
||||
ImGui::Text("Delta: %.6f MHz, %.1f dB", dF / 1e6, dA);
|
||||
ImGui::Text("D: %.6f MHz, %.1f dB", dF / 1e6, dA);
|
||||
else if (std::abs(dF) >= 1e3)
|
||||
ImGui::Text("Delta: %.3f kHz, %.1f dB", dF / 1e3, dA);
|
||||
ImGui::Text("D: %.3f kHz, %.1f dB", dF / 1e3, dA);
|
||||
else
|
||||
ImGui::Text("Delta: %.1f Hz, %.1f dB", dF, dA);
|
||||
ImGui::Text("D: %.1f Hz, %.1f dB", dF, dA);
|
||||
}
|
||||
|
||||
if (hover.active) {
|
||||
ImGui::Separator();
|
||||
if (std::abs(hover.freq) >= 1e6)
|
||||
ImGui::Text("Hover: %.6f MHz, %.1f dB", hover.freq / 1e6, hover.dB);
|
||||
ImGui::TextDisabled("%.6f MHz, %.1f dB", hover.freq / 1e6, hover.dB);
|
||||
else if (std::abs(hover.freq) >= 1e3)
|
||||
ImGui::Text("Hover: %.3f kHz, %.1f dB", hover.freq / 1e3, hover.dB);
|
||||
ImGui::TextDisabled("%.3f kHz, %.1f dB", hover.freq / 1e3, hover.dB);
|
||||
else
|
||||
ImGui::Text("Hover: %.1f Hz, %.1f dB", hover.freq, hover.dB);
|
||||
ImGui::TextDisabled("%.1f Hz, %.1f dB", hover.freq, hover.dB);
|
||||
}
|
||||
|
||||
// Averaging slider (logarithmic scale)
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
ImGui::SliderInt("##avgcount", &avgCount, 1, 20000, avgCount == 1 ? "No avg" : "Avg: %d",
|
||||
ImGuiSliderFlags_Logarithmic);
|
||||
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Cursor averaging (samples)");
|
||||
}
|
||||
|
||||
void Cursors::setCursorA(double freq, float dB, int bin) {
|
||||
|
||||
Reference in New Issue
Block a user