Multiple sound channels

BlitzMax Forums/BlitzMax Programming/Multiple sound channels

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

This code wraps sounds in a type and records the last time a particular sound was played. If the last time the sound was played was only a few milliseconds ago, it doesn't play the sound. I set it to only a few milliseconds because my goal wasn't simply to avoid having sounds be loud, but instead to avoid the flanging effect you get when two identical sounds are played just milliseconds apart, and the way sounds are louder when repeated soon after one another. You can increase the delay if it isn't long enough for your tastes. I set it to what worked well in my Lego game.

Type Sound

	Global List:TList = CreateList()

	Global Path$ = "sfx"

	Global Volume_SFX#   = 1.0
	Global Volume_Music# = 1.0
	
	Global MusicChannel:TChannel
	Global MusicTrack% = -1

	Field _TSound:TSound
	Field _Looping%	
	Field _LastPlayTime%


	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This method loads a sound. 
	' Specifying Null for Url will create a null sound which will do nothing if played.  This is useful for creating placeholder sound instances.
	' -------------------------------------------------------------------------------------------------------------------------------------------------------
		
		Function Load:Sound(Url:Object, Loop%=False)
		
			Local NS:Sound 
			
			NS = New Sound			
																								
			NS._TSound = LoadSound(Url, Loop)
			If (NS._TSound = Null) And (Url <> Null) Then RuntimeError("Error in Sound.Load() : ''" + String(Url) + "'' failed to load.  Please reinstall the game.")
			
			NS._Looping = Loop
			
			List.AddLast(NS)
			
			Return NS					
																		
		End Function
		

	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' Volume# allows you to set the sound's volume.
	' Rate# allows you to adjust the speed at which the sound is played back up or down.
	' -------------------------------------------------------------------------------------------------------------------------------------------------------

		Method Play:TChannel(Volume#=1.0, Rate#=1.0)
	
			Local Channel:TChannel
			
			If _TSound = Null Then Return Null
			
			If Volume# < 0 Then Volume# = 0
			If Volume# > 1 Then Volume# = 1
		
			' If the timer has looped, or this sound wasn't played too recently...
			If (_LastPlayTime > MilliSecs()) Or (MilliSecs() > (_LastPlayTime + 60))
	 
				' Note:
				' If any sounds are looped, we'll need to create a channel type to hold the currently active channels and so we can alter their volume when
				' the sound effects volume slider is moved.
				
				' Get sound ready to play.
					Channel = CueSound(_TSound)
						
				' Set sound volume and pitch.
					Channel.SetVolume(Volume_SFX#*Volume#)
					Channel.SetRate(Rate#) 
									
				' Start playing sound.
					Channel.SetPaused(False)
				
				' Record the time at which this sound was played so that we can avoid playing the same sound more than once in quick succession.				
					_LastPlayTime = MilliSecs()
					
				Return Channel
		
			EndIf
			
		End Method

				
End Type


' -------------------------------------------------------------------------------------------------------------------------------------------------------
' This function loads all the sounds the game needs.
' -------------------------------------------------------------------------------------------------------------------------------------------------------

	Global SOUND_MouseClick:Sound
	Global SOUND_HighlightFruit:Sound
	Global SOUND_PickFruit:Sound
	Global SOUND_UnpickFruit:Sound
	Global SOUND_SwapFruit:Sound
	
			
	Function LoadSounds()

		SOUND_MouseClick     = Sound.Load(Sound.Path$ + "mouseclick.wav")
		SOUND_HighlightFruit = Sound.Load(Sound.Path$ + "highlightfruit.wav")
		SOUND_PickFruit      = Sound.Load(Sound.Path$ + "pickfruit.wav")
		'SOUND_UnpickFruit    = Sound.Load(Sound.Path$ + "unpickfruit.wav")
		SOUND_SwapFruit      = Sound.Load(Sound.Path$ + "swapfruit.wav")
	
	End Function