Fixed issues with new module system

pull/22/head
Ryzerth 2020-09-20 00:19:39 +02:00
rodzic d6b9e1d86a
commit 9de585190f
38 zmienionych plików z 460 dodań i 358 usunięć

3
.gitignore vendored
Wyświetl plik

@ -2,4 +2,5 @@ build/
.vscode/
*.old
*.dll
*.exe
*.exe
*.zip

Wyświetl plik

@ -9,13 +9,16 @@ else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive -fsanitize=address -g")
# set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)
add_definitions(-DSDRPP_IS_CORE)
# Main code
file(GLOB SRC "src/*.cpp")
file(GLOB GUI "src/gui/*.cpp")
file(GLOB SIGPATH "src/signal_path/*.cpp")
file(GLOB IMGUI "src/imgui/*.cpp")
# Add code to dyn lib
add_library(sdrpp_core SHARED ${SRC} ${IMGUI})
add_library(sdrpp_core SHARED ${SRC} ${GUI} ${SIGPATH} ${IMGUI})
# Include core headers
target_include_directories(sdrpp_core PUBLIC "src/")

Wyświetl plik

@ -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");

Wyświetl plik

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

Wyświetl plik

@ -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;

Wyświetl plik

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

Wyświetl plik

@ -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;
};

Wyświetl plik

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

Wyświetl plik

@ -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();

Wyświetl plik

@ -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

Wyświetl plik

@ -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);
}
}

Wyświetl plik

@ -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;
};

Wyświetl plik

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

Wyświetl plik

@ -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;

Wyświetl plik

@ -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

Wyświetl plik

@ -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;

Wyświetl plik

@ -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 {

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -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;
};

Wyświetl plik

@ -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);
}
}
}

Wyświetl plik

@ -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;
};

Wyświetl plik

@ -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);
}
}
}
};

Wyświetl plik

@ -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();
};

Wyświetl plik

@ -1,6 +1,13 @@
cmake_minimum_required(VERSION 3.13)
project(demo)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive -fsanitize=address -g")
# set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)
file(GLOB SRC "src/*.cpp")
add_library(demo SHARED ${SRC})

Wyświetl plik

@ -6,7 +6,7 @@
#include <thread>
#include <ctime>
#include <stdio.h>
#include <style.h>
#include <gui/style.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())

Wyświetl plik

@ -3,53 +3,14 @@ project(radio)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
link_directories(radio "C:/Program Files/PothosSDR/lib/")
include_directories(radio "C:/Program Files/PothosSDR/include/volk/")
include_directories(radio "C:/Program Files/PothosSDR/include/")
else()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fsanitize=address -g")
include_directories(radio "/usr/include/volk")
link_libraries(pthread)
link_libraries(GL)
link_libraries(GLEW)
link_libraries(glfw)
link_libraries(fftw3)
link_libraries(fftw3f)
link_libraries(portaudio)
link_libraries(X11)
link_libraries(Xxf86vm)
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive -fsanitize=address -g")
# set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive")
endif (MSVC)
link_libraries(volk)
link_libraries(SoapySDR)
# Main code
include_directories(radio "src/")
include_directories(radio "../core/src/")
include_directories(radio "../core/src/imgui")
file(GLOB SRC "src/*.cpp")
file(GLOB IMGUI "../core/src/imgui/*.cpp")
add_library(radio SHARED ${SRC} ${IMGUI})
set_target_properties(radio PROPERTIES PREFIX "")
if (MSVC)
# Glew
find_package(GLEW REQUIRED)
target_link_libraries(radio PRIVATE GLEW::GLEW)
include_directories("src/")
# GLFW3
find_package(glfw3 CONFIG REQUIRED)
target_link_libraries(radio PRIVATE glfw)
# FFTW3
find_package(FFTW3 CONFIG REQUIRED)
target_link_libraries(radio PRIVATE FFTW3::fftw3)
find_package(FFTW3f CONFIG REQUIRED)
target_link_libraries(radio PRIVATE FFTW3::fftw3f)
# PortAudio
find_package(portaudio CONFIG REQUIRED)
target_link_libraries(radio PRIVATE portaudio portaudio_static)
endif (MSVC)
# cmake .. "-DCMAKE_TOOLCHAIN_FILE=C:/Users/Alex/vcpkg/scripts/buildsystems/vcpkg.cmake" -G "Visual Studio 15 2017 Win64"
add_library(radio SHARED ${SRC})
target_link_libraries(radio PRIVATE sdrpp_core)

Wyświetl plik

@ -25,7 +25,7 @@ MOD_EXPORT void* _INIT_(mod::API_t* _API, ImGuiContext* imctx, std::string _name
ctx->bandWidth = 200000;
ctx->bandWidthMin = 100000;
ctx->bandWidthMax = 200000;
ctx->sigPath.init(_name, 200000, 1000, API->registerVFO(_name, mod::API_t::REF_CENTER, 0, 200000, 200000, 1000));
ctx->sigPath.init(_name, 200000, 1000);
ctx->sigPath.start();
ImGui::SetCurrentContext(imctx);
return ctx;
@ -49,7 +49,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) {
ctx->bandWidthMin = 8000;
ctx->bandWidthMax = 16000;
ctx->sigPath.setDemodulator(SigPath::DEMOD_NFM, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_CENTER);
}
if (ImGui::RadioButton(CONCAT("WFM##_", ctx->name), ctx->demod == 1) && ctx->demod != 1) {
ctx->demod = 1;
@ -57,7 +56,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) {
ctx->bandWidthMin = 100000;
ctx->bandWidthMax = 200000;
ctx->sigPath.setDemodulator(SigPath::DEMOD_FM, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_CENTER);
}
ImGui::NextColumn();
if (ImGui::RadioButton(CONCAT("AM##_", ctx->name), ctx->demod == 2) && ctx->demod != 2) {
@ -66,7 +64,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) {
ctx->bandWidthMin = 6250;
ctx->bandWidthMax = 12500;
ctx->sigPath.setDemodulator(SigPath::DEMOD_AM, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_CENTER);
}
if (ImGui::RadioButton(CONCAT("DSB##_", ctx->name), ctx->demod == 3) && ctx->demod != 3) {
ctx->demod = 3;
@ -74,7 +71,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) {
ctx->bandWidthMin = 3000;
ctx->bandWidthMax = 6000;
ctx->sigPath.setDemodulator(SigPath::DEMOD_DSB, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_CENTER);
}
ImGui::NextColumn();
if (ImGui::RadioButton(CONCAT("USB##_", ctx->name), ctx->demod == 4) && ctx->demod != 4) {
@ -83,7 +79,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) {
ctx->bandWidthMin = 1500;
ctx->bandWidthMax = 3000;
ctx->sigPath.setDemodulator(SigPath::DEMOD_USB, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_LOWER);
}
if (ImGui::RadioButton(CONCAT("CW##_", ctx->name), ctx->demod == 5) && ctx->demod != 5) { ctx->demod = 5; };
ImGui::NextColumn();
@ -93,7 +88,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) {
ctx->bandWidthMin = 1500;
ctx->bandWidthMax = 3000;
ctx->sigPath.setDemodulator(SigPath::DEMOD_LSB, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_UPPER);
}
if (ImGui::RadioButton(CONCAT("RAW##_", ctx->name), ctx->demod == 7) && ctx->demod != 7) {
ctx->demod = 7;
@ -101,7 +95,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) {
ctx->bandWidthMin = 3000;
ctx->bandWidthMax = 10000;
ctx->sigPath.setDemodulator(SigPath::DEMOD_RAW, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_CENTER);
};
ImGui::Columns(1, CONCAT("EndRadioModeColumns##_", ctx->name), false);

Wyświetl plik

@ -18,11 +18,13 @@ int SigPath::sampleRateChangeHandler(void* ctx, float sampleRate) {
return _this->audioResamp.getOutputBlockSize();
}
void SigPath::init(std::string vfoName, uint64_t sampleRate, int blockSize, dsp::stream<dsp::complex_t>* input) {
void SigPath::init(std::string vfoName, uint64_t sampleRate, int blockSize) {
this->sampleRate = sampleRate;
this->blockSize = blockSize;
this->vfoName = vfoName;
vfo = sigpath::vfoManager.createVFO(vfoName, mod::API_t::REF_CENTER, 0, 200000, 200000, 1000);
_demod = DEMOD_FM;
_deemp = DEEMP_50US;
bandwidth = 200000;
@ -31,10 +33,10 @@ void SigPath::init(std::string vfoName, uint64_t sampleRate, int blockSize, dsp:
// TODO: ajust deemphasis for different output sample rates
// TODO: Add a mono to stereo for different modes
demod.init(input, 100000, 200000, 800);
amDemod.init(input, 50);
ssbDemod.init(input, 6000, 3000, 22);
cpx2stereo.init(input, 22);
demod.init(vfo->output, 100000, 200000, 800);
amDemod.init(vfo->output, 50);
ssbDemod.init(vfo->output, 6000, 3000, 22);
cpx2stereo.init(vfo->output, 22);
audioResamp.init(&demod.output, 200000, 48000, 800);
deemp.init(&audioResamp.output, 800, 50e-6, 48000);
@ -91,72 +93,79 @@ void SigPath::setDemodulator(int demId, float bandWidth) {
// Set input of the audio resampler
// TODO: Set bandwidth from argument
if (demId == DEMOD_FM) {
API->setVFOSampleRate(vfoName, 200000, bandwidth);
demod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
vfo->setSampleRate(200000, bandwidth);
demod.setBlockSize(vfo->getOutputBlockSize());
demod.setSampleRate(200000);
demod.setDeviation(bandwidth / 2.0f);
audioResamp.setInput(&demod.output);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(200000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
audioResamp.setInputSampleRate(200000, vfo->getOutputBlockSize(), audioBw, audioBw);
deemp.bypass = (_deemp == DEEMP_NONE);
vfo->setReference(mod::API_t::REF_CENTER);
demod.start();
}
else if (demId == DEMOD_NFM) {
API->setVFOSampleRate(vfoName, 16000, bandwidth);
demod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
vfo->setSampleRate(16000, bandwidth);
demod.setBlockSize(vfo->getOutputBlockSize());
demod.setSampleRate(16000);
demod.setDeviation(bandwidth / 2.0f);
audioResamp.setInput(&demod.output);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(16000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
audioResamp.setInputSampleRate(16000, vfo->getOutputBlockSize(), audioBw, audioBw);
deemp.bypass = true;
vfo->setReference(mod::API_t::REF_CENTER);
demod.start();
}
else if (demId == DEMOD_AM) {
API->setVFOSampleRate(vfoName, 12500, bandwidth);
amDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
vfo->setSampleRate(12500, bandwidth);
amDemod.setBlockSize(vfo->getOutputBlockSize());
audioResamp.setInput(&amDemod.output);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(12500, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
audioResamp.setInputSampleRate(12500, vfo->getOutputBlockSize(), audioBw, audioBw);
deemp.bypass = true;
vfo->setReference(mod::API_t::REF_CENTER);
amDemod.start();
}
else if (demId == DEMOD_USB) {
API->setVFOSampleRate(vfoName, 6000, bandwidth);
ssbDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
vfo->setSampleRate(6000, bandwidth);
ssbDemod.setBlockSize(vfo->getOutputBlockSize());
ssbDemod.setMode(dsp::SSBDemod::MODE_USB);
audioResamp.setInput(&ssbDemod.output);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
audioResamp.setInputSampleRate(6000, vfo->getOutputBlockSize(), audioBw, audioBw);
deemp.bypass = true;
vfo->setReference(mod::API_t::REF_LOWER);
ssbDemod.start();
}
else if (demId == DEMOD_LSB) {
API->setVFOSampleRate(vfoName, 6000, bandwidth);
ssbDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
vfo->setSampleRate(6000, bandwidth);
ssbDemod.setBlockSize(vfo->getOutputBlockSize());
ssbDemod.setMode(dsp::SSBDemod::MODE_LSB);
audioResamp.setInput(&ssbDemod.output);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
audioResamp.setInputSampleRate(6000, vfo->getOutputBlockSize(), audioBw, audioBw);
deemp.bypass = true;
vfo->setReference(mod::API_t::REF_UPPER);
ssbDemod.start();
}
else if (demId == DEMOD_DSB) {
API->setVFOSampleRate(vfoName, 6000, bandwidth);
ssbDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
vfo->setSampleRate(6000, bandwidth);
ssbDemod.setBlockSize(vfo->getOutputBlockSize());
ssbDemod.setMode(dsp::SSBDemod::MODE_DSB);
audioResamp.setInput(&ssbDemod.output);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
audioResamp.setInputSampleRate(6000, vfo->getOutputBlockSize(), audioBw, audioBw);
deemp.bypass = true;
vfo->setReference(mod::API_t::REF_CENTER);
ssbDemod.start();
}
else if (demId == DEMOD_RAW) {
API->setVFOSampleRate(vfoName, 10000, bandwidth);
cpx2stereo.setBlockSize(API->getVFOOutputBlockSize(vfoName));
vfo->setSampleRate(10000, bandwidth);
cpx2stereo.setBlockSize(vfo->getOutputBlockSize());
//audioResamp.setInput(&cpx2stereo.output);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(10000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
audioResamp.setInputSampleRate(10000, vfo->getOutputBlockSize(), audioBw, audioBw);
vfo->setReference(mod::API_t::REF_LOWER);
cpx2stereo.start();
}
else {
@ -192,7 +201,7 @@ void SigPath::setDeemphasis(int deemph) {
void SigPath::setBandwidth(float bandWidth) {
bandwidth = bandWidth;
API->setVFOBandwidth(vfoName, bandwidth);
vfo->setBandwidth(bandwidth);
if (_demod == DEMOD_FM) {
demod.stop();
demod.setDeviation(bandwidth / 2.0f);
@ -231,7 +240,7 @@ void SigPath::setBandwidth(float bandWidth) {
if (audioBw != _audioBw) {
audioBw = _audioBw;
audioResamp.stop();
audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
audioResamp.setInputSampleRate(6000, vfo->getOutputBlockSize(), audioBw, audioBw);
audioResamp.start();
}
}

Wyświetl plik

@ -10,11 +10,12 @@
#include <dsp/vfo.h>
#include <io/audio.h>
#include <module.h>
#include <signal_path/signal_path.h>
class SigPath {
public:
SigPath();
void init(std::string vfoName, uint64_t sampleRate, int blockSize, dsp::stream<dsp::complex_t>* input);
void init(std::string vfoName, uint64_t sampleRate, int blockSize);
void start();
void setSampleRate(float sampleRate);
void setVFOFrequency(uint64_t frequency);
@ -46,6 +47,8 @@ public:
private:
static int sampleRateChangeHandler(void* ctx, float sampleRate);
VFOManager::VFO* vfo;
dsp::stream<dsp::complex_t> input;

Wyświetl plik

@ -3,13 +3,13 @@
"Radio": {
"device": "Speakers (Realtek High Definiti",
"sampleRate": 48000.0,
"volume": 0.4032258093357086
"volume": 0.6666666865348816
}
},
"bandPlan": "General",
"bandPlanEnabled": true,
"fftHeight": 300,
"frequency": 99000000,
"frequency": 103200000,
"max": 0.0,
"maximized": false,
"menuWidth": 300,