I have written a game which uses WAVs for sound effects but I can find no way of controlling their volume from within the program.
Ploughing through MSDN I have found the waveOutSetVolume function which seems my best bet, but it requires a handle to an output device which I don't know how to find.
Assuming that I am on the right track, any guidance would be greatly appreciated.
Thanks
Kian
Yep. I was dealing with this issue a short while ago. I ended up simply using 0 for the device ID, which seemed to work. This should force it to use the first installed device, which should be suitable for most purposes. The only issue would be if there were more than one wave device installed and the first device wasnt being used.
Thanks a lot ZeroDog ;D
Does exactly what it says on the tin.
No Problem :)
If you ever get the waveOutGetVolume to work, please let me know, as I was fighting with it for quite some time before I gave up and went with a workaround.
Hope this is some help ZeroDog.
DEF split as uint64
def p as pointer
p=split
waveOutSetVolume(0,0xFFF92FFF)
waveOutGetVolume(0,p)
left=split&0xFFFF
right=(split&0xFFFF0000)/0x10000
Hello,
here is some Purebasic code I use in a command line tool to get and set the WaveOut volume.
I don't know IWBasic but it should not be to hard to translate.
;
; Set WaveOut Volume
;
;/ Mixer functions
#MMSYSERR_NOERROR = 0
#MIXER_SHORT_NAME_CHARS = 16
#MIXER_LONG_NAME_CHARS = 64
Structure MIXERCONTROL
cbStruct.l
dwControlID.l
dwControlType.l
fdwControl.l
cMultipleItems.l
szShortName.s[#MIXER_SHORT_NAME_CHARS]
szName.s[#MIXER_LONG_NAME_CHARS]
lMinimum.l
lMaximum.l
reserved.l[10]
EndStructure
;
Procedure.l Mixer_GetVolume(ComponentType.l) ; Get Volume [0, 65535]
Protected dwVolume.l, Result.l, hMixer
Protected ml.MIXERLINE, mlc.MIXERLINECONTROLS, mc.MIXERCONTROL
Protected mcdu.MIXERCONTROLDETAILS_UNSIGNED, mcd.MIXERCONTROLDETAILS
;
RtlZeroMemory_(ml, SizeOf(MIXERLINE))
RtlZeroMemory_(mlc, SizeOf(MIXERLINECONTROLS))
RtlZeroMemory_(mcd, SizeOf(MIXERCONTROLDETAILS))
RtlZeroMemory_(mcdu, SizeOf(MIXERCONTROLDETAILS_UNSIGNED))
;
Result = MixerOpen_(@hMixer, 0, 0, 0, #MIXER_OBJECTF_HMIXER)
If Result = #MMSYSERR_NOERROR
ml\cbStruct = SizeOf(MIXERLINE)
ml\dwComponentType = ComponentType
Result = MixerGetLineInfo_(hMixer, @ml, #MIXER_GETLINEINFOF_COMPONENTTYPE)
If Result = #MMSYSERR_NOERROR
mlc\cbStruct = SizeOf(MIXERLINECONTROLS)
mlc\dwLineID = ml\dwLineID
mlc\dwControlType = #MIXERCONTROL_CONTROLTYPE_VOLUME
mlc\cControls = 1
mlc\pamxctrl = @mc
mlc\cbmxctrl = SizeOf(MIXERCONTROL)
Result = MixerGetLineControls_(hMixer, @mlc, #MIXER_GETLINECONTROLSF_ONEBYTYPE)
If Result = #MMSYSERR_NOERROR
mcd\cbStruct = SizeOf(MIXERCONTROLDETAILS)
mcd\dwControlID = mc\dwControlID
mcd\paDetails = @mcdu
mcd\cbDetails = SizeOf(MIXERCONTROLDETAILS_UNSIGNED)
mcd\cChannels = 1
Result = MixerGetControlDetails_(hMixer, @mcd, #MIXER_SETCONTROLDETAILSF_VALUE)
If Result = #MMSYSERR_NOERROR
dwVolume = mcdu\dwValue
EndIf
EndIf
EndIf
EndIf
;
ProcedureReturn dwVolume
;
EndProcedure
;
Procedure Mixer_SetVolume(ComponentType.l, NewVolume.l) ; Set Volume [0, 65535] - Returns #True if success
Protected dwVolume.l, Result.l, hMixer
Protected ml.MIXERLINE, mlc.MIXERLINECONTROLS, mc.MIXERCONTROL
Protected mcdu.MIXERCONTROLDETAILS_UNSIGNED, mcd.MIXERCONTROLDETAILS
;
RtlZeroMemory_(ml, SizeOf(MIXERLINE))
RtlZeroMemory_(mlc, SizeOf(MIXERLINECONTROLS))
RtlZeroMemory_(mcd, SizeOf(MIXERCONTROLDETAILS))
RtlZeroMemory_(mcdu, SizeOf(MIXERCONTROLDETAILS_UNSIGNED))
;
Result = MixerOpen_(@hMixer, 0, 0, 0, #MIXER_OBJECTF_HMIXER)
If Result = #MMSYSERR_NOERROR
ml\cbStruct = SizeOf(MIXERLINE)
ml\dwComponentType = ComponentType
Result = MixerGetLineInfo_(hMixer, @ml, #MIXER_GETLINEINFOF_COMPONENTTYPE)
If Result = #MMSYSERR_NOERROR
mlc\cbStruct = SizeOf(MIXERLINECONTROLS)
mlc\dwLineID = ml\dwLineID
mlc\dwControlType = #MIXERCONTROL_CONTROLTYPE_VOLUME
mlc\cControls = 1
mlc\pamxctrl = @mc
mlc\cbmxctrl = SizeOf(MIXERCONTROL)
Result = MixerGetLineControls_(hMixer, @mlc, #MIXER_GETLINECONTROLSF_ONEBYTYPE)
If Result = #MMSYSERR_NOERROR
mcdu\dwValue = NewVolume
mcd\cbStruct = SizeOf(MIXERCONTROLDETAILS)
mcd\dwControlID = mc\dwControlID
mcd\paDetails = @mcdu
mcd\cbDetails = SizeOf(MIXERCONTROLDETAILS_UNSIGNED)
mcd\cChannels = 1
Result = MixerSetControlDetails_(hMixer, @mcd, #MIXER_SETCONTROLDETAILSF_VALUE)
If Result = #MMSYSERR_NOERROR
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndIf
EndIf
EndIf
;
EndProcedure
;/
;
Debug "Volume : " + Str(Mixer_GetVolume(#MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT))
;
Argument.s = UCase(ProgramParameter())
If Argument
Select Argument
Case "MAX"
Volume = 65535
Case "MIN"
Volume = 0
Default
Volume = Val(Argument)
If Volume < 0
Volume = 0
ElseIf Volume > 65535
Volume = 65535
EndIf
EndSelect
Mixer_SetVolume(#MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT, Volume)
Debug "New volume set to " + Str(Volume)
Else
MessageRequester("Information", "Set WaveOut volume" + Chr(10) + Chr(10) + "Start EXE with parameter = MIN, MAX or value = [0, 65535]" + Chr(10) + Chr(10) + "Current WaveOut volume is " + Str(Mixer_GetVolume(#MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT)), #MB_ICONINFORMATION)
EndIf
I hope it helps.
ahhh, okay, I get it now.... you gotta use a pointer to retrieve the volume... that makes sense... I dont know why I didnt think of that before... Thanks :)
My pleasure.