caravani0

caravani0

Trigger Windows' automatic audio ducking without ducking own app's audio

Hello, all.

I am excusing myself beforehand for the not Qt-related question but still, I know that your expertise extends a lot further than Qt.
The question is Windows-related and more specifically - Windows Core Audio which is strangely named similarly to Apple’s Core Audio. The application being developed relies heavily on Qt and is playing some of its sounds through it but still, the background audio ducking is controlled currently only through platform-related APIs.

I am attempting to activate the Windows’ default automatic audio ducking inside my C++ desktop app so that I can duck only the audio of the rest of the applications but not that of mine so that any important audio is heard and not overlapped by a background such. The Windows’ ducking can be either:

a) automatic: one that can be system-wide configured through the Sound control panel (mmsys.cpl) → Communications tab. The background applications’ audio can be lowered by:

  • 100% - Muted
  • 80%
  • 50%
  • 0% - Do nothing

b) manual: where one opts-out from the automatic one and can receive notifications when audio ducking would be appropriate to be started/stopped

The problem is that I not only duck the audio of the rest of the applications - Spotify, browser’s audio like YouTube, but also that of my application.

I have extracted the audio ducking functionality from this Microsoft example which can be downloaded from here.

The most obvious way to notice that the audio of the current application is also ducked is to set the audio ducking setting inside the Windows sound settings to “Mute all other sounds” as shown here.

The audio ducking example provided above simulates a communication session/activity as far as I know - a WASAPI chat. I presume this is the reason that my audio is ducked as well since despite being my app opens a communication stream still this sample communication activity from the Microsoft’s example is probably overriding my app’s audio in terms of priority. That is just a presumption/hypothesis. Presumably something should be changed in this part of the example’s code.

I am open to all suggestions what should be fixed/changed/added. I confirm again that I want to use so-called “automatic” or I would say ready-made integrated audio ducking provided by Windows - the one shown on the screenshot above. I don’t want to provide a custom ducking behavior by lowering the other apps volume to arbitrary levels.

There are two APIs that directly mention the audio ducking:
IAudioSessionControl2::SetDuckingPreference
IAudioClientDuckingControl::SetDuckingOptionsForCurrentStream

The first one only switches between the automatic ducking behavior and a custom one i.e. switch the automatic off. I am currently testing the second one. The problem with it is the minimum required Windows version.

Here’s the simplest code that triggers the automatic audio ducking on Windows:

CComPtr<IMMDeviceEnumerator> deviceEnumerator;
HRESULT hr = CoCreateInstance(
    __uuidof(MMDeviceEnumerator),
    nullptr,
    CLSCTX_ALL /* CLSCTX_INPROC_SERVER */,
    IID_PPV_ARGS(&deviceEnumerator));
if (FAILED(hr))
{
    return;
}

CComPtr<IMMDevice> communicationsDevice;
hr = deviceEnumerator->GetDefaultAudioEndpoint(
            eRender, // eCapture for microphone
            eCommunications,
            &communicationsDevice);
if (FAILED(hr))
{
    return;
}

CComPtr<IAudioClient3> audioClient;
hr = communicationsDevice->Activate(
        __uuidof(IAudioClient3),
        CLSCTX_ALL /* CLSCTX_INPROC_SERVER */,
        nullptr,
        reinterpret_cast<LPVOID*>(&audioClient));
if (FAILED(hr))
{
    return;
}

WAVEFORMATEX* mixFormat = nullptr;
hr = audioClient->GetMixFormat(&mixFormat);
if (FAILED(hr))
{
    return false;
}

hr = audioClient->Initialize(
        AUDCLNT_SHAREMODE_SHARED,
        AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE
        | AUDCLNT_STREAMFLAGS_EVENTCALLBACK
        | AUDCLNT_STREAMFLAGS_NOPERSIST,
        500000,
        0,
        mixFormat,
        nullptr);
if (FAILED(hr))
{
    return;
}

CoTaskMemFree(mixFormat);
mixFormat = nullptr;

hr = audioClient->Start();
if (FAILED(hr))
{
    return;
}

Additionally, there are buffer manipulations - both initial and on a separate thread but they don’t seem to be part of the minimum requirements to trigger the audio ducking.

Where Next?

Popular Windows topics Top

mikel
Hi. I’m new in WFP (Windows filtering platform) and I have some questions. I want to create iptables new, established and related rules...
New
Sp_ceYT
(Client / Local Script) Error: “Unrecognized request option url” game.Players.PlayerAdded:Connect(function(player) --Whenever a player ...
New
caravani0
Hello, all. I am excusing myself beforehand for the not Qt-related question but still, I know that your expertise extends a lot further ...
New
Mclovin7450
Hello Friends, I am in IT support at an institute. I have a query in our office, since we have more than 100 computers, we must prepare ...
New
Nurlan
Hello. My name is Nurlan, I’m from Kazakhstan. I need the community’s help: I’ve found myself trapped and have been unable to escape fo...
New

Other popular topics Top

PragmaticBookshelf
Learn from the award-winning programming series that inspired the Elixir language, and go on a step-by-step journey through the most impo...
New
Exadra37
I am thinking in building or buy a desktop computer for programing, both professionally and on my free time, and my choice of OS is Linux...
New
New
AstonJ
This looks like a stunning keycap set :orange_heart: A LEGENDARY KEYBOARD LIVES ON When you bought an Apple Macintosh computer in the e...
New
PragmaticBookshelf
Tailwind CSS is an exciting new CSS framework that allows you to design your site by composing simple utility classes to create complex e...
New
Exadra37
Oh just spent so much time on this to discover now that RancherOS is in end of life but Rancher is refusing to mark the Github repo as su...
New
Maartz
Hi folks, I don’t know if I saw this here but, here’s a new programming language, called Roc Reminds me a bit of Elm and thus Haskell. ...
New
New
AstonJ
If you’re getting errors like this: psql: error: connection to server on socket “/tmp/.s.PGSQL.5432” failed: No such file or directory ...
New
AstonJ
This is cool! DEEPSEEK-V3 ON M4 MAC: BLAZING FAST INFERENCE ON APPLE SILICON We just witnessed something incredible: the largest open-s...
New