feat(audio-mixer): honor ramp_ms on mute toggles, with cancel-guard - #540
Merged
Conversation
Mute toggles previously hard-coded MUTE_ANTICLICK_RAMP_MS (10 ms), so
external callers (Open Live, MCP) sending PATCH `.../mute` could not
request the broadcast-style 500 ms route fade they need for on-air /
off-air transitions. The volume path already honored `ramp_ms`; this
brings parity to mute.
Backend:
- properties.rs: mute branch passes `ramp_ms.unwrap_or(MUTE_ANTICLICK_RAMP_MS)`
into apply_mute, matching the volume branch.
- volume_ramp.rs: rename anticlick_ms -> ramp_ms in apply_mute. Add a
per-element generation counter (Arc<Mutex<HashMap<String, u64>>>)
so the tokio-scheduled `set_property("mute", true)` aborts on fire
if a later apply_mute call has bumped the generation. Without this,
a fast unmute mid-fade would still let the stale mute=true land
afterwards and silently kill the route. clear() also bumps every
generation so a stopped pipeline cannot be re-muted by leftover
scheduled toggles.
API:
- UpdatePropertyRequest.ramp_ms doc now covers `mute` and points at the
500 ms broadcast use case. OpenAPI snapshot regenerated (also picked
up the pending 0.4.12 -> 0.4.13-dev version bump).
Tests:
- long_mute_ramp_takes_full_duration: 200 ms fade-out must keep
audible level mid-ramp and only set mute=true after the full
duration + grace.
- unmute_during_long_mute_fade_cancels_pending_toggle: regression for
the cancel-guard — an unmute 40 ms into a 200 ms fade must prevent
the stale mute=true from landing 200 ms later.
- All existing volume_ramp + pipeline_lifecycle tests still green.
Usage example: `PATCH .../elements/<flow>:mixer:to_main_vol_<ch>`
with `{ property_name: "mute", value: true, ramp_ms: 500 }` now
produces a 500 ms dB-linear fade-out before mute=true lands; the
matching `value: false, ramp_ms: 500` produces a 0->pre_mute fade-in.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ramp_mslike volume does — external callers (Open Live, MCP) can ask for broadcast-style fades onto_main_vol_N:muteetc. instead of being stuck on the hard-coded 10 ms anti-click.mute=true. Without this, a 500 ms fade-out followed 40 ms later by an unmute would still let the stalemute=trueland 460 ms later and silently kill the route.UpdatePropertyRequest.ramp_msdoc and OpenAPI snapshot updated.Usage
Test plan
cargo test --test volume_ramp_test(10/10, including 2 new)long_mute_ramp_takes_full_duration— 200 ms fade-out keeps audio audible mid-ramp; mute lands only after full duration + graceunmute_during_long_mute_fade_cancels_pending_toggle— unmute 40 ms into a 200 ms fade prevents stale mute=true from landingcargo test --test pipeline_lifecycle_test(3/3)cargo test --test openapi_test(snapshot regenerated; also picked up pending 0.4.12 → 0.4.13-dev version bump)cargo buildclean, clippy clean, fmt clean🤖 Generated with Claude Code