239 lines
15 KiB
Markdown
239 lines
15 KiB
Markdown
# Implementation Plan
|
|
|
|
## Current Cut Line
|
|
|
|
Mimir is now a C# app/runtime plus native reservoir project. The live stream
|
|
machine must be direct-driver and native-buffer first.
|
|
|
|
For the source-level ownership map, read [[code-algorithm-map|Code Algorithm Map]].
|
|
|
|
- `src/Mimir.App` hosts Fensalir for windowing, rendering, and the D3D12
|
|
bridge.
|
|
- `src/Mimir.Runtime` owns stream descriptors, source polling, direct push
|
|
ingest, one rolling buffer per configured audio/video stream, and the
|
|
synchronization hub Fensalir can inspect.
|
|
- The default five-second window is an intentional latency/memory trade: use it
|
|
to line up streams and extract the volumetric audio/video field before OBS
|
|
sees program output.
|
|
- `native/reservoir` owns the lower native rolling-buffer invariant for
|
|
Fensalir/Faust integration.
|
|
- PowerShell/FFmpeg/SRT remains a bridge utility for LAN OBS feeds. It is not
|
|
the synchronized program authority.
|
|
|
|
The old script stack is gone. Do not add a compatibility edge unless it protects
|
|
a named invariant that the native runtime cannot protect yet.
|
|
|
|
## Implemented
|
|
|
|
- Mimir public identity, branding, and Face memory.
|
|
- `Mimir.slnx` with `src/Mimir.App` and `src/Mimir.Runtime`.
|
|
- Fensalir host bootstrapping from `Mimir.App`.
|
|
- `MimirSynchronizationHub`, `MimirRollingStreamBuffer`, stream descriptors, and
|
|
`IMimirStreamSource`.
|
|
- Configurable five-second default rolling buffers for local and network audio
|
|
and video streams.
|
|
- `MimirNativeIngestStreamSource` for direct push ingest into runtime buffers.
|
|
- `MimirProcessStreamSource` for bridge/network command edges.
|
|
- `MimirFrameEventProcessStreamSource` for temporary JSON-line frame metadata
|
|
from native probes into the same rolling buffers Fensalir inspects. One probe
|
|
process can accept multiple emitted `sourceId` values so it does not reopen
|
|
the same camera set once per stream.
|
|
- `native/asio_capture` plus `MimirAsioStreamSource` provide the first
|
|
production-shaped Focusrite path: a native in-process ASIO callback source
|
|
feeds sample-bearing 192 kHz Float32 blocks directly into `Mimir.Runtime`
|
|
rolling buffers on one interface clock domain.
|
|
- `src/Mimir.BufferSmoke` loads the runtime config, polls the synchronization
|
|
hub, and prints the actual rolling buffers. Use `--require-samples` when an
|
|
empty declared sensor buffer should fail the run. Use `--bioacoustic-self-test`
|
|
to render the active motif timeline into memory and verify that the decoder
|
|
recovers direct word anchors. Use `--standalone-bioacoustic-self-test` to
|
|
verify that a receiver with only the codebook/schedule can recover canonical
|
|
source offset from delayed audio. Use `--bioacoustic-train` to run the
|
|
indexed cepstral receiver hypothesis panel and write CultCache/audio receipts
|
|
under `artifacts/bioacoustic-training/`.
|
|
- `native/probes/wasapi_audio_cadence` captures WASAPI mic or render-loopback
|
|
block metadata and emits `audio-block` JSON events for the diagnostic runtime
|
|
adapter. It can probe requested shared/exclusive formats so driver state is
|
|
explicit, but Scarlett production capture belongs on ASIO.
|
|
- `native/probes/asio_audio_cadence` opens the registered Focusrite ASIO COM
|
|
driver, reports channel counts, buffer sizing, supported sample rates, and can
|
|
run a short input callback capture. Current Starfire Focusrite USB ASIO proof
|
|
with the Scarlett Solo 4th Gen shows 4 inputs / 2 outputs, including
|
|
`Loopback 1/2`, 192-frame preferred buffers, 44.1-192 kHz support, and
|
|
nonzero 4-channel `Int32LSB` input callbacks at 192 kHz. `--monitor-sweep`
|
|
emits low-gain ASIO output bursts and synchronously measures loopback/mic
|
|
response per frequency so ultrasonic acoustic claims stay measured. The probe
|
|
can also play raw mono Float32 timeline audio with `--play-f32-mono` and
|
|
capture raw interleaved Float32 ASIO input with `--record-f32-interleaved`.
|
|
- `MimirBioacousticTimeline` owns the active runtime watermark described in
|
|
[[bioacoustic-timeline-watermark|Bioacoustic Timeline Watermark]]. It renders
|
|
a low-gain birdsong-like word language: 128 self-identifying word positions,
|
|
left-speaker and right-speaker variants, four formant-rich syllables per word,
|
|
rhythm variation, and direct word identity so a correctly decoded word
|
|
identifies canonical timeline position. Runtime active sync now reports
|
|
`evidence=bioacoustic`.
|
|
- `MimirChirpletTimeline` owns the older structured chirplet calibration stream,
|
|
PCM segment rendering, matched timing trace, and per-band response kernels.
|
|
It remains a reference/diagnostic path.
|
|
- `MimirChirpletSymbolCodebook` owns the 32 symbol definitions. Each symbol has
|
|
a unique chirp shape, with inter-chirp rhythm as additional code evidence.
|
|
- `MimirChirpletStreamDecoder` is the first constrained chirplet-transform
|
|
receiver. It owns a bounded PCM window, emits transform frames with multiple
|
|
phase-invariant symbol candidates and per-candidate refined sample offsets,
|
|
decodes code-valid triplet anchors through a local trellis that requires gap
|
|
and clock coherence, and fits a per-source sample clock from those anchors.
|
|
- `MimirAudioSynchronizationAnalyzer` ports the first live sync measurement:
|
|
sample-bearing audio blocks are resampled into the Scarlett loopback timeline.
|
|
The analyzer derives delay only from matched decoded timeline anchors.
|
|
A source without at least one matched anchor has no timing report for that
|
|
window. It accepts Float32, Int16, Int24, and Int32 PCM windows so ASIO/native
|
|
capture can feed true interface formats without a pre-conversion shim.
|
|
- `MimirAudioSynchronizationStateTracker` owns the first smoothed per-source
|
|
sync state: latest fractional delay, smoothed delay, confidence, per-band
|
|
response evidence, and delay-slope/SRO estimate in ppm.
|
|
- `faust/mimir_alignment_actuator.dsp` is the first Faust-owned sample movement
|
|
surface: six channels of bounded fractional delay and gain controls. Mimir
|
|
estimates delay/SRO; Faust/native DSP applies correction.
|
|
- `MimirRuntime` updates audio sync analysis online as a bounded rotating
|
|
service and can emit live sync telemetry with
|
|
`MIMIR_SYNC_TELEMETRY_SECONDS`. UI and telemetry read cached reports/states;
|
|
they do not run synchronization analysis.
|
|
- `MimirRuntime` queues bioacoustic timeline PCM through Fensalir audio when the
|
|
active timing witness is allowed. `MimirAudioSynchronizationSettings.Mode`
|
|
selects `chirp-only`, `passive`, or `hybrid`; passive disables active
|
|
emission, chirp-only emits the active witness continuously, and hybrid emits
|
|
the active pilot only while passive confidence is below threshold.
|
|
- `MimirPassiveAudioSynchronizationEstimator` is the first program-audio timing
|
|
path. It estimates loopback-to-mic delay with PHAT-weighted cross-spectrum
|
|
correlation so music can act as the default timing witness before any audible
|
|
watermark is needed.
|
|
- `MimirChirpBinTimeline` is the old chirp-bin calibration path. It renders a
|
|
fixed-slope chirp-bin codebook and decodes symbols with cheap event-energy
|
|
proposals, dechirp plus fixed Goertzel bins, and the same de Bruijn triplet
|
|
timeline-anchor machine. The detector keeps
|
|
time/frequency ambiguity as candidate symbol/offset pairs so code constraints
|
|
can choose the coherent path. The analyzer refines the final fractional delay
|
|
with constrained local waveform correlation around the decoded active delay.
|
|
Each classified chirp carries the full bin-energy response surface, and stream
|
|
decodes aggregate that into per-band calibration evidence for frequency
|
|
response normalization. `MimirChirpBinCalibrationModel` now preserves usable
|
|
bands, expected-symbol versus observed-bin confusion observations, timing
|
|
residuals, delay hypotheses, phase summaries, and an adaptive codebook plan.
|
|
The reference decoder can consume that model as learned response weighting,
|
|
phase-coherence weighting, first-order group-delay correction, and joint
|
|
global delay/bin-shift hypotheses. The
|
|
runtime emitter also consumes the model's emission plan, rendering the smaller
|
|
reliable symbol alphabet at the higher recommended de Bruijn order when the
|
|
physical path cannot support all 32 bins.
|
|
Reports/states expose delay in microseconds as well as fractional samples.
|
|
Hybrid now emits the bioacoustic watermark as low-gain half-second bursts only
|
|
while passive confidence is weak; chirp-bin remains available for ASIO
|
|
calibration/replay commands.
|
|
Use `--bioacoustic-self-test` and `--standalone-bioacoustic-self-test` to
|
|
prove the active motif decoder. Use `--chirp-only-sync-self-test` to prove
|
|
that the analyzer can recover fractional delay from the bioacoustic runtime
|
|
watermark. The current synthetic active proof recovers a 317.375-sample delay
|
|
with printed 0.000 us error.
|
|
- `Mimir.BufferSmoke --render-chirp-bin-f32` and `--analyze-asio-f32` provide
|
|
the retained Scarlett calibration artifact proof. A 192 kHz chirp-bin run decoded
|
|
Focusrite `Loopback 1 -> Loopback 2` at `0.000 us` with 12 matched anchors and
|
|
0.999 confidence. `--calibrate-chirp-bin-asio-f32` can render/capture/analyze
|
|
a calibration session and persist the response/confusion/delay model under
|
|
`calibration/chirp-bin/`. `--analyze-asio-f32 --calibration ...` loads that
|
|
model into the chirp-bin reference decoder. Physical input 1 still failed pairwise timing
|
|
in the stored artifact, but it produced a useful response/confusion model
|
|
with two reliable symbols. Acoustic robustness remains separate from the clean
|
|
loopback timing proof, but failed timing windows now leave usable response
|
|
evidence instead of silence.
|
|
- `Mimir.BufferSmoke --calibrate-contestant-asio-f32` persists the active
|
|
packet-song physical calibration model under `calibration/bioacoustic/`.
|
|
It learns per-channel schedule offset, polarity, payload reliability,
|
|
response-normalization bands, gain, confidence, and pairwise propagation
|
|
delay from the same 192 kHz ASIO capture. The latest Scarlett receipt
|
|
`calibration/bioacoustic/scarlett-canary-packet-192k-rerun.json` clears the
|
|
current hot-loop budget at 10.7x realtime across four channels. Loopback
|
|
channels decode 37/37 with 2.524 us MAE; the co-streamer shotgun decodes
|
|
37/37 payload with 58.785 us MAE; the cardioid decodes 26/37 with
|
|
90.558 us MAE. This is a real response/propagation-delay model, but not yet
|
|
microsecond-accurate physical mic sync.
|
|
- `config/mimir-runtime.asio.example.json` is the minimal continuous Scarlett
|
|
runtime ingest proof. It loads `native/asio_capture` in process at 192 kHz
|
|
and declares `asio-ch0` through `asio-ch3` as accepted audio sources. A
|
|
two-second BufferSmoke run ingested more than 12,000 sample-bearing blocks
|
|
and retained 2,048 blocks per channel, proving loopback and mic channels enter
|
|
`Mimir.Runtime` together in one ASIO clock domain without stdout/base64
|
|
transport. BufferSmoke does not
|
|
emit speaker calibration audio, so that proof is ingest-only rather than a
|
|
sync report.
|
|
The active bioacoustic standalone receiver test recovers a delayed audio
|
|
stream to below printed microsecond precision using only the motif codebook
|
|
and schedule state. `--bioacoustic-actuator-self-test` estimates a synthetic
|
|
317.375-sample bioacoustic delay, applies the fractional correction, and
|
|
remeasures the residual below printed microsecond precision.
|
|
- `src/Mimir.Runtime/Synchronization` now contains the reusable Perfect Machine
|
|
module library distilled from the research pass: node profiles, decoder
|
|
profiles, language/emission profiles, path-learning sessions, benchmark
|
|
panels, audio actuator strategies, native capture profiles, camera ingest
|
|
strategies, reservoir strategies, audio/visual field profiles, compute
|
|
offload profiles, OBS publication profiles, CultMesh contracts, Fensalir
|
|
lowering, and assembly plans. Use
|
|
`Mimir.BufferSmoke --perfect-machine-profile-smoke` to prove the catalog
|
|
assembles, `--perfect-machine-contract-smoke` to write a CultCache contract
|
|
proof, `--perfect-machine-manifest` to export the module manifest for
|
|
tooling/UI/remote witness use, and `--perfect-machine-lowering-benchmark` to
|
|
measure the Mimir-to-Fensalir lowering path. The current six-camera/two-audio
|
|
synthetic lowering benchmark runs at roughly 2.5 us per iteration with about
|
|
2.3 KB allocated per iteration.
|
|
- `MimirVideoFrameDescriptor` for dimensions, pixel format, stride, device
|
|
timestamp, and native/GPU handle metadata.
|
|
- `IMimirVideoCaptureDriver` and `MimirVideoCaptureDriverSource` as the live
|
|
driver-facing seam for Leap, Media Foundation, DirectShow, libusb, LeapC, or
|
|
shared texture capture.
|
|
- `native/reservoir` with one shared-edge rolling buffer, typed views, C ABI,
|
|
source-id hashing, producer helpers, and typed audio/render payload
|
|
descriptors.
|
|
- Windows bridge scripts for sender discovery/start/stop and simple OBS Media
|
|
Source ingest.
|
|
- Documentation for OBS receiver setup, native rebuild boundaries, the viable
|
|
stream app, and the Mimir Face.
|
|
|
|
## Temporary
|
|
|
|
- Audio and video may still traverse separate OBS/SRT endpoints during bridge
|
|
testing so OBS can preserve independent controls.
|
|
- Process-backed stream sources are only acceptable for network bridge feeds or
|
|
diagnostics. Six-camera local ingest belongs behind direct capture drivers.
|
|
- Frame-event process sources are diagnostic only. They prove source cadence and
|
|
runtime plumbing without dragging stdout bytes into the pixel hot loop.
|
|
- Calibration artifacts may remain on disk as evidence, but live state must be
|
|
in memory inside Mimir/Fensalir/native runtime surfaces.
|
|
|
|
## Next
|
|
|
|
1. Replace the frame-event diagnostic bridge with concrete direct capture
|
|
drivers for Leap stereo IR first, then the
|
|
other cameras.
|
|
2. Feed those drivers into `MimirVideoCaptureDriverSource` and prove sustained
|
|
frame cadence in the rolling buffers.
|
|
3. Use bioacoustic motif response profiles from real microphones to tune
|
|
contour, formant, band, gain, rhythm weighting, and left/right speaker
|
|
separation without weakening the standalone word-identity receiver invariant.
|
|
Keep chirp-bin calibration artifacts as reference data, not the runtime
|
|
target. Promote the `--bioacoustic-train` receipt shape into a real
|
|
calibration loop: detected words should feed a global delay/clock/path
|
|
hypothesis and learned per-output/mic response, not per-case threshold rules.
|
|
4. Add the synchronization actuator: drive a variable-rate resampler and
|
|
fractional delay line per non-reference stream from the smoothed
|
|
`MimirAudioSynchronizationState`. First, prove the bioacoustic motif decoder
|
|
through real loopback and microphone paths so every correctly heard word
|
|
becomes a deterministic timeline anchor before the actuator moves samples.
|
|
5. Prove the bioacoustic hybrid fallback through real loopback and microphones
|
|
with probe durations long enough to keep loopback and mic windows live.
|
|
6. Bind Fensalir UI to the synchronization hub so buffer depth, stream cadence,
|
|
source timestamps, and output settings are visible and adjustable.
|
|
7. Move GPU feature extraction, fusion, material fitting, render budgeting, and
|
|
Spout2 publication into Fensalir.
|
|
8. Move mic alignment, room suppression, voice separation, spatialization, and
|
|
stem generation into Faust/native DSP.
|
|
9. Keep the OBS bridge witness ledger as evidence before expanding receiver
|
|
machinery.
|