Get/Set Sound volume level programmatically
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Get/Set Sound volume level programmatically
On Windows, does someone know how a running program can:
- See if the volume is muted or not
- Mute/Unmute volume from software
- Adjust volume level up or down
There's got to be an API for that, I just have no idea where to look.
- See if the volume is muted or not
- Mute/Unmute volume from software
- Adjust volume level up or down
There's got to be an API for that, I just have no idea where to look.
BERESHEIT
Re: Get/Set Sound volume level programmatically
I have been doing some stuff for that in GFA32 years ago.
Here a the most important declares I needed when being bussy on this.
It is really a mess to figure out how the MS-audio-mixer works I still remember.
I was using this when I was still on Win98, so I don't know what all might be changed.
If you Google for "mixerGetControlDetails" you'll get easy to the MSDN pages for more info on all these.
Another place that existed then was : http://www.borg.com/~jglatt/tech/mixer.htm (seems to be changed now).
The GFA32 style declares :
Here a the most important declares I needed when being bussy on this.
It is really a mess to figure out how the MS-audio-mixer works I still remember.
I was using this when I was still on Win98, so I don't know what all might be changed.
If you Google for "mixerGetControlDetails" you'll get easy to the MSDN pages for more info on all these.
Another place that existed then was : http://www.borg.com/~jglatt/tech/mixer.htm (seems to be changed now).
The GFA32 style declares :
Code: Select all
'***********************************************************************************************
Declare Function mixerClose Lib "winmm.dll" Alias "mixerClose" (ByVal hmx As Long) As Long
Declare Function mixerGetControlDetails Lib "winmm.dll" Alias "mixerGetControlDetailsA" (ByVal hmxobj As Long, ByRef pmxcd As MIXERCONTROLDETAILS, ByVal fdwDetails As Long) As Long
Declare Function mixerGetDevCaps Lib "winmm.dll" Alias "mixerGetDevCapsA" (ByVal uMxId As Long, ByRef pmxcaps As MIXERCAPS, ByVal cbmxcaps As Long) As Long
Declare Function mixerGetID Lib "winmm.dll" Alias "mixerGetID" (ByVal hmxobj As Long, pumxID As Long, ByVal fdwId As Long) As Long
Declare Function mixerGetLineControls Lib "winmm.dll" Alias "mixerGetLineControlsA" (ByVal hmxobj As Long, ByRef pmxlc As MIXERLINECONTROLS, ByVal fdwControls As Long) As Long
Declare Function mixerGetLineInfo Lib "winmm.dll" Alias "mixerGetLineInfoA" (ByVal hmxobj As Long, ByRef pmxl As MIXERLINE, ByVal fdwInfo As Long) As Long
Declare Function mixerGetNumDevs Lib "winmm.dll" Alias "mixerGetNumDevs" () As Long
Declare Function mixerMessage Lib "winmm.dll" Alias "mixerMessage" (ByVal hmx As Long, ByVal uMsg As Long, ByVal dwParam1 As Long, ByVal dwParam2 As Long) As Long
Declare Function mixerOpen Lib "winmm.dll" Alias "mixerOpen" (phmx As Long, ByVal uMxId As Long, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal fdwOpen As Long) As Long
Declare Function mixerSetControlDetails Lib "winmm.dll" Alias "mixerSetControlDetails" (ByVal hmxobj As Long, ByRef pmxcd As MIXERCONTROLDETAILS, ByVal fdwDetails As Long) As Long
'***********************************************************************************************
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Re: Get/Set Sound volume level programmatically
Maybe you'll need these too :
the constants an stuctures (called Type in GFA32).
I just tested that GFA source and it still works (on XP 32) yet I don't remember what all was ment for ... getting old.
It does read out all my audio devices, which was quit a job to get it done under MS, but then furthermore ... ?
I remember I wonted to create a mixer that could handle the multiple audio-cards at once (instead of the MS-mixer which handles just one device).
the constants an stuctures (called Type in GFA32).
Code: Select all
'***********************************************************************************************
'***********************************************************************************************
' General error return values
Global Const MMSYSERR_NOERROR = 0 ' no error
Global Const MMSYSERR_ERROR = 1 ' unspecified error
Global Const MMSYSERR_BADDEVICEID = 2 ' device ID out of range
Global Const MMSYSERR_NOTENABLED = 3 ' driver failed enable
Global Const MMSYSERR_ALLOCATED = 4 ' device already allocated
Global Const MMSYSERR_INVALHANDLE = 5 ' device handle is invalid
Global Const MMSYSERR_NODRIVER = 6 ' no device driver present
Global Const MMSYSERR_NOMEM = 7 ' memory allocation error
Global Const MMSYSERR_NOTSUPPORTED = 8 ' function isn't supported
Global Const MMSYSERR_BADERRNUM = 9 ' error value out of range
Global Const MMSYSERR_INVALFLAG = 10 ' invalid flag passed
Global Const MMSYSERR_INVALPARAM = 11 ' invalid parameter passed
Global Const MMSYSERR_HANDLEBUSY = 12 ' handle being used
' simultaneously on another
' thread (eg callback)
Global Const MMSYSERR_INVALIDALIAS = 13 ' "Specified alias not found in WIN.INI
Global Const MMSYSERR_LASTERROR = 13 ' last error in range
Global Const MM_MOM_POSITIONCB = &H3CA ' Callback for MEVT_POSITIONCB
Global Const MM_MCISIGNAL = &H3CB
Global Const MM_MIM_MOREDATA = &H3CC ' MIM_DONE w/ pending events
Global Const MM_MIXM_LINE_CHANGE = &H3D0
Global Const MM_MIXM_CONTROL_CHANGE = &H3D1
'
Global Const MIDICAPS_STREAM = &H8 ' driver supports midiStreamOut directly
'
Global Const MIXER_SHORT_NAME_CHARS = 16
Global Const MIXER_LONG_NAME_CHARS = 64
Global Const MIXERR_BASE = 1024
Global Const MIXERR_INVALLINE = (MIXERR_BASE + 0)
Global Const MIXERR_INVALCONTROL = (MIXERR_BASE + 1)
Global Const MIXERR_INVALVALUE = (MIXERR_BASE + 2)
Global Const MIXERR_LASTERROR = (MIXERR_BASE + 2)
'
Global Const MIXER_OBJECTF_HANDLE = &H80000000
Global Const MIXER_OBJECTF_MIXER = &H0
Global Const MIXER_OBJECTF_HMIXER = (&H80000000 Or &H0)
Global Const MIXER_OBJECTF_WAVEOUT = &H10000000
Global Const MIXER_OBJECTF_HWAVEOUT = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_WAVEOUT)
Global Const MIXER_OBJECTF_WAVEIN = &H20000000
Global Const MIXER_OBJECTF_HWAVEIN = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_WAVEIN)
Global Const MIXER_OBJECTF_MIDIOUT = &H30000000
Global Const MIXER_OBJECTF_HMIDIOUT = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIDIOUT)
Global Const MIXER_OBJECTF_MIDIIN = &H40000000
Global Const MIXER_OBJECTF_HMIDIIN = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIDIIN)
Global Const MIXER_OBJECTF_AUX = &H50000000
'
Global Const MIXERLINE_LINEF_ACTIVE = &H1
Global Const MIXERLINE_LINEF_DISCONNECTED = &H8000
Global Const MIXERLINE_LINEF_SOURCE = &H80000000
'
Global Const MIXERLINE_COMPONENTTYPE_DST_FIRST = &H0
Global Const MIXERLINE_COMPONENTTYPE_DST_UNDEFINED = 0
Global Const MIXERLINE_COMPONENTTYPE_DST_DIGITAL = 1
Global Const MIXERLINE_COMPONENTTYPE_DST_LINE = 2
Global Const MIXERLINE_COMPONENTTYPE_DST_MONITOR = 3
Global Const MIXERLINE_COMPONENTTYPE_DST_SPEAKERS = 4
Global Const MIXERLINE_COMPONENTTYPE_DST_HEADPHONES = 5
Global Const MIXERLINE_COMPONENTTYPE_DST_TELEPHONE = 6
Global Const MIXERLINE_COMPONENTTYPE_DST_WAVEIN = 7
Global Const MIXERLINE_COMPONENTTYPE_DST_VOICEIN = 8
Global Const MIXERLINE_COMPONENTTYPE_DST_LAST = 8
'
Global Const MIXERLINE_COMPONENTTYPE_SRC_FIRST = &H1000
Global Const MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 0)
Global Const MIXERLINE_COMPONENTTYPE_SRC_DIGITAL = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 1)
Global Const MIXERLINE_COMPONENTTYPE_SRC_LINE = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2)
Global Const MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3)
Global Const MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 4)
Global Const MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 5)
Global Const MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 6)
Global Const MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 7)
Global Const MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 8)
Global Const MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 9)
Global Const MIXERLINE_COMPONENTTYPE_SRC_ANALOG = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10)
Global Const MIXERLINE_COMPONENTTYPE_SRC_LAST = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10)
'
Global Const MIXERLINE_TARGETTYPE_UNDEFINED = 0
Global Const MIXERLINE_TARGETTYPE_WAVEOUT = 1
Global Const MIXERLINE_TARGETTYPE_WAVEIN = 2
Global Const MIXERLINE_TARGETTYPE_MIDIOUT = 3
Global Const MIXERLINE_TARGETTYPE_MIDIIN = 4
Global Const MIXERLINE_TARGETTYPE_AUX = 5
'
Global Const MIXER_GETLINEINFOF_DESTINATION = &H0
Global Const MIXER_GETLINEINFOF_SOURCE = &H1
Global Const MIXER_GETLINEINFOF_LINEID = &H2
Global Const MIXER_GETLINEINFOF_COMPONENTTYPE = &H3
Global Const MIXER_GETLINEINFOF_TARGETTYPE = &H4
Global Const MIXER_GETLINEINFOF_QUERYMASK = &HF
'
Global Const MIXERCONTROL_CONTROLF_UNIFORM = &H1
Global Const MIXERCONTROL_CONTROLF_MULTIPLE = &H2
Global Const MIXERCONTROL_CONTROLF_DISABLED = &H80000000
'
Global Const MIXERCONTROL_CT_CLASS_MASK = &HF0000000
Global Const MIXERCONTROL_CT_CLASS_CUSTOM = &H0
Global Const MIXERCONTROL_CT_CLASS_METER = &H10000000
Global Const MIXERCONTROL_CT_CLASS_SWITCH = &H20000000
Global Const MIXERCONTROL_CT_CLASS_NUMBER = &H30000000
Global Const MIXERCONTROL_CT_CLASS_SLIDER = &H40000000
Global Const MIXERCONTROL_CT_CLASS_FADER = &H50000000
Global Const MIXERCONTROL_CT_CLASS_TIME = &H60000000
Global Const MIXERCONTROL_CT_CLASS_LIST = &H70000000
Global Const MIXERCONTROL_CT_SUBCLASS_MASK = &HF000000
Global Const MIXERCONTROL_CT_SC_SWITCH_BOOLEAN = &H0
Global Const MIXERCONTROL_CT_SC_SWITCH_BUTTON = &H1000000
Global Const MIXERCONTROL_CT_SC_METER_POLLED = &H0
Global Const MIXERCONTROL_CT_SC_TIME_MICROSECS = &H0
Global Const MIXERCONTROL_CT_SC_TIME_MILLISECS = &H1000000
Global Const MIXERCONTROL_CT_SC_LIST_SINGLE = &H0
Global Const MIXERCONTROL_CT_SC_LIST_MULTIPLE = &H1000000
Global Const MIXERCONTROL_CT_UNITS_MASK = &HFF0000
Global Const MIXERCONTROL_CT_UNITS_CUSTOM = &H0
Global Const MIXERCONTROL_CT_UNITS_BOOLEAN = &H10000
Global Const MIXERCONTROL_CT_UNITS_SIGNED = &H20000
Global Const MIXERCONTROL_CT_UNITS_UNSIGNED = &H30000
Global Const MIXERCONTROL_CT_UNITS_DECIBELS = &H40000 ' in 10ths
Global Const MIXERCONTROL_CT_UNITS_PERCENT = &H50000 ' in 10ths
'
Global Const MIXERCONTROL_CONTROLTYPE_CUSTOM = 0
Global Const MIXERCONTROL_CONTROLTYPE_BOOLEANMETER = (MIXERCONTROL_CT_CLASS_METER Or 0 Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Global Const MIXERCONTROL_CONTROLTYPE_SIGNEDMETER = (MIXERCONTROL_CT_CLASS_METER Or 0 Or MIXERCONTROL_CT_UNITS_SIGNED)
Global Const MIXERCONTROL_CONTROLTYPE_PEAKMETER = (MIXERCONTROL_CONTROLTYPE_SIGNEDMETER + 1)
Global Const MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER = (MIXERCONTROL_CT_CLASS_METER Or 0 Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Global Const MIXERCONTROL_CONTROLTYPE_BOOLEAN = (MIXERCONTROL_CT_CLASS_SWITCH Or 0 Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Global Const MIXERCONTROL_CONTROLTYPE_ONOFF = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 1)
Global Const MIXERCONTROL_CONTROLTYPE_MUTE = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2)
Global Const MIXERCONTROL_CONTROLTYPE_MONO = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 3)
Global Const MIXERCONTROL_CONTROLTYPE_LOUDNESS = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 4)
Global Const MIXERCONTROL_CONTROLTYPE_STEREOENH = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 5)
Global Const MIXERCONTROL_CONTROLTYPE_BUTTON = (MIXERCONTROL_CT_CLASS_SWITCH Or MIXERCONTROL_CT_SC_SWITCH_BUTTON Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Global Const MIXERCONTROL_CONTROLTYPE_DECIBELS = (MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_DECIBELS)
Global Const MIXERCONTROL_CONTROLTYPE_SIGNED = (MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_SIGNED)
Global Const MIXERCONTROL_CONTROLTYPE_UNSIGNED = (MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Global Const MIXERCONTROL_CONTROLTYPE_PERCENT = (MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_PERCENT)
Global Const MIXERCONTROL_CONTROLTYPE_SLIDER = (MIXERCONTROL_CT_CLASS_SLIDER Or MIXERCONTROL_CT_UNITS_SIGNED)
Global Const MIXERCONTROL_CONTROLTYPE_PAN = (MIXERCONTROL_CONTROLTYPE_SLIDER + 1)
Global Const MIXERCONTROL_CONTROLTYPE_QSOUNDPAN = (MIXERCONTROL_CONTROLTYPE_SLIDER + 2)
Global Const MIXERCONTROL_CONTROLTYPE_FADER = (MIXERCONTROL_CT_CLASS_FADER Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Global Const MIXERCONTROL_CONTROLTYPE_VOLUME = (MIXERCONTROL_CONTROLTYPE_FADER + 1)
Global Const MIXERCONTROL_CONTROLTYPE_BASS = (MIXERCONTROL_CONTROLTYPE_FADER + 2)
Global Const MIXERCONTROL_CONTROLTYPE_TREBLE = (MIXERCONTROL_CONTROLTYPE_FADER + 3)
Global Const MIXERCONTROL_CONTROLTYPE_EQUALIZER = (MIXERCONTROL_CONTROLTYPE_FADER + 4)
Global Const MIXERCONTROL_CONTROLTYPE_SINGLESELECT = (MIXERCONTROL_CT_CLASS_LIST Or 0 Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Global Const MIXERCONTROL_CONTROLTYPE_MUX = (MIXERCONTROL_CONTROLTYPE_SINGLESELECT + 1)
Global Const MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT = (MIXERCONTROL_CT_CLASS_LIST Or MIXERCONTROL_CT_SC_LIST_MULTIPLE Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Global Const MIXERCONTROL_CONTROLTYPE_MIXER = (MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT + 1)
Global Const MIXERCONTROL_CONTROLTYPE_MICROTIME = (MIXERCONTROL_CT_CLASS_TIME Or 0 Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Global Const MIXERCONTROL_CONTROLTYPE_MILLITIME = (MIXERCONTROL_CT_CLASS_TIME Or MIXERCONTROL_CT_SC_TIME_MILLISECS Or MIXERCONTROL_CT_UNITS_UNSIGNED)
'
Global Const MIXER_GETLINECONTROLSF_ALL = &H0
Global Const MIXER_GETLINECONTROLSF_ONEBYID = &H1
Global Const MIXER_GETLINECONTROLSF_ONEBYTYPE = &H2
Global Const MIXER_GETLINECONTROLSF_QUERYMASK = &HF
'
Global Const MIXER_GETCONTROLDETAILSF_VALUE = &H0
Global Const MIXER_GETCONTROLDETAILSF_LISTTEXT = &H1
Global Const MIXER_GETCONTROLDETAILSF_QUERYMASK = &HF
'
Global Const MIXER_SETCONTROLDETAILSF_VALUE = &H0
Global Const MIXER_SETCONTROLDETAILSF_CUSTOM = &H1
Global Const MIXER_SETCONTROLDETAILSF_QUERYMASK = &HF
Type MIXERCAPS 'informatie van de geluidskaarten
wMid As Int16
wPid As Int16
vDriverVersion As Long
szPname As String * MAXPNAMELEN
fdwSupport As Long
cDestinations As Long
EndType
Type MIXERLINE 'informatie van in-output op elke geluidskaart
cbStruct As Long
dwDestination As Long
dwSource As Long
dwLineID As Long
fdwLine As Long
dwUser As Long
dwComponentType As Long 'type of audio line (digital, speaker, telephone etc.)
cChannels As Long
cConnections As Long
cControls As Long
szShortName As String * MIXER_SHORT_NAME_CHARS
szName As String * MIXER_LONG_NAME_CHARS
dwType As Long
dwDeviceID As Long
wMid As Integer
wPid As Integer
vDriverVersion As Long
szPname As String * MAXPNAMELEN
EndType
Type MIXERLINECONTROLS 'informatie van de controls op elke in-output
cbStruct As Long ' size in Byte of MIXERLINECONTROLS
dwLineID As Long ' line id (from MIXERLINE.dwLineID)
' MIXER_GETLINECONTROLSF_ONEBYID or
dwControlID As Long ' or dwControlType MIXER_GETLINECONTROLSF_ONEBYTYPE
cControls As Long ' count of controls pmxctrl points to
cbmxctrl As Long ' size in Byte of _one_ MIXERCONTROL
pamxctrl As Long 'MIXERCONTROL ' pointer to first MIXERCONTROL array
EndType
Type MIXERCONTROL 'algemene opbouw van één control
cbStruct As Long
dwControlID As Long
dwControlType As Long
fdwControl As Long
cMultipleItems As Long
szShortName As String * MIXER_SHORT_NAME_CHARS
szName As String * MIXER_LONG_NAME_CHARS
lMinimum As Long
lMaximum As Long
reserved(10) As Long
EndType
Type MIXERCONTROLDETAILS 'specifieke elementen van de control en zijn gebruik
cbStruct As Long ' size in Byte of MIXERCONTROLDETAILS
dwControlID As Long ' control id to get/set details on
cChannels As Long ' number of channels in paDetails array
cMultipleItems As Long ' hwndOwner or cMultipleItems
cbDetails As Long ' size of _one_ details_XX struct
paDetails As Long ' pointer to array of details_XX structs
EndType
Type MIXERCONTROLDETAILS_LISTTEXT
dwParam1 As Long
dwParam2 As Long
szName As String * MIXER_LONG_NAME_CHARS
EndType
Type MIXERCONTROLDETAILS_BOOLEAN
fValue As Long
EndType
Type MIXERCONTROLDETAILS_SIGNED
lValue As Long
EndType
Type MIXERCONTROLDETAILS_UNSIGNED
dwValue As Long
EndType
It does read out all my audio devices, which was quit a job to get it done under MS, but then furthermore ... ?
I remember I wonted to create a mixer that could handle the multiple audio-cards at once (instead of the MS-mixer which handles just one device).
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
-
- Addict
- Posts: 1482
- Joined: Tue Feb 22, 2011 1:16 pm
Re: Get/Set Sound volume level programmatically
netmaestro, here's a VB snippet I found years ago which I never converted to PureBasic. Maybe it's a starting point? If you get it working, please pay back the favor by posting it here. 
BTW, there are other volume examples in these forums, but they're all very long and the one I used in XP doesn't work with Win 7, due to each app on Win 7 having their own volume levels.

BTW, there are other volume examples in these forums, but they're all very long and the one I used in XP doesn't work with Win 7, due to each app on Win 7 having their own volume levels.

Code: Select all
; Option Explicit
; Private Declare Function waveOutSetVolume Lib "Winmm" (ByVal wDeviceID
; As Integer, ByVal dwVolume As Long) As Integer
; Private Declare Function waveOutGetVolume Lib "Winmm" (ByVal wDeviceID
; As Integer, dwVolume As Long) As Integer
;
; Private Sub volume(up As Boolean)
; Dim a, i As Long, getv As Long, setv As Long
; Dim tmp, vol As Long
; a = waveOutGetVolume(0, i)
; tmp = "&h" & Right(Hex$(i), 4)
; getv = CLng(tmp)
; If up Then
; setv = getv + 500
; If setv > 65535 Then setv = 65535
; Else
; setv = getv - 500
; If setv < 0 Then setv = 0
; End If
; tmp = Right((Hex$(vol + 65536)), 4)
; vol = CLng("&H" & tmp & tmp)
; a = waveOutSetVolume(0, vol)
;
; End Sub
; Full = 65535
; 3/4 = 49152
; Half = 32768
; 1/4 = 16384
; Mute = 0
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
PureBasic: Born in 1998 and still going strong to this very day!
Re: Get/Set Sound volume level programmatically
I don't have any code sorry (never tried)
Background on the new way of controlling volume for your application vs system/wide:
http://blogs.msdn.com/b/larryosterman/a ... 04158.aspx
http://blogs.msdn.com/b/larryosterman/a ... vista.aspx
I have found this:
Master volume control example
http://www.codeproject.com/Articles/185 ... me-Control
A dirty way (easy) maybe through #WM_APPCOMMAND, I think it changes too the master volume but I'm not sure.
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
Background on the new way of controlling volume for your application vs system/wide:
http://blogs.msdn.com/b/larryosterman/a ... 04158.aspx
http://blogs.msdn.com/b/larryosterman/a ... vista.aspx
I have found this:
Master volume control example
http://www.codeproject.com/Articles/185 ... me-Control
A dirty way (easy) maybe through #WM_APPCOMMAND, I think it changes too the master volume but I'm not sure.
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
"Have you tried turning it off and on again ?"
A little PureBasic review
A little PureBasic review
-
- Addict
- Posts: 1482
- Joined: Tue Feb 22, 2011 1:16 pm
Re: Get/Set Sound volume level programmatically
This one line will toggle the current mute state, but don't rely on it. I did once and it didn't work on all PCs. I think I remember that it only works on PCs that have a media keyboard? Not sure. Definitely works on Win 7 with a media keyboard.netmaestro wrote:- Mute/Unmute volume from software
- Adjust volume level up or down
You can also use #VK_VOLUME_UP and #VK_VOLUME_DOWN with virtual keystrokes. Really simple APIs, but such hacky code.
Code: Select all
keybd_event_(#VK_VOLUME_MUTE,0,0,0) : keybd_event_(#VK_VOLUME_MUTE,0,#KEYEVENTF_KEYUP,0)
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
PureBasic: Born in 1998 and still going strong to this very day!
Re: Get/Set Sound volume level programmatically
For WinVista and higher:
Greetings - Thomas
Code: Select all
EnableExplicit
#CLSCTX_INPROC_SERVER = $01
#CLSCTX_INPROC_HANDLER = $02
#CLSCTX_LOCAL_SERVER = $04
#CLSCTX_REMOTE_SERVER = $10
#CLSCTX_ALL = #CLSCTX_INPROC_SERVER|#CLSCTX_INPROC_HANDLER|#CLSCTX_LOCAL_SERVER|#CLSCTX_REMOTE_SERVER
#CLSCTX_INPROC = #CLSCTX_INPROC_SERVER|#CLSCTX_INPROC_HANDLER
#CLSCTX_SERVER = #CLSCTX_INPROC_SERVER|#CLSCTX_LOCAL_SERVER|#CLSCTX_REMOTE_SERVER
Interface IMMDeviceEnumerator Extends IUnknown
EnumAudioEndpoints(dataFlow, dwStateMask, *ppDevices);
GetDefaultAudioEndpoint(dataFlow, role, ppEndpoint);
GetDevice(pwstrId, ppDevice);
RegisterEndpointNotificationCallback(pClient);
UnregisterEndpointNotificationCallback(pClient);
EndInterface
Interface IAudioEndpointVolume Extends IUnknown
RegisterControlChangeNotify( *pNotify)
UnregisterControlChangeNotify( *pNotify)
GetChannelCount( *pnChannelCount)
SetMasterVolumeLevel( fLevelDB.f)
SetMasterVolumeLevelScalar( fLevel.f,pguidEventContext)
GetMasterVolumeLevel(*pfLevelDB)
GetMasterVolumeLevelScalar(*pfLevel)
SetChannelVolumeLevel(nChannel,fLevelDB.f,pguidEventContext)
SetChannelVolumeLevelScalar( nChannel,fLevel.f,pguidEventContext)
GetChannelVolumeLevel( nChannel,*pfLevelDB.f)
GetChannelVolumeLevelScalar( nChannel,*pfLevel.f)
SetMute( bMute, pguidEventContext)
GetMute( *pbMute)
GetVolumeStepInfo( *pnStep, *pnStepCount)
VolumeStepUp( pguidEventContext)
VolumeStepDown( pguidEventContext)
QueryHardwareSupport( *pdwHardwareSupportMask)
GetVolumeRange( *pflVolumeMindB, *pflVolumeMaxdB, *pflVolumeIncrementdB)
EndInterface
Interface IMMDevice Extends IUnknown
Activate(iid, dwClsCtx, pActivationParams, ppInterface);
OpenPropertyStore( stgmAccess, ppProperties);
GetId(ppstrId);
GetState(pdwState);
EndInterface
Procedure GetEndPointVolume(*endpointvolume)
Protected deviceEnumerator.IMMDeviceEnumerator
Protected hr, defaultDevice.IMMDevice
CoInitialize_(#Null)
hr = CoCreateInstance_(?uuidof_MMDeviceEnumerator, #Null, #CLSCTX_INPROC_SERVER, ?uuidof_IMMDeviceEnumerator,@deviceEnumerator);#CLSCTX_ALL
hr = deviceEnumerator\GetDefaultAudioEndpoint(0, 1, @defaultDevice)
deviceEnumerator\Release()
hr = defaultDevice\Activate(?uuidof_IAudioEndpointVolume, #CLSCTX_INPROC_SERVER, #Null, *endpointVolume);
defaultDevice\release()
ProcedureReturn *endpointvolume
EndProcedure
Procedure FreeEndPointVolume(*endpointvolume.IAudioEndpointVolume)
*endpointvolume\release()
CoUninitialize_()
EndProcedure
Procedure MediaGetVolume()
Protected Volume.IAudioEndpointVolume
Protected volf.f
GetEndPointVolume(@Volume)
Volume\GetMasterVolumeLevelScalar(@volf)
volf = Round(volf * 100, #PB_Round_Nearest)
FreeEndPointVolume(Volume)
ProcedureReturn Int(volf)
EndProcedure
Procedure MediaSetVolume(vol)
Protected Volume.IAudioEndpointVolume
Protected volf.f
If vol < 0 : vol = 0 : EndIf
If vol > 100 : vol = 100 : EndIf
GetEndPointVolume(@Volume)
volf = vol / 100
Volume\SetMasterVolumeLevelScalar(volf, #Null)
FreeEndPointVolume(Volume)
EndProcedure
DataSection
uuidof_IAudioEndpointVolume:
Data.l $5CDF2C82
Data.w $841E,$4546
Data.b $97,$22,$0C,$F7,$40,$78,$22,$9A
uuidof_MMDeviceEnumerator:
Data.l $BCDE0395
Data.w $E52F,$467C
Data.b $8E,$3D,$C4,$57,$92,$91,$69,$2E
uuidof_IMMDeviceEnumerator:
Data.l $A95664D2
Data.w $9614
Data.w $4F35
Data.b $A7,$46,$DE,$8D,$B6,$36,$17,$E6
EndDataSection
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.

Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.

- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Get/Set Sound volume level programmatically
Thanks to all for the help, it's appreciated!
A little background info for why I suddenly want this after ignoring sound volumes forever, I have a handy little app called Alarm Clock that we use here at home often. Last night my wife set it and went to bed. She had it set properly and all, but the sound was muted and she didn't notice. It occurred to me that the Alarm Clock program could check the volume settings a few seconds before it rings and if they aren't audible or very loud it could adjust them. It would also solve the problem of email notifications waking people up too as the volume could be muted and it wouldn't affect the alarm. So thanks again, this will be useful to me.
A little background info for why I suddenly want this after ignoring sound volumes forever, I have a handy little app called Alarm Clock that we use here at home often. Last night my wife set it and went to bed. She had it set properly and all, but the sound was muted and she didn't notice. It occurred to me that the Alarm Clock program could check the volume settings a few seconds before it rings and if they aren't audible or very loud it could adjust them. It would also solve the problem of email notifications waking people up too as the volume could be muted and it wouldn't affect the alarm. So thanks again, this will be useful to me.
BERESHEIT
Re: Get/Set Sound volume level programmatically
Yes, very interesting topic.
My son often complains of Spotify "checking" the master volume level and then pausing its commercials if muted.
So, a programmatic countermeasure would be cool to have.
But if on Windows 7, each app controls the sound level, how to dominate?
I imagine this calls for a global system hook?
My son often complains of Spotify "checking" the master volume level and then pausing its commercials if muted.

So, a programmatic countermeasure would be cool to have.
But if on Windows 7, each app controls the sound level, how to dominate?
I imagine this calls for a global system hook?
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: Get/Set Sound volume level programmatically
I have always wanted a way to "check the volume" and "normalize it" -- ie: while watching hulu or netflix, have the volume drop down when it suddenly gets louder (ie: commercials on hulu or a big car crash etc)
-
- Addict
- Posts: 1482
- Joined: Tue Feb 22, 2011 1:16 pm
Re: Get/Set Sound volume level programmatically
Here's the code I used on XP which muted/unmuted the volume, but doesn't work under Win 7 or even compile anymore. Just throwing it in here so maybe someone can update it, since this is an interesting thread with many snippets and tips on how to do it.
Code: Select all
;-MIXERCONTROL
Structure MIXERCONTROL
cbStruct.l
dwControlID.l
dwControlType.l
fdwControl.l
cMultipleItems.l
szShortName.b[#MIXER_SHORT_NAME_CHARS]
szName.b[#MIXER_LONG_NAME_CHARS]
lMinimum.l
lMaximum.l
dwMinimum.l
dwMaximum.l
Reserved.l[6]
cSteps.l
cbCustomData.l
dwReserved.l[6]
EndStructure
;-MIXERCONTROLDETAILSUNSIGNED
Structure MIXERCONTROLDETAILSUNSIGNED
dwValue.l
EndStructure
Procedure ZeroMemory(adr,len)
For i=0 To len-1 : PokeB(adr+i,0) : Next
EndProcedure
Procedure GetMasterVolumeControl(mixer,*control.MIXERCONTROL)
line.mixerline
controls.mixerlinecontrols
ZeroMemory(Line,SizeOf(mixerline))
Line\cbStruct=SizeOf(mixerline)
Line\dwComponentType=#MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
Result=mixerGetLineInfo_(Mixer,Line,#MIXER_GETLINEINFOF_COMPONENTTYPE)
If Result=#MMSYSERR_NOERROR
ZeroMemory(Controls,SizeOf(mixerlinecontrols))
Controls\cbStruct=SizeOf(mixerlinecontrols)
Controls\dwLineID=Line\dwLineID
Controls\cControls=1
Controls\dwControlType=#MIXERCONTROL_CONTROLTYPE_VOLUME
Controls\cbmxctrl=SizeOf(MIXERCONTROL)
Controls\pamxctrl=*Control
Result=mixerGetLineControls_(Mixer,Controls,#MIXER_GETLINECONTROLSF_ONEBYTYPE)
EndIf
ProcedureReturn result
EndProcedure
Procedure GetMasterMuteControl(mixer,*control.MIXERCONTROL)
line.mixerline
controls.mixerlinecontrols
ZeroMemory(Line,SizeOf(mixerline))
Line\cbStruct=SizeOf(mixerline)
Line\dwComponentType=#MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
Result=mixerGetLineInfo_(Mixer,Line,#MIXER_GETLINEINFOF_COMPONENTTYPE)
If Result=#MMSYSERR_NOERROR
ZeroMemory(Controls,SizeOf(mixerlinecontrols))
Controls\cbStruct=SizeOf(mixerlinecontrols)
Controls\dwLineID=Line\dwLineID
Controls\cControls=1
Controls\dwControlType=#MIXERCONTROL_CONTROLTYPE_MUTE
Controls\cbmxctrl=SizeOf(MIXERCONTROL)
Controls\pamxctrl=*Control
Result=mixerGetLineControls_(Mixer,Controls,#MIXER_GETLINECONTROLSF_ONEBYTYPE)
EndIf
ProcedureReturn result
EndProcedure
Procedure SetMasterVolume(mixer,value)
MasterVolume.MIXERCONTROL
Details.MIXERCONTROLDETAILS
UnsignedDetails.MIXERCONTROLDETAILSUNSIGNED
code.l
code=GetMasterVolumeControl(Mixer,MasterVolume)
If code=#MMSYSERR_NOERROR
Details\cbStruct=SizeOf(MIXERCONTROLDETAILS)
Details\dwControlID=MasterVolume\dwControlID
Details\cChannels=1
Details\Item=0
Details\cbDetails=SizeOf(MIXERCONTROLDETAILSUNSIGNED)
Details\paDetails=@UnsignedDetails
UnsignedDetails\dwValue=Value
code=mixerSetControlDetails_(Mixer,Details,#MIXER_SETCONTROLDETAILSF_VALUE)
EndIf
ProcedureReturn code
EndProcedure
Procedure SetMasterMute(mixer,value)
MasterVolume.MIXERCONTROL
Details.MIXERCONTROLDETAILS
UnsignedDetails.MIXERCONTROLDETAILSUNSIGNED
code=GetMasterMuteControl(Mixer,MasterVolume)
If code=#MMSYSERR_NOERROR
Details\cbStruct=SizeOf(MIXERCONTROLDETAILS)
Details\dwControlID=MasterVolume\dwControlID
Details\cChannels=1
Details\Item=0
Details\cbDetails=SizeOf(MIXERCONTROLDETAILSUNSIGNED)
Details\paDetails=@UnsignedDetails
UnsignedDetails\dwValue=Value
code=mixerSetControlDetails_(Mixer,Details,#MIXER_SETCONTROLDETAILSF_VALUE)
EndIf
ProcedureReturn code
EndProcedure
Procedure GetMasterVolume(mixer)
MasterVolume.MIXERCONTROL
Details.MIXERCONTROLDETAILS
UnsignedDetails.MIXERCONTROLDETAILSUNSIGNED
code=GetMasterVolumeControl(Mixer,MasterVolume)
If code=#MMSYSERR_NOERROR
Details\cbStruct=SizeOf(MIXERCONTROLDETAILS)
Details\dwControlID=MasterVolume\dwControlID
Details\cChannels=1
Details\Item=0
Details\cbDetails=SizeOf(MIXERCONTROLDETAILSUNSIGNED)
Details\paDetails=@UnsignedDetails
code=mixerGetControlDetails_(Mixer,Details,#MIXER_SETCONTROLDETAILSF_VALUE)
EndIf
ProcedureReturn UnsignedDetails\dwValue
EndProcedure
Procedure GetMasterMute(mixer)
MasterVolume.MIXERCONTROL
Details.MIXERCONTROLDETAILS
UnsignedDetails.MIXERCONTROLDETAILSUNSIGNED
code=GetMasterMuteControl(Mixer,MasterVolume)
If code=#MMSYSERR_NOERROR
Details\cbStruct=SizeOf(MIXERCONTROLDETAILS)
Details\dwControlID=MasterVolume\dwControlID
Details\cChannels=1
Details\Item=0
Details\cbDetails=SizeOf(MIXERCONTROLDETAILSUNSIGNED)
Details\paDetails=@UnsignedDetails
code=mixerGetControlDetails_(Mixer,Details,#MIXER_SETCONTROLDETAILSF_VALUE)
EndIf
ProcedureReturn UnsignedDetails\dwValue
EndProcedure
Procedure GetMasterVolumeMinimum(mixer)
Volume.MIXERCONTROL
GetMasterVolumeControl(mixer,Volume)
ProcedureReturn volume\lMinimum
EndProcedure
Procedure GetMasterVolumeMaximum(mixer)
Volume.MIXERCONTROL
GetMasterVolumeControl(mixer,Volume)
ProcedureReturn volume\lMaximum
EndProcedure
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
PureBasic: Born in 1998 and still going strong to this very day!
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Get/Set Sound volume level programmatically
All replies are much appreciated. The code from ts-soft works well but misses a couple of procedures, namely MediaGetMute() and MediaSetMute(), which if were included would make it perfect for my needs. I really don't need to support XP and earlier anyway and it would be a fair amount of work to put an include together that would serve both XP and Vista+ equally well. So I added the needed procs to ts-soft's code and now I have a complete working solution, which I have implemented in my alarm clock and now it's "mute-proof" and my wife is very impressed.
This is my SoundControls.pbi, most of it by ts-soft:
This is my SoundControls.pbi, most of it by ts-soft:
Code: Select all
#CLSCTX_INPROC_SERVER = $01
#CLSCTX_INPROC_HANDLER = $02
#CLSCTX_LOCAL_SERVER = $04
#CLSCTX_REMOTE_SERVER = $10
#CLSCTX_ALL = #CLSCTX_INPROC_SERVER|#CLSCTX_INPROC_HANDLER|#CLSCTX_LOCAL_SERVER|#CLSCTX_REMOTE_SERVER
#CLSCTX_INPROC = #CLSCTX_INPROC_SERVER|#CLSCTX_INPROC_HANDLER
#CLSCTX_SERVER = #CLSCTX_INPROC_SERVER|#CLSCTX_LOCAL_SERVER|#CLSCTX_REMOTE_SERVER
Interface IMMDeviceEnumerator Extends IUnknown
EnumAudioEndpoints(dataFlow, dwStateMask, *ppDevices)
GetDefaultAudioEndpoint(dataFlow, role, ppEndpoint)
GetDevice(pwstrId, ppDevice)
RegisterEndpointNotificationCallback(pClient)
UnregisterEndpointNotificationCallback(pClient)
EndInterface
Interface IAudioEndpointVolume Extends IUnknown
RegisterControlChangeNotify( *pNotify)
UnregisterControlChangeNotify( *pNotify)
GetChannelCount( *pnChannelCount)
SetMasterVolumeLevel( fLevelDB.f)
SetMasterVolumeLevelScalar( fLevel.f,pguidEventContext)
GetMasterVolumeLevel(*pfLevelDB)
GetMasterVolumeLevelScalar(*pfLevel)
SetChannelVolumeLevel(nChannel,fLevelDB.f,pguidEventContext)
SetChannelVolumeLevelScalar( nChannel,fLevel.f,pguidEventContext)
GetChannelVolumeLevel( nChannel,*pfLevelDB.f)
GetChannelVolumeLevelScalar( nChannel,*pfLevel.f)
SetMute( bMute, pguidEventContext)
GetMute( *pbMute)
GetVolumeStepInfo( *pnStep, *pnStepCount)
VolumeStepUp( pguidEventContext)
VolumeStepDown( pguidEventContext)
QueryHardwareSupport( *pdwHardwareSupportMask)
GetVolumeRange( *pflVolumeMindB, *pflVolumeMaxdB, *pflVolumeIncrementdB)
EndInterface
Interface IMMDevice Extends IUnknown
Activate(iid, dwClsCtx, pActivationParams, ppInterface);
OpenPropertyStore( stgmAccess, ppProperties);
GetId(ppstrId);
GetState(pdwState);
EndInterface
Procedure GetEndPointVolume(*endpointvolume)
Protected deviceEnumerator.IMMDeviceEnumerator
Protected hr, defaultDevice.IMMDevice
CoInitialize_(#Null)
hr = CoCreateInstance_(?uuidof_MMDeviceEnumerator, #Null, #CLSCTX_INPROC_SERVER, ?uuidof_IMMDeviceEnumerator,@deviceEnumerator);#CLSCTX_ALL
hr = deviceEnumerator\GetDefaultAudioEndpoint(0, 1, @defaultDevice)
deviceEnumerator\Release()
hr = defaultDevice\Activate(?uuidof_IAudioEndpointVolume, #CLSCTX_INPROC_SERVER, #Null, *endpointVolume);
defaultDevice\release()
ProcedureReturn *endpointvolume
EndProcedure
Procedure FreeEndPointVolume(*endpointvolume.IAudioEndpointVolume)
*endpointvolume\release()
CoUninitialize_()
EndProcedure
Procedure MediaGetVolume()
Protected Volume.IAudioEndpointVolume
Protected volf.f
GetEndPointVolume(@Volume)
Volume\GetMasterVolumeLevelScalar(@volf)
volf = Round(volf * 100, #PB_Round_Nearest)
FreeEndPointVolume(Volume)
ProcedureReturn Int(volf)
EndProcedure
Procedure MediaGetMute()
Protected Volume.IAudioEndpointVolume
Protected mute.i
GetEndPointVolume(@Volume)
Volume\GetMute(@mute)
FreeEndPointVolume(Volume)
ProcedureReturn mute
EndProcedure
Procedure MediaSetVolume(vol)
Protected Volume.IAudioEndpointVolume
Protected volf.f
If vol < 0 : vol = 0 : EndIf
If vol > 100 : vol = 100 : EndIf
GetEndPointVolume(@Volume)
volf = vol / 100
Volume\SetMasterVolumeLevelScalar(volf, #Null)
FreeEndPointVolume(Volume)
EndProcedure
Procedure MediaSetMute(value)
Protected Volume.IAudioEndpointVolume
Protected mute.i=1
GetEndPointVolume(@Volume)
Volume\SetMute(value, #Null)
FreeEndPointVolume(Volume)
EndProcedure
DataSection
uuidof_IAudioEndpointVolume:
Data.l $5CDF2C82
Data.w $841E,$4546
Data.b $97,$22,$0C,$F7,$40,$78,$22,$9A
uuidof_MMDeviceEnumerator:
Data.l $BCDE0395
Data.w $E52F,$467C
Data.b $8E,$3D,$C4,$57,$92,$91,$69,$2E
uuidof_IMMDeviceEnumerator:
Data.l $A95664D2
Data.w $9614
Data.w $4F35
Data.b $A7,$46,$DE,$8D,$B6,$36,$17,$E6
EndDataSection
; Test prog: Set volume to 10% and mute the speakers, this should play loudly anyway...
If MediaGetMute()
MediaSetMute(0)
EndIf
MediaSetVolume(100)
Beep_(2500,500)
BERESHEIT
Re: Get/Set Sound volume level programmatically
It does not work on XP (like you said someway) but I think it's not that big thing, only as newbee PBuser...
[10:13:11] Waiting for executable to start...
[10:13:11] Executable type: Windows - x86 (32bit)
[10:13:11] Executable started.
[10:13:11] [ERROR] Line: 54
[10:13:11] [ERROR] Invalid memory access. (read error at address 0)
[10:13:19] The Program was killed.
This is the error line :
hr = deviceEnumerator\GetDefaultAudioEndpoint(0, 1, @defaultDevice)
in :
[10:13:11] Waiting for executable to start...
[10:13:11] Executable type: Windows - x86 (32bit)
[10:13:11] Executable started.
[10:13:11] [ERROR] Line: 54
[10:13:11] [ERROR] Invalid memory access. (read error at address 0)
[10:13:19] The Program was killed.
This is the error line :
hr = deviceEnumerator\GetDefaultAudioEndpoint(0, 1, @defaultDevice)
in :
Code: Select all
Procedure GetEndPointVolume(*endpointvolume)
Protected deviceEnumerator.IMMDeviceEnumerator
Protected hr, defaultDevice.IMMDevice
CoInitialize_(#Null)
hr = CoCreateInstance_(?uuidof_MMDeviceEnumerator, #Null, #CLSCTX_INPROC_SERVER, ?uuidof_IMMDeviceEnumerator,@deviceEnumerator);#CLSCTX_ALL
hr = deviceEnumerator\GetDefaultAudioEndpoint(0, 1, @defaultDevice)
deviceEnumerator\Release()
hr = defaultDevice\Activate(?uuidof_IAudioEndpointVolume, #CLSCTX_INPROC_SERVER, #Null, *endpointVolume);
defaultDevice\release()
ProcedureReturn *endpointvolume
EndProcedure
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Re: Get/Set Sound volume level programmatically
Vista and higher have a completely new sound system, this code will never be able to run under XP!Joris wrote:It does not work on XP (like you said someway) but I think it's not that big thing, only as newbee PBuser...
More infos can you found in the thread from luis: http://www.purebasic.fr/english/viewtop ... 59#p403759
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.

Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.

- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Get/Set Sound volume level programmatically
@Joris: Thanks, I'll encase the new sound stuff in a CompilerIf block for the windows version to prevent crashes and include a note in the About box saying that for XP and earlier it won't force the sound.
BERESHEIT