feat(audio): music beds start at -18 dB and duck under the voice - #797
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (34)
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review. 📝 WalkthroughWalkthroughThe audio pipeline adds per-file loudness measurement and normalization, output peak limiting, and voice-responsive music ducking. Track kinds and kind-specific defaults are carried through scene data and editor controls. Electron exposes an asynchronous loudness-gain request, which the preview uses for recordings and voiceovers. ChangesAudio processing and preview
Priority: ➖ Normal Estimated code review effort: 4 (Complex) | ~50 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant Preview as VirtualPreview
participant Preload as Electron preload
participant IPC as get-loudness-gain handler
participant Service as CompositorViewService
participant Addon as compositor-view addon
participant Native as loudness_gain_db
Preview->>Preload: getLoudnessGain(filePath)
Preload->>IPC: invoke get-loudness-gain
IPC->>Service: loudnessGainDb(filePath)
Service->>Addon: loudnessGainDb(path)
Addon->>Native: measure file loudness asynchronously
Native-->>Addon: gain in dB
Addon-->>Service: gain in dB
Service-->>IPC: gain or null
IPC-->>Preload: success and gainDb
Preload-->>Preview: loudness gain result
Suggested reviewers: Merge Risk: ⚪ Minimal · up to The identified preview concerns do not block merging; proceed with normal checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to Music ducking changes playback and export behavior, including for existing projects. The reviewed commit does not appear to add file-access authority or a new security boundary, but some inherited file-handling behavior remains uncertain. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… the voice Imported music landed at 0 dB with hard edges and sat at full level under the narration. A new music track now starts at -18 dB with 1 s fades (the inspector's reset returns to the same values); tracks already saved keep the level their author set. At export the music dips 10 dB while the voice (the recording plus every voiceover) is above -35 dBFS, looking ahead 250 ms, holding 500 ms across pauses and releasing over 600 ms. The preview runs the same ballistics on a live analyser of the voice, without the look-ahead.
aaec31c to
9938f65
Compare
c769d3e
into
integration/demo-never-ugly
Summary
Music no longer buries the voice. A new music bed starts at −18 dB with 1 s fades, and every bed dips 10 dB while someone speaks. Audit finding #6, part 2 of 2.
Stacked on #796. The first commit is #796; review only the last one. Merge #796 first, then this rebases to one commit.
What changed
createAudioTrackgiveskind: "music"−18 dB, 1000 ms fade-in and fade-out; a voiceover stays at 0 dB (the export levels it). It is the one door every new track goes through. The schema's parse defaults are untouched.mix_external_tracks). Voiceovers are summed first, so the voice is the recording plus every take. 10 ms RMS above −35 dBFS counts as speech. The dip starts 250 ms ahead (the export sees the whole voice), holds 500 ms across pauses, releases over 600 ms, as straight ramps in dB, interpolated per sample.AnalyserNodeon the voice in the existing rAF loop.Existing projects
Decisions to confirm
Still differs between preview and export
Related issue
Part of the Screen Studio design audit, finding #6.
Type of change
Release impact
Desktop impact
Rust changes stay in
audio.rs, shared by the three pipelines. Only the Windows build ran here.Testing
Measured through the native export (the addon's
exportMulti, fed the scene built bybuildSceneDescription). A −24 LUFS speech track notched at 3 kHz, a steady 3 kHz tone at −13 LUFS as the music, so a 3 kHz band-pass reads the bed alone.Checks
cargo test -p openscreen-compositor --lib audio: 49 passed. New: dip ahead of the voice and recovery, no pumping in a 0.3 s breath, no dip on silence or on a boosted noise floor, a bed summed under the curve and a voiceover not.npx tsc --noEmit,npx tsc -p tsconfig.test.json --noEmit: clean.npm run lint: clean (existing warnings).npm run i18n:check: passed.npx vitest --run: 261/261 files. Two stale expectations (placed bed at 0 dB, fake AudioContext withoutcreateAnalyser) fixed and rerun green.🤖 Generated with Claude Code
Summary by CodeRabbit