Results 1 to 11 of 11

Thread: [RESOLVED] How to change master volume level?

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2009
    Posts
    258

    Resolved [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?

  2. #2
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,763

    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)
    Last edited by sapator; Feb 27th, 2010 at 03:38 AM.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  3. #3
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,763

    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
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  4. #4
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,763

    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
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  5. #5
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,763

    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
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  6. #6
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,763

    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.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2009
    Posts
    258

    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.

  8. #8
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,763

    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.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  9. #9

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2009
    Posts
    258

    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.

  10. #10
    Lively Member Amerigo's Avatar
    Join Date
    Dec 2008
    Location
    PSR B1620-26 c-1
    Posts
    126

    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.
    Anyone who does not wonder, is either omnipotent or a fool.
    Amerigoware <<<My Projects

  11. #11
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,763

    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....
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width