2020-06-10 02:13:56 +00:00
|
|
|
#pragma once
|
|
|
|
#include <vector>
|
|
|
|
#include <mutex>
|
2020-12-05 21:42:12 +00:00
|
|
|
#include <gui/widgets/bandplan.h>
|
2020-10-07 20:44:54 +00:00
|
|
|
#include <imgui/imgui.h>
|
|
|
|
#include <imgui/imgui_internal.h>
|
2021-07-04 00:25:36 +00:00
|
|
|
#include <utils/event.h>
|
2020-06-10 02:13:56 +00:00
|
|
|
|
2022-01-22 17:13:46 +00:00
|
|
|
#include <utils/opengl_include_code.h>
|
2022-01-22 17:03:14 +00:00
|
|
|
|
2021-12-19 21:11:44 +00:00
|
|
|
#define WATERFALL_RESOLUTION 1000000
|
2020-07-11 19:15:10 +00:00
|
|
|
|
2020-06-10 02:13:56 +00:00
|
|
|
namespace ImGui {
|
2020-08-10 00:30:25 +00:00
|
|
|
class WaterfallVFO {
|
|
|
|
public:
|
2020-10-15 14:09:01 +00:00
|
|
|
void setOffset(double offset);
|
|
|
|
void setCenterOffset(double offset);
|
|
|
|
void setBandwidth(double bw);
|
2020-08-10 00:30:25 +00:00
|
|
|
void setReference(int ref);
|
2020-10-20 12:59:42 +00:00
|
|
|
void setSnapInterval(double interval);
|
2021-12-25 23:22:16 +00:00
|
|
|
void setNotchOffset(double offset);
|
|
|
|
void setNotchVisible(bool visible);
|
2020-10-15 14:09:01 +00:00
|
|
|
void updateDrawingVars(double viewBandwidth, float dataWidth, double viewOffset, ImVec2 widgetPos, int fftHeight); // NOTE: Datawidth double???
|
2020-08-10 00:30:25 +00:00
|
|
|
void draw(ImGuiWindow* window, bool selected);
|
|
|
|
|
|
|
|
enum {
|
|
|
|
REF_LOWER,
|
|
|
|
REF_CENTER,
|
|
|
|
REF_UPPER,
|
|
|
|
_REF_COUNT
|
|
|
|
};
|
|
|
|
|
2020-10-15 14:09:01 +00:00
|
|
|
double generalOffset;
|
|
|
|
double centerOffset;
|
|
|
|
double lowerOffset;
|
|
|
|
double upperOffset;
|
|
|
|
double bandwidth;
|
|
|
|
double snapInterval = 5000;
|
2020-08-10 00:30:25 +00:00
|
|
|
int reference = REF_CENTER;
|
|
|
|
|
2021-12-25 23:22:16 +00:00
|
|
|
double notchOffset = 0;
|
|
|
|
bool notchVisible = false;
|
|
|
|
|
2021-07-04 14:41:46 +00:00
|
|
|
bool leftClamped;
|
|
|
|
bool rightClamped;
|
|
|
|
|
2020-08-10 00:30:25 +00:00
|
|
|
ImVec2 rectMin;
|
|
|
|
ImVec2 rectMax;
|
|
|
|
ImVec2 lineMin;
|
|
|
|
ImVec2 lineMax;
|
2021-02-10 20:35:56 +00:00
|
|
|
ImVec2 wfRectMin;
|
|
|
|
ImVec2 wfRectMax;
|
|
|
|
ImVec2 wfLineMin;
|
|
|
|
ImVec2 wfLineMax;
|
2021-04-17 01:38:48 +00:00
|
|
|
ImVec2 lbwSelMin;
|
|
|
|
ImVec2 lbwSelMax;
|
|
|
|
ImVec2 rbwSelMin;
|
|
|
|
ImVec2 rbwSelMax;
|
|
|
|
ImVec2 wfLbwSelMin;
|
|
|
|
ImVec2 wfLbwSelMax;
|
|
|
|
ImVec2 wfRbwSelMin;
|
|
|
|
ImVec2 wfRbwSelMax;
|
2021-12-25 23:22:16 +00:00
|
|
|
ImVec2 notchMin;
|
|
|
|
ImVec2 notchMax;
|
2020-08-10 00:30:25 +00:00
|
|
|
|
|
|
|
bool centerOffsetChanged = false;
|
|
|
|
bool lowerOffsetChanged = false;
|
|
|
|
bool upperOffsetChanged = false;
|
|
|
|
bool redrawRequired = true;
|
|
|
|
bool lineVisible = true;
|
2021-04-17 20:37:50 +00:00
|
|
|
bool bandwidthChanged = false;
|
|
|
|
|
|
|
|
double minBandwidth;
|
|
|
|
double maxBandwidth;
|
|
|
|
bool bandwidthLocked;
|
2021-05-04 18:41:23 +00:00
|
|
|
|
|
|
|
ImU32 color = IM_COL32(255, 255, 255, 50);
|
2021-08-20 18:40:14 +00:00
|
|
|
|
|
|
|
Event<double> onUserChangedBandwidth;
|
2021-12-25 23:22:16 +00:00
|
|
|
Event<double> onUserChangedNotch;
|
2020-08-10 00:30:25 +00:00
|
|
|
};
|
|
|
|
|
2020-06-10 02:13:56 +00:00
|
|
|
class WaterFall {
|
|
|
|
public:
|
|
|
|
WaterFall();
|
|
|
|
|
2020-10-22 01:16:11 +00:00
|
|
|
void init();
|
|
|
|
|
2020-07-11 19:15:10 +00:00
|
|
|
void draw();
|
2020-12-12 04:34:58 +00:00
|
|
|
float* getFFTBuffer();
|
|
|
|
void pushFFT();
|
2020-06-10 02:13:56 +00:00
|
|
|
|
2021-11-16 19:23:52 +00:00
|
|
|
inline void doZoom(int offset, int width, int outWidth, float* data, float* out, bool fast) {
|
|
|
|
// NOTE: REMOVE THAT SHIT, IT'S JUST A HACKY FIX
|
|
|
|
if (offset < 0) {
|
|
|
|
offset = 0;
|
|
|
|
}
|
|
|
|
if (width > 524288) {
|
|
|
|
width = 524288;
|
|
|
|
}
|
|
|
|
|
|
|
|
float factor = (float)width / (float)outWidth;
|
|
|
|
|
|
|
|
if (fast) {
|
|
|
|
for (int i = 0; i < outWidth; i++) {
|
|
|
|
out[i] = data[(int)(offset + ((float)i * factor))];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
float sFactor = ceilf(factor);
|
|
|
|
float uFactor;
|
|
|
|
float id = offset;
|
2022-01-16 07:28:57 +00:00
|
|
|
float maxVal;
|
2021-11-16 19:23:52 +00:00
|
|
|
int sId;
|
|
|
|
for (int i = 0; i < outWidth; i++) {
|
|
|
|
maxVal = -INFINITY;
|
|
|
|
sId = (int)id;
|
|
|
|
uFactor = (sId + sFactor > rawFFTSize) ? sFactor - ((sId + sFactor) - rawFFTSize) : sFactor;
|
|
|
|
for (int j = 0; j < uFactor; j++) {
|
|
|
|
if (data[sId + j] > maxVal) { maxVal = data[sId + j]; }
|
|
|
|
}
|
|
|
|
out[i] = maxVal;
|
|
|
|
id += factor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-11 19:15:10 +00:00
|
|
|
void updatePallette(float colors[][3], int colorCount);
|
2020-12-31 13:26:12 +00:00
|
|
|
void updatePalletteFromArray(float* colors, int colorCount);
|
2020-07-11 19:15:10 +00:00
|
|
|
|
2020-10-15 14:09:01 +00:00
|
|
|
void setCenterFrequency(double freq);
|
|
|
|
double getCenterFrequency();
|
2020-07-11 19:15:10 +00:00
|
|
|
|
2020-10-15 14:09:01 +00:00
|
|
|
void setBandwidth(double bandWidth);
|
|
|
|
double getBandwidth();
|
2020-07-11 19:15:10 +00:00
|
|
|
|
2020-10-15 14:09:01 +00:00
|
|
|
void setViewBandwidth(double bandWidth);
|
|
|
|
double getViewBandwidth();
|
2020-07-19 13:59:44 +00:00
|
|
|
|
2020-10-15 14:09:01 +00:00
|
|
|
void setViewOffset(double offset);
|
|
|
|
double getViewOffset();
|
2020-07-11 19:15:10 +00:00
|
|
|
|
|
|
|
void setFFTMin(float min);
|
|
|
|
float getFFTMin();
|
|
|
|
|
|
|
|
void setFFTMax(float max);
|
|
|
|
float getFFTMax();
|
|
|
|
|
|
|
|
void setWaterfallMin(float min);
|
|
|
|
float getWaterfallMin();
|
|
|
|
|
|
|
|
void setWaterfallMax(float max);
|
|
|
|
float getWaterfallMax();
|
|
|
|
|
2020-10-15 14:09:01 +00:00
|
|
|
void setZoom(double zoomLevel);
|
|
|
|
void setOffset(double zoomOffset);
|
2020-07-11 19:15:10 +00:00
|
|
|
|
|
|
|
void autoRange();
|
|
|
|
|
2020-08-11 16:33:42 +00:00
|
|
|
void selectFirstVFO();
|
|
|
|
|
2020-08-20 16:29:23 +00:00
|
|
|
void showWaterfall();
|
|
|
|
void hideWaterfall();
|
|
|
|
|
2020-09-25 12:25:36 +00:00
|
|
|
void showBandplan();
|
|
|
|
void hideBandplan();
|
|
|
|
|
2020-08-20 16:29:23 +00:00
|
|
|
void setFFTHeight(int height);
|
|
|
|
int getFFTHeight();
|
|
|
|
|
2021-11-03 15:30:32 +00:00
|
|
|
void setRawFFTSize(int size);
|
2020-12-12 04:34:58 +00:00
|
|
|
|
2021-04-12 21:02:45 +00:00
|
|
|
void setFastFFT(bool fastFFT);
|
|
|
|
|
2021-04-13 02:54:47 +00:00
|
|
|
void setFullWaterfallUpdate(bool fullUpdate);
|
|
|
|
|
2021-04-13 23:45:21 +00:00
|
|
|
void setBandPlanPos(int pos);
|
|
|
|
|
2020-07-19 13:59:44 +00:00
|
|
|
bool centerFreqMoved = false;
|
|
|
|
bool vfoFreqChanged = false;
|
2020-08-05 19:13:53 +00:00
|
|
|
bool bandplanEnabled = false;
|
|
|
|
bandplan::BandPlan_t* bandplan = NULL;
|
2020-07-19 13:59:44 +00:00
|
|
|
|
2021-09-13 21:31:01 +00:00
|
|
|
bool mouseInFFTResize = false;
|
2021-04-23 23:24:27 +00:00
|
|
|
bool mouseInFreq = false;
|
|
|
|
bool mouseInFFT = false;
|
|
|
|
bool mouseInWaterfall = false;
|
|
|
|
|
2021-04-30 02:28:08 +00:00
|
|
|
float selectedVFOSNR = NAN;
|
|
|
|
|
2021-07-21 02:08:28 +00:00
|
|
|
bool centerFrequencyLocked = false;
|
|
|
|
|
2020-08-10 00:30:25 +00:00
|
|
|
std::map<std::string, WaterfallVFO*> vfos;
|
2020-12-08 03:36:37 +00:00
|
|
|
std::string selectedVFO = "";
|
2020-08-11 16:33:42 +00:00
|
|
|
bool selectedVFOChanged = false;
|
2020-08-10 00:30:25 +00:00
|
|
|
|
2021-07-04 00:25:36 +00:00
|
|
|
struct FFTRedrawArgs {
|
|
|
|
ImVec2 min;
|
|
|
|
ImVec2 max;
|
|
|
|
double lowFreq;
|
|
|
|
double highFreq;
|
|
|
|
double freqToPixelRatio;
|
|
|
|
double pixelToFreqRatio;
|
|
|
|
ImGuiWindow* window;
|
|
|
|
};
|
|
|
|
|
|
|
|
Event<FFTRedrawArgs> onFFTRedraw;
|
|
|
|
|
2021-07-04 14:41:46 +00:00
|
|
|
struct InputHandlerArgs {
|
|
|
|
ImVec2 fftRectMin;
|
|
|
|
ImVec2 fftRectMax;
|
|
|
|
ImVec2 freqScaleRectMin;
|
|
|
|
ImVec2 freqScaleRectMax;
|
|
|
|
ImVec2 waterfallRectMin;
|
|
|
|
ImVec2 waterfallRectMax;
|
|
|
|
double lowFreq;
|
|
|
|
double highFreq;
|
|
|
|
double freqToPixelRatio;
|
|
|
|
double pixelToFreqRatio;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool inputHandled = false;
|
2021-09-13 18:07:40 +00:00
|
|
|
bool VFOMoveSingleClick = false;
|
2021-07-04 14:41:46 +00:00
|
|
|
Event<InputHandlerArgs> onInputProcess;
|
|
|
|
|
2020-07-19 13:59:44 +00:00
|
|
|
enum {
|
|
|
|
REF_LOWER,
|
|
|
|
REF_CENTER,
|
|
|
|
REF_UPPER,
|
|
|
|
_REF_COUNT
|
|
|
|
};
|
|
|
|
|
2021-04-13 23:45:21 +00:00
|
|
|
enum {
|
|
|
|
BANDPLAN_POS_BOTTOM,
|
|
|
|
BANDPLAN_POS_TOP,
|
|
|
|
_BANDPLAN_POS_COUNT
|
|
|
|
};
|
|
|
|
|
2022-02-13 16:25:23 +00:00
|
|
|
ImVec2 fftAreaMin;
|
|
|
|
ImVec2 fftAreaMax;
|
|
|
|
ImVec2 freqAreaMin;
|
|
|
|
ImVec2 freqAreaMax;
|
|
|
|
ImVec2 wfMin;
|
|
|
|
ImVec2 wfMax;
|
|
|
|
|
2020-06-10 02:13:56 +00:00
|
|
|
private:
|
2020-07-11 19:15:10 +00:00
|
|
|
void drawWaterfall();
|
|
|
|
void drawFFT();
|
2020-08-10 00:30:25 +00:00
|
|
|
void drawVFOs();
|
2020-08-05 19:13:53 +00:00
|
|
|
void drawBandPlan();
|
2020-08-10 00:30:25 +00:00
|
|
|
void processInputs();
|
2020-07-11 19:15:10 +00:00
|
|
|
void onPositionChange();
|
|
|
|
void onResize();
|
|
|
|
void updateWaterfallFb();
|
|
|
|
void updateWaterfallTexture();
|
2021-05-04 00:52:59 +00:00
|
|
|
void updateAllVFOs(bool checkRedrawRequired = false);
|
2021-06-29 01:32:40 +00:00
|
|
|
bool calculateVFOSignalInfo(float* fftLine, WaterfallVFO* vfo, float& strength, float& snr);
|
2020-06-10 02:13:56 +00:00
|
|
|
|
2020-07-11 19:15:10 +00:00
|
|
|
bool waterfallUpdate = false;
|
|
|
|
|
|
|
|
uint32_t waterfallPallet[WATERFALL_RESOLUTION];
|
2021-12-19 21:11:44 +00:00
|
|
|
|
2020-07-11 19:15:10 +00:00
|
|
|
ImVec2 widgetPos;
|
|
|
|
ImVec2 widgetEndPos;
|
|
|
|
ImVec2 widgetSize;
|
|
|
|
|
|
|
|
ImVec2 lastWidgetPos;
|
|
|
|
ImVec2 lastWidgetSize;
|
|
|
|
|
|
|
|
ImGuiWindow* window;
|
|
|
|
|
|
|
|
GLuint textureId;
|
|
|
|
|
2021-11-03 15:30:32 +00:00
|
|
|
std::recursive_mutex buf_mtx;
|
2020-07-11 19:15:10 +00:00
|
|
|
|
2020-07-19 19:26:37 +00:00
|
|
|
float vRange;
|
|
|
|
|
|
|
|
int maxVSteps;
|
|
|
|
int maxHSteps;
|
|
|
|
|
2021-12-19 21:11:44 +00:00
|
|
|
int dataWidth; // Width of the FFT and waterfall
|
|
|
|
int fftHeight; // Height of the fft graph
|
|
|
|
int waterfallHeight = 0; // Height of the waterfall
|
2020-07-11 19:15:10 +00:00
|
|
|
|
2020-10-15 14:09:01 +00:00
|
|
|
double viewBandwidth;
|
|
|
|
double viewOffset;
|
2020-07-11 19:15:10 +00:00
|
|
|
|
2020-10-15 14:09:01 +00:00
|
|
|
double lowerFreq;
|
|
|
|
double upperFreq;
|
|
|
|
double range;
|
2020-07-11 19:15:10 +00:00
|
|
|
|
2020-07-19 13:59:44 +00:00
|
|
|
float lastDrag;
|
|
|
|
|
|
|
|
int vfoRef = REF_CENTER;
|
|
|
|
|
2020-07-11 19:15:10 +00:00
|
|
|
// Absolute values
|
2020-10-15 14:09:01 +00:00
|
|
|
double centerFreq;
|
|
|
|
double wholeBandwidth;
|
2020-07-11 19:15:10 +00:00
|
|
|
|
|
|
|
// Ranges
|
|
|
|
float fftMin;
|
|
|
|
float fftMax;
|
|
|
|
float waterfallMin;
|
|
|
|
float waterfallMax;
|
|
|
|
|
2020-12-12 04:34:58 +00:00
|
|
|
//std::vector<std::vector<float>> rawFFTs;
|
|
|
|
int rawFFTSize;
|
|
|
|
float* rawFFTs = NULL;
|
2020-07-11 19:15:10 +00:00
|
|
|
float* latestFFT;
|
2020-12-12 04:34:58 +00:00
|
|
|
int currentFFTLine = 0;
|
|
|
|
int fftLines = 0;
|
2020-07-11 19:15:10 +00:00
|
|
|
|
|
|
|
uint32_t* waterfallFb;
|
|
|
|
|
2020-08-20 16:29:23 +00:00
|
|
|
bool draggingFW = false;
|
|
|
|
int FFTAreaHeight;
|
|
|
|
int newFFTAreaHeight;
|
|
|
|
|
|
|
|
bool waterfallVisible = true;
|
2020-09-25 12:25:36 +00:00
|
|
|
bool bandplanVisible = false;
|
2021-04-12 21:02:45 +00:00
|
|
|
|
|
|
|
bool _fastFFT = true;
|
2021-04-13 02:54:47 +00:00
|
|
|
bool _fullUpdate = true;
|
2021-04-13 23:45:21 +00:00
|
|
|
|
|
|
|
int bandPlanPos = BANDPLAN_POS_BOTTOM;
|
2021-04-17 20:37:50 +00:00
|
|
|
|
|
|
|
// UI Select elements
|
2021-09-13 21:31:01 +00:00
|
|
|
bool fftResizeSelect = false;
|
2021-04-17 20:37:50 +00:00
|
|
|
bool freqScaleSelect = false;
|
|
|
|
bool vfoSelect = false;
|
|
|
|
bool vfoBorderSelect = false;
|
|
|
|
WaterfallVFO* relatedVfo = NULL;
|
|
|
|
ImVec2 mouseDownPos;
|
2021-05-18 00:26:55 +00:00
|
|
|
|
|
|
|
ImVec2 lastMousePos;
|
2020-06-10 02:13:56 +00:00
|
|
|
};
|
|
|
|
};
|