在c#中获取主音量

时间:2010-03-28 21:16:41

标签: c# audio volume mixer

我需要将当前音量输出到声卡。

任何想法如何?

7 个答案:

答案 0 :(得分:12)

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

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

答案 1 :(得分:3)

    static int PlayerVolume()
    {
        RecordPlayer rp = new RecordPlayer();
        rp.PlayerID = -1;
        int playerVolume = rp.PlayerVolume;
        return playerVolume;
    }

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

答案 2 :(得分:2)

查看MSDN信息:

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

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

答案 3 :(得分:2)

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

按照马克希思给出的精彩提示,我得到了我想要的东西:

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

答案 4 :(得分:1)

也许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

答案 5 :(得分:0)

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

  

本文作为使用手册   对于我创建的UserControl调用   AnalogSignalMeter。此控件使用   Direct3D绘制控件,和   DirectSound采样音频   信号。

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

答案 6 :(得分:0)

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

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

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