[RESOLVED] How to change master volume level?
Okay, I have an application that plays wav and mp3 files using the Microsoft.DirectX.AudioVideoPlayback.Audio() function. It works fine, and I can easily set the volume level of the playback... within limits.
That limit is the system volume level. I can set the playback level for the mp3, but if the system volume is muted or set real low it may still play softly. So I want to add controls that will tell the user what the system volume and mute are set to, and allow him to change those from inside my app.
So how do I set the master volume level, including making sure it isn't muted?
Re: How to change master volume level?
Hi.
So here is a mixture of random classes i've found over the net.Most of them in VB6 so i had a heck of a time changing them.
What works is the ''mixersetter.SetVolume (zero for no sound)
and the mixsetter.Getvolume.
Muting and finding if a control is muted proved very complex.If anyone from the API people here can take a look.Basically the problem is that the MIXERCONTROLDETAILS is not getting the dwControlID.
So i will post the class (mixersetter), you must import it on your appliaction and the do a mixersetter.SetVolume(0) to low the volume. If you provide larger numbers then the volume will raise.
Mind you it very big so i will probably cut it in 2-3 posts.
Code:
Imports System
Imports System.Runtime.InteropServices
Public Class mixersetter
Public Const MMSYSERR_NOERROR As Integer = 0
Public Const MAXPNAMELEN As Integer = 32
Public Const MIXER_LONG_NAME_CHARS As Integer = 64
Public Const MIXER_SHORT_NAME_CHARS As Integer = 16
Public Const MIXER_GETLINEINFOF_COMPONENTTYPE As Integer = &H3
Public Const MIXER_GETCONTROLDETAILSF_VALUE As Integer = &H0
Public Const MIXER_GETLINECONTROLSF_ONEBYTYPE As Integer = &H2
Public Const MIXER_SETCONTROLDETAILSF_VALUE As Integer = &H0
Public Const MIXERLINE_COMPONENTTYPE_DST_FIRST As Integer = &H0
Public Const MIXERLINE_COMPONENTTYPE_SRC_FIRST As Integer = &H1000
Public Const MIXERLINE_COMPONENTTYPE_DST_SPEAKERS As Integer = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 4)
Public Const MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE As Integer = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3)
Public Const MIXERLINE_COMPONENTTYPE_SRC_LINE As Integer = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2)
Public Const MIXERCONTROL_CT_CLASS_FADER As Integer = &H50000000
Public Const MIXERCONTROL_CT_UNITS_UNSIGNED As Integer = &H30000
Public Const MIXERCONTROL_CONTROLTYPE_FADER As Integer = (MIXERCONTROL_CT_CLASS_FADER Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Public Const MIXERCONTROL_CONTROLTYPE_VOLUME As Integer = (MIXERCONTROL_CONTROLTYPE_FADER + 1)
Private Declare Function mixerGetLineInfo Lib "winmm.dll" Alias "mixerGetLineInfoA" (ByVal hmxobj As Int32, ByVal pmxl As MIXERLINE, ByVal fdwInfo As Int32) As Int32
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Int32, ByVal dwBytes As Int32) As Int32
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Int32) As IntPtr
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Int32) As Int32
Private Declare Function mixerGetLineControls Lib "winmm.dll" Alias "mixerGetLineControlsA" (ByVal hmxobj As Int32, ByVal pmxlc As MIXERLINECONTROLS, ByVal fdwControls As Int32) As Int32
Public Shared uMixerControls(20) As MIXERCONTROL ' local array to store mixer controls
Public Shared hMixerHandle As Int32 ' handle for mixer
''Private Declare Sub CopyStructFromPtr Lib "kernel32" Alias "RtlMoveMemory" (ByVal struct As Object, ByVal ptr As IntPtr, ByVal cb As Int32)
Private Declare Sub CopyStructFromPtr Lib "kernel32" Alias "RtlMoveMemory" (<MarshalAs(UnmanagedType.AsAny)> ByVal struct As Object, ByVal ptr As IntPtr, ByVal cb As Int32)
'' Private Declare Sub CopyPtrFromStruct Lib "kernel32" Alias "RtlMoveMemory" (ByVal ptr As IntPtr, ByVal struct As Object, ByVal cb As Int32)
Private Declare Sub CopyPtrFromStruct Lib "kernel32" Alias "RtlMoveMemory" (ByVal ptr As IntPtr, <MarshalAs(UnmanagedType.AsAny)> ByVal struct As Object, ByVal cb As Int32)
'
' MMRESULT error return values specific to the mixer API
'
Private Const MIXERR_BASE = 1024
Private Const MIXERR_INVALLINE = (MIXERR_BASE + 0)
Private Const MIXERR_INVALCONTROL = (MIXERR_BASE + 1)
Private Const MIXERR_INVALVALUE = (MIXERR_BASE + 2)
Private Const MIXERR_LASTERROR = (MIXERR_BASE + 2)
Private Const MIXER_OBJECTF_HANDLE = &H80000000
Private Const MIXER_OBJECTF_MIXER = &H0&
Private Const MIXER_OBJECTF_HMIXER = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIXER)
Private Const MIXER_OBJECTF_WAVEOUT = &H10000000
Private Const MIXER_OBJECTF_HWAVEOUT = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_WAVEOUT)
Private Const MIXER_OBJECTF_WAVEIN = &H20000000
Private Const MIXER_OBJECTF_HWAVEIN = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_WAVEIN)
Private Const MIXER_OBJECTF_MIDIOUT = &H30000000
Private Const MIXER_OBJECTF_HMIDIOUT = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIDIOUT)
Private Const MIXER_OBJECTF_MIDIIN = &H40000000
Private Const MIXER_OBJECTF_HMIDIIN = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIDIIN)
Private Const MIXER_OBJECTF_AUX = &H50000000
'
' MIXERLINE.fdwLine
'
Private Const MIXERLINE_LINEF_ACTIVE = &H1&
Private Const MIXERLINE_LINEF_DISCONNECTED = &H8000&
Private Const MIXERLINE_LINEF_SOURCE = &H80000000
'
' MIXERLINE.dwComponentType
'
Private Const MIXERLINE_COMPONENTTYPE_DST_UNDEFINED = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 0)
Private Const MIXERLINE_COMPONENTTYPE_DST_DIGITAL = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 1)
Private Const MIXERLINE_COMPONENTTYPE_DST_LINE = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 2)
Private Const MIXERLINE_COMPONENTTYPE_DST_MONITOR = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 3)
Private Const MIXERLINE_COMPONENTTYPE_DST_HEADPHONES = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 5)
Private Const MIXERLINE_COMPONENTTYPE_DST_TELEPHONE = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 6)
Private Const MIXERLINE_COMPONENTTYPE_DST_WAVEIN = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 7)
Private Const MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 4)
Private Const MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 5)
Private Const MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 7)
Private Const MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 8)
Private Const MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 9)
'
' MIXERLINE.Target.dwType
'
Private Const MIXERLINE_TARGETTYPE_UNDEFINED = 0
Private Const MIXERLINE_TARGETTYPE_WAVEOUT = 1
Private Const MIXERLINE_TARGETTYPE_WAVEIN = 2
Private Const MIXERLINE_TARGETTYPE_MIDIOUT = 3
Private Const MIXERLINE_TARGETTYPE_MIDIIN = 4
Private Const MIXERLINE_TARGETTYPE_AUX = 5
'
' MIXERCONTROL.fdwControl
'
Private Const MIXERCONTROL_CONTROLF_UNIFORM = &H1&
Private Const MIXERCONTROL_CONTROLF_MULTIPLE = &H2&
Private Const MIXERCONTROL_CONTROLF_DISABLED = &H80000000
'
' MIXERCONTROL_CONTROLTYPE_xxx building block defines
'
Private Const MIXERCONTROL_CT_CLASS_SWITCH = &H20000000
Private Const MIXERCONTROL_CT_SC_SWITCH_BOOLEAN = &H0&
Private Const MIXERCONTROL_CT_UNITS_BOOLEAN = &H10000
Private Const MIXERCONTROL_CONTROLTYPE_BOOLEAN = (MIXERCONTROL_CT_CLASS_SWITCH Or MIXERCONTROL_CT_SC_SWITCH_BOOLEAN Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Private Const MIXERCONTROL_CONTROLTYPE_MUTE = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2)
Re: How to change master volume level?
Code:
<DllImport("winmm.dll", CharSet:=CharSet.Ansi)> _
Private Shared Function mixerClose(ByVal hmx As Integer) As Integer
End Function
<DllImport("winmm.dll", CharSet:=CharSet.Ansi)> _
Private Shared Function mixerGetControlDetailsA(ByVal hmxobj As Integer, ByRef pmxcd As MIXERCONTROLDETAILS, ByVal fdwDetails As Integer) As Integer
End Function
<DllImport("winmm.dll", CharSet:=CharSet.Ansi)> _
Private Shared Function mixerGetDevCapsA(ByVal uMxId As Integer, ByVal pmxcaps As MIXERCAPS, ByVal cbmxcaps As Integer) As Integer
End Function
<DllImport("winmm.dll", CharSet:=CharSet.Ansi)> _
Private Shared Function mixerGetID(ByVal hmxobj As Integer, ByVal pumxID As Integer, ByVal fdwId As Integer) As Integer
End Function
<DllImport("winmm.dll", CharSet:=CharSet.Ansi)> _
Private Shared Function mixerGetLineControlsA(ByVal hmxobj As Integer, ByRef pmxlc As MIXERLINECONTROLS, ByVal fdwControls As Integer) As Integer
End Function
<DllImport("winmm.dll", CharSet:=CharSet.Ansi)> _
Private Shared Function mixerGetLineInfoA(ByVal hmxobj As Integer, ByRef pmxl As MIXERLINE, ByVal fdwInfo As Integer) As Integer
End Function
<DllImport("winmm.dll", CharSet:=CharSet.Ansi)> _
Private Shared Function mixerGetNumDevs() As Integer
End Function
<DllImport("winmm.dll", CharSet:=CharSet.Ansi)> _
Private Shared Function mixerMessage(ByVal hmx As Integer, ByVal uMsg As Integer, ByVal dwParam1 As Integer, ByVal dwParam2 As Integer) As Integer
End Function
<DllImport("winmm.dll", CharSet:=CharSet.Ansi)> _
Private Shared Function mixerOpen(ByRef phmx As Integer, ByVal uMxId As Integer, ByVal dwCallback As Integer, ByVal dwInstance As Integer, ByVal fdwOpen As Integer) As Integer
End Function
<DllImport("winmm.dll", CharSet:=CharSet.Ansi)> _
Private Shared Function mixerSetControlDetails(ByVal hmxobj As Integer, ByRef pmxcd As MIXERCONTROLDETAILS, ByVal fdwDetails As Integer) As Integer
End Function
Public Structure MIXERCAPS
Public wMid As Integer
Public wPid As Integer
Public vDriverVersion As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAXPNAMELEN)> _
Public szPname As String
Public fdwSupport As Integer
Public cDestinations As Integer
End Structure
Public Structure MIXERCONTROL
Public cbStruct As Integer
Public dwControlID As Integer
Public dwControlType As Integer
Public fdwControl As Integer
Public cMultipleItems As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MIXER_SHORT_NAME_CHARS)> _
Public szShortName As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MIXER_LONG_NAME_CHARS)> _
Public szName As String
Public lMinimum As Integer
Public lMaximum As Integer
<MarshalAs(UnmanagedType.U4, SizeConst:=10)> _
Public reserved As Integer
End Structure
Public Structure MIXERCONTROLDETAILS
Public cbStruct As Integer
Public dwControlID As Integer
Public cChannels As Integer
Public item As Integer
Public cbDetails As Integer
Public paDetails As IntPtr
End Structure
Public Structure MIXERCONTROLDETAILS_UNSIGNED
Public dwValue As Integer
End Structure
Public Structure MIXERLINE
Public cbStruct As Integer
Public dwDestination As Integer
Public dwSource As Integer
Public dwLineID As Integer
Public fdwLine As Integer
Public dwUser As Integer
Public dwComponentType As Integer
Public cChannels As Integer
Public cConnections As Integer
Public cControls As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MIXER_SHORT_NAME_CHARS)> _
Public szShortName As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MIXER_LONG_NAME_CHARS)> _
Public szName As String
Public dwType As Integer
Public dwDeviceID As Integer
Public wMid As Integer
Public wPid As Integer
Public vDriverVersion As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAXPNAMELEN)> _
Public szPname As String
End Structure
Public Structure MIXERLINECONTROLS
Public cbStruct As Integer
Public dwLineID As Integer
Public dwControl As Integer
Public cControls As Integer
Public cbmxctrl As Integer
Public pamxctrl As IntPtr
End Structure
Public Enum MUTE_CONTROL
SPEAKER_MUTE = 7
LINEIN_MUTE = 8
MICROPHONE_MUTE = 9
SYNTHESIZER_MUTE = 10
COMPACTDISC_MUTE = 11
WAVEOUT_MUTE = 12
AUXILIARY_MUTE = 13
End Enum
Public Enum VOL_CONTROL
SPEAKER = 0
LINEIN = 1
MICROPHONE = 2
SYNTHESIZER = 3
COMPACTDISC = 4
WAVEOUT = 5
AUXILIARY = 6
End Enum
Re: How to change master volume level?
Code:
Public Shared Function GetVolumeControl(ByVal hmixer As Integer, ByVal componentType As Integer, ByVal ctrlType As Integer, ByRef mxc As MIXERCONTROL, ByRef vCurrentVol As Integer) As Boolean
' This function attempts to obtain a mixer control.
' Returns True if successful.
Dim mxlc As New MIXERLINECONTROLS
Dim mxl As New MIXERLINE
Dim pmxcd As New MIXERCONTROLDETAILS
Dim du As New MIXERCONTROLDETAILS_UNSIGNED
mxc = New MIXERCONTROL
Dim rc As Integer
Dim retValue As Boolean
vCurrentVol = -1
mxl.cbStruct = Marshal.SizeOf(mxl)
mxl.dwComponentType = componentType
rc = mixerGetLineInfoA(hmixer, mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)
If MMSYSERR_NOERROR = rc Then
Dim sizeofMIXERCONTROL As Integer = 152
Dim ctrl As Integer = Marshal.SizeOf(GetType(MIXERCONTROL))
mxlc.pamxctrl = Marshal.AllocCoTaskMem(sizeofMIXERCONTROL)
mxlc.cbStruct = Marshal.SizeOf(mxlc)
mxlc.dwLineID = mxl.dwLineID
mxlc.dwControl = ctrlType
mxlc.cControls = 1
mxlc.cbmxctrl = sizeofMIXERCONTROL
' Allocate a buffer for the control
mxc.cbStruct = sizeofMIXERCONTROL
' Get the control
rc = mixerGetLineControlsA(hmixer, mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE)
If MMSYSERR_NOERROR = rc Then
retValue = True
' Copy the control into the destination structure
mxc = DirectCast(Marshal.PtrToStructure(mxlc.pamxctrl, GetType(MIXERCONTROL)), MIXERCONTROL)
Else
retValue = False
End If
Dim sizeofMIXERCONTROLDETAILS As Integer = Marshal.SizeOf(GetType(MIXERCONTROLDETAILS))
Dim sizeofMIXERCONTROLDETAILS_UNSIGNED As Integer = Marshal.SizeOf(GetType(MIXERCONTROLDETAILS_UNSIGNED))
pmxcd.cbStruct = sizeofMIXERCONTROLDETAILS
pmxcd.dwControlID = mxc.dwControlID
pmxcd.paDetails = Marshal.AllocCoTaskMem(sizeofMIXERCONTROLDETAILS_UNSIGNED)
pmxcd.cChannels = 1
pmxcd.item = 0
pmxcd.cbDetails = sizeofMIXERCONTROLDETAILS_UNSIGNED
rc = mixerGetControlDetailsA(hmixer, pmxcd, MIXER_GETCONTROLDETAILSF_VALUE)
du = DirectCast(Marshal.PtrToStructure(pmxcd.paDetails, GetType(MIXERCONTROLDETAILS_UNSIGNED)), MIXERCONTROLDETAILS_UNSIGNED)
vCurrentVol = du.dwValue
Return retValue
End If
retValue = False
Return retValue
End Function
Private Shared Function SetVolumeControl(ByVal hmixer As Integer, ByVal mxc As MIXERCONTROL, ByVal volume As Integer) As Boolean
' This function sets the value for a volume control.
' Returns True if successful
Dim retValue As Boolean
Dim rc As Integer
Dim mxcd As New MIXERCONTROLDETAILS
Dim vol As New MIXERCONTROLDETAILS_UNSIGNED
mxcd.item = 0
mxcd.dwControlID = mxc.dwControlID
mxcd.cbStruct = Marshal.SizeOf(mxcd)
mxcd.cbDetails = Marshal.SizeOf(vol)
' Allocate a buffer for the control value buffer
mxcd.cChannels = 1
vol.dwValue = volume
' Copy the data into the control value buffer
mxcd.paDetails = Marshal.AllocCoTaskMem(Marshal.SizeOf(GetType(MIXERCONTROLDETAILS_UNSIGNED)))
Marshal.StructureToPtr(vol, mxcd.paDetails, False)
' Set the control value
rc = mixerSetControlDetails(hmixer, mxcd, MIXER_SETCONTROLDETAILSF_VALUE)
If MMSYSERR_NOERROR = rc Then
retValue = True
Else
retValue = False
End If
Return retValue
End Function
Public Shared Function GetVolume() As Integer
Dim mixer As Integer
Dim volCtrl As New MIXERCONTROL
Dim currentVol As Integer
mixerOpen(mixer, 0, 0, 0, 0)
Dim type As Integer = MIXERCONTROL_CONTROLTYPE_VOLUME
GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, type, volCtrl, currentVol)
mixerClose(mixer)
Return currentVol
End Function
Public Shared Sub SetVolume(ByVal vVolume As Integer)
Dim mixer As Integer
Dim volCtrl As New MIXERCONTROL
Dim currentVol As Integer
mixerOpen(mixer, 0, 0, 0, 0)
Dim type As Integer = MIXERCONTROL_CONTROLTYPE_VOLUME
GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, type, volCtrl, currentVol)
If vVolume > volCtrl.lMaximum Then
vVolume = volCtrl.lMaximum
End If
If vVolume < volCtrl.lMinimum Then
vVolume = volCtrl.lMinimum
End If
SetVolumeControl(mixer, volCtrl, vVolume)
GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, type, volCtrl, currentVol)
If vVolume <> currentVol Then
Throw New Exception("Cannot Set Volume")
End If
mixerClose(mixer)
End Sub
Public Shared Function SetControlValue(ByVal hMixer As Int32, ByVal mxc As MIXERCONTROL, ByVal NewVolume As Int32) As Boolean
'This function sets the value for a control. Returns True if successful
Dim mxcd As MIXERCONTROLDETAILS
Dim vol As MIXERCONTROLDETAILS_UNSIGNED
Dim hMem As Int32
Dim ret As Int32
Dim sizeofMIXERCONTROLDETAILS As Integer = Marshal.SizeOf(GetType(MIXERCONTROLDETAILS))
Dim sizeofMIXERCONTROLDETAILS_UNSIGNED As Integer = Marshal.SizeOf(GetType(MIXERCONTROLDETAILS_UNSIGNED))
mxcd.item = 0
mxcd.dwControlID = mxc.dwControlID
mxcd.cbStruct = sizeofMIXERCONTROLDETAILS
' mxcd.cbStruct = Len(mxcd)
mxcd.cbDetails = Marshal.SizeOf(vol)
' Allocate a buffer for the control value buffer
hMem = GlobalAlloc(&H40, Marshal.SizeOf(vol))
mxcd.paDetails = GlobalLock(hMem)
mxcd.cChannels = 1
' setup value, use percent of range if max is greater than 100
If mxc.lMaximum > 100 Then
vol.dwValue = NewVolume * (mxc.lMaximum \ 100)
Else
vol.dwValue = NewVolume
End If
If vol.dwValue > mxc.lMaximum Then vol.dwValue = mxc.lMaximum
If vol.dwValue < mxc.lMinimum Then vol.dwValue = mxc.lMinimum
' Copy the data into the control value buffer
CopyPtrFromStruct(mxcd.paDetails, vol, Marshal.SizeOf(vol))
' Set the control value
ret = mixerSetControlDetails(hMixer, mxcd, MIXER_SETCONTROLDETAILSF_VALUE)
GlobalFree(hMem)
If ret = MMSYSERR_NOERROR Then SetControlValue = True
End Function
Re: How to change master volume level?
Code:
Public Shared Function GetControlValue(ByVal hMixer As Int32, ByVal mxc As MIXERCONTROL) As Int32
'This function gets the value for a control.
Dim mxcd As MIXERCONTROLDETAILS
Dim vol As MIXERCONTROLDETAILS_UNSIGNED
Dim hMem As Int32
Dim ret As Int32
Dim sizeofMIXERCONTROLDETAILS As Integer = Marshal.SizeOf(GetType(MIXERCONTROLDETAILS))
Dim sizeofMIXERCONTROLDETAILS_UNSIGNED As Integer = Marshal.SizeOf(GetType(MIXERCONTROLDETAILS_UNSIGNED))
' pmxcd.cbStruct = sizeofMIXERCONTROLDETAILS
' pmxcd.dwControlID = mxc.dwControlID
mxcd.item = 0
mxcd.dwControlID = mxc.dwControlID
' mxcd.cbStruct = Len(mxcd)
mxcd.cbStruct = sizeofMIXERCONTROLDETAILS
mxcd.cbDetails = Marshal.SizeOf(vol)
''mxcd.cbDetails = Len(vol)
hMem = GlobalAlloc(&H40, Marshal.SizeOf(vol))
mxcd.paDetails = GlobalLock(hMem)
mxcd.cChannels = 1
' Get the control value
ret = mixerGetControlDetailsA(hMixer, mxcd, MIXER_GETCONTROLDETAILSF_VALUE)
' Copy the data into the control value buffer
CopyStructFromPtr(vol, mxcd.paDetails, Marshal.SizeOf(vol))
If mxc.lMaximum > 100 Then
GetControlValue = (vol.dwValue * 100) / mxc.lMaximum - mxc.lMinimum
Else
GetControlValue = vol.dwValue
End If
GlobalFree(hMem)
End Function
Private Shared Function GetMixerControl(ByVal hMixer As Int32, ByVal componentType As Int32, ByVal ctrlType As Int32, ByRef mxc As MIXERCONTROL) As Int32 ' This function attempts to obtain a mixer control. Returns True if successful.
Dim mxlc As MIXERLINECONTROLS
Dim mxl As MIXERLINE
Dim hMem As Int32
Dim ret As Int32
''mxl.cbStruct = Len(mxl)
mxl.cbStruct = Marshal.SizeOf(mxl)
mxl.dwComponentType = componentType
' Obtain a line corresponding to the component type
ret = mixerGetLineInfo(hMixer, mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)
'' If ret = MMSYSERR_NOERROR Then
If ret <> MMSYSERR_NOERROR Then
''mxlc.cbStruct = Len(mxlc)
mxlc.cbStruct = Marshal.SizeOf(mxl)
mxlc.dwLineID = mxl.dwLineID
mxlc.dwControl = ctrlType
mxlc.cControls = 1
mxlc.cbmxctrl = Marshal.SizeOf(mxc)
' Allocate a buffer for the control
hMem = GlobalAlloc(&H40, Marshal.SizeOf(mxc))
mxlc.pamxctrl = GlobalLock(hMem)
mxc.cbStruct = Marshal.SizeOf(mxc)
' Get the control
Dim mc As New mixersetter.MIXERCONTROL
ret = mixerGetLineControls(hMixer, mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE)
'' If ret = MMSYSERR_NOERROR Then
If ret <> MMSYSERR_NOERROR Then
GetMixerControl = True
'' Marshal.StructureToPtr(mxc, mxlc.pamxctrl, Len(mxc))
' Copy the control into the destination structure
CopyStructFromPtr(mxc, mxlc.pamxctrl, Marshal.SizeOf(mxc))
Else
GetMixerControl = False
End If
GlobalFree(hMem)
Exit Function
End If
GetMixerControl = False
End Function
Public Shared Function SetMute(ByVal Control As MUTE_CONTROL, ByVal MuteState As Boolean) As Boolean
Dim Mute As Integer
Mute = MuteState
SetMute = SetControlValue(hMixerHandle, uMixerControls(Control), Mute)
End Function
Public Shared Function GetMute(ByVal Control As MUTE_CONTROL) As Boolean
GetMute = CBool(-GetControlValue(hMixerHandle, uMixerControls(Control)))
End Function
Public Shared Function OpenMixer(ByVal MixerNumber As Int32) As Int32
Dim ret As Int32
' is there a mixer available?
If MixerNumber < 0 Or MixerNumber > mixerGetNumDevs() - 1 Then Exit Function
' open the mixer
ret = mixerOpen(hMixerHandle, MixerNumber, 0, 0, 0)
If ret <> MMSYSERR_NOERROR Then Exit Function
' get the primary line controls by name, (this does not get all of the controls).
' speaker (master) volume
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, MIXERCONTROL_CONTROLTYPE_VOLUME, uMixerControls(VOL_CONTROL.SPEAKER))
' microphone volume
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, MIXERCONTROL_CONTROLTYPE_VOLUME, uMixerControls(VOL_CONTROL.MICROPHONE))
' Line volume
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY, MIXERCONTROL_CONTROLTYPE_VOLUME, uMixerControls(VOL_CONTROL.AUXILIARY))
' CD volume
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC, MIXERCONTROL_CONTROLTYPE_VOLUME, uMixerControls(VOL_CONTROL.COMPACTDISC))
' Synthesizer volume
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER, MIXERCONTROL_CONTROLTYPE_VOLUME, uMixerControls(VOL_CONTROL.SYNTHESIZER))
' wave volume
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT, MIXERCONTROL_CONTROLTYPE_VOLUME, uMixerControls(VOL_CONTROL.WAVEOUT))
' Aux volume
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_LINE, MIXERCONTROL_CONTROLTYPE_VOLUME, uMixerControls(VOL_CONTROL.LINEIN))
' speaker (master) mute
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, MIXERCONTROL_CONTROLTYPE_MUTE, uMixerControls(MUTE_CONTROL.SPEAKER_MUTE))
' microphone mute
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, MIXERCONTROL_CONTROLTYPE_MUTE, uMixerControls(MUTE_CONTROL.MICROPHONE_MUTE))
' Line mute
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY, MIXERCONTROL_CONTROLTYPE_MUTE, uMixerControls(MUTE_CONTROL.AUXILIARY_MUTE))
' CD mute
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC, MIXERCONTROL_CONTROLTYPE_MUTE, uMixerControls(MUTE_CONTROL.COMPACTDISC_MUTE))
' Synthesizer mute
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER, MIXERCONTROL_CONTROLTYPE_MUTE, uMixerControls(MUTE_CONTROL.SYNTHESIZER_MUTE))
' wave mute
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT, MIXERCONTROL_CONTROLTYPE_MUTE, uMixerControls(MUTE_CONTROL.WAVEOUT_MUTE))
' Aux mute
ret = GetMixerControl(hMixerHandle, MIXERLINE_COMPONENTTYPE_SRC_LINE, MIXERCONTROL_CONTROLTYPE_MUTE, uMixerControls(MUTE_CONTROL.LINEIN_MUTE))
' return the mixer handle
OpenMixer = True
End Function
Public Function CloseMixer() As Int32
CloseMixer = mixerClose(hMixerHandle)
hMixerHandle = 0
End Function
Public Function SetVolume(ByVal Control As VOL_CONTROL, ByVal NewVolume As Int32) As Int32
SetVolume = SetControlValue(hMixerHandle, uMixerControls(Control), NewVolume)
End Function
Public Function GetVolume(ByVal Control As VOL_CONTROL) As Int32
GetVolume = GetControlValue(hMixerHandle, uMixerControls(Control))
End Function
End Class
Re: How to change master volume level?
So i think you had it coming :)
Good luck.
P.S. Since i have not found a decent mute code i played around a little bit. It will be good for the API gurus here to fix the mute so we can have a solid class.As i've said the MIXERCONTROLDETAILS dwControlID is always zero.Somewhare in here it's not getting the control id correct but i'm to messed up to look into it.
The idea is to set the OpenMixer(0 usually one mixer) first so it can get the controls inside CopyStructFromPtr and then use SetMute to mute the control you want.
So somewhere in the GetMixerControl i'm missing something CopyStructFromPtr was the original.I tryied some marshaling but it's the same result.
Anyway if you like you can look around.
Re: How to change master volume level?
Thanks... I downloaded the code and it seems to work fairly well.
The Get/SetVolume works perfectly and is just what I needed. The SetMute... not so much. But the short work-around is to temporarily set volume to zero and restore it to previous value when mute removed. It's not perfect, by any means, but it's a short work-around.
But this IS what I needed, so thanks.
Re: [RESOLVED] How to change master volume level?
No problem.
As i said if anyone will take a look and fix the mute then this is a good class to have around.
Re: [RESOLVED] How to change master volume level?
No promises, but I'll look at it when I get a chance. At the moment I'm slapping a few final features on it before product release.
But thanks for the code, warts and all.
Re: [RESOLVED] How to change master volume level?
mute is easy enough. The following code works well with windows 7 and really mutes the volume so that the volume icon in the taskbar shows that the volume is muted.
Code:
Imports System.Runtime.InteropServices
Public Class Mute
Private Const APPCOMMAND_VOLUME_MUTE As Integer = &H80000
Private Const WM_APPCOMMAND As Integer = &H319
Declare Function SendMessageW Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
Private Sub Mute_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SendMessageW(Me.Handle, WM_APPCOMMAND, Me.Handle, CType(APPCOMMAND_VOLUME_MUTE, IntPtr))
Me.Close()
End Sub
End Class
I'm looking for a simple way to obtain the current volume level (preferably as a percentage) and show on a label without adding the huge bundle of code as above that I keep finding in forums like this.
Re: [RESOLVED] How to change master volume level?
Aha,interesting but the actual problem was not to do a simple mute.
I was working(and i say was because i got stuffed with other asp.net projects so i don't think i will redo this project) on a class that will mute every control and also mute individual channels.So you could mute p.e. left speaker or on dts p.e. left channel and sub woofer.
Ok back to another week of vacation now....