Repository navigation
Conversation
The ducked levels are a fixed share of the maximum volume, so with a quiet starting volume level 1/3 actually raised it. On top of that, volume ramps were never cancelled: the AirPods step from 3 to 6 quickly, so the ramp towards the ducked level could still be running after the restore to the original volume had finished, and it won, leaving the volume above where it started. Ducking now never goes above the volume recorded when speaking started, every ramp supersedes the previous one, and level 2 also records the starting volume since it means 'started speaking' too.
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.
The bug
With conversation awareness on, the volume does duck while you talk. But once you stop it comes back higher than it was, and each conversation pushes it a bit further. Captured on a Xiaomi 14 Pro (HyperOS's volume scale is 0..150, so 43 % = 64 and 20 % = 30), starting from 44:
Three things compound:
conversationAwarenessVolume= 43 %,conversationAwarenessReducedVolume= 20 % of max) and are never compared with the current volume. Below 43 %, level 1 and level 3 raise the volume. The previousstartSpeaking(), still inMediaControllerbut commented out, had aninitialVolume > max * percentguard for this.smoothVolumeTransitionposts its own 50 ms stepper, so a ramp heading up to the ducked level keeps running underneath the restore and can be the last one to write.stopSpeaking()clearsinitialVolume, so the next 1 records whatever the still-running ramp has reached. The "original" volume ratchets up 44 → 46 → 48 → … → 64, and that's what gets restored.The fix
MediaController.duckVolume(percent): likesetVolume, but capped at the volume recorded when speaking started, so ducking can only lower.smoothVolumeTransitionstamps each ramp with a generation number, and a ramp that has been superseded stops instead of finishing.startSpeaking(). Both 1 and 2 mean "started speaking", andstartSpeaking()only records when nothing is recorded yet, so a sequence that opens on 2 still gets restored.setVolumeis left unchanged for any other caller.Testing
On the same device, starting at 40/150, I talked in four separate bursts with music playing. The build I tested also carried #852 (strings only, it doesn't touch this code path). This branch is the same commit cherry-picked onto the current
android/rewrite. Every burst recorded 40 as the starting volume, ducked 40 → 30, and came back to 40: