web-dev-qa-db-ja.com

C#でマスターサウンドボリュームを取得する

サウンドカードへの出力の現在の音量を取得する必要があります。

どのようにアイデアはありますか?

20
Alon Gubkin

これらの値は、VistaおよびWin7のCoreAudioAPIで IAudioMeterInformation を使用して取得できます。

マネージラッパーは NAudio で利用できます(MMDeviceからAudioMeterInformationを取得します)。

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

変更から c#のマイクボリューム 記事

3
Basil

他の音がないときにある種の「エレベーターミュージック」を開始する(まだリリースされていない...)アプリケーションに取り組んでいたときに、これを解決しました。

マークヒースによって与えられた素晴らしいヒントに従って、私は私が欲しいものを手に入れました:

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

次のMSDN情報を確認してください。

  • IMMDeviceCollection、IMMDevice、およびIAudioEndpointVolume(Windows Vista、Windows 7のみ)。
  • mixerGetNumDevs、mixerGetLineControls、.。

これは「一般的な」情報です。 C#にはもっと便利な方法がある可能性があります(わかりません)。

2
VitalyVal

多分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: [email protected]
    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

1
JoeBilly

XPで現在のピークを取得する簡単な方法があるとは思いません。 MIXERC​​ONTROL_CONTROLTYPE_PEAKMETERは存在しますが、ほとんどサポートされていないと思います(現在のマシンにあります)。現在のオーディオ出力を分析する独自の方法を作成していると思います。DSPセクションをご覧ください ここ

実行時にどの方法を使用するかを決めることができます。XPとVista/7では、オーディオの処理方法が大きく異なります。以前に書いたこの問題に関する役立つ情報は、次のとおりです。 ここ

私の意見では、MSDNドキュメントとLarry Osterman(彼はSOのメンバーでもあります)のブログは、おそらく現在のWindowsオーディオインフラストラクチャの2つの最も有用なソースです。

0
Andrew

コードプロジェクトからこのコードをチェックしてください: DirectXを使用したLEDスタイルのボリュームメーター

この記事は、AnalogSignalMeterと呼ばれる私が作成したUserControlの使用マニュアルとして機能します。このコントロールは、Direct3Dを使用してコントロールをペイントし、DirectSoundを使用してオーディオ信号をサンプリングします。

これにはAnalogSignalMeterオブジェクトがあり、現在の左右のスピーカーレベルを報告するイベントが発生します。

0
GalacticJello