Ogg Vorbis Loader

BlitzMax Forums/BlitzMax Programming/Ogg Vorbis Loader

Vertex(Posted 2007) [#1]
I want to use the original function ov_open_callbacks to getting a streamed Ogg loader in my OpenAL module.

Here is the test case:
SuperStrict

Framework Pub.OggVorbis
Import BRL.FileSystem

Const NOTOPEN   : Int = 0
Const PARTOPEN  : Int = 1
Const OPENED    : Int = 2
Const STREAMSET : Int = 3
Const INITSET   : Int = 4

Const SEEK_SET : Int = 0
Const SEEK_CUR : Int = 1
Const SEEK_END : Int = 2

Type ov_callbacks
	Field read_func  : Byte Ptr
	Field seek_func  : Byte Ptr
	Field close_func : Byte Ptr
	Field tell_func  : Byte Ptr
End Type

Extern
	Function ov_clear:Int(vf:Byte Ptr)
	Function ov_open_callbacks:Int(datasource:Byte Ptr, vf:Byte Ptr, ..
	                               initial:Byte Ptr, ibytes:Long, callbacks:Byte Ptr)
End Extern

Global Stream    : TStream, ..
       Callbacks : ov_callbacks, ..
       OggFile   : Byte Ptr

Stream = ReadStream("Test.ogg")
If Not Stream Then Throw("Unable to open ogg file")

Callbacks = New ov_callbacks
Callbacks.read_func  = VorbisRead
Callbacks.seek_func  = VorbisSeek
Callbacks.close_func = VorbisClose
Callbacks.tell_func  = VorbisTell

OggFile = MemAlloc(1024*1024)
If Not ov_open_callbacks(Stream, OggFile, Null, 0, Callbacks) = 0 Then ..
	Throw("Unable to open ogg file")

Function VorbisRead:Int(Buffer:Byte Ptr, ByteSize:Int, Count:Int, Stream:TStream)
	DebugLog "read: " + ByteSize + " | " + Count
	Return Stream.Read(Buffer, ByteSize*Count)/ByteSize
End Function

Function VorbisSeek:Int(Stream:TStream, Offset:Long, Origin:Int)
	Local Success:Int

	DebugLog "seek: " + Offset + " | " + Origin

	Success = -1
	Select Origin
		Case SEEK_SET
			Success = Stream.Seek(Offset)
		
		Case SEEK_CUR
			Success = Stream.Seek(Stream.Pos() + Offset)
		
		Case SEEK_END
			Success = Stream.Seek(Stream.Size() + Offset)
	End Select

	If Success = -1 Then Return -1

	Return 0
End Function

Function VorbisClose:Int(Stream:TStream)
	DebugLog "close"
	Stream.Close()
End Function

Function VorbisTell:Long(Stream:TStream)
	DebugLog "tell"
	Return Stream.Pos()
End Function


Returns me an "Unhandled Memory Exception Error"

But wat is wrong? OggFile or is there no way for Callbacks?

cu olli


skidracer(Posted 2007) [#2]
I can't see anything obviously wrong, I didn't use any 64 bit parameters in the original so that may have been a problem at the time or bmx didn't support longs then, can't remember.

Checking out redi.maxmod.oggstream.bmx and that still uses my Decode_Ogg C stub also so not sure if it's possible from pure bmx or not.


Vertex(Posted 2007) [#3]
How can I find your module?

The following code does work:
SuperStrict

Framework Vertex.OpenAL
Import Pub.OggVorbis
Import BRL.FileSystem
Import BRL.PolledInput

Const SEEK_SET : Int = 0
Const SEEK_CUR : Int = 1
Const SEEK_END : Int = 2

Global Stream    : TStream, ..
       Samples   : Int, ..
       Channels  : Int, ..
       Frequence : Int, ..
       OggFile   : Byte Ptr, ..
       Size      : Int, ..
       OggBuffer : Byte Ptr, ..
       Format    : Int

Global Device  : Byte Ptr, ..
       Context : Byte Ptr, ..
       Buffer  : Int, ..
       Source  : Int, ..
       State   : Int


Stream = ReadStream("Test.ogg")
If Not Stream Then Throw("Unable to load file")

OggFile = Decode_Ogg(Stream, VorbisRead, VorbisSeek, VorbisClose, VorbisTell, ..
                     Samples, Channels, Frequence)
If Not OggFile Then Throw("Unable to read file")

Size = Samples*2*Channels
OggBuffer = MemAlloc(Size)

Select Channels
	Case 1
		Format = AL_FORMAT_MONO16
	Case 2
		Format = AL_FORMAT_STEREO16
End Select

Device = alcOpenDevice(Null)
Context = alcCreateContext(Device, Null)
alcMakeContextCurrent(Context)

alGenBuffers(1, Varptr(Buffer))
Read_Ogg(OggFile, OggBuffer, Size)
alBufferData(Buffer, Format, OggBuffer, Size, Frequence)

alGenSources(1, Varptr(Source))
alSourcei(Source, AL_BUFFER, Buffer)

alSourcePlay(Source)
Repeat
	alGetSourcei(Source, AL_SOURCE_STATE, Varptr(State))
	Delay 30 ' Dropping CPU Usage
Until State <> AL_PLAYING

alcDestroyContext(Context)
alcCloseDevice(Device) 
End

Function VorbisRead:Int(Buffer:Byte Ptr, ByteSize:Int, Count:Int, Stream:Object)
	Return TStream(Stream).Read(Buffer, ByteSize*Count)/ByteSize
End Function

Function VorbisSeek:Int(Stream:Object, Offset0:Int, Offset1:Int, Origin:Int)
	Local Success:Int

	Success = -1
	Select Origin
		Case SEEK_SET
			Success = TStream(Stream).Seek(Int(Offset0))
		
		Case SEEK_CUR
			Success = TStream(Stream).Seek(TStream(Stream).Pos() + Offset0)
		
		Case SEEK_END
			Success = TStream(Stream).Seek(TStream(Stream).Size() + Offset0)
	End Select

	If Success = -1 Then Return -1

	Return 0
End Function

Function VorbisClose:Int(Stream:Object)
	TStream(Stream).Close()
End Function

Function VorbisTell:Int(Stream:Object)
	Return TStream(Stream).Pos()
End Function


But I want to link the libogg and libvorbis directly without Pub.OggLoader

cu olli


skidracer(Posted 2007) [#4]
why?


Vertex(Posted 2007) [#5]
Pub.OggVorbis is not realy a nice module. No super strict mode and so on. I want to write my own module, with comments, seeking etc. http://xiph.org/vorbis/doc/vorbisfile/reference.html

cu olli