Skip to content

Use PlaySound for custom bell audio to preserve mixer volume (#17733)#20031

Open
aarushisingh04 wants to merge 4 commits intomicrosoft:mainfrom
aarushisingh04:fix/17733-volume-mixer-bell
Open

Use PlaySound for custom bell audio to preserve mixer volume (#17733)#20031
aarushisingh04 wants to merge 4 commits intomicrosoft:mainfrom
aarushisingh04:fix/17733-volume-mixer-bell

Conversation

@aarushisingh04
Copy link
Copy Markdown

summary of the pull request

switch bell sound playback for profile bellSound files from winrt mediaplayer to win32 playsoundw to address #17733, where windows mixer volume for terminal bell audio does not persist across app restarts.

references and relevant issues

detailed description of the pull request / additional comments

this change updates terminalpanecontent to use playsoundw with snd_filename | snd_async | snd_sentry | snd_nodefault for custom bell audio files.

what changed:

  • removed winrt mediaplayer bell playback state and lifecycle code from terminalpanecontent.
  • changed _playbellsound(...) to accept a resolved sound path and call playsoundw.
  • preserved existing system alias fallback path for non-custom bell sound behavior.
  • added safe handling for file: uri-form bell paths by decoding to a filesystem path before calling playsoundw.
  • kept normal filesystem path handling intact (for example c:\...) without uri parsing.

rationale:

  • issue discussion suggested this may be tied to winrt media player behavior.
  • using classic win32 playback aligns with that maintainer hypothesis and is intended to preserve per-app mixer behavior across restarts.

known limitation:

  • playsoundw with snd_async is single-channel for this process path, so rapid consecutive bells may interrupt each other. this is existing acceptable behavior for this fix scope and can be revisited separately if needed.

validation steps performed

manual/source validation:

  1. verified bellsound resources are resolved by settings model before playback (resolved() path).
  2. verified file: uri strings are converted to filesystem paths before playback.
  3. verified fallback alias playback path remains unchanged.

recommended manual validation on a dev machine:

  1. set a profile bellsound to a local .wav.
  2. trigger bell, set terminal app volume to a non-100 value in windows volume mixer.
  3. fully close terminal, relaunch terminal, trigger bell again.
  4. confirm terminal app mixer volume persists.
  5. repeat on windows 10 and windows 11.

pr checklist

@aarushisingh04
Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@aarushisingh04 aarushisingh04 changed the title Use PlaySound for custom bell audio to preserve mixer volume Use PlaySound for custom bell audio to preserve mixer volume (#17733) Mar 28, 2026
const auto resourceUri{ winrt::Windows::Foundation::Uri{ soundPath } };
if (resourceUri)
{
const auto uriPath{ winrt::Windows::Foundation::Uri::UnescapeComponent(resourceUri.Path()) };
Copy link
Copy Markdown
Member

@lhecker lhecker Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You always copy soundPath into another string. That's unnecessary.

A single call to PathCreateFromUrlW should do the trick for your lengthy path conversion code. The function supports input and output pointer being the same. And URI -> path is naturally always shorter than the input URI. So, this?

if (til::starts_with_insensitive_ascii(soundPath, L"file:"))
{
    // Ensure that the URI has a null terminator.
    std::wstring path{ soundPath }; 
    
    // PathCreateFromUrlW supports writing to the input pointer,
    // and the resulting path can never be longer than the URI.
    const auto ptr = path.data();
    auto len = gsl::narrow<DWORD>(path.size());
    if (FAILED_LOG(PathCreateFromUrlW(ptr, ptr, &len, 0))) {
        return;
    }

    path.resize(len);
}

if (!til::is_legal_path(path))
{
    return;
}

PlaySoundW(filePath.c_str(), nullptr, SND_FILENAME | SND_ASYNC | SND_SENTRY | SND_NODEFAULT);

(Pseudo-code.)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switched to PathCreateFromUrlW as suggested, removed the winrt uri parsing. also fixed the scoping so filePath is declared before the if block so it's available for the legality check and playsoundw call

{
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
auto sounds{ _profile.BellSound() };
Copy link
Copy Markdown
Member

@lhecker lhecker Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you use AI to make this PR? Open the file in a text editor of your choice and convert the line endings to CRLF please. AI tools tend to f line endings up. 😄

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, converted to crlf throughout. sorry about that!

@DHowett
Copy link
Copy Markdown
Member

DHowett commented Mar 28, 2026

I'm not sure I understand why we need a URL parser at all. Bell sounds are resolved via IMediaResource, and by the time they get here they should be plain file paths.

Copy link
Copy Markdown
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My question about the URI still stands.

@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Mar 30, 2026
@zadjii-msft zadjii-msft added the spam thought we wouldn't notice, but we did label Apr 1, 2026
@aarushisingh04
Copy link
Copy Markdown
Author

@DHowett

i added the URI handling because of the earlier maintainer suggestion to simplify the conversion logic if file: URIs could reach this layer.

after tracing it back through the settings model though, i agree that this shouldn't be necessary here because BellSound is resolved through IMediaResource and Resolved() should already be a filesystem path by the time it reaches TerminalPaneContent.

if this sounds fine, then i'll remove the URL parsing and keep this code path focused on playing the resolved local path?

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs-Attention The core contributors need to come back around and look at this ASAP. and removed Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something labels Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs-Attention The core contributors need to come back around and look at this ASAP. spam thought we wouldn't notice, but we did

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Volume Mixer Sound Setting not saved for Windows Terminal

4 participants