获取主音量在C#
我需要获得声卡输出的当前音量。
任何想法如何?
您可以使用Vista中的CoreAudio API中的IAudioMeterInformation和Win 7获取这些值。
NAudio提供托pipe包装(从MMDevice获取AudioMeterInformation)。
static int PlayerVolume() { RecordPlayer rp = new RecordPlayer(); rp.PlayerID = -1; int playerVolume = rp.PlayerVolume; return playerVolume; }
从c#文章中修改的麦克风音量
查看MSDN信息:
- IMMDeviceCollection,IMMDevice和IAudioEndpointVolume(仅适用于Windows Vista,Windows 7)。
- mixerGetNumDevs,mixerGetLineControls,…
这是“常见”信息。 有可能C#有更方便的方法(我不知道)。
当我正在处理一个(还没有被释放的…)应用程序时,我解决了这个问题,当没有其他声音出现时,它会启动某种“电梯音乐”。
遵循Mark Heath提供的精彩技巧,我得到了我想要的:
using NAudio.CoreAudioApi; MMDeviceEnumerator devEnum = new MMDeviceEnumerator(); MMDevice defaultDevice = devEnum.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); string currVolume = "MasterPeakVolume : " + defaultDevice.AudioMeterInformation.MasterPeakValue.ToString();
也许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
从代码项目中查看此代码: 使用DirectX的LED风格音量计
本文作为我创build的名为AnalogSignalMeter的UserControl的使用手册。 此控件使用Direct3D绘制控件,并使用DirectSound对audio信号进行采样。
它有一个AnalogSignalMeter对象,触发一个事件,它将报告当前的左右扬声器级别。
我不相信有一个简单的方法来获得XP下的当前峰值。 MIXERCONTROL_CONTROLTYPE_PEAKMETER是存在的,但我相信这是很大程度上不受支持(这是在我目前的机器上)。 我猜你会创build自己的方法来分析当前的audio输出,看看这里的DSP部分。
你可以在运行时决定你想使用哪种方法,XP和Vista / 7有不同的处理方法。 关于这个我以前写的东西的一些可能有用的信息可以在这里。
在我看来,MSDN文档和Larry Osterman(他也是SO的成员)博客可能是目前Windowsaudio基础架构最有用的两个来源。