FMOD - can't change a loop status on a sample....

BlitzMax Forums/BlitzMax Programming/FMOD - can't change a loop status on a sample....

Space Fractal(Posted 2009) [#1]
http://www.spacefractal.com/files/Loop_Music_System.zip

Strict
Import BaH.FMOD

Global SoundSystem:TFMODSystem = New TFMODSystem.create()
Global secs:Int
SoundSystem.Init(100)

Graphics 640, 480

Sound.MusicPlay("Jungle")
Delay 200
FlushKeys
Repeat
	Cls
	Sound.MusicUpdate("Jungle")
	SetColor 255,255,255
	DrawText "Music Playing in secs: " + secs / 60, 0, 0
	
	If KeyHit(KEY_SPACE)
		Sound.Pause("Jungle", 0)
		Delay 1000
		Sound.Pause("Jungle", 1)
	EndIf
	Flip
	secs = secs + 1
Until KeyHit(KEY_ESCAPE)


Type Sound
	Field soundFX:TFMODSound
	Field channel:TFMODChannel
	Field loop=0
	Field FX$
	Field ChannelNr=0
	Field cvolume#=1.0
	Field Song:Int[1]
	Field Playing=0
	Field LoopOff=0
	Field WavRestarted=0
	Field LastPosition=1000
	Field SystemTimer=0
	Field SystemPause=0
	
	Global SystemSecs=0
	Global Tempo:Int
	Global Length:Int
	
	Global List:TList=New TList
	Global gvolume#=1.0
	Global Counter=0
	
	Function AppExit()
		SoundSystem.SystemRelease()
	EndFunction

	Function MusicUpdate(File$)
		Global LastFrame
		Local frame=0
		For Local s:Sound=EachIn List
			frame:+1
			If s.FX$=file$

				' change volume
				Local secs#=((Float(MilliSecs())-Float(s.SystemTimer))/1000.0/Float(tempo)*60)+1.0
				If s.song[secs#]=1
					If s.channel<>Null Then s.channel.setVolume(1)
					If s.playing<>1 And s.LoopOff=0
						s.soundFX.setmode(FMOD_LOOP_NORMAL)
						s.soundFX.SetLoopCount(-1)
						s.channel=SoundSystem.PlaySound(s.ChannelNr, s.soundFX)
						s.playing=1
						s.LoopOff=0
						Print s.channelnr+" :: PLAY CHANNEL"
					EndIf
				ElseIf s.song[secs]=0
					If s.playing=1 Or s.loopoff=1
						If s.channel<>Null
							' commented out for testing the bug below.
						'	s.channel.setVolume(0); 'Print "test "+Rand(1,1000)
							Print s.channelnr+" :: VOLUMEOFF"
							s.loopoff=0
						EndIf
					EndIf
					s.playing=0
				EndIf

				If s.song[secs+1]=0 And s.LoopOff=0 And s.playing=1
				
					' **** BUG HERE ****
					' I can NOT set a new LoopCount on a allready playing sample. For some mystery reason
					' you need to replay the sample again (using PlaySound command), but I do want to do 
					' that in a on going looped sampled. But for some reason I did never get that one to
					' work without using PlaySound.
					'
					' It seen there is missing something here to set the loop count on a current channel?
					s.soundFX.SetLoopCount(0)

					Print s.channelnr+" :: LOOPOFF"				
					s.LoopOff=1
					' **** BUG END ****
				EndIf
						
				If frame=1
					DrawText "Music Frame: " + secs+" "+MilliSecs()+" "+s.SystemTimer+" "+s.song[secs], 0, 20
				EndIf
			EndIf
		Next
		
		
	EndFunction

	Function MusicPlay:Int(file$)
		Print "MusicPlay: "+file$
		Counter:+1
		Local newsound:sound=New Sound

		Local Count=0
		
		' read the music files into channels
		For Local i=1 To 10
			Local loadfile$="music/"+file$+"/"+File$+"-loop-"+i+".wav"
			Loadfile$=Trim(LoadFile$)
			Local newsound:sound=New sound
			Print "wav found: "+loadfile$
			If FileType(loadfile$)=1
				newsound.soundFX:TFMODSound = SoundSystem.CreateSoundURL(loadfile$, 0)
				If newsound.soundFX=Null Then Print "could not load"
				Count:+1
				newsound.ChannelNr=Count
				newsound.FX$=Trim(file$)
				list.addlast(newsound)
			Else
				Print "file not found"
				Exit
			EndIf
		Next
		Print ""

		' read how the song should been played.
		Local FileOpen:TStream=OpenFile("music/"+file$+"/"+File$+"-loop.ini")
		Repeat
			Local Line$=ReadLine$(FileOpen)
			If Line$="" Then Exit
		
			Local Name$=Lower$(Trim(StringField(line$, 1, "=")))
			Local Value$=Lower$(Trim(StringField(line$, 2, "=")))

			If name$="tempo" Then Tempo=Value$.toint()
			If name$="length" 
				Length=Value$.toint()
				For Local s:Sound=EachIn List
					If s.FX$=file$
						s.Song=New Int[length+5]
						For Local i=1 To length
							s.song[i]=-1
						Next
					EndIf
				Next
			EndIf
			
			If name$="loop"
				Local channel=StringField(Value$, 1, "|").toint()
				count=1
				For Local s:Sound=EachIn List
					If s.FX$=file$ And channel=S.ChannelNr
						Print "loop: "+channel
						Repeat
							count:+1
							Local Line$=StringField(Value$, Count, "|")
							Line$=Replace(line$,"|","")
							If Line$="" Then Exit
							name$=Lower$(Trim(StringField(line$, 1, ",")))
							Local Value2$=Lower$(Trim(StringField(line$, 2, ",")))
							If name$.toint()<length
								s.song[name$.toint()]=Value2$.toint()
							EndIf
						Forever
					EndIf
				Next
			EndIf
		Forever
			
		' play all loops found in the directoy.
		For Local s:Sound=EachIn List
			If s.fx$=file$
				s.playing=0
			EndIf
		Next
		MusicUpdate(File$)
	EndFunction
		
	Function Pause(snd$, resume=0)
		For Local s:Sound=EachIn List
			If s.FX$=snd$ Or snd$="all"
				If s.channel<>Null
					If resume=0
						s.channel.setPaused(1)
						s.SystemPause=MilliSecs()
					ElseIf s.SystemPause>0
						s.channel.setPaused(0)
						Local secs=MilliSecs()-s.SystemPause
						s.SystemTimer:+secs
						If s.channelnr=0
							s.channel.setVolume(gvolume#*s.cvolume#)
						EndIf
					EndIf
				EndIf
			EndIf
		Next
	EndFunction
EndType

' a stringfield help function
Function StringField$(TXT$, Index, Delimeter$)
	Local RESULT$=""
	For Local I=1 To Len(TXT$)
		Local char$=Mid$(TXT$, i, 1)
		If char$=Delimeter$ Or i=Len(TXT$)
			index:-1
			If index=0 And i=Len(Txt$) Then Return RESULT$+char$
			If index=0 Then Return RESULT$
			If i=Len(Txt$) Then Return ""
			RESULT$=""
		Else
			RESULT$=RESULT$+char$
		EndIf
	Next
	Return ""
EndFunction


look for the **** BUG comment, so I guess that is all for now **** Not sure its a FMOD bug or?