mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-06-25 12:07:49 +02:00
Fixed support in the module manager
This commit is contained in:
@ -77,6 +77,7 @@ namespace dsp {
|
||||
// NOTE: For some reason, the base class destrcutor doesn't get called.... this is a temporary fix I guess
|
||||
// I also don't check for _block_init for the exact sample reason, something's weird
|
||||
~Reshaper() {
|
||||
if (!generic_block<Reshaper<T>>::_block_init) { return; }
|
||||
generic_block<Reshaper<T>>::stop();
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ namespace dsp {
|
||||
void updateWindow(dsp::filter_window::generic_complex_window* window) {
|
||||
assert(generic_block<FMStereoDemuxPilotFilter>::_block_init);
|
||||
std::lock_guard<std::mutex> lck(generic_block<FMStereoDemuxPilotFilter>::ctrlMtx);
|
||||
std::lock_guard<std::mutex> lck2(bufMtx);
|
||||
_window = window;
|
||||
volk_free(taps);
|
||||
tapCount = window->getTapCount();
|
||||
@ -59,7 +60,7 @@ namespace dsp {
|
||||
int count = _in->read();
|
||||
if (count < 0) { return -1; }
|
||||
|
||||
generic_block<FMStereoDemuxPilotFilter>::ctrlMtx.lock();
|
||||
bufMtx.lock();
|
||||
|
||||
memcpy(bufStart, _in->readBuf, count * sizeof(complex_t));
|
||||
_in->flush();
|
||||
@ -70,12 +71,14 @@ namespace dsp {
|
||||
|
||||
memcpy(dataOut.writeBuf, &buffer[tapCount - ((tapCount-1)/2)], count * sizeof(complex_t));
|
||||
|
||||
if (!dataOut.swap(count)) { return -1; }
|
||||
if (!pilotOut.swap(count)) { return -1; }
|
||||
if (!pilotOut.swap(count) || !dataOut.swap(count)) {
|
||||
bufMtx.unlock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
memmove(buffer, &buffer[count], tapCount * sizeof(complex_t));
|
||||
|
||||
generic_block<FMStereoDemuxPilotFilter>::ctrlMtx.unlock();
|
||||
bufMtx.unlock();
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -89,6 +92,8 @@ namespace dsp {
|
||||
|
||||
dsp::filter_window::generic_complex_window* _window;
|
||||
|
||||
std::mutex bufMtx;
|
||||
|
||||
complex_t* bufStart;
|
||||
complex_t* buffer;
|
||||
int tapCount;
|
||||
|
@ -212,7 +212,7 @@ void MainWindow::init() {
|
||||
|
||||
initComplete = true;
|
||||
|
||||
onInitComplete.emit(true);
|
||||
core::moduleManager.doPostInitAll();
|
||||
}
|
||||
|
||||
void MainWindow::fftHandler(dsp::complex_t* samples, int count, void* ctx) {
|
||||
|
@ -35,7 +35,6 @@ public:
|
||||
bool playButtonLocked = false;
|
||||
|
||||
Event<bool> onPlayStateChange;
|
||||
Event<bool> onInitComplete;
|
||||
|
||||
private:
|
||||
void generateFFTWindow(int win, int size);
|
||||
|
@ -16,11 +16,6 @@ namespace module_manager_menu {
|
||||
modTypes.clear();
|
||||
modTypesTxt = "";
|
||||
for (auto& [name, mod] : core::moduleManager.modules) {
|
||||
// TEMPORARY EXCLUSION FOR SOURCES AND SINKS
|
||||
if (name.find("source") != std::string::npos) { continue; }
|
||||
if (name.find("sink") != std::string::npos) { continue; }
|
||||
if (name.find("recorder") != std::string::npos) { continue; }
|
||||
if (name.find("discord") != std::string::npos) { continue; }
|
||||
modTypes.push_back(name);
|
||||
modTypesTxt += name;
|
||||
modTypesTxt += '\0';
|
||||
@ -38,13 +33,6 @@ namespace module_manager_menu {
|
||||
float height = ImGui::CalcTextSize("-").y;
|
||||
|
||||
for (auto& [name, inst] : core::moduleManager.instances) {
|
||||
// TEMPORARY EXCLUSION FOR SOURCES AND SINKS
|
||||
std::string type = inst.module.info->name;
|
||||
if (type.find("source") != std::string::npos) { continue; }
|
||||
if (type.find("sink") != std::string::npos) { continue; }
|
||||
if (type.find("recorder") != std::string::npos) { continue; }
|
||||
if (type.find("discord") != std::string::npos) { continue; }
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
@ -83,6 +71,7 @@ namespace module_manager_menu {
|
||||
if (strlen(modName) == 0) { style::beginDisabled(); }
|
||||
if (ImGui::Button("+##module_mgr_add_btn", ImVec2(16,0))) {
|
||||
core::moduleManager.createInstance(modName, modTypes[modTypeId]);
|
||||
core::moduleManager.postInit(modName);
|
||||
}
|
||||
if (strlen(modName) == 0) { style::endDisabled(); }
|
||||
ImGui::EndTable();
|
||||
|
@ -12,6 +12,14 @@ namespace sourecmenu {
|
||||
double customOffset = 0.0;
|
||||
double effectiveOffset = 0.0;
|
||||
|
||||
EventHandler<std::string> sourceRegisteredHandler;
|
||||
EventHandler<std::string> sourceUnregisterHandler;
|
||||
EventHandler<std::string> sourceUnregisteredHandler;
|
||||
|
||||
std::vector<std::string> sourceNames;
|
||||
std::string sourceNamesTxt;
|
||||
std::string selectedSource;
|
||||
|
||||
enum {
|
||||
OFFSET_MODE_NONE,
|
||||
OFFSET_MODE_CUSTOM,
|
||||
@ -42,41 +50,94 @@ namespace sourecmenu {
|
||||
sigpath::sourceManager.setTuningOffset(effectiveOffset);
|
||||
}
|
||||
|
||||
void refreshSources() {
|
||||
sourceNames = sigpath::sourceManager.getSourceNames();
|
||||
sourceNamesTxt.clear();
|
||||
for (auto name : sourceNames) {
|
||||
sourceNamesTxt += name;
|
||||
sourceNamesTxt += '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void selectSource(std::string name) {
|
||||
if (sourceNames.empty()) {
|
||||
selectedSource.clear();
|
||||
return;
|
||||
}
|
||||
auto it = std::find(sourceNames.begin(), sourceNames.end(), name);
|
||||
if (it == sourceNames.end()) {
|
||||
selectSource(sourceNames[0]);
|
||||
}
|
||||
sourceId = std::distance(sourceNames.begin(), it);
|
||||
selectedSource = sourceNames[sourceId];
|
||||
sigpath::sourceManager.selectSource(sourceNames[sourceId]);
|
||||
}
|
||||
|
||||
void onSourceRegistered(std::string name, void* ctx) {
|
||||
refreshSources();
|
||||
|
||||
if (selectedSource.empty()) {
|
||||
sourceId = 0;
|
||||
selectSource(sourceNames[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
sourceId = std::distance(sourceNames.begin(), std::find(sourceNames.begin(), sourceNames.end(), selectedSource));
|
||||
}
|
||||
|
||||
void onSourceUnregister(std::string name, void* ctx) {
|
||||
if (name != selectedSource) { return; }
|
||||
|
||||
// TODO: Stop everything
|
||||
}
|
||||
|
||||
void onSourceUnregistered(std::string name, void* ctx) {
|
||||
refreshSources();
|
||||
|
||||
if (sourceNames.empty()) {
|
||||
selectedSource = "";
|
||||
return;
|
||||
}
|
||||
|
||||
if (name == selectedSource) {
|
||||
sourceId = std::clamp<int>(sourceId, 0, sourceNames.size() - 1);
|
||||
selectSource(sourceNames[sourceId]);
|
||||
return;
|
||||
}
|
||||
|
||||
sourceId = std::distance(sourceNames.begin(), std::find(sourceNames.begin(), sourceNames.end(), selectedSource));
|
||||
}
|
||||
|
||||
void init() {
|
||||
core::configManager.acquire();
|
||||
std::string name = core::configManager.conf["source"];
|
||||
auto it = std::find(sigpath::sourceManager.sourceNames.begin(), sigpath::sourceManager.sourceNames.end(), name);
|
||||
if (it != sigpath::sourceManager.sourceNames.end()) {
|
||||
sigpath::sourceManager.selectSource(name);
|
||||
sourceId = std::distance(sigpath::sourceManager.sourceNames.begin(), it);
|
||||
}
|
||||
else if (sigpath::sourceManager.sourceNames.size() > 0) {
|
||||
sigpath::sourceManager.selectSource(sigpath::sourceManager.sourceNames[0]);
|
||||
}
|
||||
else {
|
||||
spdlog::warn("No source available...");
|
||||
}
|
||||
std::string selected = core::configManager.conf["source"];
|
||||
customOffset = core::configManager.conf["offset"];
|
||||
offsetMode = core::configManager.conf["offsetMode"];
|
||||
updateOffset();
|
||||
|
||||
refreshSources();
|
||||
selectSource(selected);
|
||||
|
||||
sourceRegisteredHandler.handler = onSourceRegistered;
|
||||
sourceUnregisterHandler.handler = onSourceUnregister;
|
||||
sourceUnregisteredHandler.handler = onSourceUnregistered;
|
||||
sigpath::sourceManager.onSourceRegistered.bindHandler(&sourceRegisteredHandler);
|
||||
sigpath::sourceManager.onSourceUnregister.bindHandler(&sourceUnregisterHandler);
|
||||
sigpath::sourceManager.onSourceUnregistered.bindHandler(&sourceUnregisteredHandler);
|
||||
|
||||
core::configManager.release();
|
||||
}
|
||||
|
||||
void draw(void* ctx) {
|
||||
std::string items = "";
|
||||
for (std::string name : sigpath::sourceManager.sourceNames) {
|
||||
items += name;
|
||||
items += '\0';
|
||||
}
|
||||
float itemWidth = ImGui::GetContentRegionAvailWidth();
|
||||
|
||||
if (gui::mainWindow.sdrIsRunning()) { style::beginDisabled(); }
|
||||
|
||||
ImGui::SetNextItemWidth(itemWidth);
|
||||
if (ImGui::Combo("##source", &sourceId, items.c_str())) {
|
||||
sigpath::sourceManager.selectSource(sigpath::sourceManager.sourceNames[sourceId]);
|
||||
if (ImGui::Combo("##source", &sourceId, sourceNamesTxt.c_str())) {
|
||||
selectSource(sourceNames[sourceId]);
|
||||
core::configManager.acquire();
|
||||
core::configManager.conf["source"] = sigpath::sourceManager.sourceNames[sourceId];
|
||||
core::configManager.conf["source"] = sourceNames[sourceId];
|
||||
core::configManager.release(true);
|
||||
}
|
||||
|
||||
@ -110,6 +171,5 @@ namespace sourecmenu {
|
||||
ImGui::InputDouble("##freq_offset", &effectiveOffset, 1.0, 100.0);
|
||||
style::endDisabled();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -140,6 +140,14 @@ bool ModuleManager::instanceEnabled(std::string name) {
|
||||
return instances[name].instance->isEnabled();
|
||||
}
|
||||
|
||||
void ModuleManager::postInit(std::string name) {
|
||||
if (instances.find(name) == instances.end()) {
|
||||
spdlog::error("Cannot post-init '{0}', instance doesn't exist", name);
|
||||
return;
|
||||
}
|
||||
instances[name].instance->postInit();
|
||||
}
|
||||
|
||||
std::string ModuleManager::getInstanceModuleName(std::string name) {
|
||||
if (instances.find(name) == instances.end()) {
|
||||
spdlog::error("Cannot get module name of'{0}', instance doesn't exist", name);
|
||||
@ -159,4 +167,11 @@ int ModuleManager::countModuleInstances(std::string module) {
|
||||
if (instance.module == mod) { count++; }
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void ModuleManager::doPostInitAll() {
|
||||
for (auto& [name, inst] : instances) {
|
||||
spdlog::info("Running post-init for {0}", name);
|
||||
inst.instance->postInit();
|
||||
}
|
||||
}
|
@ -42,6 +42,7 @@ public:
|
||||
|
||||
class Instance {
|
||||
public:
|
||||
virtual void postInit() = 0;
|
||||
virtual void enable() = 0;
|
||||
virtual void disable() = 0;
|
||||
virtual bool isEnabled() = 0;
|
||||
@ -84,10 +85,13 @@ public:
|
||||
void enableInstance(std::string name);
|
||||
void disableInstance(std::string name);
|
||||
bool instanceEnabled(std::string name);
|
||||
void postInit(std::string name);
|
||||
std::string getInstanceModuleName(std::string name);
|
||||
|
||||
int countModuleInstances(std::string module);
|
||||
|
||||
void doPostInitAll();
|
||||
|
||||
Event<std::string> onInstanceCreated;
|
||||
Event<std::string> onInstanceDelete;
|
||||
Event<std::string> onInstanceDeleted;
|
||||
|
@ -115,7 +115,7 @@ void SinkManager::registerStream(std::string name, SinkManager::Stream* stream)
|
||||
core::configManager.release();
|
||||
if (available) { loadStreamConfig(name); }
|
||||
|
||||
streamRegisteredEvnt.emit(name);
|
||||
onStreamRegistered.emit(name);
|
||||
}
|
||||
|
||||
void SinkManager::unregisterStream(std::string name) {
|
||||
@ -123,12 +123,13 @@ void SinkManager::unregisterStream(std::string name) {
|
||||
spdlog::error("Cannot unregister stream '{0}', this stream doesn't exist", name);
|
||||
return;
|
||||
}
|
||||
streamUnregisteredEvnt.emit(name);
|
||||
onStreamUnregister.emit(name);
|
||||
SinkManager::Stream* stream = streams[name];
|
||||
stream->stop();
|
||||
delete stream->sink;
|
||||
streams.erase(name);
|
||||
streamNames.erase(std::remove(streamNames.begin(), streamNames.end(), name), streamNames.end());
|
||||
onStreamUnregistered.emit(name);
|
||||
}
|
||||
|
||||
void SinkManager::startStream(std::string name) {
|
||||
|
@ -110,8 +110,9 @@ public:
|
||||
|
||||
std::vector<std::string> getStreamNames();
|
||||
|
||||
Event<std::string> streamRegisteredEvnt;
|
||||
Event<std::string> streamUnregisteredEvnt;
|
||||
Event<std::string> onStreamRegistered;
|
||||
Event<std::string> onStreamUnregister;
|
||||
Event<std::string> onStreamUnregistered;
|
||||
|
||||
private:
|
||||
void loadStreamConfig(std::string name);
|
||||
|
@ -12,7 +12,27 @@ void SourceManager::registerSource(std::string name, SourceHandler* handler) {
|
||||
return;
|
||||
}
|
||||
sources[name] = handler;
|
||||
sourceNames.push_back(name);
|
||||
onSourceRegistered.emit(name);
|
||||
}
|
||||
|
||||
void SourceManager::unregisterSource(std::string name) {
|
||||
if (sources.find(name) == sources.end()) {
|
||||
spdlog::error("Tried to unregister non existant source: {0}", name);
|
||||
return;
|
||||
}
|
||||
onSourceUnregister.emit(name);
|
||||
if (name == selectedName) {
|
||||
sigpath::signalPath.setInput(&nullSource);
|
||||
selectedHandler = NULL;
|
||||
}
|
||||
sources.erase(name);
|
||||
onSourceUnregistered.emit(name);
|
||||
}
|
||||
|
||||
std::vector<std::string> SourceManager::getSourceNames() {
|
||||
std::vector<std::string> names;
|
||||
for (auto const& [name, src] : sources) { names.push_back(name); }
|
||||
return names;
|
||||
}
|
||||
|
||||
void SourceManager::selectSource(std::string name) {
|
||||
@ -20,7 +40,7 @@ void SourceManager::selectSource(std::string name) {
|
||||
spdlog::error("Tried to select non existant source: {0}", name);
|
||||
return;
|
||||
}
|
||||
if (selectedName != "") {
|
||||
if (selectedHandler != NULL) {
|
||||
sources[selectedName]->deselectHandler(sources[selectedName]->ctx);
|
||||
}
|
||||
selectedHandler = sources[name];
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <map>
|
||||
#include <dsp/stream.h>
|
||||
#include <dsp/types.h>
|
||||
#include <utils/event.h>
|
||||
|
||||
class SourceManager {
|
||||
public:
|
||||
@ -21,6 +22,7 @@ public:
|
||||
};
|
||||
|
||||
void registerSource(std::string name, SourceHandler* handler);
|
||||
void unregisterSource(std::string name);
|
||||
void selectSource(std::string name);
|
||||
void showSelectedMenu();
|
||||
void start();
|
||||
@ -28,7 +30,11 @@ public:
|
||||
void tune(double freq);
|
||||
void setTuningOffset(double offset);
|
||||
|
||||
std::vector<std::string> sourceNames;
|
||||
std::vector<std::string> getSourceNames();
|
||||
|
||||
Event<std::string> onSourceRegistered;
|
||||
Event<std::string> onSourceUnregister;
|
||||
Event<std::string> onSourceUnregistered;
|
||||
|
||||
private:
|
||||
std::map<std::string, SourceHandler*> sources;
|
||||
@ -36,5 +42,6 @@ private:
|
||||
SourceHandler* selectedHandler = NULL;
|
||||
double tuneOffset;
|
||||
double currentFreq;
|
||||
dsp::stream<dsp::complex_t> nullSource;
|
||||
|
||||
};
|
Reference in New Issue
Block a user