Solved

Check for Window's Audio

Posted on 2009-07-09
1
258 Views
Last Modified: 2013-11-27
Is there a way that I can check to see if a user has muted Window's audio using code. I have a program that runs in the background that alerts the user if something happens, however, if they mute audio, the alert isn't hear. I'd like to monitor the audio (to see if it is muted), and reset the volume if the user sets it too low. Is there something I can do?

ADawn
0
Comment
Question by:ADawn
1 Comment
 
LVL 96

Accepted Solution

by:
Bob Learned earned 100 total points
ID: 24841538
You might be able to use calls from the winmm.dll, through p/invoke.

Here is some code from my bag-o-tricks that I haven't used in a long time, and is untested.
' Source:

'  Converted from C# code

'  http://csharp-home.com/index/tiki-print_article.php?articleId=134&PHPSESSID=72a4b6031f43a4ec8a61b288669cf9c9
 

Imports System.Math

Imports System.Runtime.InteropServices
 

Public Class AudioMixer
 

	Private Const MMSYSERR_NOERROR As Integer = 0

	Private Const MAXPNAMELEN As Integer = &H20

	Private Const MIXER_LONG_NAME_CHARS As Integer = &H40

	Private Const MIXER_SHORT_NAME_CHARS As Integer = &H10

	Private Const MIXER_GETLINEINFOF_COMPONENTTYPE As Integer = 3

	Private Const MIXER_GETCONTROLDETAILSF_VALUE As Integer = 0

	Private Const MIXER_GETLINECONTROLSF_ONEBYTYPE As Integer = 2

	Private Const MIXER_SETCONTROLDETAILSF_VALUE As Integer = 0

	Private Const MIXERLINE_COMPONENTTYPE_DST_FIRST As Integer = 0

	Private Const MIXERLINE_COMPONENTTYPE_SRC_FIRST As Integer = &H1000

	Private Const MIXERLINE_COMPONENTTYPE_DST_SPEAKERS As Integer = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 4)

	Private Const MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE As Integer = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3)

	Private Const MIXERLINE_COMPONENTTYPE_SRC_LINE As Integer = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2)

	Private Const MIXERCONTROL_CT_CLASS_FADER As Integer = &H50000000

	Private Const MIXERCONTROL_CT_UNITS_UNSIGNED As Integer = &H30000

	Private Const MIXERCONTROL_CONTROLTYPE_FADER As Integer = (MIXERCONTROL_CT_CLASS_FADER Or MIXERCONTROL_CT_UNITS_UNSIGNED)

	Private Const MIXERCONTROL_CONTROLTYPE_VOLUME As Integer = (MIXERCONTROL_CONTROLTYPE_FADER + 1)
 

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

	<StructLayout(LayoutKind.Sequential)> _

	Private 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
 

	Private 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
 

	Private Structure MIXERCONTROLDETAILS_UNSIGNED

		Public dwValue As Integer

	End Structure
 

	Private 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
 

	Private 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
 

#Region "Public Members"
 

    Public Shared Function GetVolume() As Integer
 

        Dim volCtrl As MIXERCONTROL = New MIXERCONTROL

        Dim currentVol As Integer

        Dim mixer 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 volCtrl As MIXERCONTROL = New MIXERCONTROL

		Dim mixer As Integer

		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)

		vVolume = Min(vVolume, volCtrl.lMaximum)

		vVolume = Max(vVolume, volCtrl.lMinimum)

		SetVolumeControl(mixer, volCtrl, vVolume)

		GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, type, volCtrl, currentVol)

		If Not (vVolume = currentVol) Then

			Throw New Exception("Cannot Set Volume")

		End If

		mixerClose(mixer)

    End Sub
 

#End Region
 

#Region "Private Members"
 

    Private 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
 

        Dim mxlc As MIXERLINECONTROLS = New MIXERLINECONTROLS

        Dim mxl As MIXERLINE = New MIXERLINE

        Dim pmxcd As MIXERCONTROLDETAILS = New MIXERCONTROLDETAILS

        Dim du As MIXERCONTROLDETAILS_UNSIGNED = New MIXERCONTROLDETAILS_UNSIGNED
 

        mxc = New MIXERCONTROL
 

        Dim retValue As Boolean
 

        vCurrentVol = -1
 

        mxl.cbStruct = Marshal.SizeOf(mxl)

        mxl.dwComponentType = componentType
 

        Dim rc As Integer = mixerGetLineInfoA(hMixer, mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)

        If rc = MMSYSERR_NOERROR 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

            mxc.cbStruct = sizeofMIXERCONTROL

            rc = mixerGetLineControlsA(hMixer, mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE)

            If rc = MMSYSERR_NOERROR Then

                retValue = True

                mxc = CType(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 = CType(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
 

        Dim retValue As Boolean

        Dim rc As Integer

        Dim mxcd As MIXERCONTROLDETAILS = New MIXERCONTROLDETAILS

        Dim vol As MIXERCONTROLDETAILS_UNSIGNED = New MIXERCONTROLDETAILS_UNSIGNED
 

        mxcd.item = 0

        mxcd.dwControlID = mxc.dwControlID

        mxcd.cbStruct = Marshal.SizeOf(mxcd)

        mxcd.cbDetails = Marshal.SizeOf(vol)

        mxcd.cChannels = 1
 

        vol.dwValue = volume
 

        mxcd.paDetails = Marshal.AllocCoTaskMem(Marshal.SizeOf(GetType(MIXERCONTROLDETAILS_UNSIGNED)))
 

        Marshal.StructureToPtr(vol, mxcd.paDetails, False)
 

        rc = mixerSetControlDetails(hMixer, mxcd, MIXER_SETCONTROLDETAILSF_VALUE)

        If rc = MMSYSERR_NOERROR Then

            retValue = True

        Else

            retValue = False

        End If
 

        Return retValue
 

    End Function
 

#End Region
 

End Class

Open in new window

0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now