在 Windows 中查找扬声器输出的当前音量级别

Posted

技术标签:

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

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

【问题讨论】:

自 Windows XP 以来,Windows 音频子系统发生了巨大变化。查看 EndpointVolume API。 【参考方案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

【讨论】:

以上是关于在 Windows 中查找扬声器输出的当前音量级别的主要内容,如果未能解决你的问题,请参考以下文章

获取音频混合器中可视化的单个 Windows 应用程序当前音量输出级别

使用 C# 在 Windows 10 上控制左右扬声器平衡级别

电脑突然没有声音了怎么恢复正常

MATLAB 中的声音输出电平

从 C 代码中获取 ALSA 峰值

如何获得当前音量[重复]