The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
SDL_mixer: automatic playlist advance
Christoph Nelles
Guest

Hi,

has anybody a neat idea how to start another music track after the the
current track expired?
The simplest way would be a small callback which simply calls
Mix_PlayMusic() with the next Mix_Music pointer, but that's not allowed.
Setting a boolean variable like trackfinished is easy too, but needs
constantly polling when to switch to the next song and may lead to
unnecessary delays. Creating a short lived thread each time isn't too
complicate either, but probably very wasteful.

Any other ideas or comments?

Thanks in advance

--
Christoph Nelles

E-Mail :
Jabber : ICQ : 78819723

PGP-Key : ID 0x424FB55B on subkeys.pgp.net
or http://evilazrael.net/pgp.txt
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
SDL_mixer: automatic playlist advance
David Olofson
Guest

On Monday 30 November 2009, at 16.44.05, Christoph Nelles
wrote:
Quote:
Hi,

has anybody a neat idea how to start another music track after the the
current track expired?
The simplest way would be a small callback which simply calls
Mix_PlayMusic() with the next Mix_Music pointer, but that's not allowed.

I suppose this is because Mix_PlayMusic() needs to do some heavy
initialization, or at least some memory allocation and other "realtime unsafe"
stuff... Doing that in the contexts of the audio callback would obviously be a
bad idea.


Quote:
Setting a boolean variable like trackfinished is easy too, but needs
constantly polling when to switch to the next song and may lead to
unnecessary delays.

I don't know what you're doing here, but games tend to have a main loop
spinning at some 30+ fps. Polling from there wouldn't cause any significant in
this context.

If you need it tighter than that, I don't think you can get away without
hacking SDL_mixer internals, or perhaps using SDL_sound or something instead.

SDL_sound + custom mixing code would do the trick, and you'd even be able to
cross-fade instead of just playing the songs back-to-back. Initialize songs
some time (seconds) before they're supposed to start playing, and you'll be
ready to start streaming exactly when you need to.


Quote:
Creating a short lived thread each time isn't too complicate either, but
probably very wasteful.

Creating and destroying threads should definitely be avoided in the audio
callback, especially if you're targeting various general purpose operating
systems. It may not even be possible, if the audio callback is running in some
sort of interrupt context, though you probably won't see that often these
days. (Win16 and Mac OS prior to X did that.)

If going for threads, I'd set up a permanent background thread for such
things, and have that block on a suitable locking mechanism, waiting for
commands from other contexts. To avoid timing issues on less realtime friendly
platforms, you may use lock-free mechanisms and have that thread poll at a
sensible rate.


--
//David Olofson - Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://olofson.net http://kobodeluxe.com http://audiality.org |
| http://eel.olofson.net http://zeespace.net http://reologica.se |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
SDL_mixer: automatic playlist advance
Christoph Nelles
Guest

On Mon, 30 Nov 2009 17:10:19 +0100, David Olofson
wrote:
Quote:
On Monday 30 November 2009, at 16.44.05, Christoph Nelles
wrote:
Quote:
Hi,
I suppose this is because Mix_PlayMusic() needs to do some heavy
initialization, or at least some memory allocation and other "realtime
unsafe"
stuff... Doing that in the contexts of the audio callback would
obviously
Quote:
be a
bad idea.

I went through the code, it uses SDL_LockAudio which seems to be like a
non-recursive mutex.

Quote:
I don't know what you're doing here, but games tend to have a main loop
spinning at some 30+ fps. Polling from there wouldn't cause any
significant in
this context.

If you're lucky enough to get 30+ fps. The timing is not the real problem,
but i am relunctant to resort to polling when there's a callback.

Quote:
Quote:
Creating a short lived thread each time isn't too complicate either,
but
Quote:
Quote:
probably very wasteful.

Creating and destroying threads should definitely be avoided in the
audio
Quote:
callback, especially if you're targeting various general purpose
operating
Quote:
systems. It may not even be possible, if the audio callback is running
in
Quote:
some
sort of interrupt context, though you probably won't see that often
these
Quote:
days. (Win16 and Mac OS prior to X did that.)

I think that's not a problem anymore. There were threads in those good old
days?

Quote:
If going for threads, I'd set up a permanent background thread for such
things, and have that block on a suitable locking mechanism, waiting for

Quote:
commands from other contexts. To avoid timing issues on less realtime

So let a thread wait for a signal would be better?

Quote:
friendly
platforms, you may use lock-free mechanisms and have that thread poll at
a
Quote:
sensible rate.

Then i could poll again in the main thread. Which is really the simplest
way. But there must be some more fancy way.

--
Christoph Nelles

E-Mail :
Jabber : ICQ : 78819723

PGP-Key : ID 0x424FB55B on subkeys.pgp.net
or http://evilazrael.net/pgp.txt
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
SDL_mixer: automatic playlist advance
David Olofson
Guest

On Monday 30 November 2009, at 17.35.43, Christoph Nelles
wrote:
[...]
Quote:
Quote:
I suppose this is because Mix_PlayMusic() needs to do some heavy
initialization, or at least some memory allocation and other "realtime
unsafe"
stuff... Doing that in the contexts of the audio callback would obviously
be a bad idea.

I went through the code, it uses SDL_LockAudio which seems to be like a
non-recursive mutex.

That would probably generate a loooooong drop-out...! :-D


Quote:
Quote:
I don't know what you're doing here, but games tend to have a main loop
spinning at some 30+ fps. Polling from there wouldn't cause any
significant in
this context.

If you're lucky enough to get 30+ fps. The timing is not the real problem,
but i am relunctant to resort to polling when there's a callback.

Of course, but then it's either doing the job right then and there, or relying
on some proper blocking mechanism.


[...]
Quote:
Quote:
It may not even be possible, if the audio callback is running in some
sort of interrupt context, though you probably won't see that often these
days. (Win16 and Mac OS prior to X did that.)

I think that's not a problem anymore. There were threads in those good old
days?

Threads and various other strange contexts have coexisted on many Windows
versions at least, and I suppose they still do, although in an "emulated"
form, in the Win16 compatibility layer... And of course, there are Kernel
Streams in later NT based systems. (2000 and later, IIRC.)

If you want to include less common systems, there are various industrial
realtime platforms (Linux/RTAI, for example) that "piggy-back" on a general
purpose OS, where realtime threads and normal treads play by rather different
rules.

That said, I *think* the only time you'll see any of this with SDL is if
you're running on a pre-OSX Mac. Don't know about handheld devices and game
consoles, though...


Quote:
Quote:
If going for threads, I'd set up a permanent background thread for such
things, and have that block on a suitable locking mechanism, waiting for
commands from other contexts. To avoid timing issues on less realtime

So let a thread wait for a signal would be better?

Yes. At least, that's designed to be fast and low overhead, whereas creating
and destroying threads is not.


Quote:
Quote:
friendly
platforms, you may use lock-free mechanisms and have that thread poll at
a sensible rate.

Then i could poll again in the main thread. Which is really the simplest
way.

Yes, exactly.

Or, since you're probably checking for SDL events somewhere anyway, possibly
even blocking on them, how about sending an SDL_USEREVENT to your mainloop?


That said, a worker thread is motivated in some situations, such as:
* You have a main loop that blocks, waiting for input events.
* You're writing a library, and don't want to force applications
to call some do_some_background_work() on a regular basis.
* You need to do some long term heavy work in the background,
while the game/UI loop keeps running.

I suppose none of those motivations really apply here, though.


Quote:
But there must be some more fancy way.

Well, the cleanest, most accurate and most efficient way would probably be to
have playlist support in SDL_mixer, but I suspect that might be non-trivial to
implement. Initializing a new song probably isn't a "realtime safe" operation
with some music formats (and this is assuming all data is already in RAM!), so
SDL_mixer would have to send that off to a background thread.

Basically, there's no way you can avoid that issue without risking audio drop-
outs when switching songs. It's just a matter of where and how it's
implemented.


--
//David Olofson - Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://olofson.net http://kobodeluxe.com http://audiality.org |
| http://eel.olofson.net http://zeespace.net http://reologica.se |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Jesse A.


Joined: 19 Sep 2009
Posts: 43
I've implemented seamless track queueing with SDL_mixer by doing my own streaming and mixing via the 'music' mixer hook. The downside is that you have to do your own streaming, but it does make for perfectly smooth transitions.

Whether this is worth the trouble or not probably depends on the situation. I'm using track queueing to assemble arrangements from multiple sections; the music is rhythmic in nature, so seamless transitions are required. If you're just playing tracks in sequence though, and/or the music is not strongly rhythmic, you may be able to get away with polling or using the 'music finished' callback instead.
SDL_mixer: automatic playlist advance
AKHRES Nader
Guest

Sounds interesting Smile
Have you done any wrapping API to this, if we want to use it without
knowing much about streaming?

Jesse A. a écrit :
Quote:
I've implemented seamless track queueing with SDL_mixer by doing my
own streaming and mixing via the 'music' mixer hook. The downside is
that you have to do your own streaming, but it does make for perfectly
smooth transitions.

Whether this is worth the trouble or not probably depends on the
situation. I'm using track queueing to assemble arrangements from
multiple sections; the music is rhythmic in nature, so seamless
transitions are required. If you're just playing tracks in sequence
though, and/or the music is not strongly rhythmic, you may be able to
get away with polling or using the 'music finished' callback instead.
------------------------------------------------------------------------

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: SDL_mixer: automatic playlist advance
Jesse A.


Joined: 19 Sep 2009
Posts: 43
AKHRES Nader wrote:
Have you done any wrapping API to this

Unfortunately not - the music system is pretty tightly integrated with my overall game framework.

I do think that a track queueing system for SDL_mixer would be a great addition, but as mentioned previously, integrating this feature into the existing API would probably require a fair amount of work.
SDL_mixer: automatic playlist advance
Christoph Nelles
Guest

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

David Olofson schrieb:
Quote:
On Monday 30 November 2009, at 17.35.43, Christoph Nelles
wrote:
Or, since you're probably checking for SDL events somewhere anyway, possibly
even blocking on them, how about sending an SDL_USEREVENT to your mainloop?

Oh, i will do this nevertheless to give the user/programmer the
possibility to intervene.

Quote:


That said, a worker thread is motivated in some situations, such as:
* You have a main loop that blocks, waiting for input events.
* You're writing a library, and don't want to force applications
to call some do_some_background_work() on a regular basis.

That's exactly my case *g* Perhaps this a good idea when there i am
implementing the other parts.

Quote:

I suppose none of those motivations really apply here, though.


Quote:
But there must be some more fancy way.

Well, the cleanest, most accurate and most efficient way would probably be to
have playlist support in SDL_mixer, but I suspect that might be non-trivial to
implement. Initializing a new song probably isn't a "realtime safe" operation
with some music formats (and this is assuming all data is already in RAM!), so
SDL_mixer would have to send that off to a background thread.

I haven't looked to close into the code, but i assume (unproofed) that
this could be an atomic operation if you provide another Mix_Music
yourself (i hope so)

Quote:
Basically, there's no way you can avoid that issue without risking audio drop-
outs when switching songs. It's just a matter of where and how it's
implemented.

Yes, probably an own mixer function like Jesse proposed is the best way,
but that's too low level for me.

Thanks for the enlightenment in the thread stuff.

- --
Christoph Nelles

E-Mail :
Jabber : ICQ : 78819723

PGP-Key : ID 0x424FB55B on subkeys.pgp.net
or http://evilazrael.net/pgp.txt

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAksW1fIACgkQBcR1PkJPtVuYMACeLrb/HkobnCAyyoLlxWaVbt7J
6MIAn0mNpMpBDxva1y0mTrB1Z8DHZy+G
=PDz+
-----END PGP SIGNATURE-----
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org