Music via RWops => plays for a few seconds then segfault

Hi guys,

I’m loading music using RWops so as to benefit from the easy asset loading
on Android. Here’s my code (ASSERT macros basically just check that an
expression is true):

  • SDL_RWops* binary_file;
    binary_file = SDL_RWFromFile(source_file, “rb”); // read binary
    ASSERT(binary_file, “Opening music file using SDL_RWops”);

// Attempt to read the file contents as music
Mix_Music* music;
ASSERT_MIX(music = Mix_LoadMUS_RW(binary_file),
“Extracting music from SDL_RWops structure”);

// Attempt to play the music
ASSERT_MIX(Mix_PlayMusic(music, -1) != -1, “Setting music to loop”);*

This works: all the assertions check out and the music plays… for maybe
10-15 seconds. Then the app crashes.

I feel I’m close to a breakthrough here -I haven’t managed to get sound
working on android via SDL till now- but it’s so close yet so far. Does
anybody know why I might be having issues here? The same code runs fine on
Linux (ie. doesn’t crash even after a full loop of the music).

I’m initialising SDL_Mixer as follows (that’s frequency and chunk size btw):

Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 1024
);

Maybe it’s running out of buffer or something? Logcat sometimes show up a
bunch of warning entries just before crashing, but there are no errors:

W/dalvikvm(22087): JNI WARNING: DeleteLocalRef(0x4a32cde8) failed to find
entry (valid=1)

Any ideas?

Thanks,

William

I had similar problems on Windows XP not too long ago, I never found the
source of the crash, but I did find a workaround by forcing a different
audio driver, and switching to MPG123.

You might want to print out some more diagnostics to track down the source.
I used something like the following:

cout << “Available Audio Drivers:\n”;

for(int i = 0; i < SDL_GetNumAudioDrivers(); ++i)

cout << '\t' << i << ") " << SDL_GetAudioDriver(i) << endl;

cout << “Available Video Drivers:\n”;

for(int i = 0; i < SDL_GetNumVideoDrivers(); ++i)

cout << '\t' << i << ") " << SDL_GetVideoDriver(i) << endl;

cout << "Using Audio Driver: " << SDL_GetCurrentAudioDriver() << endl;

cout << "Using Video Driver: " << SDL_GetCurrentVideoDriver() << endl;

For the record I had quite a few problems with SDL_Mixer playing music and
ended up streaming the music myself and feeding it to SDL_mixer in the
postprocess callback. It now works fine with no crashes and good
performance, but I stick to the FX functions and stay clear of streaming
music.

Good luck, I hope someone else gives you a better answer!

Jeremy Jurksztowicz, aka eclectocratOn Fri, Mar 16, 2012 at 9:07 PM, William Dyce wrote:

Hi guys,

I’m loading music using RWops so as to benefit from the easy asset loading
on Android. Here’s my code (ASSERT macros basically just check that an
expression is true):

  • SDL_RWops* binary_file;
    binary_file = SDL_RWFromFile(source_file, “rb”); // read binary
    ASSERT(binary_file, “Opening music file using SDL_RWops”);

// Attempt to read the file contents as music
Mix_Music* music;
ASSERT_MIX(music = Mix_LoadMUS_RW(binary_file),
“Extracting music from SDL_RWops structure”);

// Attempt to play the music
ASSERT_MIX(Mix_PlayMusic(music, -1) != -1, “Setting music to loop”);*

This works: all the assertions check out and the music plays… for maybe
10-15 seconds. Then the app crashes.

I feel I’m close to a breakthrough here -I haven’t managed to get sound
working on android via SDL till now- but it’s so close yet so far. Does
anybody know why I might be having issues here? The same code runs fine on
Linux (ie. doesn’t crash even after a full loop of the music).

I’m initialising SDL_Mixer as follows (that’s frequency and chunk size
btw):

*Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, **1024
*);

Maybe it’s running out of buffer or something? Logcat sometimes show up a
bunch of warning entries just before crashing, but there are no errors:

W/dalvikvm(22087): JNI WARNING: DeleteLocalRef(0x4a32cde8) failed to
find entry (valid=1)

Any ideas?

Thanks,

William


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

On Linux:

Code:
Available Audio Drivers:
0) pulseaudio
1) alsa
2) dsp
3) esd
4) nas
5) disk
6) dummy
Available Video Drivers:
0) x11
1) dummy

On Android:

Code:
03-17 13:28:17.942: I/APP(22646): -----Audio driver: dummy
03-17 13:28:17.942: I/APP(22646): -----Audio driver: android
03-17 13:28:17.942: I/APP(22646): Startup: Available Video Drivers
03-17 13:28:17.942: I/APP(22646): -----Video driver: Android

ended up streaming the music myself and feeding it to SDL_mixer in the postprocess callback

I’m not sure how to do this I’m afraid :? I wonder if it would work better to use OpenAL directly - it certainly worked better using OpenGL than an SDL Renderer…

Jonas Thiem wrote:

To my knowledge, streaming happens in a separate thread. SDL_RWops on Android are not thread-safe, so this might be the reason for your issues (access from a non-mainthread breaks things).

Interesting… In this case maybe I could open the file using RWops on startup, dump it to the sdcard (somewhere like /data/my-game/) and then stream it back using the standard Mixer operations rather than RW. Does that sound like it would work? I’m none too experienced with SDL_RWops: I’ve never used them for writing, though I have managed to read text (pass XML to TinyXML) and now music. Guess I should check the documentation…

I’m now testing sound in Linux: I managed to compile this example here http://content.gpwiki.org/index.php/C:Playing_a_WAV_Sound_File_With_SDL_mixer integrating the code with mine seems to come up with an “unrecognized file type (not WAVE)” error, despite it being the same file I’m trying to read. I can only think that there’s some disparity between SDL 1.2 and SDL 2.0 which is causing the issue… I’ll keep working away at it [Wink] [/quote]

In the Corona SDK for Android, we are currently copying out the audio
files to an external area like you suggest because Android 2.2 sucks
and doesn’t have a good way of reading directly from in an APK on the
NDK side. (2.3 addresses this but lots of people can’t upgrade.)

I’m going to plug my ALmixer library. ALmixer provides a similar
interface to SDL_mixer but not identical because it removes the
distinction of music vs. sound channels. Instead, the difference is in
how you load the file and you are allowed multiple streaming channels.
It also uses OpenAL instead of SDL. However, SDL_sound is used as the
decoder backend and has RWops interfaces.

We haven’t hit the RWops threading problems you mentioned probably for
multiple reasons. One, we externalize all the assets (which sucks),
two the audio backend works completely differently, three we are
pretty much not touching the SDL/Android code paths except via
SDL_sound for sound decoding.

http://playcontrol.net/opensource/ALmixer/

-EricOn 3/17/12, wilbefast wrote:

Jonas Thiem wrote:

To my knowledge, streaming happens in a separate thread. SDL_RWops on
Android are not thread-safe, so this might be the reason for your issues
(access from a non-mainthread breaks things).

Interesting… In this case maybe I could open the file using RWops on
startup, dump it to the sdcard (somewhere like /data/my-game/) and then
stream it back using the standard Mixer operations rather than RW. Does that
sound like it would work? I’m none too experienced with SDL_RWops: I’ve
never used them for writing, though I have managed to read text (pass XML to
TinyXML) and now music. Guess I should check the documentation…

I’m now testing sound in Linux: I managed to compile this example here
http://content.gpwiki.org/index.php/C:Playing_a_WAV_Sound_File_With_SDL_mixer
integrating the code with mine seems to come up with an “unrecognized file
type (not WAVE)” error, despite it being the same file I’m trying to read. I
can only think that there’s some disparity between SDL 1.2 and SDL 2.0 which
is causing the issue… I’ll keep working away at it [Wink] [/quote]


Beginning iPhone Games Development
http://playcontrol.net/iphonegamebook/

Eric Wing wrote:

In the Corona SDK for Android, we are currently copying out the audio
files to an external area like you suggest because Android 2.2 sucks
and doesn’t have a good way of reading directly from in an APK on the
NDK side. (2.3 addresses this but lots of people can’t upgrade.)

I’m going to plug my ALmixer library. ALmixer provides a similar
interface to SDL_mixer but not identical because it removes the
distinction of music vs. sound channels. Instead, the difference is in
how you load the file and you are allowed multiple streaming channels.
It also uses OpenAL instead of SDL. However, SDL_sound is used as the
decoder backend and has RWops interfaces.

We haven’t hit the RWops threading problems you mentioned probably for
multiple reasons. One, we externalize all the assets (which sucks),
two the audio backend works completely differently, three we are
pretty much not touching the SDL/Android code paths except via
SDL_sound for sound decoding.

http://playcontrol.net/opensource/ALmixer/

Okay, good to have multiple options, especially since sound doesn’t seem to be working either (on Linux Mixer seems not to recognise my wave files as wave files).
It would be useful to have some example code though (start up, load, play, stop, shut down), to get me going. Is there anything out there on the net? A quick search hasn’t turned up anything. I know I should probably just rtfm, but from experience I’ve found grabbing something that works and fiddling with it to be far more effective than writing something from scratch and then trying to figure out why it doesn’t work.

I admit, tutorials are lacking. There are two tiny example programs
that come with the source code in the EXAMPLES directory.

playsound.c
playstream.c

Alternatively, you can look up the Corona SDK documentation under the
"audio.*" APIs. The API design is almost a passthrough to the ALmixer
API (with a couple of Lua-isms added for convenience in Corona).

Corona SDK has a free unlimited trial, so you can actually play with
it in Corona if you want to see how the APIs work. (And since we
dynamically link the libraries, you can actually grab the libraries
and use them to get around the fact that I haven’t put out a formal
binary distribution yet either.)

-EricOn 3/17/12, wilbefast wrote:

Eric Wing wrote:

In the Corona SDK for Android, we are currently copying out the audio
files to an external area like you suggest because Android 2.2 sucks
and doesn’t have a good way of reading directly from in an APK on the
NDK side. (2.3 addresses this but lots of people can’t upgrade.)

I’m going to plug my ALmixer library. ALmixer provides a similar
interface to SDL_mixer but not identical because it removes the
distinction of music vs. sound channels. Instead, the difference is in
how you load the file and you are allowed multiple streaming channels.
It also uses OpenAL instead of SDL. However, SDL_sound is used as the
decoder backend and has RWops interfaces.

We haven’t hit the RWops threading problems you mentioned probably for
multiple reasons. One, we externalize all the assets (which sucks),
two the audio backend works completely differently, three we are
pretty much not touching the SDL/Android code paths except via
SDL_sound for sound decoding.

http://playcontrol.net/opensource/ALmixer/

Okay, good to have multiple options, especially since sound doesn’t seem to
be working either (on Linux Mixer seems not to recognise my wave files as
wave files).
It would be useful to have some example code though (start up, load, play,
stop, shut down), to get me going. Is there anything out there on the net? A
quick search hasn’t turned up anything. I know I should probably just rtfm,
but from experience I’ve found grabbing something that works and fiddling
with it to be far more effective than writing something from scratch and
then trying to figure out why it doesn’t work.


Beginning iPhone Games Development
http://playcontrol.net/iphonegamebook/