P1c: microphone recording through the material pipeline
This commit is contained in:
+45
@@ -98,3 +98,48 @@ Screenshots: `preview-p1b-quarry.png`, `preview-p1b-restored.png`.
|
||||
- Only the source bytes are archived; trimming/recording will add derived assets.
|
||||
- The engine is still the standalone daemon; the Tauri backend does not host it yet.
|
||||
- A failed autosave logs a warning and leaves the in-memory session running; the surface does not yet show a save error.
|
||||
|
||||
---
|
||||
|
||||
# P1c · recording
|
||||
|
||||
The quarry can now take a microphone take and turn it into material.
|
||||
|
||||
## Path
|
||||
|
||||
```
|
||||
record click
|
||||
→ getUserMedia({ mono, no AGC/NS/echo })
|
||||
→ AudioContext (requested 48 kHz) → AudioWorklet 'zhila-recorder'
|
||||
→ Float32 chunks on the main thread
|
||||
→ 16-bit PCM WAV encoder (in the surface)
|
||||
→ the existing binary import path with seal 'recorded'
|
||||
→ material decode + onset analysis + sixteen faces
|
||||
→ project asset + autosave
|
||||
```
|
||||
|
||||
The worklet copies each 128-frame render quantum; the main thread owns the growing chunk list so the audio thread never allocates the take. A mute GainNode keeps the input out of the speakers. The take name is `take-01.wav`, `take-02.wav`, …; the core name drops the extension. The recorder stops at 30 s; the user can stop earlier. Errors (permission denied, no device, worklet failure) surface under the quarry header.
|
||||
|
||||
The WAV is mono 16-bit PCM at the AudioContext rate (requested 48 kHz). The material crate already handles WAV; no daemon or protocol change was needed beyond `Seal::Recorded`.
|
||||
|
||||
## UI
|
||||
|
||||
- `record` in the quarry header and in the empty state: dot + label; `stop 0:12` while active with a pulsing dot.
|
||||
- `take a core` is disabled while recording; import is disabled while recording.
|
||||
- The take is imported with the recorded seal; the core strip and side facts show `recorded`.
|
||||
- The timer is in the button; no modal, no separate recorder panel.
|
||||
|
||||
## Verification
|
||||
|
||||
- `npm --prefix ui run record-smoke` launches Chromium with `--use-fake-ui-for-media-stream --use-fake-device-for-media-stream --use-file-for-fake-audio-capture=fixtures/clicks-01.wav`, records 2.3 s through the real UI/worklet/encoder, stops, waits for `take-01`, and checks 16 faces, the recorded seal, and the wire import.
|
||||
- The take is persisted in `~/.local/share/zhila/descent-04` (`core-4525165cd5.wav`, 16 faces, seal recorded) and shown by the state.
|
||||
- `./scripts/check.sh` remains green.
|
||||
|
||||
Screenshot: `preview-p1c-record.png`.
|
||||
|
||||
## Limits
|
||||
|
||||
- Mono, 16-bit, 30 s max, no monitor, no device picker, no gain control.
|
||||
- WebKitGTK/Tauri microphone support is untested; the Tauri binary also embeds an older surface build and must be rebuilt to see the record button.
|
||||
- No trim, fade or manual loop points yet; the take is cut by the automatic seams.
|
||||
- The take is stored as the encoded WAV, not the float PCM; trimming will later add derived assets.
|
||||
|
||||
Reference in New Issue
Block a user