From 8f28b2f76821fa0fcee844d9e2a7fe2684223d43 Mon Sep 17 00:00:00 2001 From: itten Date: Thu, 9 Jul 2026 20:39:41 +0300 Subject: [PATCH] gaindb node --- CMakeLists.txt | 1 + gain-check.json | 24 +++++++++++++++ nodes/gaindb/CMakeLists.txt | 4 +++ nodes/gaindb/main.cpp | 58 +++++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 gain-check.json create mode 100644 nodes/gaindb/CMakeLists.txt create mode 100644 nodes/gaindb/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fc7eb0..ecc4e80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,6 +114,7 @@ endif() add_subdirectory(nodes/videoin) add_subdirectory(nodes/pip) +add_subdirectory(nodes/gaindb) # ── Asio standalone (needed by Crow; no Boost) ─────────────────────────────── FetchContent_Declare(asio_fc diff --git a/gain-check.json b/gain-check.json new file mode 100644 index 0000000..831cb32 --- /dev/null +++ b/gain-check.json @@ -0,0 +1,24 @@ +{ + "nodes": [ + { "id": "testpattern", "type": "testpattern", "params": { "pattern": "bars" } }, + { "id": "gaindb", "type": "gaindb", "params": {} }, + { "id": "ndiout", "type": "ndiout", "params": {} } + ], + "edges": [ + { + "from": "testpattern", "from_port": "video_flow_id", + "to": "ndiout", "to_port": "video_flow_id", + "format": { "kind": "video", "width": 1920, "height": 1080, "fps_num": 25, "fps_den": 1 } + }, + { + "from": "testpattern", "from_port": "audio_flow_id", + "to": "gaindb", "to_port": "audio_in_flow_id", + "format": { "kind": "audio", "sample_rate": 48000, "channels": 2, "bit_depth": 32 } + }, + { + "from": "gaindb", "from_port": "audio_out_flow_id", + "to": "ndiout", "to_port": "audio_flow_id", + "format": { "kind": "audio", "sample_rate": 48000, "channels": 2, "bit_depth": 32 } + } + ] +} diff --git a/nodes/gaindb/CMakeLists.txt b/nodes/gaindb/CMakeLists.txt new file mode 100644 index 0000000..2063b5a --- /dev/null +++ b/nodes/gaindb/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable(dmf-node-gaindb main.cpp) +target_compile_features(dmf-node-gaindb PRIVATE cxx_std_20) +target_link_libraries(dmf-node-gaindb PRIVATE dmf-shared) +install(TARGETS dmf-node-gaindb RUNTIME DESTINATION bin) diff --git a/nodes/gaindb/main.cpp b/nodes/gaindb/main.cpp new file mode 100644 index 0000000..6dc8db1 --- /dev/null +++ b/nodes/gaindb/main.cpp @@ -0,0 +1,58 @@ +#include +#include "NodeBase.hpp" +#include "FlowDef.hpp" +#include +#include + +namespace dmf { +class GainDbNode: public dmf::NodeBase { + void run() override { + if (!config().contains("audio_in_flow_id") || !config().contains("audio_out_flow_id")) { + log("no audio connected to in or out"); + return; + } + const std::string in_flow_id = config().at("audio_in_flow_id").at("id").get(); + dmf::AudioFlowInfo in_flow_info = dmf::read_audio_flow_info(domain(), in_flow_id); + int gain = 0; + if (config().contains("gain")) { + gain = config().at("gain").get(); + } + // create writer + int sample_rate = in_flow_info.sample_rate; + const std::string out_flow_id = config().at("audio_out_flow_id").at("id").get(); + std::string flow_def = dmf::make_audio_flow_def( + out_flow_id, + node_id(), + sample_rate, + in_flow_info.channels, + 32, + sample_rate, + in_flow_info.samples_per_grain + ); + mxlFlowWriter writer{}; + mxlFlowConfigInfo cfg{}; + bool created = false; + mxlStatus st = mxlCreateFlowWriter(instance(), flow_def.c_str(), nullptr, &writer, &cfg, &created); + if (st != MXL_STATUS_OK) { + log("audio mxlCreateFlowWriter failed (%s) — continuing without audio", dmf::mxl_status_str(st)); + } else { + log("audio channels=%u buffer=%u samples", + cfg.continuous.channelCount, cfg.continuous.bufferLength); + } + + const mxlRational rate = {sample_rate, 1}; + uint64_t index = mxlGetCurrentIndex(&rate); + while (dmf::g_running.load(std::memory_order_relaxed)) { + mxlMutableBufferSlice slice{}; + uint8_t* buf = nullptr; + + } + mxlReleaseFlowWriter(instance(), writer); + } +}; +} + +int main() { + dmf::GainDbNode node; + return node.execute(); +} \ No newline at end of file