Streaming Multiple Ogg Files From Sd


Joined
Feb 19, 2005
Messages
162
Age
36
Location
Madrid
(Sorry in advance for any stupid/naive observations, this is my first half-serious attempt at C++ plus SDL).

I'm trying to write a music player of a certain tracker-like format. The format in question stores the notes and timing in a small text file, and the sound samples in dozens of (separate) small OGG files.

So far I've only tried using SDL_mixer. Loading all samples with Mix_LoadWAV before starting playback works fine on the PC but not on the Wiz, since that function uncompresses OGG files on-the-fly and stores them uncompressed in memory, which quickly eats up all of it. (Btw, Mix_LoadWAV loads many kinds of formats, not just WAV).

Then I tried loading and unloading samples during playback; this way only those samples being played are stored in memory at any given time. Again, this worked on the PC but causes noticeable momentarily "hang ups" as samples are loaded and decoded.

I can't use Mix_LoadMUS (which streams music from disk) because AFAIK there's only one channel reserved for music, and I need at least 8 channels.

What would you guys think would be a possible solution? Should I have a look at SDL_audio? Or maybe work directly with libvorbis? Thanks in advance.

(BTW, make sure you have a look at gp32spain's contest if you have any project in mind, there's a $2,000+ bounty so far :) ).
 
I think asking the Wiz to decode 8 OGG streams at once might be a bit much. It might be able to do it at 533mhz, it might not.

If I were conquering this problem I would do it one of two ways:

Both ways involve using the upper 32MB of RAM usually inaccessible to Linux programs. Have a look at this page on the GP2X wiki for an idea on how to use the Wiz's upper memory. I don't know offhand where the Wiz locates its upper RAM so you might have to change the offset in the example code. If you scroll all the way down you can also find a rudimentary malloc function that you can get started with.

First way:
Hack SDL_Mixer's MIX_LoadWav function to use the upper memory malloc instead of glibc malloc. This way you can preload all your OGG streams and hopefully they will all fit. The upper memory malloc function can regress to using the standard glibc malloc if it ever runs out of upper RAM.

Second way (if there's way too many samples to fit uncompressed into 32MB RAM):
Somehow get a linux RAM disk to use most or all of the upper RAM. Copy the current song's OGG sample files to this RAM disk when the song starts and load them on the fly like you are already trying to do using MIX_LoadWav. Might be more or less of a pain in the ass than the first way. The Linux kernel and modules don't use glibc malloc and there are many limitations on what you can do from inside it versus a standard Linux program. Hacking it will require a bit more finesse but honestly it might end up being just as easy. Never know until you try. Since the Wiz uses a 2.6 kernel, you have a lot more options here than you did on the GP2X. There might be something out there like the FUSE stuff or whatever (have to do some research in this department) that will allow you to avoid doing kernel hacking and instead easily write a userspace program that allows a filesystem to exist in the upper memory.
 
i'd suggest to hack into SDL - and implement a way to add 8 music files. because: everything is already there, there are these channels, there's the way to stream music - just try to extend the mixer?
maybe this all isn't needed, how big are your music files uncompressed? maybe it's just enough to get enough memory... (like senor quack said - use upper memory)
 
Thanks for your advice :)

Uncompressed samples can take as little as a few megs, up to more than 50 MB. Senor Quack's first idea sounds like a simple solution which would work very well with most songs, so I'll have a look at how MAME does it. Creating a RAM disk would make even more songs play fine (not all - a few use very long samples), and I'd probably learn a lot while getting it to work, but I don't think I have the knowledge right now to do something like that :)

Hacking SDL_mixer to allow several music channels would also be very convenient. I'm using the official SDK, which only comes with precompiled libraries plus their respective header files but no source for them. Where can I get the latest SDL sources for the Wiz?
 
with more than 50MB, there's not much memory left for the rest of your application - so i think preloading all oggs will not work. streaming is the only way i can think of, seriously.

i think you can just take the original SDL_mixer source code ( http://www.libsdl.org/projects/SDL_mixer/ ) and start hacking. as it is based upon SDL you may only need to link against the precompiled SDL and it should work.
 
Hmmm, I overestimated my knowledge/free time a bit :p I tried looking at SDL_mixer but it was a bit overwhelming. I'm now experimenting with SDL_audio which makes it very easy to decode OGG files streaming them from the HD (edited - I was getting high CPU usage stats due to a mistake on my part, it's fixed now).

Using SDL_sound+SDL_audio directly works very well (possible performance issues on the Wiz aside). I now need those two libraries compiled for the Wiz. Has this been done before? It'd save me a lot of hassle to have the libraries already compiled, but I guess that'd be a good way not to learn anything :p

Thanks again for your suggestions. If streaming takes too much CPU time I'll try high memory.
 
Back
Top