potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

C++20&WIL&Win API MMDevice APIでミュートを切り替える

Windows Vistaからはマスター音量(システム全体の音量)の変更にCOMベースのMMDevice API (Windows Multimedia Device API)が用いらます。ここではミュートを切り替えるコードを記載します。

#define STRICT
#define NOMINMAX
#include <Windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>

#include <wil/com.h>

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    auto coinit{ wil::CoInitializeEx(COINIT_APARTMENTTHREADED) };

    // デバイス列挙オブジェクトを取得する
    wil::com_ptr<IMMDeviceEnumerator> deviceEnumerator{
        wil::CoCreateInstance<MMDeviceEnumerator, IMMDeviceEnumerator>() };

    // TODO:ここでデバイス列挙オブジェクトを処理する
    //

    // 既定のマルチメディア出力デバイス(スピーカー)を取得する
    wil::com_ptr<IMMDevice> device;
    THROW_IF_FAILED(deviceEnumerator->GetDefaultAudioEndpoint(
        EDataFlow::eRender,
        ERole::eMultimedia,
        device.put()));

    // TODO:ここで既定のマルチメディア出力デバイス(スピーカー)を処理する
    //

    // オーディオエンドポイントのボリュームオブジェクトを作成する
    wil::com_ptr<IAudioEndpointVolume> audioEndpointVolume;
    THROW_IF_FAILED(device->Activate(
        __uuidof(IAudioEndpointVolume),
        CLSCTX_INPROC_SERVER,
        nullptr,
        audioEndpointVolume.put_void()));

    // TODO:ここでボリュームオブジェクトを処理する
    //

    // ミュート設定を反転する
    BOOL mute;
    THROW_IF_FAILED(audioEndpointVolume->GetMute(&mute));
    THROW_IF_FAILED(audioEndpointVolume->SetMute(!mute, nullptr));

    return 0;
}