Fixed issues with new module system

This commit is contained in:
Ryzerth
2020-09-20 00:19:39 +02:00
parent d6b9e1d86a
commit 9de585190f
38 changed files with 460 additions and 358 deletions

View File

@ -4,12 +4,12 @@
#include <stdio.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <main_window.h>
#include <style.h>
#include <icons.h>
#include <gui/main_window.h>
#include <gui/style.h>
#include <gui/icons.h>
#include <version.h>
#include <spdlog/spdlog.h>
#include <bandplan.h>
#include <gui/bandplan.h>
#include <module.h>
#include <stb_image.h>
#include <config.h>
@ -139,23 +139,23 @@ int sdrpp_main() {
// ====================================================
// glfwPollEvents();
ImGui_ImplOpenGL3_NewFrame();
// ImGui_ImplGlfw_NewFrame();
// ImGui::NewFrame();
// // glfwPollEvents();
// ImGui_ImplOpenGL3_NewFrame();
// // ImGui_ImplGlfw_NewFrame();
// // ImGui::NewFrame();
// ImGui::ShowDemoWindow();
// // ImGui::ShowDemoWindow();
// ImGui::Render();
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(0.0666f, 0.0666f, 0.0666f, 1.0f);
//glClearColor(0.9f, 0.9f, 0.9f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
// // ImGui::Render();
// int display_w, display_h;
// glfwGetFramebufferSize(window, &display_w, &display_h);
// glViewport(0, 0, display_w, display_h);
// glClearColor(0.0666f, 0.0666f, 0.0666f, 1.0f);
// //glClearColor(0.9f, 0.9f, 0.9f, 1.0f);
// glClear(GL_COLOR_BUFFER_BIT);
// // ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
// glfwSwapBuffers(window);
// ====================================================
spdlog::info("Loading icons");

View File

@ -1,4 +1,4 @@
#include <bandplan.h>
#include <gui/bandplan.h>
namespace bandplan {
std::map<std::string, BandPlan_t> bandplans;

View File

@ -1,4 +1,4 @@
#include <frequency_select.h>
#include <gui/frequency_select.h>
bool isInArea(ImVec2 val, ImVec2 min, ImVec2 max) {
return val.x >= min.x && val.x < max.x && val.y >= min.y && val.y < max.y;

6
core/src/gui/gui.cpp Normal file
View File

@ -0,0 +1,6 @@
#include <gui/gui.h>
namespace gui {
ImGui::WaterFall waterfall;
FrequencySelect freqSelect;
};

9
core/src/gui/gui.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#include <gui/waterfall.h>
#include <gui/frequency_select.h>
#include <module.h>
namespace gui {
SDRPP_EXPORT ImGui::WaterFall waterfall;
SDRPP_EXPORT FrequencySelect freqSelect;
};

View File

@ -1,4 +1,4 @@
#include <icons.h>
#include <gui/icons.h>
#define STB_IMAGE_IMPLEMENTATION
#include <imgui/stb_image.h>

View File

@ -1,9 +1,8 @@
#include <main_window.h>
#include <gui/main_window.h>
#include <gui/gui.h>
std::thread worker;
std::mutex fft_mtx;
ImGui::WaterFall wtf;
FrequencySelect fSel;
fftwf_complex *fft_in, *fft_out;
fftwf_plan p;
float* tempData;
@ -14,8 +13,6 @@ ImFont* bigFont;
int fftSize = 8192 * 8;
io::SoapyWrapper soapy;
SignalPath sigPath;
std::vector<float> _data;
std::vector<float> fftTaps;
void fftHandler(dsp::complex_t* samples) {
@ -33,7 +30,7 @@ void fftHandler(dsp::complex_t* samples) {
_data[i] = (_data[i - 4] + _data[i - 3] + _data[i - 2] + _data[i - 1] + _data[i]) / 5.0f;
}
wtf.pushFFT(_data, fftSize);
gui::waterfall.pushFFT(_data, fftSize);
_data.clear();
}
@ -87,7 +84,7 @@ void loadSourceConfig(std::string name) {
else {
srId = std::distance(soapy.sampleRates.begin(), _srIt);
}
sigPath.setSampleRate(sampleRate);
sigpath::signalPath.setSampleRate(sampleRate);
soapy.setSampleRate(sampleRate);
// Set gains
@ -107,8 +104,8 @@ void loadSourceConfig(std::string name) {
}
// Update GUI
wtf.setBandwidth(sampleRate);
wtf.setViewBandwidth(sampleRate);
gui::waterfall.setBandwidth(sampleRate);
gui::waterfall.setViewBandwidth(sampleRate);
bw.val = sampleRate;
}
@ -158,21 +155,19 @@ void windowInit() {
spdlog::info("Initializing SoapySDR");
soapy.init();
fSel.init();
gui::freqSelect.init();
fft_in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
fft_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
p = fftwf_plan_dft_1d(fftSize, fft_in, fft_out, FFTW_FORWARD, FFTW_ESTIMATE);
sigPath.init(sampleRate, 20, fftSize, &soapy.output, (dsp::complex_t*)fft_in, fftHandler);
sigPath.start();
vfoman::init(&wtf, &sigPath);
sigpath::signalPath.init(sampleRate, 20, fftSize, &soapy.output, (dsp::complex_t*)fft_in, fftHandler);
sigpath::signalPath.start();
uiGains = new float[soapy.gainList.size()];
spdlog::info("Loading modules");
mod::initAPI(&wtf);
mod::initAPI(&gui::waterfall);
mod::loadFromList(config::getRootDirectory() + "/module_list.json");
bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF((config::getRootDirectory() + "/res/fonts/Roboto-Medium.ttf").c_str(), 128.0f);
@ -206,7 +201,7 @@ void windowInit() {
sourceName = soapy.devNameList[0];
}
sampleRate = soapy.getSampleRate();
sigPath.setSampleRate(sampleRate);
sigpath::signalPath.setSampleRate(sampleRate);
}
// Search for the first source in the list to have a config
// If no pre-defined source, selected default device
@ -229,10 +224,10 @@ void windowInit() {
// Update UI settings
fftMin = config::config["min"];
fftMax = config::config["max"];
wtf.setFFTMin(fftMin);
wtf.setWaterfallMin(fftMin);
wtf.setFFTMax(fftMax);
wtf.setWaterfallMax(fftMax);
gui::waterfall.setFFTMin(fftMin);
gui::waterfall.setWaterfallMin(fftMin);
gui::waterfall.setFFTMax(fftMax);
gui::waterfall.setWaterfallMax(fftMax);
bandPlanEnabled.val = config::config["bandPlanEnabled"];
bandPlanEnabled.markAsChanged();
@ -243,10 +238,10 @@ void windowInit() {
bandplanId.val = std::distance(bandplan::bandplans.begin(), bandplan::bandplans.find(bandPlanName));
if (bandPlanEnabled.val) {
wtf.bandplan = &bandplan::bandplans[bandPlanName];
gui::waterfall.bandplan = &bandplan::bandplans[bandPlanName];
}
else {
wtf.bandplan = NULL;
gui::waterfall.bandplan = NULL;
}
}
else {
@ -255,16 +250,16 @@ void windowInit() {
bandplanId.markAsChanged();
fSel.setFrequency(frequency);
fSel.frequencyChanged = false;
gui::freqSelect.setFrequency(frequency);
gui::freqSelect.frequencyChanged = false;
soapy.setFrequency(frequency);
wtf.setCenterFrequency(frequency);
wtf.setBandwidth(sampleRate);
wtf.setViewBandwidth(sampleRate);
gui::waterfall.setCenterFrequency(frequency);
gui::waterfall.setBandwidth(sampleRate);
gui::waterfall.setViewBandwidth(sampleRate);
bw.val = sampleRate;
wtf.vfoFreqChanged = false;
wtf.centerFreqMoved = false;
wtf.selectFirstVFO();
gui::waterfall.vfoFreqChanged = false;
gui::waterfall.centerFreqMoved = false;
gui::waterfall.selectFirstVFO();
for (auto [name, stream] : audio::streams) {
if (config::config["audio"].contains(name)) {
@ -277,7 +272,7 @@ void windowInit() {
}
}
audioStreamName = audio::getNameFromVFO(wtf.selectedVFO);
audioStreamName = audio::getNameFromVFO(gui::waterfall.selectedVFO);
if (audioStreamName != "") {
volume = &audio::streams[audioStreamName]->volume;
}
@ -287,18 +282,18 @@ void windowInit() {
showWaterfall = config::config["showWaterfall"];
if (!showWaterfall) {
wtf.hideWaterfall();
gui::waterfall.hideWaterfall();
}
fftHeight = config::config["fftHeight"];
wtf.setFFTHeight(fftHeight);
gui::waterfall.setFFTHeight(fftHeight);
}
void setVFO(float freq) {
ImGui::WaterfallVFO* vfo = wtf.vfos[wtf.selectedVFO];
ImGui::WaterfallVFO* vfo = gui::waterfall.vfos[gui::waterfall.selectedVFO];
float currentOff = vfo->centerOffset;
float currentTune = wtf.getCenterFrequency() + vfo->generalOffset;
float currentTune = gui::waterfall.getCenterFrequency() + vfo->generalOffset;
float delta = freq - currentTune;
float newVFO = currentOff + delta;
@ -306,38 +301,38 @@ void setVFO(float freq) {
float vfoBottom = newVFO - (vfoBW / 2.0f);
float vfoTop = newVFO + (vfoBW / 2.0f);
float view = wtf.getViewOffset();
float viewBW = wtf.getViewBandwidth();
float view = gui::waterfall.getViewOffset();
float viewBW = gui::waterfall.getViewBandwidth();
float viewBottom = view - (viewBW / 2.0f);
float viewTop = view + (viewBW / 2.0f);
float wholeFreq = wtf.getCenterFrequency();
float BW = wtf.getBandwidth();
float wholeFreq = gui::waterfall.getCenterFrequency();
float BW = gui::waterfall.getBandwidth();
float bottom = -(BW / 2.0f);
float top = (BW / 2.0f);
// VFO still fints in the view
if (vfoBottom > viewBottom && vfoTop < viewTop) {
vfoman::setCenterOffset(wtf.selectedVFO, newVFO);
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFO);
return;
}
// VFO too low for current SDR tuning
if (vfoBottom < bottom) {
wtf.setViewOffset((BW / 2.0f) - (viewBW / 2.0f));
gui::waterfall.setViewOffset((BW / 2.0f) - (viewBW / 2.0f));
float newVFOOffset = (BW / 2.0f) - (vfoBW / 2.0f) - (viewBW / 10.0f);
vfoman::setCenterOffset(wtf.selectedVFO, newVFOOffset);
wtf.setCenterFrequency(freq - newVFOOffset);
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset);
gui::waterfall.setCenterFrequency(freq - newVFOOffset);
soapy.setFrequency(freq - newVFOOffset);
return;
}
// VFO too high for current SDR tuning
if (vfoTop > top) {
wtf.setViewOffset((viewBW / 2.0f) - (BW / 2.0f));
gui::waterfall.setViewOffset((viewBW / 2.0f) - (BW / 2.0f));
float newVFOOffset = (vfoBW / 2.0f) - (BW / 2.0f) + (viewBW / 10.0f);
vfoman::setCenterOffset(wtf.selectedVFO, newVFOOffset);
wtf.setCenterFrequency(freq - newVFOOffset);
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset);
gui::waterfall.setCenterFrequency(freq - newVFOOffset);
soapy.setFrequency(freq - newVFOOffset);
return;
}
@ -349,15 +344,15 @@ void setVFO(float freq) {
float newViewTop = newViewOff + (viewBW / 2.0f);
if (newViewBottom > bottom) {
wtf.setViewOffset(newViewOff);
vfoman::setCenterOffset(wtf.selectedVFO, newVFO);
gui::waterfall.setViewOffset(newViewOff);
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFO);
return;
}
wtf.setViewOffset((BW / 2.0f) - (viewBW / 2.0f));
gui::waterfall.setViewOffset((BW / 2.0f) - (viewBW / 2.0f));
float newVFOOffset = (BW / 2.0f) - (vfoBW / 2.0f) - (viewBW / 10.0f);
vfoman::setCenterOffset(wtf.selectedVFO, newVFOOffset);
wtf.setCenterFrequency(freq - newVFOOffset);
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset);
gui::waterfall.setCenterFrequency(freq - newVFOOffset);
soapy.setFrequency(freq - newVFOOffset);
}
else {
@ -366,15 +361,15 @@ void setVFO(float freq) {
float newViewTop = newViewOff + (viewBW / 2.0f);
if (newViewTop < top) {
wtf.setViewOffset(newViewOff);
vfoman::setCenterOffset(wtf.selectedVFO, newVFO);
gui::waterfall.setViewOffset(newViewOff);
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFO);
return;
}
wtf.setViewOffset((viewBW / 2.0f) - (BW / 2.0f));
gui::waterfall.setViewOffset((viewBW / 2.0f) - (BW / 2.0f));
float newVFOOffset = (vfoBW / 2.0f) - (BW / 2.0f) + (viewBW / 10.0f);
vfoman::setCenterOffset(wtf.selectedVFO, newVFOOffset);
wtf.setCenterFrequency(freq - newVFOOffset);
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset);
gui::waterfall.setCenterFrequency(freq - newVFOOffset);
soapy.setFrequency(freq - newVFOOffset);
}
}
@ -382,61 +377,61 @@ void setVFO(float freq) {
void drawWindow() {
ImGui::Begin("Main", NULL, WINDOW_FLAGS);
ImGui::WaterfallVFO* vfo = wtf.vfos[wtf.selectedVFO];
ImGui::WaterfallVFO* vfo = gui::waterfall.vfos[gui::waterfall.selectedVFO];
if (vfo->centerOffsetChanged) {
fSel.setFrequency(wtf.getCenterFrequency() + vfo->generalOffset);
fSel.frequencyChanged = false;
config::config["frequency"] = fSel.frequency;
gui::freqSelect.setFrequency(gui::waterfall.getCenterFrequency() + vfo->generalOffset);
gui::freqSelect.frequencyChanged = false;
config::config["frequency"] = gui::freqSelect.frequency;
config::configModified = true;
}
vfoman::updateFromWaterfall();
sigpath::vfoManager.updateFromWaterfall(&gui::waterfall);
if (wtf.selectedVFOChanged) {
wtf.selectedVFOChanged = false;
fSel.setFrequency(vfo->generalOffset + wtf.getCenterFrequency());
fSel.frequencyChanged = false;
if (gui::waterfall.selectedVFOChanged) {
gui::waterfall.selectedVFOChanged = false;
gui::freqSelect.setFrequency(vfo->generalOffset + gui::waterfall.getCenterFrequency());
gui::freqSelect.frequencyChanged = false;
mod::broadcastEvent(mod::EVENT_SELECTED_VFO_CHANGED);
audioStreamName = audio::getNameFromVFO(wtf.selectedVFO);
audioStreamName = audio::getNameFromVFO(gui::waterfall.selectedVFO);
if (audioStreamName != "") {
volume = &audio::streams[audioStreamName]->volume;
}
config::config["frequency"] = fSel.frequency;
config::config["frequency"] = gui::freqSelect.frequency;
config::configModified = true;
}
if (fSel.frequencyChanged) {
fSel.frequencyChanged = false;
setVFO(fSel.frequency);
if (gui::freqSelect.frequencyChanged) {
gui::freqSelect.frequencyChanged = false;
setVFO(gui::freqSelect.frequency);
vfo->centerOffsetChanged = false;
vfo->lowerOffsetChanged = false;
vfo->upperOffsetChanged = false;
config::config["frequency"] = fSel.frequency;
config::config["frequency"] = gui::freqSelect.frequency;
config::configModified = true;
}
if (wtf.centerFreqMoved) {
wtf.centerFreqMoved = false;
soapy.setFrequency(wtf.getCenterFrequency());
fSel.setFrequency(wtf.getCenterFrequency() + vfo->generalOffset);
config::config["frequency"] = fSel.frequency;
if (gui::waterfall.centerFreqMoved) {
gui::waterfall.centerFreqMoved = false;
soapy.setFrequency(gui::waterfall.getCenterFrequency());
gui::freqSelect.setFrequency(gui::waterfall.getCenterFrequency() + vfo->generalOffset);
config::config["frequency"] = gui::freqSelect.frequency;
config::configModified = true;
}
if (dcbias.changed()) {
sigPath.setDCBiasCorrection(dcbias.val);
sigpath::signalPath.setDCBiasCorrection(dcbias.val);
}
if (bandplanId.changed() && bandPlanEnabled.val) {
wtf.bandplan = &bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]];
gui::waterfall.bandplan = &bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]];
}
if (bandPlanEnabled.changed()) {
wtf.bandplan = bandPlanEnabled.val ? &bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]] : NULL;
gui::waterfall.bandplan = bandPlanEnabled.val ? &bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]] : NULL;
}
int _fftHeight = wtf.getFFTHeight();
int _fftHeight = gui::waterfall.getFFTHeight();
if (fftHeight != _fftHeight) {
fftHeight = _fftHeight;
config::config["fftHeight"] = fftHeight;
@ -472,7 +467,7 @@ void drawWindow() {
else {
if (ImGui::ImageButton(icons::PLAY, ImVec2(40, 40), ImVec2(0, 0), ImVec2(1, 1), 0) && soapy.devList.size() > 0) {
soapy.start();
soapy.setFrequency(wtf.getCenterFrequency());
soapy.setFrequency(gui::waterfall.getCenterFrequency());
playing = true;
}
}
@ -494,7 +489,7 @@ void drawWindow() {
ImGui::SameLine();
fSel.draw();
gui::freqSelect.draw();
ImGui::SameLine();
@ -564,9 +559,9 @@ void drawWindow() {
srId = 0;
sampleRate = soapy.getSampleRate();
bw.val = sampleRate;
wtf.setBandwidth(sampleRate);
wtf.setViewBandwidth(sampleRate);
sigPath.setSampleRate(sampleRate);
gui::waterfall.setBandwidth(sampleRate);
gui::waterfall.setViewBandwidth(sampleRate);
sigpath::signalPath.setSampleRate(sampleRate);
if (soapy.gainList.size() >= 0) {
delete[] uiGains;
@ -576,7 +571,7 @@ void drawWindow() {
}
}
}
setVFO(fSel.frequency);
setVFO(gui::freqSelect.frequency);
config::config["source"] = sourceName;
config::configModified = true;
}
@ -586,9 +581,9 @@ void drawWindow() {
spdlog::info("Changed sample rate: {0}", srId);
sampleRate = soapy.sampleRates[srId];
soapy.setSampleRate(sampleRate);
wtf.setBandwidth(sampleRate);
wtf.setViewBandwidth(sampleRate);
sigPath.setSampleRate(sampleRate);
gui::waterfall.setBandwidth(sampleRate);
gui::waterfall.setViewBandwidth(sampleRate);
sigpath::signalPath.setSampleRate(sampleRate);
bw.val = sampleRate;
if (!config::config["sourceSettings"].contains(sourceName)) {
@ -739,7 +734,7 @@ void drawWindow() {
if (ImGui::CollapsingHeader("Display", ImGuiTreeNodeFlags_DefaultOpen)) {
if (ImGui::Checkbox("Show waterfall", &showWaterfall)) {
showWaterfall ? wtf.showWaterfall() : wtf.hideWaterfall();
showWaterfall ? gui::waterfall.showWaterfall() : gui::waterfall.hideWaterfall();
}
ImGui::Spacing();
}
@ -747,7 +742,7 @@ void drawWindow() {
if(ImGui::CollapsingHeader("Debug")) {
ImGui::Text("Frame time: %.3f ms/frame", 1000.0f / ImGui::GetIO().Framerate);
ImGui::Text("Framerate: %.1f FPS", ImGui::GetIO().Framerate);
ImGui::Text("Center Frequency: %.0f Hz", wtf.getCenterFrequency());
ImGui::Text("Center Frequency: %.0f Hz", gui::waterfall.getCenterFrequency());
ImGui::Text("Source name: %s", sourceName.c_str());
ImGui::Spacing();
}
@ -769,7 +764,7 @@ void drawWindow() {
ImGui::BeginChild("Waterfall");
wtf.draw();
gui::waterfall.draw();
ImGui::EndChild();
@ -807,14 +802,14 @@ void drawWindow() {
ImGui::EndChild();
if (bw.changed()) {
wtf.setViewBandwidth(bw.val);
wtf.setViewOffset(vfo->centerOffset);
gui::waterfall.setViewBandwidth(bw.val);
gui::waterfall.setViewOffset(vfo->centerOffset);
}
wtf.setFFTMin(fftMin);
wtf.setFFTMax(fftMax);
wtf.setWaterfallMin(fftMin);
wtf.setWaterfallMax(fftMax);
gui::waterfall.setFFTMin(fftMin);
gui::waterfall.setFFTMax(fftMax);
gui::waterfall.setWaterfallMin(fftMin);
gui::waterfall.setWaterfallMax(fftMax);
ImGui::End();

View File

@ -13,19 +13,20 @@
#include <complex>
#include <dsp/source.h>
#include <dsp/math.h>
#include <waterfall.h>
#include <frequency_select.h>
#include <gui/waterfall.h>
#include <gui/frequency_select.h>
#include <fftw3.h>
#include <signal_path.h>
#include <signal_path/dsp.h>
#include <io/soapy.h>
#include <icons.h>
#include <bandplan.h>
#include <gui/icons.h>
#include <gui/bandplan.h>
#include <watcher.h>
#include <module.h>
#include <vfo_manager.h>
#include <audio.h>
#include <style.h>
#include <signal_path/vfo_manager.h>
#include <signal_path/audio.h>
#include <gui/style.h>
#include <config.h>
#include <signal_path/signal_path.h>
#define WINDOW_FLAGS ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground

24
core/src/gui/menu.cpp Normal file
View File

@ -0,0 +1,24 @@
#include <gui/menu.h>
Menu::Menu() {
}
void Menu::registerEntry(std::string name, void (*drawHandler)(void* ctx), void* ctx) {
MenuItem_t item;
item.drawHandler = drawHandler;
item.ctx = ctx;
items[name] = item;
}
void Menu::removeEntry(std::string name) {
items.erase(name);
}
void Menu::draw() {
MenuItem_t item;
for (std::string name : order) {
item = items[name];
item.drawHandler(item.ctx);
}
}

23
core/src/gui/menu.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <string>
#include <vector>
#include <map>
class Menu {
public:
Menu();
struct MenuItem_t {
void (*drawHandler)(void* ctx);
void* ctx;
};
void registerEntry(std::string name, void (*drawHandler)(void* ctx), void* ctx = NULL);
void removeEntry(std::string name);
void draw();
std::vector<std::string> order;
private:
std::map<std::string, MenuItem_t> items;
};

View File

@ -1,4 +1,4 @@
#include <style.h>
#include <gui/style.h>
namespace style {
void setDefaultStyle() {

View File

@ -1,4 +1,4 @@
#include <waterfall.h>
#include <gui/waterfall.h>
float COLOR_MAP[][3] = {
{0x00, 0x00, 0x20},
@ -650,6 +650,7 @@ namespace ImGui {
}
void WaterfallVFO::setOffset(float offset) {
printf("WaterfallVFO::SetOffset: %p\n", this);
generalOffset = offset;
if (reference == REF_CENTER) {
centerOffset = offset;

View File

@ -5,7 +5,7 @@
#include <mutex>
#include <GL/glew.h>
#include <imutils.h>
#include <bandplan.h>
#include <gui/bandplan.h>
#include <algorithm>
#define WATERFALL_RESOLUTION 1000000

View File

@ -1,7 +1,7 @@
#include <module.h>
#include <vfo_manager.h>
#include <main_window.h>
#include <audio.h>
#include <signal_path/vfo_manager.h>
#include <gui/main_window.h>
#include <signal_path/audio.h>
namespace mod {
API_t API;
@ -16,16 +16,6 @@ namespace mod {
void initAPI(ImGui::WaterFall* wtf) {
_wtf = wtf;
// VFO Manager
API.registerVFO = vfoman::create;
API.setVFOOffset = vfoman::setOffset;
API.setVFOCenterOffset = vfoman::setCenterOffset;
API.setVFOBandwidth = vfoman::setBandwidth;
API.setVFOSampleRate = vfoman::setSampleRate;
API.getVFOOutputBlockSize = vfoman::getOutputBlockSize;
API.setVFOReference = vfoman::setReference;
API.removeVFO = vfoman::remove;
// GUI
API.getSelectedVFOName = api_getSelectedVFOName;
API.bindVolumeVariable = bindVolumeVariable;

View File

@ -7,16 +7,25 @@
#include <spdlog/spdlog.h>
#include <dsp/types.h>
#include <dsp/stream.h>
#include <waterfall.h>
#include <gui/waterfall.h>
#include <json.hpp>
#ifdef _WIN32
#ifdef SDRPP_IS_CORE
#define SDRPP_EXPORT extern "C" __declspec(dllexport)
#else
#define SDRPP_EXPORT extern "C" __declspec(dllimport)
#endif
#else
#define SDRPP_EXPORT /**/
#endif
#ifdef _WIN32
#include <Windows.h>
#define MOD_EXPORT extern "C" \
__declspec(dllexport)
#define MOD_EXPORT extern "C" __declspec(dllexport)
#else
#include <dlfcn.h>
#define MOD_EXPORT extern "C"
#define MOD_EXPORT extern "C"
#endif
namespace mod {

View File

@ -1,4 +1,4 @@
#include <audio.h>
#include <signal_path/audio.h>
namespace audio {
std::map<std::string, AudioStream_t*> streams;

View File

@ -1,4 +1,4 @@
#include <signal_path.h>
#include <signal_path/dsp.h>
SignalPath::SignalPath() {

View File

@ -0,0 +1,6 @@
#include <signal_path/signal_path.h>
namespace sigpath {
SignalPath signalPath;
VFOManager vfoManager;
};

View File

@ -0,0 +1,9 @@
#pragma once
#include <signal_path/dsp.h>
#include <signal_path/vfo_manager.h>
#include <module.h>
namespace sigpath {
SDRPP_EXPORT SignalPath signalPath;
SDRPP_EXPORT VFOManager vfoManager;
};

View File

@ -0,0 +1,128 @@
#include <signal_path/vfo_manager.h>
#include <signal_path/signal_path.h>
VFOManager::VFO::VFO(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize) {
this->name = name;
dspVFO = sigpath::signalPath.addVFO(name, sampleRate, bandwidth, offset);
wtfVFO = new ImGui::WaterfallVFO;
wtfVFO->setReference(reference);
wtfVFO->setBandwidth(bandwidth);
wtfVFO->setOffset(offset);
output = dspVFO->output;
printf("Created VFO: %p", wtfVFO);
gui::waterfall.vfos[name] = wtfVFO;
}
VFOManager::VFO::~VFO() {
gui::waterfall.vfos.erase(name);
sigpath::signalPath.removeVFO(name);
delete wtfVFO;
}
void VFOManager::VFO::setOffset(float offset) {
wtfVFO->setOffset(offset);
dspVFO->setOffset(wtfVFO->centerOffset);
}
void VFOManager::VFO::setCenterOffset(float offset) {
wtfVFO->setCenterOffset(offset);
dspVFO->setOffset(offset);
}
void VFOManager::VFO::setBandwidth(float bandwidth) {
wtfVFO->setBandwidth(bandwidth);
dspVFO->setBandwidth(bandwidth);
}
void VFOManager::VFO::setSampleRate(float sampleRate, float bandwidth) {
dspVFO->setOutputSampleRate(sampleRate, bandwidth);
wtfVFO->setBandwidth(bandwidth);
}
void VFOManager::VFO::setReference(int ref) {
wtfVFO->setReference(ref);
}
int VFOManager::VFO::getOutputBlockSize() {
return dspVFO->getOutputBlockSize();
}
VFOManager::VFOManager() {
}
VFOManager::VFO* VFOManager::createVFO(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize) {
if (vfos.find(name) != vfos.end() || name == "") {
return NULL;
}
VFOManager::VFO* vfo = new VFO(name, reference, offset, bandwidth, sampleRate, blockSize);
vfos[name] = vfo;
return vfo;
}
void VFOManager::deleteVFO(VFOManager::VFO* vfo) {
std::string name = "";
for (auto const& [_name, _vfo] : vfos) {
if (_vfo == vfo) {
name == _name;
break;
}
}
if (name == "") {
return;
}
vfos.erase(name);
}
void VFOManager::setOffset(std::string name, float offset) {
if (vfos.find(name) == vfos.end()) {
return;
}
vfos[name]->setOffset(offset);
}
void VFOManager::setCenterOffset(std::string name, float offset) {
if (vfos.find(name) == vfos.end()) {
return;
}
vfos[name]->setCenterOffset(offset);
}
void VFOManager::setBandwidth(std::string name, float bandwidth) {
if (vfos.find(name) == vfos.end()) {
return;
}
vfos[name]->setBandwidth(bandwidth);
}
void VFOManager::setSampleRate(std::string name, float sampleRate, float bandwidth) {
if (vfos.find(name) == vfos.end()) {
return;
}
vfos[name]->setSampleRate(sampleRate, bandwidth);
}
void VFOManager::setReference(std::string name, int ref) {
if (vfos.find(name) == vfos.end()) {
return;
}
vfos[name]->setReference(ref);
}
int VFOManager::getOutputBlockSize(std::string name) {
if (vfos.find(name) == vfos.end()) {
return -1;
}
return vfos[name]->getOutputBlockSize();
}
void VFOManager::updateFromWaterfall(ImGui::WaterFall* wtf) {
for (auto const& [name, vfo] : vfos) {
if (vfo->wtfVFO->centerOffsetChanged) {
spdlog::info("UH OH: Change!");
vfo->wtfVFO->centerOffsetChanged = false;
vfo->dspVFO->setOffset(vfo->wtfVFO->centerOffset);
}
}
}

View File

@ -0,0 +1,47 @@
#pragma once
#include <dsp/vfo.h>
#include <gui/waterfall.h>
#include <gui/gui.h>
class VFOManager {
public:
VFOManager();
class VFO {
public:
VFO(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize);
~VFO();
void setOffset(float offset);
void setCenterOffset(float offset);
void setBandwidth(float bandwidth);
void setSampleRate(float sampleRate, float bandwidth);
void setReference(int ref);
int getOutputBlockSize();
dsp::stream<dsp::complex_t>* output;
friend class VFOManager;
private:
std::string name;
dsp::VFO* dspVFO;
ImGui::WaterfallVFO* wtfVFO;
};
VFOManager::VFO* createVFO(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize);
void deleteVFO(VFOManager::VFO* vfo);
void setOffset(std::string name, float offset);
void setCenterOffset(std::string name, float offset);
void setBandwidth(std::string name, float bandwidth);
void setSampleRate(std::string name, float sampleRate, float bandwidth);
void setReference(std::string name, int ref);
int getOutputBlockSize(std::string name);
void updateFromWaterfall(ImGui::WaterFall* wtf);
private:
std::map<std::string, VFO*> vfos;
};

View File

@ -1,99 +0,0 @@
#include <vfo_manager.h>
namespace vfoman {
std::map<std::string, VFO_t> vfos;
ImGui::WaterFall* _wtf;
SignalPath* _sigPath;
void init(ImGui::WaterFall* wtf, SignalPath* sigPath) {
_wtf = wtf;
_sigPath = sigPath;
}
dsp::stream<dsp::complex_t>* create(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize) {
if (vfos.find(name) != vfos.end()) {
spdlog::warn("Tried to add VFO with an already existing name: {0}", name);
return NULL;
}
spdlog::info("Creating new VFO '{0}'", name);
VFO_t vfo;
vfo.dspVFO = _sigPath->addVFO(name, sampleRate, bandwidth, offset);
vfo.wtfVFO = new ImGui::WaterfallVFO;
vfo.wtfVFO->setReference(reference);
vfo.wtfVFO->setBandwidth(bandwidth);
vfo.wtfVFO->setOffset(offset);
_wtf->vfos[name] = vfo.wtfVFO;
vfos[name] = vfo;
return vfo.dspVFO->output;
}
void setOffset(std::string name, float offset) {
if (vfos.find(name) == vfos.end()) {
return;
}
VFO_t vfo = vfos[name];
vfo.wtfVFO->setOffset(offset);
vfo.dspVFO->setOffset(vfo.wtfVFO->centerOffset);
}
void setCenterOffset(std::string name, float offset) {
if (vfos.find(name) == vfos.end()) {
return;
}
VFO_t vfo = vfos[name];
vfo.wtfVFO->setCenterOffset(offset);
vfo.dspVFO->setOffset(offset);
}
void setBandwidth(std::string name, float bandwidth) {
if (vfos.find(name) == vfos.end()) {
return;
}
VFO_t vfo = vfos[name];
vfo.wtfVFO->setBandwidth(bandwidth);
vfo.dspVFO->setBandwidth(bandwidth);
}
void setSampleRate(std::string name, float sampleRate, float bandwidth) {
if (vfos.find(name) == vfos.end()) {
return;
}
VFO_t vfo = vfos[name];
vfo.dspVFO->setOutputSampleRate(sampleRate, bandwidth);
vfo.wtfVFO->setBandwidth(bandwidth);
}
void setReference(std::string name, int ref){
if (vfos.find(name) == vfos.end()) {
return;
}
vfos[name].wtfVFO->setReference(ref);
}
int getOutputBlockSize(std::string name) {
if (vfos.find(name) == vfos.end()) {
return -1;
}
return vfos[name].dspVFO->getOutputBlockSize();
}
void remove(std::string name) {
if (vfos.find(name) == vfos.end()) {
return;
}
VFO_t vfo = vfos[name];
_wtf->vfos.erase(name);
_sigPath->removeVFO(name);
delete vfo.wtfVFO;
vfos.erase(name);
}
void updateFromWaterfall() {
for (auto const& [name, vfo] : vfos) {
if (vfo.wtfVFO->centerOffsetChanged) {
vfo.wtfVFO->centerOffsetChanged = false;
vfo.dspVFO->setOffset(vfo.wtfVFO->centerOffset);
}
}
}
};

View File

@ -1,24 +0,0 @@
#pragma once
#include <dsp/vfo.h>
#include <waterfall.h>
#include <signal_path.h>
namespace vfoman {
struct VFO_t {
dsp::VFO* dspVFO;
ImGui::WaterfallVFO* wtfVFO;
};
void init(ImGui::WaterFall* wtf, SignalPath* sigPath);
dsp::stream<dsp::complex_t>* create(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize);
void setOffset(std::string name, float offset);
void setCenterOffset(std::string name, float offset);
void setBandwidth(std::string name, float bandwidth);
void setSampleRate(std::string name, float sampleRate, float bandwidth);
void setReference(std::string name, int ref);
int getOutputBlockSize(std::string name);
void remove(std::string name);
void updateFromWaterfall();
};