Streaming OGGs?

BlitzMax Forums/BlitzMax Beginners Area/Streaming OGGs?

Ferminho(Posted 2005) [#1]
Hi everyone!

First time I post, although I have been working with blitzmax for some time x)

I have an issue regarding loadtimes in my game... I'd like to play large OGGs; the problem is... the only way is to load the entire OGG first. When talking about 15 min long music it becomes a loadtime of... about 25-30 secs on my AMD Duron 800. I can't afford that in terms of speed and/or memory, as I need to dynamically load and play music :/

The question: isn't there a way to play an OGG streaming it / loading it on the fly? I'm aware of the FMOD wrapper, but I'd like to think of another solution before that.

Any ideas?

Thanks,
Ferminho


Rimmsy(Posted 2005) [#2]
I was about to post the same question. There's a Blitz3d version in the archives by King Dave but because we don't have the playmusic command it's impossible to emulate.

I too would like to see a way of streaming sounds. Any idea, boffins?


DannyD(Posted 2005) [#3]
Not a solution but a suggestion: Split your 15min long ogg into 3 or 5 segments and load them when needed ?


Mystik(Posted 2005) [#4]
I've not found a cross platform way to do this other than by using fmod.

Would be really interested though if someone does find a way that does not need an expensive license.

Steve.


JaviCervera(Posted 2005) [#5]
OpenAL allows to do streaming.


Ferminho(Posted 2005) [#6]
First, thanks for the replies

@DannyD
I'm afraid that won't work. Game would be paralised for a moment (maybe some seconds...) when a new segment is loaded :/ if done in small enough chunks so that stop cannot be appreciated... but well, that's going back to streaming x)

I've been thinking for a while, and *maybe* I could try to do it. Is there a way to do a LoadSound from memory? i.e., from a pointer to a stream or a byte ptr or something like that...?


Hotcakes(Posted 2005) [#7]
if done in small enough chunks so that stop cannot be appreciated... but well, that's going back to streaming x)

That's essentially manual streaming =] It's entirely possible, but very fiddly. It may be your best option.

The shame here, is that the audio system in Max sets up a thread for itself (the audio system is allowed a thread, but not anything else!), the loading of .oggs should be moved there...

Is there a way to do a LoadSound from memory?

I think so. I think all the loading functions are stream based now, so they should be able to load from anywhere... hmm... if LoadSound streams in an ogg from an http: address, does it wait until the entire sound is loaded, or does it continue program execution? When can playback of the sound commence? One would hope that LoadSound would stream properly, but I don't think it does... yet...


LarsG(Posted 2005) [#8]
I'm not 100% sure, but I think it waits until the whole thing is loaded (streamed)...


Ferminho(Posted 2005) [#9]
LoadSound does, but not OpenStream... so here is my crazy idea.

I've been having a look at the ogg specs... I could try to code some type of manual StreamOgg. Read the full ogg in a stream; copy the ogg header to a new stream...
Now each "streaming" pass, create a new stream, copy the headers into it, copy some audio packets (an ogg page) from the main stream, and loadsound+playsound. Timing is hard to do without threads but I've come up with a way to do it (I think)

However the ogg format is very complex, and I'm not very sure... but I think the same file headers can be "recycled" for each of these "chunks".

Taken from http://www.xiph.org/ogg/vorbis/doc/Vorbis_I_spec.html :
<<Note: Vorbis can initiate decode at any arbitrary packet within a bitstream so long as the codec has been initialized/setup with the setup headers.>>

I guess I'd need only to identify an ogg page (that's easy as they're marked with the string 'OggS') and copy n of them to the new chunk...

I don't know how will it work in terms of performance though. Could try to use TCStreams and do it under C++ ...

What do you think? Shall I try it? or shall I stop dreaming?


Ferminho(Posted 2005) [#10]
I'll finally started to code it; I guess it's not so easy. If I miss any ogg page when copying to a new stream LoadSound returns null. I'll have to look more into it, but I think it's because he checks the Page sequence number, an 8 byte array each page has. If he misses 1... no ogg loaded :/ (in fact, that's only my guess)

More advances (I hope) soon


Ferminho(Posted 2005) [#11]
I'm at a dead end at the moment :/ although in theory ogg vorbis can be cropped and played from any ogg page start (provided the header pages are loaded) still doesn't work. I do this under bmax (each [] means an "ogg page" of variable size):

I load:

OGG1: [header1][header2][header3][a1][a2][a3][a4][a5]...[a15]

Then I make 2 streams and copy the data this way:

OGG2: [header1][header2][header3][a1][a2]...[a5]
OGG3: [header1][header2][header3][a6][a7]...[a10]

OGG2 is loaded and played OK.
Then OGG3 hangs up the app when doing LoadSound. I tried copying page headers from a1 to a6, a2 to a7 etc (things as the page sequence number, granulate position...) to see if LoadSound was checking the correct order of ogg pages... but same result.

If anyone knows the format / how the ogg loader works... any clue of what could be wrong?

PD: btw this has become more an advanced than a beginner question. doh! x)