satdump/src-core/dsp/flowgraph/dsp_flowgraph_handler.cpp
juliasat 6322781773
freq_shift using block.h WIP!!
Will be brought back to block_simple.h
2025-05-17 13:06:53 -03:00

217 lines
9 KiB
C++

#include "dsp_flowgraph_handler.h"
#include "core/plugin.h"
#include "dsp/agc/agc.h"
#include "dsp/device/dev.h"
#include "dsp/fft/fft_pan.h"
#include "dsp/filter/rrc.h"
#include "dsp/io/file_source.h"
#include "dsp/utils/cyclostationary_analysis.h"
#include "dsp/utils/freq_shift.h"
#include "imgui/imnodes/imnodes.h"
#include "logger.h"
#include "common/widgets/fft_plot.h"
#include "common/dsp/filter/firdes.h"
#include "dsp/filter/fir.h"
#include "dsp/clock_recovery/clock_recovery_mm.h"
#include "dsp/const/const_disp.h"
#include "dsp/pll/costas.h"
#include "dsp/utils/correct_iq.h"
#include "dsp/utils/delay_one_imag.h"
#include "dsp/utils/freq_shift.h"
#include "nlohmann/json_utils.h"
#include <memory>
// #include "dsp/device/airspy/airspy_dev.h"
namespace satdump
{
namespace viewer
{
class NodeTestFileSource : public ndsp::NodeInternal
{
public:
NodeTestFileSource(const ndsp::Flowgraph *f) : ndsp::NodeInternal(f, std::make_shared<ndsp::FileSourceBlock>()) {}
virtual bool render()
{
ndsp::NodeInternal::render();
float prog = double(((ndsp::FileSourceBlock *)blk.get())->d_progress) / double(((ndsp::FileSourceBlock *)blk.get())->d_filesize);
ImGui::ProgressBar(prog, {100, 20});
return false;
}
};
class NodeTestConst : public ndsp::NodeInternal
{
public:
NodeTestConst(const ndsp::Flowgraph *f) : ndsp::NodeInternal(f, std::make_shared<ndsp::ConstellationDisplayBlock>()) {}
virtual bool render()
{
ndsp::NodeInternal::render();
((ndsp::ConstellationDisplayBlock *)blk.get())->constel.draw();
return false;
}
};
// class NodeTestFreqShift : public ndsp::NodeInternal
// {
// public:
// NodeTestFreqShift(const ndsp::Flowgraph *f) : ndsp::NodeInternal(f, std::make_shared<ndsp::FreqShiftBlock>()) { ((ndsp::FreqShiftBlock *)blk.get())->set_freq(6e6, 10000); }
// };
class NodeTestFFT : public ndsp::NodeInternal
{
private:
widgets::FFTPlot fft;
public:
NodeTestFFT(const ndsp::Flowgraph *f) : ndsp::NodeInternal(f, std::make_shared<ndsp::FFTPanBlock>()), fft(((ndsp::FFTPanBlock *)blk.get())->output_fft_buff, 8192, -150, 150)
{
((ndsp::FFTPanBlock *)blk.get())->set_fft_settings(8192, 6e6);
}
virtual bool render()
{
ndsp::NodeInternal::render();
fft.draw({500, 500});
return false;
}
};
DSPFlowGraphHandler::DSPFlowGraphHandler()
{
// TODOREWORK
if (ImNodes::GetCurrentContext() == nullptr)
ImNodes::CreateContext();
handler_tree_icon = u8"\uf92f";
flowgraph.node_internal_registry.insert({"file_source_cc", {"IO/File Source", [](const ndsp::Flowgraph *f) { return std::make_shared<NodeTestFileSource>(f); }}});
flowgraph.node_internal_registry.insert(
{"agc_cc", {"Agc/Agc CC", [](const ndsp::Flowgraph *f) { return std::make_shared<ndsp::NodeInternal>(f, std::make_shared<ndsp::AGCBlock<complex_t>>()); }}});
flowgraph.node_internal_registry.insert({"fft_pan_cc", {"FFT/FFT Pan", [](const ndsp::Flowgraph *f) { return std::make_shared<NodeTestFFT>(f); }}});
// flowgraph.node_internal_registry.insert({"fir_rrc_cc", {"Filter/FIR RRC Filter CC", [](const ndsp::Flowgraph *f) { return std::make_shared<NodeTestRRC>(f, true); }}});
// flowgraph.node_internal_registry.insert({"fir_rrc_ff", {"Filter/FIR RRC Filter FF", [](const ndsp::Flowgraph *f) { return std::make_shared<NodeTestRRC>(f, false); }}});
flowgraph.node_internal_registry.insert(
{"costas_cc", {"PLL/Costas Loop", [](const ndsp::Flowgraph *f) { return std::make_shared<ndsp::NodeInternal>(f, std::make_shared<ndsp::CostasBlock>()); }}});
flowgraph.node_internal_registry.insert({"const_disp_cc", {"View/Constellation Display", [](const ndsp::Flowgraph *f) { return std::make_shared<NodeTestConst>(f); }}});
flowgraph.node_internal_registry.insert(
{"mm_clock_recovery_cc",
{"PLL/Clock Recovery MM CC", [=](const ndsp::Flowgraph *f) { return std::make_shared<ndsp::NodeInternal>(f, std::make_shared<ndsp::MMClockRecoveryBlock<complex_t>>()); }}});
flowgraph.node_internal_registry.insert(
{"rrc_fir_cc", {"RRC FIR CC", [](const ndsp::Flowgraph *f) { return std::make_shared<ndsp::NodeInternal>(f, std::make_shared<ndsp::RRC_FIRBlock<complex_t>>()); }}});
flowgraph.node_internal_registry.insert(
{"cyclostationary_analysis_cf",
{"Utils/Cyclostationary Analysis", [](const ndsp::Flowgraph *f) { return std::make_shared<ndsp::NodeInternal>(f, std::make_shared<ndsp::CyclostationaryAnalysis>()); }}});
flowgraph.node_internal_registry.insert(
{"delay_one_imag_cc", {"Utils/Delay One Imag", [](const ndsp::Flowgraph *f) { return std::make_shared<ndsp::NodeInternal>(f, std::make_shared<ndsp::DelayOneImagBlock>()); }}});
flowgraph.node_internal_registry.insert(
{"correct_iq_cc", {"Utils/Correct IQ", [](const ndsp::Flowgraph *f) { return std::make_shared<ndsp::NodeInternal>(f, std::make_shared<ndsp::CorrectIQBlock<complex_t>>()); }}});
flowgraph.node_internal_registry.insert(
{"freq_shift_cc", {"Utils/Frequency Shift", [](const ndsp::Flowgraph *f) { return std::make_shared<ndsp::NodeInternal>(f, std::make_shared<ndsp::FreqShiftBlock>()); }}});
// flowgraph.node_internal_registry.insert({"airspy_dev_cc", {"Airspy Dev", [=](const ndsp::Flowgraph *f)
// { return std::make_shared<ndsp::NodeInternal>(f, std::make_shared<ndsp::AirspyDevBlock>()); }}});
eventBus->fire_event<RegisterNodesEvent>({flowgraph.node_internal_registry});
#if 0
// Local devices!!
std::vector<ndsp::DeviceInfo> found_devices = ndsp::getDeviceList();
for (auto &dev : found_devices)
{
flowgraph.node_internal_registry.insert({"idk_dev_cc",
{"Local Devs/" + dev.name, [dev](const ndsp::Flowgraph *f)
{ return std::make_shared<ndsp::NodeInternal>(f, ndsp::getDeviceInstanceFromInfo(dev, ndsp::DeviceBlock::MODE_NORMAL)); }}});
}
#endif
}
DSPFlowGraphHandler::~DSPFlowGraphHandler()
{
if (flow_thread.joinable())
flow_thread.join();
}
void DSPFlowGraphHandler::drawMenu()
{
bool running = flowgraph.is_running;
if (ImGui::CollapsingHeader("Flowgraph"))
{
if (running)
{
if (ImGui::Button("Stop"))
flowgraph.stop();
}
else
{
if (ImGui::Button("Start"))
{
if (flow_thread.joinable())
flow_thread.join();
auto fun = [&]() { flowgraph.run(); };
flow_thread = std::thread(fun);
}
}
if (running)
style::beginDisabled();
/*auto pos = ImGui::GetCursorPos();
ImGui::Button("##test", {50, 50});
pos.x += 10;
ImGui::GetWindowDrawList()
->AddTriangleFilled({pos.x + 10, pos.y + 43},
{pos.x + 10, pos.y + 77},
{pos.x + 40, pos.y + 60},
ImColor(255, 255, 255, 255));*/
// needs_to_update |= TODO; // TODOREWORK move in top drawMenu?
if (ImGui::Button("To JSON"))
{
std::string json = flowgraph.getJSON().dump(4);
ImGui::SetClipboardText(json.c_str());
}
if (ImGui::Button("From JSON"))
{
nlohmann::json v = nlohmann::json::parse(ImGui::GetClipboardText());
flowgraph.setJSON(v);
}
if (running)
style::endDisabled();
}
if (ImGui::CollapsingHeader("Variables"))
{
if (running)
style::beginDisabled();
// flowgraph.var_manager_test.drawVariables();
if (running)
style::endDisabled();
}
}
void DSPFlowGraphHandler::drawContents(ImVec2 win_size) { flowgraph.render(); }
} // namespace viewer
} // namespace satdump