Windows Fmod example?

BlitzMax Forums/BlitzMax Programming/Windows Fmod example?

AntonyWells(Posted 2005) [#1]
Any about? I got svieung's Fmod release, it compiled fine, but the only example I could find was for a mac alteration.

But once converted to windows (I.e changing sound output driver), it doesn't load anything. Returns null.


GW(Posted 2005) [#2]
this one worked for me.
http://drago-tech.net/FmodWin32.zip
from this thread.
http://www.blitzbasic.com/Community/posts.php?topic=49584


Neuro(Posted 2005) [#3]
The download link doesn't seem to work. Is there another working one?


Sveinung(Posted 2005) [#4]
Hello and I'm very sorry for not including a sample.
I've uppdated the Fmod module and included a sample.
Still some issues with the asio-driver. Will fix
this later.

FMOD 3.74

Regards
Sveinung


AntonyWells(Posted 2005) [#5]
Thanks sven.

I found the problem though. FSound_Stream_Play expects a C Formatted string, but you use a regular string.

I changed the mod def from filename:String to fileName:Byte ptr,
and in blitz used FSound_Stream_Load("title.mp3".toCString() ) (A build in blitz func) and it then worked fine.


Here's my audio lib, now with Fmod support. It can load two custom formats, one compressed, one streaming(Streaming using blitz's own sound funcs from disk), and it can also stream/utilise fmod. it's all done by the lib, usage is similar to blitz's own 2d stuff, but this includes a proper 2d 'ear' system that takes rotation into account.


Strict

Const iForm = SF_Mono16BE
Global StreamBufSize = BytesperSample[iForm]*80000

Global chaloc[128]

Function requestChannel()
	For Local j=1 To 127
		If Not chaloc[j]
			chaloc[j]=True
			Return j
		EndIf
	Next
	Return -1
End Function

Function freeChannel( chan )

	chaloc[chan]=0

End Function



Type sound
	Field chan:TChannel,frm:Sfx
	Field x#,y#
	Field loop,scal#
	Field xu:Float Ptr,yu:Float Ptr
	Field isStream 
	Field sPos,sBuf:Byte Ptr,bStr:Tramstream
	Field sAud:TAudioSample
	Field fChan,isfMod,chanId
	
	Method New()
		ListAddLast sound.sounds,Self
		scal=1
		xu=Null
		yu=Null
	End Method
	
	
	Method Delete()
		
		If ListContains(sound.sounds,Self)
			ListRemove sound.sounds,Self
		End If
		
		If isStream
			MemFree sBuf,StreamBufSize
		EndIf
		
		If frm.isFmod
			freeChannel( chanId )
		End If
		
	End Method
	
	Method Position( ax#,ay# )
		x=ax
		y=ay
	End Method
	
	Method updatePars( xp:Float Ptr,yp:Float Ptr )
		xu = xp
		yu = yp
		
	End Method
	
	Method stop()
	
		If isfMod
			If chanid<>0
				If Not playing()
					fsound_stopsound( chanid )
					chanid=0
				EndIf
			EndIf
			Return
		EndIf
		If chan=Null Return 
		If ChannelPlaying(chan) StopChannel( chan )
		
		
	End Method
	
	Method SyncData()
			
			If frm.isFmod
				If chanid=0 
					Return 
				EndIf
				If Fsound_isplaying( fChan ) = False
					If loop
						fChan = fsound_Stream_play(chanId,frm.fstream)
						If fchan=-1
							Print "Failed to loop music stream."
							End
						EndIf
					Else
						freeChannel( chanId )
						chanId=0
					EndIf
				EndIf
				Return 
			EndIf

			If chan = Null Or ChannelPlaying( chan ) = False
			If isStream
	
				If sBuf = Null
					sBuf = MemAlloc( StreamBufSize )
					bStr = CreateRamStream( sbuf,StreamBufSize,True,True )
				EndIf
				Print "Streaming new Dat"
				Local res=False
			 	SeekStream( bstr,0 )
				Local csiz = streambufSize
				If StreamPos(frm.audstream)+cSiz>StreamSize(frm.audStream)
					cSiz = StreamSize(frm.audStream)-StreamPos(frm.audstream)			
					res=True
				EndIf
				
				For Local j=0 To csiz-1 
					WriteByte bstr,ReadByte(frm.audStream)
				Next
				
				If Eof(frm.audStream) Or res=True
					SeekStream frm.audStream,12
				EndIf
				sAud = CreateStaticAudioSample( sbuf,csiz/BytesPerSample[frm.aformat],frm.ahertz,frm.aformat )
				Local na:TSound = LoadSound( sAud )
				chan = PlaySound( na )
				
										
			Else
				If loop
					chan = PlaySound( frm.id )
				Else
					ListRemove sound.sounds,Self
				EndIf
			EndIf
			
		End If
	
	End Method
	
	Method sync()
		
		SyncData()
		If isFMod=True And chanId=0
			Return
		End If
		
		
		If xu<>Null
			x=xu[0]
			y=yu[0]
		EndIf
		
		Local xd#,yd#
		
		Local tx#,ty#
		Local nx#,ny#
		tx = sfx.ex - x
		ty = sfx.ey - y
		Local vr# = 360-sfx.eyaw
		nx=Cos (vr)*tx - Sin (vr)*ty
		ny=Sin (vr)*tx + Cos (vr)*ty	
		tx = sfx.ex+nx
		ty = sfx.ey+ny
		
		xd = tx-sfx.ex
		yd = ty-sfx.ey
		Local td# = 1.0-(Sqr(xd*xd+yd*yd)/sfx.er)
		If td>1 td=1
		If td<0 td=0
		
		
		Local axd# = xd
		
		Local ps# = -(xd/sfx.er)
		If ps<-1 ps=-1
		If ps>1 ps =1
		If frm.isfMod
			fsound_setVolume( chanid,td*255 )
			fsound_setpan( chanid,128+128*ps )
			fsound_setfrequency( chanid,frm.ffreq*scal )
			Return 
		EndIf
		
		SetChannelVolume chan,td
		SetChannelRate chan,scal
		SetChannelPan chan,ps

	
	End Method
	
	Method Playing()
	
		If frm.isfmod
			If frm.fStream<>0
				If FSound_stream_getposition(frm.fstream)=>fSound_Stream_getLength(frm.fstream)
					Return False
				EndIf
				Return True
			Else
				Return FSound_isplaying( chanId )
			EndIf
			
		EndIf
		
		
		Return ChannelPlaying(chan)
		sync()
	End Method
	
	Function Scale(scal#)
		
		For Local snd:Sound = EachIn sound.sounds
			snd.scal = scal
			snd.sync()
		Next
			
	End Function
	
	
	Function update()
		For Local snd:Sound = EachIn sounds
			snd.sync()
		Next
	End Function
	
	Global sounds:TList	
End Type
sound.sounds = CreateList()

sfx.scache = CreateList()
Type sfx
	Global sCache:TList
	Field id:TSound,loop
	Field filename:String
	Field raw:TAudioSample
	Field isStream
	Field aHertz,aLength
	Field ffreq
	Field audStream:Tstream,aformat
	Field isfmod,fStream
	
	Method fromStream( str:TStream )
	
		isStream=True
		audStream = str
		ahertz = Readint(str)
		alength = Readint(str)
		aformat = Readint(str)
			
	End Method

	
	Function Load:sfx(File:String,dloop=True,andRaw=False)
		
		
		For Local sn:Sfx = EachIn sfx.scache
			If sn.filename = file	
				Return sn
			EndIf
		Next
		Local out:sfx = New sfx
		
		Select ExtractExt(file).tolower()
			Case "mp3","ogg","wav"
				out.isFMod=True
				out.fStream = FSOUND_Stream_Open(file.tocstring(),FSOUND_NORMAL,0,0)			
			Case "stream"
				Local fil:tstream = ReadFile(File)
				If fil=Null
					Throw "streamabe file not found "+file
				EndIf
				Local out:Sfx = New sfx
				out.FromStream( fil )
				Return out
			Case "buck"
			Try
				Local bstream:Buckstream = createbuckstream( file )
				out.id = LoadSound( bstream.stream() )
				
			Catch s$
				Notify s
				End
			End Try
			If out.id=Null	
				Return Null
			Else
				Print "Buckets go now."
			EndIf
			FlushMem	
		Case "freeWav"
			out.id = LoadSound(file )
			If out.id = Null 
				FlushMem
				Return Null
			EndIf
			out.isstream=False
			If andRaw
				
				out.raw =  LoadAudioSample( file )
				'out.raw=out.raw.convert( iForm )
			
			EndIf
			
		End Select
				
		out.filename = file 
		out.loop=dloop
		ListAddLast sfx.scache,out
		Return out
		
	End Function
	
	Method SaveAudioStream( file:String )
		If raw = Null
			Throw "No raw audio sample to save."
		EndIf
		Local fil:TStream = WriteFile( file )
		Local buf:Byte Ptr = raw.samples
		Local pos
		Local plen = raw.length*bytespersample[ iform ]

		WriteInt fil,raw.hertz
		WriteInt fil,raw.length
		WriteInt fil,raw.format

		Local ist:TRamstream =CreateRamStream( buf,raw.length*BytesPerSample[ iform],True,False )
		CopyStream( ist,fil )
			
		CloseFile fil		
		
	End Method
	
	
	
	Method Play:sound(ax#,ay#)

		Local out:Sound = New sound
		If isFmod
			If fStream<>0
				out.chanId = requestChannel()
				out.fchan= fsound_stream_play(out.chanId,fstream)
				out.isfmod=True
				ffreq = fsound_GetFrequency( out.chanId )
				Print "Frequency was:"+ffreq
				If out.fchan = -1
					Print "Audio failed to stream."
					End
				EndIf				
			EndIf	
		Else
			If isStream
				out.isStream=True
			Else
				out.chan = PlaySound( id )
			EndIf
		EndIf
		
		out.loop = loop
		out.frm = Self
		out.sync()
		FlushMem
		
		Return out
		
	End Method
	
	Function setEar(x#,y#,yaw#=0)
		ex=x
		ey=y
		eyaw=yaw
	End Function
	
	Global er#
	Global ex#,ey#
	Global eYaw#
End Type 
sfx.er=200



Type buckStream
	Field str:TRamstream
	Field raw:Byte Ptr,siz
	Method Delete()
		MemFree raw,siz
	End Method
	Method stream:TRamstream()
		Return str
	End Method
End Type
	

Function CreateBuckStream:BuckStream( file:String )
	Local fil:tstream = ReadFile(file)
	If fil = Null
		Throw "File does not exist "+File+" filesize:"+FileSize(file)
	End If
	Local osiz = Readint(fil)
	Local csiz = Readint(Fil)
	Local raw:Byte Ptr = MemAlloc( csiz )
	Local real:Byte Ptr = MemAlloc( osiz )	
	Local rs1:TRamStream = CreateRamStream(raw,csiz,False,True)
	CopyStream(fil,rs1)	
	uncompress real,osiz,raw,csiz
	MemFree raw,csiz
	CloseStream fil
	CloseStream rs1
	rs1=CreateRamStream( real,osiz,True,False)
	Local out:Buckstream = New buckstream
	out.raw = real
	out.str = rs1
	out.siz=osiz
	Return out
End Function

Global vb:Byte Ptr 
Function initBufSys()
	vb = MemAlloc( streambufSize )
End Function



Function CreateSoundBuck( file:String )
	Local fil:TStream=ReadFile(file)
	If fil = Null
		Throw "File does not exist "+File
	EndIf
	Local siz=StreamSize( fil )
	Local raw:Byte Ptr =MemAlloc( FileSize( file ) )
	Local com:Byte Ptr =MemAlloc( FileSize( file ) )
	Local dlen=siz
	Local iStream:TRamstream = CreateRamStream( raw,FileSize(file),True,True )
	CopyStream( fil,istream )
	compress com,dlen,raw,siz
	
	CloseStream fil
	MemFree raw,siz
	fil = WriteFile( ExtractDir( file)+"\"+StripAll(file)+".buck")
	If fil=Null
		Throw "Unable to write buck file "+ExtractDir(file)+StripAll(file)+".buck"
	EndIf
	CloseStream istream
	istream = CreateRamStream( com,dlen,True,False )
	WriteInt fil,siz
	WriteInt fil,dlen
	CopyStream(istream,fil)
	CloseStream fil
	CloseStream istream
	MemFree com,siz
	
'	Print "Was "+siz+" Bytes |"+String(siz/1024)+"K"
'	Print "Is "+dlen+" Bytes |"+String(dlen/1024)+"K"
'	Print "Saved :"+String((siz/1024)-(dlen/1024))+" K"		
End Function




Fsound_init(44100,64,0)
FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND) ' Ensure you use FSOUND_OUTPUT_MAC 
FSOUND_SetDriver(0)

Rem
Local ac:Sound
Local sf:Sfx
Graphics 640,480,0
Local sx# = 20
Local sy# = 20



sf = Sfx.Load("sfx\music\title.mp3",True,False)
ac:Sound = sf.play( sx,sy )

Local t=0
Repeat
Cls

	sx=MouseX()
	sy=MouseY()
	
	ac.position( sx,sy )
		
	sfx.ex=320
	sfx.ey=240
	
	t=t+1
	If t=20
		sound.update()
		t=0
	EndIf
	
	sfx.eyaw:-90
	DrawLine 320,240,320+Cos(sfx.eyaw-45)*sfx.er,240+Sin(sfx.eyaw-45)*sfx.er
	DrawLine 320,240,320+Cos(sfx.eyaw+45)*sfx.er,240+Sin(sfx.eyaw+45)*sfx.er
	sfx.eyaw:+90
	
	sfx.eyaw=MouseZ()*7
	
	DrawRect sfx.ex-10,sfx.ey-10,20,20
	DrawRect sx-10,sy-10,20,20
	Delay 10
	FlushMem
Flip

Until KeyDown(KEY_ESCAPE)



End Rem



Neuro(Posted 2005) [#6]
Ok, I can't seem to get this FMOD thing to work. I got the FMOD dlls and put them in same directory as the bmx file, but it still says "Require FMOD.DLL"...need to reinstall....
Did I miss a step?


HCow33(Posted 2005) [#7]
One small error in Sveinung FMod Module:

Function FSOUND_GetIsPlaying:Byte(channel:Int) should be
Function FSOUND_IsPlaying:Byte(channel:int)


AntonyWells(Posted 2005) [#8]
Yeah, HC I fixed that one already.
Neuro, all I did was copy the lib Files into the fmod module folder, THEN compile mods, then copy teh .dll flder into my app dir.

Worked fine.


Robert Cummings(Posted 2005) [#9]
How about updating the fmod thread in one place with the fixes? I think that will be a nice thing. Also they really should host user mods here at blitz research if they happen to be spectacular like FMOD


Neuro(Posted 2005) [#10]
I'm still having problmes with this. This is what I did :
- copied the fmod stuff into the pub.mod folder
- compiled the mods
- copied the the 2 fmod dlls (fmodex.dll) and (fmodexp.dll) into the same folder of my bmx app
- run the app and still got the message. so i changed one of the dll file names to fmod.dll and then got some entry point error...
Any other steps i should take?


Sveinung(Posted 2005) [#11]
@Nuero
I think you need to Build Module (Alt + D on win32). You should allso put the libfmod.a in the lib folder in the blitzmax folder.

Sveinung


Sveinung(Posted 2005) [#12]
New update...
Check main Fmod tread

Sveinung


Neuro(Posted 2005) [#13]
I think you need to Build Module (Alt + D on win32).


Can you clairify? I already ran the BMK tool to rebuild all the modules. Its when I'm running my test app, it tells me that fmod.dll is not found. The strange thing is that the only dlls that come with the fmod api are (fmodex.dll) and (fmodexp.dll).