9.8 KiB
9.8 KiB
Implementation Plan
Implemented
- Repo-local persistence machinery.
- First architecture map.
- Example config for one video source plus two audio sources.
- Sender device discovery script.
- Sender launch script with dry-run mode and per-source FFmpeg commands.
- OBS receiver setup notes.
- Neighbor sender deployment under
C:\Meta\LocalCastBridge. - Madman's desktop start/stop launchers for the sender.
- Receiver OBS scene has
Neighbor PC - VideoandNeighbor PC - FocusriteMedia Sources. - Direct co-streamer loopback capture is now attempted with the repo WASAPI shim instead of Voicemeeter.
- Receiver OBS scene has
Neighbor PC - System Audioon SRT port5102. - Sender script uses
-nostdinand repo-root logs so desktop launchers stay alive and diagnostics land inC:\Meta\LocalCastBridge\logs. - Sender video config is
1920x1080for the interactive desktop. The1024x768SSH session size is not the streaming target. - Desktop
.cmdlaunchers delegate to PowerShell wrappers so paths with spaces and apostrophes are handled in one place. - Audio-field sidecar profile and tool:
config/audio-field.example.jsondeclares the actual distributed six-mic rig: two Kiyo mics, two PS Eye mics, local Focusrite shielded cardioid, neighbor Focusrite shotgun on the co-streamer, two local speakers, placeholder geometry, clock domains, capture policy, calibration sweep settings, and FOA AmbiX ACN/SN3D output.scripts/audio_field.pylists devices, validates shared or distributed profiles, checks local distributed sources, generates calibration sweeps, summarizes clock-domain sync requirements, preserves shared-input capture helpers, and encodes already aligned offline WAVs to FOA.audio_field/contains testable core modules for source buffering, bounded latency convergence, injectable capture/alignment/encoder/sink ports, and pipeline orchestration.docs/audio-field.mdmaps the audio pipeline and its invariants.
- Sensor-fusion render bridge:
localcast.sensor_fusion.calibration_spacesolves fixed-board ChArUco observations into camera poses in one common world frame.localcast.sensor_fusion.surface_featuresmatches cross-view features and triangulates calibrated surface tracks.localcast.sensor_fusion.render_bridgeemits render-frame packets with visual/audio timing metadata and Spout sender identity.localcast.sensor_fusion.cultcache_docsstores live visual state as typed CultCache MessagePack documents.localcast.sensor_fusion.spout_outputrenders render-frame packets into a GPU texture and publishes it as a named Spout sender for OBS.scripts/live_sensor_fusion.pywrites fused render frames intocalibration/runs/visual-state.msgpack.- The live visual producer writes a multi-LOD scene cache with source kind and priority. Real Leap frames are promoted as the highest-priority visual timing/spatial evidence; Leap fallback frames remain lower-priority diagnostics.
- Live clap calibration is wired into the visual producer. It keeps a rolling frame window from the Kiyo pair plus Leap, reads the live spatial audio frame for transient candidates, publishes
clap-events.msgpack, injects clap calibration markers into the render frame, and writes clap evidence into the LOD cache. Kiyo stereo owns the current rough 3D solve; Leap owns the best visual timing witness until its geometric model is calibrated. - Clap peaks now update a per-camera clock sync model. The point-cloud builder can sample camera history buffers at
oracle_time - camera_offsetinstead of using whichever frame arrived last. localcast.sensor_fusion.chirp_poseconverts live phase-field delay meaning for Kiyo/PS Eye microphone sources into camera-body range constraints. It can load camera-mic and speaker geometry from the audio-field profile, with the example profile used as the live fallback until measured local geometry exists.scripts/live_sensor_fusion.pyinjects those constraints ascamera-chirp:*render points andchirp-camera-poseLOD evidence.scripts/stream_spout.pyruns the deadline Spout sender loop from the typed cache with typed and JSON heartbeat status.- The deadline Spout renderer has a named
kiyo-mid-deruvirtual camera preset: eye at the midpoint between the two Kiyo-class cameras and target on the co-streamer body volume. It also applies a renderer-owned point budget with pinned calibration/cross-modal constraints, stable high-confidence anchors, and frame-varying remainder samples so downstream TAA/supersampling can accumulate detail without forcing every source claim into every OBS frame. docs/obs-spout-streaming.mddocuments OBS setup and the Aquarium replacement boundary.docs/typed-visual-state.mddocuments the CultCache/CultNet visual boundary.
- OBS synchronized program surface:
scripts/setup_obs_synced_program.pyderives OBS-controllable stems from an aligned program audio timeline: host voice, co-streamer voice, ambient, transients, co-streamer loopback, and local loopback.scripts/capture_co_streamer_surfaces.pycaptures neighbor Focusrite and neighbor loopback with local loopback ground truth, estimates the late remote-family offset, and writes aligned co-streamer surfaces for the stem packer.scripts/wasapi-loopback-capture.ps1is the direct primary-playback loopback path. It must run in the neighbor's interactive console session; SSH-only capture sees the device but receives no render packets.- The tool creates/updates local OBS Media Sources for those stems and mutes/disables raw unsynchronized inputs.
- Strict mode disables every scene item except the synchronized LocalCastBridge program video and stem controls.
- Live phase-field meaning:
audio_field.phase_meaningextracts actionable delay, coherence, confidence, suppression, correction-energy, and active-probe need from internal phase/chirplet evidence.localcast.audio.phase_fieldis a typed CultCache document atcalibration/runs/audio-phase-field.msgpack.scripts/stream_phase_field.pypublishes the live meaning document from an aligned mic field plus known program/loopback reference without exposing raw phase bands as the renderer API.audio_field.active_probewires low phase-field confidence intoActiveProbeOptimizer, emits bounded chirplet WAVs plusactive-probes.jsonl, and can play probes through the default output device.scripts/start-live-audio-phase-field.ps1starts the live dense harmonic confidence loop with near-ultrasonic probes;scripts/stop-live-audio-phase-field.ps1stops the PID recorded inlogs/audio-phase-field.pid.
- Faust voice-separation boundary:
localcast.audio.mic_fieldpublishes aligned six-mic float32 blocks atcalibration/runs/audio-mic-field.msgpack.faust/localcast_voice_separation.dspis the first Aquarium-hosted graph surface for host voice, co-streamer voice, ambient, transient, and loopback stems.scripts/start-live-faust-mic-field.ps1starts the mic-field publisher for Aquarium/Faust.
Temporary
- Audio and video are separate SRT endpoints. This preserves OBS mixing authority but may need latency tuning.
- Audio defaults to AAC inside MPEG-TS for compatibility; test Opus later only if there is a concrete reason.
- Desktop capture uses
gdigrabfirst because it is broadly available.ddagrabis a candidate once the installed FFmpeg build is confirmed. - The scripts assume Windows sender and OBS receiver on the same LAN.
Next
- Open OBS and confirm the three
Neighbor PCsources load. - Start the sender from Madman's interactive desktop, not SSH.
- Smoke-test the video endpoint in OBS.
- Smoke-test the Focusrite endpoint in OBS.
- Smoke-test the system-loopback endpoint in OBS.
- Tune SRT latency and FFmpeg buffering for the local network.
- Decide whether a small OBS scene/source generator is worth adding.
- Reconsider plugin/fork only if standard OBS Media Source cannot preserve the required behavior.
- Create local
config/audio-field.json, confirm local Kiyo/PS Eye/Focusrite device matches, and confirm the neighbor Focusrite shotgun capture/transport path. - Replace placeholder mic/speaker geometry with measured world coordinates, then build the delay/SRO alignment stage that feeds the bounded field cache and emits aligned six-channel blocks before FOA encoding.
- Move the render-frame consumer into Aquarium Engine so dense brush/splat rendering replaces the deadline OpenGL point sink behind the same OBS Spout boundary.
- Capture fixed-board ChArUco observations for every camera, solve
config/sensor-fusion.json, and verify cross-view feature triangulation withscripts/triangulate_surface_features.py. - Replace synthetic live-fusion observations with PS3 Eye detector observations and calibrated surface-feature tracks.
- Replace the example speaker/camera-mic geometry used by
chirp_posewith measured localconfig/audio-field.jsoncoordinates, then let the common-space optimizer consume range residuals instead of only visualizing them. - Calibrate Leap as a geometric camera in the shared rig so the timing authority can also contribute direct 3D rays instead of only visual timing peaks.
- Fix the live Leap capture backend so actual Leap frames, not fallback frames, populate
leap-ground-truthcells in the multi-LOD cache. - Keep the neighbor loopback leg running through the scheduled interactive WASAPI capture path and use it as the timing witness once actual neighbor app audio is present.
- Let the co-streamer surface delay drive the shared presentation buffer horizon for audio stems, AmbiX, and remote video.
- Wire
stream_phase_field.pyandstream_faust_mic_field.pyto the real live aligned-field producer instead of replaying WAV artifacts, then feed emitted active chirps back through loopback/mic capture so confidence maintenance closes against fresh observations instead of dry-run probe manifests.