2010-03-28 35 views
20

Necesito obtener el volumen actual de la salida de la tarjeta de sonido.Obtener volumen de sonido principal en C#

¿Alguna idea de cómo?

+0

¿Quieres que el volumen actual, o el volumen máximo actual? Si quiere el volumen máximo actual, esto es aparentemente "diferente" para Vista + vs. XP, vea http://stackoverflow.com/q/4640106/32453 – rogerdpack

+0

Otra solución es este artículo (también) de Code Project: [VolumeMeter (DirectX administrado)] (http://www.codeproject.com/KB/directx/volumemeter.aspx) – loraderon

Respuesta

12

Se puede llegar a estos valores utilizando IAudioMeterInformation en el API CoreAudio en Vista y Win 7.

contenedores administrados están disponibles en NAudio (llegar a la AudioMeterInformation del MMDevice).

2

Buscar en la información de MSDN para:

  • IMMDeviceCollection, IMMDevice y IAudioEndpointVolume (sólo Windows Vista, Windows 7).
  • mixerGetNumDevs, mixerGetLineControls, ...

Esta es la información "común". Es posible que C# tenga formas más convenientes (no sé).

+0

Está solicitando la medición de volumen de salida de audio real en tiempo real en el canal maestro, no un control para configurar el dial del mezclador. ¿Ves la parte que seleccionó en la captura de pantalla? Por lo que puedo decir, esas API de Win no ofrecen acceso a esa información en "tiempo real". –

+1

Mike Atlas, tienes razón. En este caso, debe usarse IAudioMeterInformation (como señaló Mark Heath). – VitalyVal

0

Salida este código de Proyecto Código: LED Style Volume Meter Using DirectX

Este artículo sirve como un manual de uso para un control de usuario que creé llamado AnalogSignalMeter. Este control usa Direct3D para pintar el control y DirectSound para muestrear la señal de audio .

Tiene un objeto AnalogSignalMeter, que activa un evento que informará el nivel actual de los altavoces izquierdo y derecho.

0

No creo que hay una manera fácil de obtener el pico de corriente bajo XP. MIXERCONTROL_CONTROLTYPE_PEAKMETER está presente, pero creo que no está soportado (está en mi máquina actual). Supongo que habrá creado su propio método para analizar la salida de audio actual, eche un vistazo a la sección DSP here.

Usted puede simplemente decidir en tiempo de ejecución del método que desea utilizar, XP y Vista/7 tienen muy diferentes métodos de tratar con el audio. Alguna información posiblemente útil sobre este asunto que escribí anteriormente puede ser here.

La documentación de MSDN y el blog de Larry Osterman (él también es miembro de SO) son probablemente las 2 fuentes más útiles para la infraestructura actual de audio de Windows en mi opinión.

1

Tal vez el winmm.dll puede ayudarle a:

De 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 

O tal vez esto: http://blackbeltvb.com/index.htm?free/mcisamp.htm

+0

Parece que configura el volumen, creo que están pidiendo la salida de audio actual, o qué tan fuerte es el sonido que está emitiendo actualmente desde los altavoces. – GalacticJello

+0

Oh, entendí que estaba pidiendo el valor del volumen de audio: el auxGetVolume parece proporcionar esta información. ¿Entonces quizás las auxGetDevCaps pueden ayudar con el dispositivo de salida actual? – JoeBilly

2

He resuelto esto cuando yo estaba trabajando en un (todavía aún no se ha lanzado ...) aplicación que inicia algún tipo de "música de ascensor" cuando no hay otro sonido presente.

seguido las puntas brillantes dados por Mark Heath, obtuve lo que quería:

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

Esto no funciona en XP. – svick

+1

¡Funcionó! ¡Gracias! (Necesito agregar NAudio de Nuget) –

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

de Microphone Volume in c# artículo modificado

Cuestiones relacionadas