Commit Graph

15 Commits

Author SHA1 Message Date
JohannesItten 3820d0eeb7 combiner.md 2026-07-09 15:49:35 +03:00
JohannesItten 6c6225d831 fix: don't double-send status to command requester
load_graph/stop_node/start_node each called notify() (push to all
clients) and then sent a direct response — the requesting client
got two identical messages, breaking test recv sequencing.

Use thread_local tl_requester to skip the requesting connection
in the push. notify() is called synchronously from the command,
so the thread_local is visible from the status_cb. Other clients
still receive the push; the requester gets only the direct response.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 22:39:09 +03:00
JohannesItten 0b6e9ce46a fist API trys 2026-07-07 18:56:15 +03:00
JohannesItten 1496cc2e1e refactor: rename video port flow_id → video_flow_id everywhere
All nodes now use video_flow_id/audio_flow_id consistently:
- nodes/testpattern: flow_id → video_flow_id
- nodes/fakesink:    flow_id → video_flow_id
- graph.json:        from_port/to_port flow_id → video_flow_id
- studio-manager:    hardcoded build_graph edges + FlowGraph.hpp comment

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-05 12:52:48 +03:00
JohannesItten a422cd832a feat: graph-level fanout — reuse flow UUID for same from_node+from_port
Edges that share the same source node and port now get the same MXL flow
UUID. One writer, multiple independent readers — each tracks its own
position in the ring buffer. Enables 1-to-N routing in graph.json without
any splitter node.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 10:43:41 +03:00
JohannesItten 2b0dfb10c6 feat: load pipeline graph from graph.json
studio-manager now accepts an optional path argument:
  dmf-studio-manager graph.json

load_graph() parses nodes and edges from JSON, generating fresh UUIDs
for each MXL flow on every launch. Falls back to hardcoded build_graph()
when no argument is given.

graph.json at repo root defines the current testpattern→ndiout pipeline.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 10:36:20 +03:00
JohannesItten f2515b7ce2 fix: MXL_ERR_FLOW_INVALID reconnect, nullptr→"" options, null guards
Readers (ndiout, fakesink) now handle MXL_ERR_FLOW_INVALID by releasing
and recreating the flow reader, then realigning the index to current time.
This lets consumer nodes survive a producer restart without exiting.

All mxlCreateInstance/FlowWriter/FlowReader options args changed from
nullptr to "" to match MXL reference implementation style.

mxlReleaseFlowReader calls guarded with null checks so cleanup is safe
when a mid-run reconnect attempt fails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 10:28:30 +03:00
JohannesItten 21a8ee4ba0 feat: garbage collection on startup, readable status strings, audio/float32
studio-manager: call mxlGarbageCollectFlows before launching nodes to
clean up stale flow directories left by previous crashed runs.

shared/NodeBase.hpp: add mxl_status_str(mxlStatus) — converts error
codes to readable names (e.g. MXL_ERR_OUT_OF_RANGE_TOO_LATE). All
nodes now log these names instead of raw integers.

shared/FlowDef.hpp: use "audio/float32" as media_type for 32-bit audio
flows, matching the MXL SDK examples. audio/L{n} kept for other depths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 10:20:53 +03:00
itten ba3c2994ee ndi out before refactoring 2026-07-03 09:52:29 +03:00
JohannesItten bb4d527cbe feat: sine tone audio in testpattern node
testpattern now optionally writes an audio flow when audio_flow_id is
wired in the graph. Each channel generates a sine wave at (c+1)*1000 Hz
(ch0=1kHz, ch1=2kHz, ...) at -18 dBFS broadcast reference level.

Phase is derived from the absolute audio_index so there are no clicks
at frame boundaries. One audio chunk per video frame (1920 samples at
48kHz/25fps), written via mxlFlowWriterOpenSamples with ring-buffer
fragment and channel stride handling matching ndiin.

build_graph: separate UUIDs for testpattern and ndiin flows; wire
testpattern audio_flow_id (no sink yet).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 13:26:22 +03:00
JohannesItten 42507886fe feat: multiple test patterns in testpattern node
V210.hpp: add fill_colorbars, fill_ire_ramp, fill_black, fill_white.
Shared fill_solid helper stamps the first line across all rows via
memcpy. Generic write_palette_line template handles both SMPTE and
IRE bar palettes. fill_frame kept as a backward-compat alias.

testpattern/main.cpp: read "pattern" from node config and dispatch
to the appropriate fill function (bars/ire/black/white).

build_graph: pass {"pattern","bars"} to testpattern node params.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 13:24:06 +03:00
JohannesItten cc1011cced feat: NDI in node receives and writes audio flow
- FlowDef.hpp: add make_audio_flow_def (NMOS IS-04 audio/Lnn flow)
- NDIReceiver: replace capture_v210 with capture() — single recv call
  dispatches to FrameKind::{Video,Audio,None}; AudioInfo struct carries
  sample_rate/channels/samples/channel_stride
- ndiin: optional audio writer when graph wires audio_flow_id; single
  loop with 5ms NDI poll; audio grains written immediately on arrival;
  video grains written when mxlGetCurrentIndex reaches video_index
- build_graph: rename ndiin video port flow_id → video_flow_id; add
  audio_flow_id edge (no sink yet — wired to ndiin only)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 12:39:35 +03:00
JohannesItten 10d1282059 feat: fan-out ndiin video flow to both fakesink and ndiout
Share a single UUID across both edges so both readers connect to the
same MXL flow. MXL supports multiple readers per flow natively — each
reader has its own read pointer into the ring buffer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 12:18:12 +03:00
itten 51a1b1b2c8 looks like i forgot about commits 2026-06-25 12:43:53 +03:00
JohannesItten ca682eaf0a Initial commit: testpattern → fakesink pipeline over MXL shared memory
- NodeBase, Signal, FlowDef, V210 shared headers
- testpattern node: SMPTE 75% color bars writer at 25fps
- fakesink node: non-blocking MXL reader with per-second stats
- studio-manager: FlowGraph data model, graph-driven fork/exec launcher
- mxl pinned as submodule at 0ae1dc5

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 13:35:01 +03:00