【问题标题】:Finding the current volume level of the speaker output in Windows在 Windows 中查找扬声器输出的当前音量级别
【发布时间】:2020-02-19 22:05:28
【问题描述】:

已编辑:我正在尝试编写一种音频可视化工具,我需要获取发送到扬声器的当前音量。我需要声音的实际音量,而不仅仅是设备的主音量。我一直在尝试使用this 来实现它,但我不确定如何实现它。调用了IAudioCaptureClient::GetBuffer() 方法后,不知道如何使用生成的数据包来查找我需要的内容。音频为 2 通道,每个样本 32 位。任何帮助将不胜感激。

【问题讨论】:

  • 自 Windows XP 以来,Windows 音频子系统发生了巨大变化。查看 EndpointVolume API。

标签: c++ winapi audio


【解决方案1】:

从 Windows 7 开始,现有的 API 得到了改进和新的 已添加 API 以支持新方案。流和会话 管理 API 已得到改进,因此应用程序现在可以 枚举并获得对音频会话的扩展控制。通过使用 新的 API,应用程序可以实现自定义流 衰减体验。新的设备相关 API 提供对 端点设备的驱动程序属性。

参考:Core Audio APIs

这里有一个简单的demo供参考:

#include <Windows.h>
#include <stdio.h>
#include <mmeapi.h>
#include <mmdeviceapi.h> 
#include <endpointvolume.h>
#include <audioclient.h>

#pragma comment(lib,"Winmm.lib")

bool GetVolumeLevel()
{
    HRESULT hr;
    IMMDeviceEnumerator* pDeviceEnumerator = 0;
    IMMDevice* pDevice = 0;
    IAudioEndpointVolume* pAudioEndpointVolume = 0;

    try {
        hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pDeviceEnumerator);
        if (FAILED(hr)) throw "CoCreateInstance";
        hr = pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &pDevice);
        if (FAILED(hr)) throw "GetDefaultAudioEndpoint";
        hr = pDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&pAudioEndpointVolume);
        if (FAILED(hr)) throw "pDevice->Active";

        float fVolume;

        hr = pAudioEndpointVolume->GetMasterVolumeLevelScalar(&fVolume);
        printf("%lf", fVolume);
        if (FAILED(hr)) throw "SetMasterVolumeLevelScalar";

        pAudioEndpointVolume->Release();
        pDevice->Release();
        pDeviceEnumerator->Release();
            return true;
    }
    catch (...) {
        if (pAudioEndpointVolume) pAudioEndpointVolume->Release();
        if (pDevice) pDevice->Release();
        if (pDeviceEnumerator) pDeviceEnumerator->Release();
        throw;
    }
    return false;
}

int main()
{
    CoInitialize(0);
    try {
        GetVolumeLevel();

    }
    catch (...) {
        //err handle..
    }
    CoUninitialize();

    getchar();
    return 0;
}

它将返回到当前扬声器的音量。

你可以关注这个api:IAudioEndpointVolume::GetMasterVolumeLevelScal

GetMasterVolumeLevelScalar 方法获取主音量级别 进入或离开音频端点设备的音频流。这 音量级别表示为标准化的音频锥形值 范围从 0.0 到 1.0。

【讨论】:

  • 混合原始指针和 C++ 异常处理将不可避免地使您的代码无法维护。要么使用 RAII,要么只是不向模型控制流抛出异常。请特别注意,无论检索它的调用是否成功,您都在打印该卷。
  • 获取主卷。我需要获得发送到扬声器的声音的实际幅度。我发现了这个:docs.microsoft.com/en-us/windows/win32/coreaudio/…,但我在实现它时遇到了麻烦。
  • @CameronNeil 您可以编辑问题或发布新问题以显示您遇到的问题的详细信息。相信会有很多社区成员愿意帮你解决。
  • @CameronNeil 正常的、未压缩的音频表示只是它的幅度作为时间的函数。 .wav 文件通常是未压缩的,因此单声道 .WAV 文件实际上是最简单的音频文件:只是一个标题,后跟一系列幅度。请参阅this。您想获得类似于波形的音频幅度吗?
【解决方案2】:

不确定您是否自己找到了它。 我将从 peakmeter 信息开始:​​

https://docs.microsoft.com/en-us/windows/win32/coreaudio/peak-meters

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 2014-02-07
    • 2011-10-28
    相关资源
    最近更新 更多