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?
|