March 29, 2024, 09:59:27 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


WAV sound volume control

Started by Kian, October 25, 2010, 01:17:13 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Kian

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

ZeroDog

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.

Kian

Thanks a lot ZeroDog  ;D
Does exactly what it says on the tin.

ZeroDog

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.

Kian

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



gnozal

October 27, 2010, 02:42:20 AM #5 Last Edit: October 27, 2010, 03:10:27 AM by gnozal
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.

ZeroDog

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

Kian