Page 1 of 1

Set/Get Master Volume/Mute

Posted: Tue Apr 08, 2003 8:41 pm
by BackupUser
Restored from previous forum. Originally posted by GPI.

After a LONG (VERY VERY VERY LONG) time of seariching a function Example, i found a Delphi-Example.

So, here it is:

Code: Select all

;-MIXERLINE
Structure MIXERLINE
  cbStruct.l
  dwDestination.l
  dwSource.l
  dwLineID.l
  fdwLine.l
  dwUser.l
  dwComponentType.l
  cChannels.l
  cConnections.l
  cControls.l
  szShortName.b[#MIXER_SHORT_NAME_CHARS]
  szName.b[#MIXER_LONG_NAME_CHARS]
  ;target
  dwType.l
  dwDeviceID.l
  wMid.w
  wPid.w
  vDriverVersion.l
  szPname.b[#MAXPNAMELEN]
EndStructure
;-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;  // set all channels
    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.l
  
  code=GetMasterMuteControl(Mixer,MasterVolume)
  If code=#MMSYSERR_NOERROR
    Details\cbStruct = SizeOf(MIXERCONTROLDETAILS);
    Details\dwControlID = MasterVolume\dwControlID;
    Details\cChannels = 1;  // set all channels
    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.l
  
  code=GetMasterVolumeControl(Mixer,MasterVolume)
  If code=#MMSYSERR_NOERROR
    Details\cbStruct = SizeOf(MIXERCONTROLDETAILS);
    Details\dwControlID = MasterVolume\dwControlID;
    Details\cChannels = 1;  // set all channels
    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.l
  
  code=GetMasterMuteControl(Mixer,MasterVolume)
  If code=#MMSYSERR_NOERROR
    Details\cbStruct = SizeOf(MIXERCONTROLDETAILS);
    Details\dwControlID = MasterVolume\dwControlID;
    Details\cChannels = 1;  // set all channels
    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

;little example
;Debug Hex(getMasterVolume(0))

;normal mixer 0 is the default soundcard
Debug mixerGetNumDevs_(); -Numbers of Soundcards
; mixer can be 0 to (mixerGetNumDevs()-1)

For i=0 To $ff00 Step $100
  setMasterVolume(0,i)
  Delay(100)
Next

For i=0 To 3
  Debug "mute"
  setmastermute(0,1)
  Delay(1000)
  Debug "sound"
  setmastermute(0,0)
  Delay(1000)
Next

PII 333, 256MB, Asus TNT2Ultra 32MB, AWE Gold 64 4MB

Posted: Tue Apr 08, 2003 9:34 pm
by BackupUser
Restored from previous forum. Originally posted by Berikco.
Originally posted by GPI

After a LONG (VERY VERY VERY LONG) time of seariching a function Example, i found a Delphi-Example.

So, here it is:
Very nice :)

Regards,

Berikco

http://users.pandora.be/berikco/purebasic.htm

Re: Set/Get Master Volume/Mute

Posted: Sun Nov 09, 2003 7:01 am
by PB
GPI, is there any way to mute specific inputs with your example?
Like, just the aux-in line, or CD input, etc?

Re: Set/Get Master Volume/Mute

Posted: Sun Nov 09, 2003 9:18 am
by GPI
PB wrote:GPI, is there any way to mute specific inputs with your example?
Like, just the aux-in line, or CD input, etc?
Look in the jaPBe-Includepack "VolumeMute.pbi".

Posted: Sun Nov 09, 2003 7:48 pm
by Hi-Toro
Very nice -- very useful too!

Re: Set/Get Master Volume/Mute

Posted: Tue Nov 11, 2003 5:24 am
by PB
Thanks GPI, it worked. :) Nice IncludeFile pack, too.

Re: Set/Get Master Volume/Mute

Posted: Mon Jun 28, 2010 10:29 am
by Mr Coder
This code to mute the volume doesn't work with Windows 7. Anyone know how to fix? From what I can see, each app in Windows 7 can have its own volume control, so master mute doesn't work anymore with it.

Re: Set/Get Master Volume/Mute

Posted: Mon Jun 28, 2010 3:02 pm
by Michael Vogel
Here's something I wrote some years ago, because my notebook doesn't have a "on screen display" for the volume level...

Code: Select all

Global ScrX=GetSystemMetrics_(#SM_CXSCREEN)
Global ScrY=GetSystemMetrics_(#SM_CYSCREEN)
Global MidX=ScrX>>1
Global MidY=ScrY>>1

Global VolumeID

Global CloseVolumeWindow=#MAXLONG
Global VolumeLevel

#VolumeHeight=10
#VolumeDelay=1000

#VolumeWindow=1001
#VolumeGadget=1002
#VolumeBitmap=1003

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

Structure MIXERCONTROLDETAILSUNSIGNED
	dwValue.l
EndStructure

Procedure ZeroMemory(adr,len)
	While len
		len-1
		PokeB(adr+len,0)
	Wend
EndProcedure
Procedure GetSoundControl(mode,*control.MIXERCONTROL)

	Protected line.mixerline
	Protected controls.mixerlinecontrols
	Protected Result

	ZeroMemory(Line,SizeOf(mixerline))
	Line\cbStruct=SizeOf(mixerline)
	Line\dwComponentType=#MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
	Result=mixerGetLineInfo_(0,Line,#MIXER_GETLINEINFOF_COMPONENTTYPE)

	If Result=#MMSYSERR_NOERROR
		ZeroMemory(Controls,SizeOf(mixerlinecontrols));
		Controls\cbStruct=SizeOf(mixerlinecontrols);
		Controls\dwLineID=Line\dwLineID;
		Controls\cControls=1;
		Controls\cbmxctrl=SizeOf(MIXERCONTROL);
		Controls\pamxctrl=*Control;

		If mode
			; Lautstärke
			Controls\dwControlType=#MIXERCONTROL_CONTROLTYPE_VOLUME;
		Else
			; Mute-Status
			Controls\dwControlType = #MIXERCONTROL_CONTROLTYPE_MUTE;
		EndIf

		Result=mixerGetLineControls_(0,Controls,#MIXER_GETLINECONTROLSF_ONEBYTYPE)

	EndIf

	ProcedureReturn result
EndProcedure
Procedure GetSoundState()

	Protected MasterVolume.MIXERCONTROL
	Protected Details.MIXERCONTROLDETAILS
	Protected UnsignedDetails.MIXERCONTROLDETAILSUNSIGNED
	Protected code.l

	i=0;	zuerst den Mute-Status abfragen, dann die Lautstärke
	j=1;	nehmen wir mal an, Mute ist inaktiv (Lautstärkenwert positiv zurückgeben)

	Repeat
		code=GetSoundControl(i,MasterVolume)
		If code=#MMSYSERR_NOERROR
			Details\cbStruct=SizeOf(MIXERCONTROLDETAILS);
			Details\dwControlID=MasterVolume\dwControlID;
			Details\cChannels=1;  // set all channels
			Details\Item=0;
			Details\cbDetails=SizeOf(MIXERCONTROLDETAILSUNSIGNED);
			Details\paDetails=@UnsignedDetails;
			code=mixerGetControlDetails_(0,Details,#MIXER_SETCONTROLDETAILSF_VALUE);
		EndIf

		j*(UnsignedDetails\dwValue+1);	+1, damit Mute ein/aus auch bei abgeschalteter Lautstärke erkannt wird

		If (i=0) And (j=2)
			j=-1;	Mute ist aktiv (negativer Lautstärkenwert)
		EndIf

		i+1
	Until i=2

	ProcedureReturn j

EndProcedure

VolumeLevel=GetSoundState()

i=OpenWindow(#VolumeWindow,0,0,MidX+2,#VolumeHeight+2,"*",#PB_Window_BorderLess|#PB_Window_Invisible|#PB_Window_ScreenCentered)
SetWindowLong_(i,#GWL_EXSTYLE,GetWindowLong_(i,#GWL_EXSTYLE)|#WS_EX_TOOLWINDOW); Fenster nicht in Taskleiste anzeigen
;SetWindowPos_(i,#HWND_TOPMOST,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE|#SWP_FRAMECHANGED); Fenster zurechtrücken (Update)
SetWindowColor(#VolumeWindow,#Black)

VolumeID=CreateImage(#VolumeBitmap,MidX,#VolumeHeight)
;CreateGadgetList(WindowID(#VolumeWindow))
ImageGadget(#VolumeGadget,1,1,MidX,#VolumeHeight,VolumeID)

StickyWindow(#VolumeWindow,1)
AddWindowTimer(#VolumeWindow,1,100)


Repeat

	If WaitWindowEvent(100)=#PB_Event_Timer
		i=GetSoundState()

		If i<>VolumeLevel

			VolumeLevel=i
			If i<=0
				j=#Gray
				i=-i
			Else
				j=#Green
			EndIf

			StartDrawing(ImageOutput(#VolumeBitmap))
			i*(MidX+1)
			i>>16
			i&$ffff

			Box(0,0,i,#VolumeHeight,j)
			Box(i,0,MidX-i,#VolumeHeight,#Black+((j&$ff)>>1)*$10101); grauer Balken bei aktivem 'Mute'
			StopDrawing()

			SetGadgetState(#VolumeGadget,VolumeID)
			ShowWindow_(WindowID(#VolumeWindow),#SW_SHOWNA)

			CloseVolumeWindow=GetTickCount_()+#VolumeDelay

		ElseIf GetTickCount_()>CloseVolumeWindow

			HideWindow(#VolumeWindow,#True)
			CloseVolumeWindow=#MAXLONG

		EndIf
	EndIf

ForEver

Re: Set/Get Master Volume/Mute

Posted: Tue Jun 29, 2010 1:50 am
by Mr Coder
Thanks Michael, but I don't see how to mute/unmute the volume with it? Also, the window was invisible due to the #PB_Window_Invisible flag, and wouldn't show up until I removed the flag. Is that expected?

Re: Set/Get Master Volume/Mute

Posted: Tue Jun 29, 2010 6:34 am
by Michael Vogel
Mr Coder wrote:Thanks Michael, but I don't see how to mute/unmute the volume with it? Also, the window was invisible due to the #PB_Window_Invisible flag, and wouldn't show up until I removed the flag. Is that expected?
Yes, this code snippet (which never quits) only checks the actual volume state and activates the window, if another program changes the volume level or mute state. My notebook has function keys for doing this, but I never got any screen feedback – so I wrote this program.

To check the effect, start my code and then the code of the initial post :wink:

Michael

Re: Set/Get Master Volume/Mute

Posted: Tue Jun 29, 2010 7:08 am
by Mr Coder
Okay then, but if it only monitors the volume, then it doesn't answer my question. I need to know how to mute and unmute Windows. The original code in this thread works for XP, but not 7. If your app just monitors it, then it's no good in helping me (sorry!).