diff --git a/logs/laneB.md b/logs/laneB.md index 0fa960b..6e890d6 100644 --- a/logs/laneB.md +++ b/logs/laneB.md @@ -134,3 +134,48 @@ BLOCKED/REQUESTS: none. Verified with a throwaway harness (`_check.html`, NEXT: M2 polish complete. Undo already wired (Ctrl+Z). Open for M4 timeline work when unlocked (audio tracks on the timeline UI + Web Audio sync, per PLAN ยง5 M4) or any SYNC 3 fixes. Holding until orchestrator flips M4. + +## 2026-07-18 session 4 (M4-B: audio + visemes) +DONE: M4-B all three items. + 1. Audio rows in tlui from scene.audio[]: one lane per clip below Cameras, + green block at the DECODED buffer width (fallback width until decoded), + gain in the name column, drag = offset (moveAudio), right-click = + delete. ๐ŸŽต button reads /assets/tree audio category into a small floating + menu โ†’ addAudio at the playhead. + 2. Web Audio draft playback synced to the master clock: lazy AudioContext, + decode+cache buffers (/assets/file), _audioStart schedules + AudioBufferSourceNodes at (start - time) with per-clip gain, _audioStop on + pause/natural-end, user seeks reschedule (_seek helper). step()/render + never touch audio โ€” server muxes from scene.audio. + 3. morphs track kind: _evalMorphs lerps per viseme name โ†’ stage.setMorph; + importRhubarb(id, json, t0) maps mouthCues โ†’ morph keys; tlui shows a + "โ†ณ visemes" lane guarded by stage.visemeTargets(id).length > 0. + Model (timeline.js, stagestub.js, timeline_test.mjs) committed ba29d0c; + tests cover morph lerp, rhubarb keys, audio mutators+undo. All green. +VERIFIED (real server :8020, real assets): ๐ŸŽต picker listed + added + audio/test/tone.wav, buffer decoded (8s), green block drawn, Web Audio + scheduled/rescheduled/stopped (ctx running), viseme lane rendered + importRhubarb keys, setMorph fired while scrubbing. Contract match confirmed: + real stage.js ships setMorph(id,name,weight) + visemeTargets(id) (returns + Object.keys(visemes)) โ€” my `.length>0` guard works against both. +DECISIONS: + - Audio duration is a client draw concern (decode+cache in tlui), NOT stored + in the {path,start,gain} schema โ€” server already knows durations at mux. + - importRhubarb = simple per-cue ramp (shape 1 at cue start โ†’ 0 at end); + hold/crossfade tuning deferred (ponytail marker in timeline.js) until it + looks wrong on a real blendshape character. + - Audio blocks can extend past scene.duration (tone.wav is 8s in a 6s scene) + โ€” left as-is; the ruler just clips visually. Trim is a later nicety. +BLOCKED/REQUESTS: + - **Ownership note for orchestrator**: my tlui.js M4-B changes (+146 lines) + were committed inside Lane A's `df4e06f [laneA] M4-A ...`, not a [laneB] + commit โ€” Lane A's commit swept my then-uncommitted tlui.js working changes + along with their dock.js/stage.js. Code is intact + verified; only the + attribution is off. Heads-up that our git hygiene let a cross-lane file + ride in on another lane's commit; a `git add ` (not `-A`) avoids + it. Nothing for me to fix. +NEXT: M4-B complete. Open items if a session 5 lands: audio block trim/clip to + duration, viseme import UI button (currently importRhubarb is API-only; Lane + C has a /rhubarb endpoint โ€” could wire a "lip-sync from audio" button that + POSTs the clip and feeds the result to importRhubarb). Holding for SYNC/next + orchestrator update.