NDIlib_audio_frame_v3_t.p_data is uint8_t*, not float*. Calling
vector<float>::assign(uint8_t*, uint8_t*+N) converted each individual
byte (0-255) into a separate float instead of reinterpreting 4 bytes
as one float sample — producing complete noise on playback.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
On status_change, probe() the new format and compare against the
format used to create the MXL flow. If resolution or fps changed,
throw with a descriptive message so the caller exits cleanly.
The existing catch in NDIInNode::run() logs the reason and breaks
out of the loop, causing the process to exit. Studio-manager detects
the exit and logs it — operator can restart to pick up the new format.
Same-format status changes (e.g. metadata only) still return false
and repeat the last frame as before.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>