Problems With Playing Ogg Files Using Sdl Mixer?


Dimacus

Member
Joined
Jan 25, 2006
Messages
349
Age
37
Location
Land of the 'åäö'
Website
luminare.no-ip.org
[EDIT]

Problem Solved.
I was linking to both the normal vorbis libs AND the integer onces, probably cause a collision.
I removed ogg, vorbis and vorbis file and kept vorbisidec.

Thanks to all who helped me!

[/EDIT]

As the topics says; I'm having trouble with playing ogg files using SDL mixer.

The problem that i keep encountering is that my game keeps segfaulting after ALSA waring about an underrun after calling Mix_LoadWAV().
Gdb gives me this:
Code:
ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured
[Lumina]:-> Trying to load music and effects

Breakpoint 1, soundHandler::loadMusicFromFile (this=0x501f8, 
    file=0x415ec "./sys/bopp.ogg", name=0x415fc "music1") at src/sound.cpp:54
54	    aSound *tSfx = new aSound;
(gdb) n
ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured
55	    tSfx->isMusic = true;
(gdb) n 
ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured
56	    tSfx->sound=Mix_LoadWAV(file);
(gdb) n 
ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured

Program received signal SIGSEGV, Segmentation fault.
0x400cdc70 in _vorbis_block_ripcord () from /usr/lib/libvorbisidec.so.1
(gdb) n
Single stepping until exit from function _vorbis_block_ripcord, 
which has no line number information.
ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured
[New LWP 6317]
[LWP 6317 exited]
0x400f38c4 in pthread_join () from /lib/libpthread.so.0
(gdb)

At first I tought it might be since I had some version conflicting / too old libs, but I think I rule that out now that I have tried to compile it on the Pandora and I still have the same problem.
I find it abit strange that ALSA begins to complain/warn before I try to call Mix_LoadWAV. (This is the first time i call any sound related function other than "Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 1024)").

Searching a bit dosn't cast much light on my situation either :/
Anyone have any idea of what might be causing this?
 
You didn't post the code in question :)

I've not used ogg in SDL but I never really had a problem with SDL's basic audio system; maybe you need to pause the audio, or not start it up, until you've got audio samples ready to feed it? Still, an underrun should just do nothing (ie: skip, stutter, garbage or silence, depending) and not crash. Probably your crash is a bug in your code as normal, or perhaps an odd one -- perhaps your audio callback function is assuming certain thigns are ready, but your main thread hasn't yet loaded up samples or whatever, and so your callback is coming before things are ready and crashing?

jefftired
 
The buffer underrun warning only means that the sound thread could not run often/soon enough. It should not be related to the crash. It only means that a sound buffer could not be filled
by the time the sound chip needed it to be filled, the result is that there will be a small gap in the playback, which can result in clicks and pops. Increasing the buffer size in Mix_OpenAudio should help (maybe to 4096).

Clearly the crash is in the vorbis decoder. You should get a backtrace of the crash (gdb command "thread apply all bt") in order to debug it further.
 
Hello, thanks for the replies.

[Edit]
Hmm, it appears that the attach function has been removed, or im just blind.
Oh well, you can download the source and data here: http://luminare.no-ip.org/Lumina_panda.zip


Skeezix:

The function crashing is my audio loading function (and Mix_LoadWAV is SDL_mixer's loading wrapper for SDL's audio loading functions), I'm not trying to play anything.
If you want to take a look at the source (and perhaps my makefile, I'm not too used to using them) go right ahead, they should be included in this post.
Do excuse the state of my code tough, it's not very tidy as it is right now :)

hmn:
Yeah, I too found it difficult to belive that the underrun should cause the crash, I'll try and increase the buffer tough, just to see if it has any effect.

I can't backtrace that much since vorbis trashes is.
There also seem so be some sort of problem with libthread, maybe that has something to do with it?

Anyway, here is a more or less complete run trough gdb:
panda:/media/2GIGSD/Panda tests/1$ gdb ./lumina.x
GNU gdb (GDB) 7.0

...

Reading symbols from /media/2GIGSD/Panda tests/1/lumina.x...done.
(gdb) directory /media/2GBSD/src
Warning: /media/2GBSD/src: No such file or directory.
Source directories searched: /media/2GBSD/src:$cdir:$cwd

(gdb) directory /media/2GIGSD/src
Source directories searched: /media/2GIGSD/src:/media/2GBSD/src:$cdir:$cwd

(gdb) b sound.cpp:54
Breakpoint 1 at 0x3bf68: file src/sound.cpp, line 54.

(gdb) start
Temporary breakpoint 2 at 0x3d664: file src/main.cpp, line 39.
Starting program: /media/2GIGSD/Panda tests/1/lumina.x
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
(repeated about 10 times)

Temporary breakpoint 2, main (argc=1, argv=0xbeb4c9e4) at src/main.cpp:39
39 gameSettings.hasBeenPrepared = false;
(gdb) c
Continuing.
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
(repeated about 10 times)

ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured
ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured
[Lumina]:-> Trying to load music and effects


Breakpoint 1, soundHandler::loadMusicFromFile (this=0x501f8,
file=0x415f4 "./sys/bopp.ogg", name=0x41604 "music1") at src/sound.cpp:54
54 aSound *tSfx = new aSound;
(gdb) thread apply all bt

Thread 1 (LWP 1528):
#0 soundHandler::loadMusicFromFile (this=0x501f8,
file=0x415f4 "./sys/bopp.ogg", name=0x41604 "music1") at src/sound.cpp:54
#1 0x0003dbe8 in main (argc=1, argv=0xbeb4c9e4) at src/main.cpp:131


(gdb) bt
#0 soundHandler::loadMusicFromFile (this=0x501f8,
file=0x415f4 "./sys/bopp.ogg", name=0x41604 "music1") at src/sound.cpp:54
#1 0x0003dbe8 in main (argc=1, argv=0xbeb4c9e4) at src/main.cpp:131
(gdb) n
55 tSfx->isMusic = true;

(gdb)
ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured
56 tSfx->sound=Mix_LoadWAV(file);
(gdb) thread apply all bt

Thread 1 (LWP 1528):
#0 soundHandler::loadMusicFromFile (this=0x501f8,
file=0x415f4 "./sys/bopp.ogg", name=0x41604 "music1") at src/sound.cpp:56
#1 0x0003dbe8 in main (argc=1, argv=0xbeb4c9e4) at src/main.cpp:131

(gdb) step
ALSA lib pcm.c:7234:(snd_pcm_recover) underrun occured

Program received signal SIGSEGV, Segmentation fault.
0x400cdc70 in _vorbis_block_ripcord () from /usr/lib/libvorbisidec.so.1
(gdb) thread apply all bt

Thread 1 (LWP 1528):
#0 0x400cdc70 in _vorbis_block_ripcord () from /usr/lib/libvorbisidec.so.1
#1 0x400cdce0 in vorbis_block_clear () from /usr/lib/libvorbisidec.so.1
#2 0x400bf678 in ov_clear () from /usr/lib/libvorbisfile.so.3
#3 0x400d2e3c in ?? () from /usr/lib/libvorbisidec.so.1
#4 0x400d2e3c in ?? () from /usr/lib/libvorbisidec.so.1
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

(gdb)

Thanks for helping, I really appreciate i.t
 
I would try narrowing down the problem a bit: convert the .OGG file to a .WAV file (oggdec?) and then try loading the WAV file instead and see what happens.

EDIT:
found a bug here in sound.cpp line 60:
Code:
sprintf(tmpMsg,"Error, could not load %s as a Music file.");

You forgot to add the filename string variable to the end there. It's also missing in the function after this one for sound effects.

Also:
Code:
if(name!=null){
   tSfx->name=new char[strlen(name)+1];
   strcpy(tSfx->name,name);
}else{
   tSfx = null;   // DANGER - memory leak
}

I would think you would want this instead but I am not really willing to delve into all the code to see how it all works, just guessing this is what you meant:
Code:
if(name){  // Note: much faster and cleaner just to type this to check for non-NULLness
   tSfx->name=new char[strlen(name)+1];
   strcpy(tSfx->name,name);
}else{
   delete tSfx;
   tSfx = null;
   return false;  // if you don't have this here, you are going to have big troubles a few lines later!
}
 
I just tested it loading a wav file instead, and that works, even tough it's slows the gameplay down alot and the playback is way too fast.
So it seems as if it's related to the ogg file.
I tried to play it back (the ogg file that is) in mplayer and that worked just fine..

Senor Quack:
Thanks for pointing out those bugs and the speed up :)
The second one is supposed to set tSfx->name to null, rather than the whole struct.
 
AFAIK, Clonekeen uses OGG playing and that works. Not sure what Pickle used to play the files, but it might be normal SDL_Mixer.
 
Dimacus said:
I just tested it loading a wav file instead, and that works, even tough it's slows the gameplay down alot and the playback is way too fast.
So it seems as if it's related to the ogg file.
I tried to play it back (the ogg file that is) in mplayer and that worked just fine..

Senor Quack:
Thanks for pointing out those bugs and the speed up :)
The second one is supposed to set tSfx->name to null, rather than the whole struct.

Sure thing man.. Oh and that isn't a speedup that is just to save you some typing in the future if ya like (it will compile to the exact same instructions).

As for the main problem you have: Try re-encoding the file (just for an experiment) using oggenc using just the standard settings and see if it still shits the bed. I have seen OGG files from ages past do strange things when played on the ARM using Mix_SDL but after I decoded it to a WAV file and re-encoded it as an experiment it played fine. This, despite the fact that the OGG file would play in other music players. This was when I was porting rRootage to the GP2X and Wiz handhelds (ARM CPUs like Pandora). One of the three music files did this and the other two did not and it was definitely because of corruption. I ended up just leaving that one OGG music file as a decoded .WAV file instead and left it like that and noticed absolutely no speed difference between playing it versus the OGG .

Now, for this reason, it amazes me that you are experiencing slowdown when playing that file. It's not like you are loading it like I did, like a music file. You are loading it as a sound effect which, I would have to guess, is being loaded in entirety into RAM, not streamed off the SD. Also, I am confused why you aren't using Mix_LoadMUS to load your music and using Mix_LoadWAV to load the sound files. I guess it would work both ways, and your way gives more flexibility than Mix_SDL offers when using its music playback features.
 
Last edited by a moderator:
I tried reencoding the file (using audacity) to a wave then to a new ogg file, but it didn't help.
It seems the wave file i used for testing first was strange or something (just a random wave file i had laying around),
because this much bigger wave file i got from decoding the ogg file dosn't do anything to speed at all, and it plays back at the right speed, strange that.

And my choice of using LoadWAV instead of LoadMUS is because of flexibility, i can't remember the exact reasons since i made that choice a long time ago tough.
 
I was looking at SDL Mixers documentation when i found out that they had added a new init function called Mix_Init. (http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer_9.html#SEC9)
Calling mix_init isn't required, but I thought why not.
I't didn't solve my problem, but it changed it, it no longer segfaults, now it just sits in a loop somewhere eating 99% cpu (ctrl-c in gdb tells me it's at the same place the segfault happens).
It Might be that this new flavor of the problem is more related to me changeing the sampling freq to 22050 both on the file i try to load and in the Mix_openaudio function.
 
EvilDragon said:
AFAIK, Clonekeen uses OGG playing and that works. Not sure what Pickle used to play the files, but it might be normal SDL_Mixer.

Hmm, perhaps I'm looking at the wrong sources (from the clonekeen sourceforge page) but he dosn't link to any other libs than SDL and stdc++ in the make file.
Looking at the sources also gives the same feeling of just using SDL's audio functions.
 
Last edited by a moderator:
Ah, Problem solved.
I was a "he didn't know what he was doing" misstake, I was linking both to vorbisidev (tremor) and to the normal vorbis lib, i guess they didn't like that :p
I removed the normal libs (vorbis, vorbisfile and ogg) and there it was, ogg music in my game :D (im guessing tremor might be slightly faster?)

Im a bit supprised that nothing complained that I liked to both of them, but I guess SDL_mixer is built with both i mind, just not at the same time ;)

Thanks for the help!
 
C and C++ allow you to multiply define symbols _From a library_ -- ie: it is sometimes important to override lib functions with another function, so they permit it; multiple symbol errors occur for multiple local definitions, though.

When you start to see stuff like 'libthread is behaving strangely', you usualyl have to invoke an old old rule -- if you start to doubt the compiler, or multiple 'proven' libraries.. the problem is almost certainly your own instead :) (Back in the 80s, you often could doubt the compilers output but in the 90s+ the compilers and included libs tend to be pretty solid :)

jeff
 
Back
Top