在 c# 中获取主音量

Posted

技术标签:

【中文标题】在 c# 中获取主音量【英文标题】:Get Master Sound Volume in c# 【发布时间】:2011-02-01 20:07:22 【问题描述】:

我需要获取当前输出到声卡的音量。

有什么想法吗?

【问题讨论】:

另一个解决方案是来自代码项目的这篇文章(也是):VolumeMeter (Managed DirectX) 您想要当前音量还是当前最大音量?如果您想要当前的最大音量,这对于 Vista+ 与 XP 显然是“不同的”,请参阅 ***.com/q/4640106/32453 【参考方案1】:

在 MSDN 信息中查找:

IMMDeviceCollection、IMMDevice 和 IAudioEndpointVolume(仅限 Windows Vista、Windows 7)。 mixerGetNumDevs、mixerGetLineControls、...

这是“常见”信息。 C# 可能有更方便的方法(我不知道)。

【讨论】:

他要求在主通道上进行实际的实时音频输出音量测量,而不是设置调音台拨盘的句柄。看到他在屏幕截图上选择的部分了吗?据我所知,那些 Win API 不提供对“实时”信息的访问。 迈克阿特拉斯,你是对的。在这种情况下,应该使用 IAudioMeterInformation(正如 Mark Heath 所指出的那样)。【参考方案2】:

您可以在 Vista 和 Win 7 的 CoreAudio API 中使用 IAudioMeterInformation 获取这些值。

NAudio 中提供了托管包装器(从 MMDevice 获取 AudioMeterInformation)。

【讨论】:

【参考方案3】:

从代码项目中查看此代码:LED Style Volume Meter Using DirectX

本文作为使用手册 对于我创建的 UserControl,称为 模拟信号表。该控件使用 Direct3D 绘制控件,以及 DirectSound 对音频进行采样 信号。

它有一个 AnalogSignalMeter 对象,触发一个事件,报告当前左右扬声器的电平。

【讨论】:

【参考方案4】:

我不相信有一种简单的方法可以在 XP 下获得当前的峰值。 MIXERC​​ONTROL_CONTROLTYPE_PEAKMETER 存在,但我相信它在很大程度上不受支持(它在我当前的机器上)。我猜您将创建自己的方法来分析当前音频输出,请查看 DSP 部分 here。

您可以在运行时决定要使用哪种方法,XP 和 Vista/7 处理音频的方法非常不同。我之前写的关于这个问题的一些可能有用的信息可以是here.

在我看来,MSDN 文档和 Larry Osterman(他也是 SO 的成员)的博客可能是当前 Windows 音频基础设施的两个最有用的资源。

【讨论】:

【参考方案5】:

也许 winmm.dll 可以帮助你:

来自 EDDYKT (VB):

Private Const HIGHEST_VOLUME_SETTING = 100 '%
Private Const AUX_MAPPER = -1&
Private Const MAXPNAMELEN = 32
Private Const AUXCAPS_CDAUDIO = 1   '  audio from internal CD-ROM drive
Private Const AUXCAPS_AUXIN = 2   '  audio from auxiliary input jacks
Private Const AUXCAPS_VOLUME = &H1          '  supports volume control
Private Const AUXCAPS_LRVOLUME = &H2          '  separate left-right volume control
Private Const MMSYSERR_NOERROR = 0
Private Const MMSYSERR_BASE = 0
Private Const MMSYSERR_BADDEVICEID = (MMSYSERR_BASE + 2)
Private Type AUXCAPS
       wMid As Integer
       wPid As Integer
       vDriverVersion As Long
       szPname As String * MAXPNAMELEN
       wTechnology As Integer
       dwSupport As Long
End Type
Private Type VolumeSetting
    LeftVol As Integer
    RightVol As Integer
End Type
Private Declare Function auxGetNumDevs Lib "winmm.dll" () As Long
Private Declare Function auxGetDevCaps Lib "winmm.dll" Alias "auxGetDevCapsA" (ByVal uDeviceID As Long, lpCaps As AUXCAPS, ByVal uSize As Long) As Long
Private Declare Function auxSetVolume Lib "winmm.dll" (ByVal uDeviceID As Long, ByVal dwVolume As Long) As Long
Private Declare Function auxGetVolume Lib "winmm.dll" (ByVal uDeviceID As Long, ByRef lpdwVolume As VolumeSetting) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Function nSigned(ByVal lUnsignedInt As Long) As Integer
    Dim nReturnVal As Integer                          ' Return value from Function
    If lUnsignedInt > 65535 Or lUnsignedInt < 0 Then
        MsgBox "Error in conversion from Unsigned to nSigned Integer"
        nSignedInt = 0
        Exit Function
    End If
    If lUnsignedInt > 32767 Then
        nReturnVal = lUnsignedInt - 65536
    Else
        nReturnVal = lUnsignedInt
    End If
    nSigned = nReturnVal
End Function
Private Function lUnsigned(ByVal nSignedInt As Integer) As Long
    Dim lReturnVal As Long                          ' Return value from Function
    If nSignedInt < 0 Then
        lReturnVal = nSignedInt + 65536
    Else
        lReturnVal = nSignedInt
    End If
    If lReturnVal > 65535 Or lReturnVal < 0 Then
        MsgBox "Error in conversion from nSigned to Unsigned Integer"
        lReturnVal = 0
    End If
    lUnsigned = lReturnVal
End Function
Private Function lSetVolume(ByRef lLeftVol As Long, ByRef lRightVol As Long, lDeviceID As Long) As Long
    Dim Volume As VolumeSetting, lBothVolumes As Long
    Volume.LeftVol = nSigned(lLeftVol * 65535 / HIGHEST_VOLUME_SETTING)
    Volume.RightVol = nSigned(lRightVol * 65535 / HIGHEST_VOLUME_SETTING)
    'copy our Volume-variable to a long
    CopyMemory lBothVolumes, Volume.LeftVol, Len(Volume)
    'call the SetVolume-function
    lSetVolume = auxSetVolume(lDeviceID, lBothVolumes)
End Function
Private Sub Form_Load()
    'KPD-Team 2000
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net
    Dim Volume As VolumeSetting, Cnt As Long, AC As AUXCAPS
    'set the output to a persistent graphic
    Me.AutoRedraw = True
    'loop through all the devices
    For Cnt = 0 To auxGetNumDevs - 1 'auxGetNumDevs is zero-based
        'get the volume
        auxGetVolume Cnt, Volume
        'get the device capabilities
        auxGetDevCaps Cnt, AC, Len(AC)
        'print the name on the form
        Me.Print "Device #" + Str$(Cnt + 1) + ":  " + Left(AC.szPname, InStr(AC.szPname, vbNullChar) - 1)
        'print the left- and right volume on the form
        Me.Print "Left volume:" + Str$(HIGHEST_VOLUME_SETTING * lUnsigned(Volume.LeftVol) / 65535)
        Me.Print "Right volume:" + Str$(HIGHEST_VOLUME_SETTING * lUnsigned(Volume.RightVol) / 65535)
        'set the left- and right-volume to 50%
        lSetVolume 50, 50, Cnt
        Me.Print "Both volumes now set to 50%"
        'empty line
        Me.Print
    Next
End Sub

或者这个:http://blackbeltvb.com/index.htm?free/mcisamp.htm

【讨论】:

看起来它设置了音量,我想他们是在询问当前的音频输出,或者当前从扬声器发出的声音有多大。 哦,我明白他要求音频音量值:auxGetVolume 接缝提供此信息。那么也许 auxGetDevCaps 可能对当前的输出设备有所帮助?【参考方案6】:

我在开发一个(尚未发布...)应用程序时解决了这个问题,该应用程序在没有其他声音时会启动某种“电梯音乐”。

按照 Mark Heath 给出的绝妙技巧,我得到了我想要的:

 using NAudio.CoreAudioApi; 
 MMDeviceEnumerator devEnum = new MMDeviceEnumerator();
 MMDevice defaultDevice = devEnum.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
 string currVolume = "MasterPeakVolume : " + defaultDevice.AudioMeterInformation.MasterPeakValue.ToString();

【讨论】:

成功了!谢谢! (需要从 Nuget 添加 NAudio)【参考方案7】:
    static int PlayerVolume()
    
        RecordPlayer rp = new RecordPlayer();
        rp.PlayerID = -1;
        int playerVolume = rp.PlayerVolume;
        return playerVolume;
    

来自修改Microphone Volume in c#的文章

【讨论】:

以上是关于在 c# 中获取主音量的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C# 使用 ALSA 在 Linux 中获取和设置音量?

在 Windows 应用程序中获取声卡输出音量

在 C# 中将主音量从 XP 更改为 Windows 8

C# Win7如何获得系统主音量 只需知道主音大小 无需修改

C# - 使用外部 Midi 控制器更改音量

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