SDL_mixer resource leak fixes -> RWops revamp

Hi all,

I’ve been working to clear up some of the bugs in SDL_mixer:

http://bugzilla.libsdl.org/buglist.cgi?product=SDL_mixer&component=misc&resolution=---

A few of the bugs involving resource leaks (1003, 1021 & 1168) all
seem to stem from the same cause: confusion over the responsibility
for cleaning up after SDL_RWops. Some functions assume the SDL_RWops
should be SDL_RWclosed right away. Some systems store the SDL_RWops
object in another struct for later usage, and of those, some close (or
incorrectly free) the object, and others do nothing. Some functions
provide a way for callers to express their intent (freesrc parameters,
and the like), others do not.

In an effort to to clean this up, I’m trying to standardize and refine
RWops usage. Below is a birds-eye view of my proposal. Any feedback
would be appreciated.---------------------------

Attachments:

SDL.diff - shows changes to the base SDL_RWops functionality
SDL_mixer.diff - shows fixes for bugs 1021 & 1168 following the guidelines below

I’ll be following up with an example of bringing SDL_image into
compliance per Sam’s request


Public API functions that abstract the stream as a whole
(Mix_LoadMUS_RW, IMG_LoadGIF_RW) shall provide an "autoclose"
parameter (not necessarily with that name) indicating that SDL should
take responsibility for closing the RWops. See below for how this
parameter is used

Functions that operate on parts of the stream
(SDL_RWread/write/seek/etc) shall NOT provide that parameter

Internal functions are free to ignore autoclose as appropriate. Just
be sure that it’s observed somewhere up the call stack.

If an autoclose function exits with an error, seek to the beginning
without making any changes to the RWops (NOTE: This overrides any of
the rules below)

The rules for handling the autoclose parameter depend on whether the
function uses the RWops transiently or persistently. Library functions
shall document which is the case.

Functions that use the RWops transiently (e.g. MOD_new_RW):

* When autoclose is true, call SDL_RWclose on the RWops before

exiting the function.
* When autoclose is false, seek to the end and leave the RWops open

Functions that use the RWops persistently (e.g. WAVStream_LoadSong_RW):

* When autoclose is true, set the RWops.autoclose field.
* If autoclose is false, no extra action is necessary on the

Library’s part. However, client code must not close the RWops until
the new container (the WAVStream in the case of WAVStream_LoadSong_RW)
is freed

NOTE: In both cases, it is an error for client code to pass an RWops
that is already flagged for autoclose.


Another shortcoming of the RWops system is that it’s not easily
extensible by 3rd-party libraries. The different types (windows file,
stdio file, pre-allocated memory) are baked into the SDL_RWops struct.
In order to make it easier for library writers to take advantage of
this useful abstraction, I’ve generalized the design a bit.

The base data structure now looks like this:

typedef struct SDL_RWops
{
    long (* seek)(<parameters>);
    size_t (* read)(<parameters>);
    size_t (* write)(<parameters>);
    int (* close)(<parameters>);
    SDL_bool autoclose;
    void *extra;
} SDL_RWops;

The “extra” field replaces the old “hidden” union, whose typedefs are
now internal to SDL_rwops.c. The basic process for creating a new
RWops type looks like this:

typedef struct DoughnutsExtra
{
    FILLING filling;
    FROSTING frosting;
    int count;
} DoughnutsExtra;

/* doughnut_seek/read/write go here */

static int SDLCALL doughnut_close(SDL_RWops *context)
{
    if (context) {
        /* Release any resources stored *inside* the DoughnutsExtra struct
         * where appropriate (this example doesn't use any)
         */

        SDL_FreeRW(context);
    }
    return 0;
}

SDL_RWops *SDL_RWFromDoughnuts(Dougnuts doughnuts)
{
    SDL_RWops *rwops = NULL;
    Doughnuts *extra = NULL;

    rwops = SDL_AllocRW(sizeof(DoughnutsExtra));
    if (rwops != NULL) {
        rwops->seek = doughnut_seek;
        rwops->read = doughnut_read;
        rwops->write = doughnut_write;
        rwops->close = doughnut_close;

        extra = (DoughnutsExtra *)rwops->extra;
        extra->filling = FILLING_LEMON;
        extra->frosting = FROSTING_GLAZE;
        extra->count = BAKERS_DOZEN;
     }
    return (rwops);
}

If there aren’t any major objections, I’ll keep on this course and
make sure all instances of RWops usage are brought up to date.


Matthew Orlando
http://cogwheel.info
-------------- next part --------------
A non-text attachment was scrubbed…
Name: SDL.diff
Type: text/x-patch
Size: 19440 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20110412/7bd665b9/attachment.bin
-------------- next part --------------
A non-text attachment was scrubbed…
Name: SDL_mixer.diff
Type: text/x-patch
Size: 4345 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20110412/7bd665b9/attachment-0001.bin

Actually, I’m not really happy with my seek behavior for errors and false
autoclose parameters. It was inspired by some usage I had seen in the
library, but it’s not as consistently applicable as I thought. Perhaps the
stream should be left as-is upon return in all cases?

I’ll include that change with my SDL_image retrofit to see what it looks
like.On Tue, Apr 12, 2011 at 1:43 PM, Matthew Orlando <@Matthew_Orlando>wrote:

If an autoclose function exits with an error, seek to the beginning
without making any changes to the RWops (NOTE: This overrides any of
the rules below)

The rules for handling the autoclose parameter depend on whether the
function uses the RWops transiently or persistently. Library functions
shall document which is the case.

Functions that use the RWops transiently (e.g. MOD_new_RW):

  • When autoclose is true, call SDL_RWclose on the RWops before
    exiting the function.
  • When autoclose is false, seek to the end and leave the RWops open


Matthew Orlando
http://cogwheel.info

I realized it’s better to leave it up to libraries to determine the
stream position on exit. SDL_image loaders would seek the RWops back
to the point they were when called if there was an error, so I left
them that way (and fixed ones that didn’t).

Seeking forward to the end for false autoclose didn’t really make
sense when I gave it a third thought. As such, I removed the
SDL_RWautoclose macro.

Diff of SDL_image is attached. Besides bringing some miscellaneous
functions into consistency and cleaning up a bit of redundancy, the
only major change is moving the freesrc check from the non-specific
IMG_LoadTyped_RW to the individual IMG_LoadXXX_RW functions.On Tue, Apr 12, 2011 at 2:46 PM, Matthew Orlando <@Matthew_Orlando> wrote:

Actually, I’m not really happy with my seek behavior for errors and false autoclose parameters. It was inspired by some usage I had seen in the library, but it’s not as consistently applicable as I thought. Perhaps the stream should be left as-is upon return in all cases?
I’ll include that change with my SDL_image retrofit to see what it looks like.

On Tue, Apr 12, 2011 at 1:43 PM, Matthew Orlando <@Matthew_Orlando> wrote:

If an autoclose function exits with an error, seek to the beginning
without making any changes to the RWops (NOTE: This overrides any of
the rules below)

The rules for handling the autoclose parameter depend on whether the
function uses the RWops transiently or persistently. Library functions
shall document which is the case.

Functions that use the RWops transiently (e.g. MOD_new_RW):

? ?* When autoclose is true, call SDL_RWclose on the RWops before
exiting the function.
? ?* When autoclose is false, seek to the end and leave the RWops open


Matthew Orlando
http://cogwheel.info
-------------- next part --------------
A non-text attachment was scrubbed…
Name: SDL_image.diff
Type: text/x-patch
Size: 21781 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20110413/dec17b62/attachment.bin

Your proposed change to the structure itself is most appropriate. This would allow an application to, for example, treat an FTP response as a readable file.

As far as auto-close… it’s a tricky subject. Some would say that it should always be in the hands of the developer using the library, but then there’s the fact that this can get quite complicated for him (because of those recurring use functions you mentioned). I recommend using reference counting and always requiring the developer to release it once manually, and after this SDL can take care of it. Essentially the programmer would be saying “I don’t need to reference this anymore” and SDL will act as a very specific-purpose garbage collector. :P------------------------
EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

As I was working on this, I actually thought to myself: “you know, this is
only a couple abstractions away from a reference-counting garbage
collector.” :slight_smile: I was already well into the changes I’ve posted so far,
though, and I wanted to get some feedback before I continued.

I definitely like the idea of requiring the client to close the RWops. It
would eliminate the need for the autoclose parameters entirely while still
enabling safe persistence.

I can’t imagine it being a good idea to provide an RWops to two different
functions that store it persistently (this could just be a failure of my
imagination), but I suppose that should be left up to the library writers
and clients to decide.

Speaking of which, would it be a good idea for the functions that persist
RWops (e.g. the wavestream loader) to reject any that have a reference count

1?

Cheers,

Matthew “Cogwheel” OrlandoOn Wed, Apr 13, 2011 at 10:05 PM, Nathaniel J Fries wrote:

Your proposed change to the structure itself is most appropriate. This
would allow an application to, for example, treat an FTP response as a
readable file.

As far as auto-close… it’s a tricky subject. Some would say that it
should always be in the hands of the developer using the library, but then
there’s the fact that this can get quite complicated for him (because of
those recurring use functions you mentioned). I recommend using reference
counting and always requiring the developer to release it once manually, and
after this SDL can take care of it. Essentially the programmer would be
saying “I don’t need to reference this anymore” and SDL will act as a very
specific-purpose garbage collector. [image: Razz]


EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Matthew Orlando wrote:

As I was working on this, I actually thought to myself: “you know, this is only a couple abstractions away from a reference-counting garbage collector.” :)??I was already well into the changes I’ve posted so far, though, and I wanted to get some feedback before I continued.

I figured you would wind up coming to that conclusion on your own.

I definitely like the idea of requiring the client to close the RWops. It would eliminate the need for the autoclose parameters entirely while still enabling safe persistence.

That’s the purpose. That and forcing the user to take responsibility for his memory allocations (which is important – abstracting it away causes people to forget that the need exists elsewhere).

I can’t imagine it being a good idea to provide an RWops to two different functions that store it persistently (this could just be a failure of my imagination), but I suppose that should be left up to the library writers and clients to decide.

As long as the functions don’t assume anything about the seeking position (repeated function calls should have an offset argument or something to seek to immediately) and the user doesn’t attempt to access the RWops across multiple threads (race condition in the best case, inconsistent read/write positions in the worst case), it should be fine.

Speaking of which,??would it be a good idea for the functions that persist RWops (e.g. the wavestream loader) to reject any that have a reference count > 1?

The flaw this this is that the user can free it, and then it’ll be 1… =/
we can add extra struct members to tell if the user has flagged it for freeing or not and go through a bunch of other implementation hell, but I really think that the above solution is the simplest way.------------------------
EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Speaking of which,? would it be a good idea for the functions that persist
RWops (e.g. the wavestream loader) to reject any that have a reference count

1?

The flaw this this is that the user can free it, and then it’ll be 1… =/
we can add extra struct members to tell if the user has flagged it for
freeing or not and go through a bunch of other implementation hell, but I
really think that the above solution is the simplest way.

I just meant the initial function that stores the RWops. For example,
calling WAVStream_LoadSong_RW twice with the same RWops and then trying to
use each of the resulting WAVStreams is almost certainly in error.

The reference count might change once it has been stored, but this check
would be a simple safeguard for the SDL_mixer library to provide. (It’s just
a library feature rather than something fundamental to RWops usage.)On Thu, Apr 14, 2011 at 12:33 PM, Nathaniel J Fries wrote:

Matthew Orlando wrote:> On Thu, Apr 14, 2011 at 12:33 PM, Nathaniel J Fries <@Nathaniel_J_Fries (@Nathaniel_J_Fries)> wrote:

Speaking of which,???would it be a good idea for the functions that persist RWops (e.g. the wavestream loader) to reject any that have a reference count > 1?

The flaw this this is that the user can free it, and then it’ll be 1… =/
we can add extra struct members to tell if the user has flagged it for freeing or not and go through a bunch of other implementation hell, but I really think that the above solution is the simplest way.

I just meant the initial function that stores the RWops. For example, calling WAVStream_LoadSong_RW twice with the same RWops and then trying to use each of the resulting WAVStreams is almost certainly in error.

The reference count might change once it has been stored, but this check would be a simple safeguard for the SDL_mixer library to provide. (It’s just a library feature rather than something fundamental to RWops usage.)

What if they want a canon effect? Can a single Mix_Music* be played simultaneously on two channels?


EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Matthew Orlando wrote:> On Thu, Apr 14, 2011 at 12:33 PM, Nathaniel J Fries <@Nathaniel_J_Fries (@Nathaniel_J_Fries)> wrote:

Speaking of which,???would it be a good idea for the functions that persist RWops (e.g. the wavestream loader) to reject any that have a reference count > 1?

The flaw this this is that the user can free it, and then it’ll be 1… =/
we can add extra struct members to tell if the user has flagged it for freeing or not and go through a bunch of other implementation hell, but I really think that the above solution is the simplest way.

I just meant the initial function that stores the RWops. For example, calling WAVStream_LoadSong_RW twice with the same RWops and then trying to use each of the resulting WAVStreams is almost certainly in error.

The reference count might change once it has been stored, but this check would be a simple safeguard for the SDL_mixer library to provide. (It’s just a library feature rather than something fundamental to RWops usage.)

What if they want a canon effect? Can a single Mix_Music* be played simultaneously on two channels?


EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Nope. Music is played separately from the rest of the mixer channels
and only one is active at a time.

On top of that, wavestream reads from the stream as it plays unlike
some of the others that copy the music into a buffer. If you make two
separate wavestreams from the same RWops, they’ll mess each other up
with their seeking. Now, you could make two separate RWops from the
same underlying source and be OK, hence the proposed sanity check.On Thu, Apr 14, 2011 at 2:31 PM, Nathaniel J Fries wrote:

What if they want a canon effect? Can a single Mix_Music* be played simultaneously on two channels?


Matthew Orlando
http://cogwheel.info

Any way that could be fixed without rearchitecting the entirety of
SDL_Mixer? Treating music as something completely different than
normal sound is extremely limiting and just feels like a design flaw to me.>----- Original Message ----

From: Matthew Orlando
Subject: Re: [SDL] SDL_mixer resource leak fixes -> RWops revamp

On Thu, Apr 14, 2011 at 2:31 PM, Nathaniel J Fries wrote:

What if they want a canon effect? Can a single Mix_Music* be played
simultaneously on two channels?

Nope. Music is played separately from the rest of the mixer channels
and only one is active at a time.

On top of that, wavestream reads from the stream as it plays unlike
some of the others that copy the music into a buffer. If you make two
separate wavestreams from the same RWops, they’ll mess each other up
with their seeking. Now, you could make two separate RWops from the
same underlying source and be OK, hence the proposed sanity check.

Ok. I changed it to a reference counter and revised my changes to SDL_image
and SDL_mixer. Fresh diffs against the SDL tip are attached.

This GREATLY simplifies the rules for everyone involved.

Library writers: If you persist a client-provided RWops, increase the ref
count.

Everyone: If you create or persist an RWops, close it when finished.

Compare that with the 8 or so paragraphs from my original message describing
how autoclose should be handled. :POn Thu, Apr 14, 2011 at 9:08 AM, Matthew Orlando <@Matthew_Orlando>wrote:

As I was working on this, I actually thought to myself: “you know, this is
only a couple abstractions away from a reference-counting garbage
collector.” :slight_smile: I was already well into the changes I’ve posted so far,
though, and I wanted to get some feedback before I continued.

I definitely like the idea of requiring the client to close the RWops. It
would eliminate the need for the autoclose parameters entirely while still
enabling safe persistence.

I can’t imagine it being a good idea to provide an RWops to two different
functions that store it persistently (this could just be a failure of my
imagination), but I suppose that should be left up to the library writers
and clients to decide.

Speaking of which, would it be a good idea for the functions that persist
RWops (e.g. the wavestream loader) to reject any that have a reference count

1?

Cheers,

Matthew “Cogwheel” Orlando

On Wed, Apr 13, 2011 at 10:05 PM, Nathaniel J Fries wrote:

Your proposed change to the structure itself is most appropriate. This
would allow an application to, for example, treat an FTP response as a
readable file.

As far as auto-close… it’s a tricky subject. Some would say that it
should always be in the hands of the developer using the library, but then
there’s the fact that this can get quite complicated for him (because of
those recurring use functions you mentioned). I recommend using reference
counting and always requiring the developer to release it once manually, and
after this SDL can take care of it. Essentially the programmer would be
saying “I don’t need to reference this anymore” and SDL will act as a very
specific-purpose garbage collector. [image: Razz]


EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

-------------- next part --------------
A non-text attachment was scrubbed…
Name: SDL.diff
Type: text/x-patch
Size: 19441 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20110414/e549edad/attachment.bin
-------------- next part --------------
A non-text attachment was scrubbed…
Name: SDL_image.diff
Type: text/x-patch
Size: 7801 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20110414/e549edad/attachment-0001.bin
-------------- next part --------------
A non-text attachment was scrubbed…
Name: SDL_mixer.diff
Type: text/x-patch
Size: 2220 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20110414/e549edad/attachment-0002.bin

Mason Wheeler wrote:

Any way that could be fixed without rearchitecting the entirety of
SDL_Mixer? Treating music as something completely different than
normal sound is extremely limiting and just feels like a design flaw to me.

Agreed. I’m not too familiar with SDL_Mixer (I’ve never used sound in my projects before, as most have been proof-of-concept or making an engine for somebody else or a small open-source venture), but I don’t like the sounds of such a limitation.------------------------
EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Mason Wheeler wrote:

Any way that could be fixed without rearchitecting the entirety of
SDL_Mixer? Treating music as something completely different than
normal sound is extremely limiting and just feels like a design
flaw to me.

Agreed. I’m not too familiar with SDL_Mixer (I’ve never used sound
in my projects before, as most have been proof-of-concept or making
an engine for somebody else or a small open-source venture), but I
don’t like the sounds of such a limitation.

I’m no expert on the subject, but I think the distinction stems from
the fact that music is (or maybe was) the only channel that could
playback midi-style data. The libraries that can handle midi output
provide much less fine-grained control on what you can do to a stream
during playback, and thus as a result so does SDL_Mixer.

In general there’s no reason to use the so-called music channel,
unless you need to support midi background music. Just use one of the
standard channels for your background music and you’ll be a lot
happier.

b

In some cases, music is completely different from normal sound.
Waves, MP3s, and the like are intended to reproduce the original
recorded wave form (or at least a close enough approximation that it
SOUNDS like the original).

MOD & MIDI, on the other hand, are more like musical scores than sound
files. They describe how to put together a musical arrangement from
different “voices.” They simply don’t have the same capabilities as
the above formats.

Assuming appropriate abstractions to ignore this distinction, I still
think there’s merit in having a simplified music API. It’s easier to
use, supports more formats, and it doesn’t even take up one of the
regular sound channels! :wink: If you want finer-grained control now, you
can just use the regular mixer facilities.

That being said, a bit of re-architecture might not be out of the
question heading into 1.3 (considering what started this line of
discussion :P). Having the option to use the music APIs on the regular
sound channels would be nice.

mixer API could use a bit of a clean-up. The image library feels much
more coherent by comparison.On Thu, Apr 14, 2011 at 3:52 PM, Mason Wheeler wrote:

Any way that could be fixed without rearchitecting the entirety of
SDL_Mixer? ?Treating music as something completely different than
normal sound is extremely limiting and just feels like a design flaw to me.

From my experience with the RWops revamp, I have to agree that the

Now that we are on the subject of rearchitecturing sdl_mixer, it
would be great to have an effects API that gave some sort of access to
the channel stream as input instead of a fixed length buffer. This way
it could be easier to implement effects that alter the speed of the
stream.On Thursday, April 14, 2011, Matthew Orlando wrote:

On Thu, Apr 14, 2011 at 3:52 PM, Mason Wheeler wrote:

Any way that could be fixed without rearchitecting the entirety of
SDL_Mixer? ?Treating music as something completely different than
normal sound is extremely limiting and just feels like a design flaw to me.

In some cases, music is completely different from normal sound.
Waves, MP3s, and the like are intended to reproduce the original
recorded wave form (or at least a close enough approximation that it
SOUNDS like the original).

MOD & MIDI, on the other hand, are more like musical scores than sound
files. They describe how to put together a musical arrangement from
different “voices.” They simply don’t have the same capabilities as
the above formats.

Assuming appropriate abstractions to ignore this distinction, I still
think there’s merit in having a simplified music API. It’s easier to
use, supports more formats, and it doesn’t even take up one of the
regular sound channels! :wink: If you want finer-grained control now, you
can just use the regular mixer facilities.

That being said, a bit of re-architecture might not be out of the
question heading into 1.3 (considering what started this line of
discussion :P). Having the option to use the music APIs on the regular
sound channels would be nice.

From my experience with the RWops revamp, I have to agree that the
mixer API could use a bit of a clean-up. The image library feels much
more coherent by comparison.


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

Mason Wheeler wrote:

Any way that could be fixed without rearchitecting the entirety of
SDL_Mixer? Treating music as something completely different than
normal sound is extremely limiting and just feels like a design
flaw to me.

Agreed. I’m not too familiar with SDL_Mixer (I’ve never used sound
in my projects before, as most have been proof-of-concept or making
an engine for somebody else or a small open-source venture), but I
don’t like the sounds of such a limitation.

I’m no expert on the subject, but I think the distinction stems from
the fact that music is (or maybe was) the only channel that could
playback midi-style data. The libraries that can handle midi output
provide much less fine-grained control on what you can do to a stream
during playback, and thus as a result so does SDL_Mixer.

What do you mean? I’ve looked at the code for the MIDI decoder, and
it does the same thing that the other decoders do: decode a certain
length of time worth of sound through the library and pass it to a buffer,
which then gets mixed and passed to the SDL audio routines. After
the library-specific decoding is finished, you have a sound buffer like any
other, and there’s no good reason why you shouldn’t be able to apply
effects to it, or have more than one of them.

In general there’s no reason to use the so-called music channel,
unless you need to support midi background music. Just use one of the
standard channels for your background music and you’ll be a lot
happier.

That’s the problem. I do need to support MIDI.>----- Original Message ----

From: Brian Raiter
Subject: Re: [SDL] SDL_mixer resource leak fixes -> RWops revamp

Any way that could be fixed without rearchitecting the entirety of
SDL_Mixer? Treating music as something completely different than
normal sound is extremely limiting and just feels like a design flaw to me.

In some cases, music is completely different from normal sound.
Waves, MP3s, and the like are intended to reproduce the original
recorded wave form (or at least a close enough approximation that it
SOUNDS like the original).

MOD & MIDI, on the other hand, are more like musical scores than sound
files. They describe how to put together a musical arrangement from
different “voices.” They simply don’t have the same capabilities as
the above formats.

No, they have different capabilities. Tracked (“MOD”) music, for example,
has the all-important capability to loop to an arbitrary section of the song,
which is crucial for video game music. Waveform formats simply can’t
do this.

Assuming appropriate abstractions to ignore this distinction, I still
think there’s merit in having a simplified music API. It’s easier to
use, supports more formats, and it doesn’t even take up one of the
regular sound channels! :wink: If you want finer-grained control now, you
can just use the regular mixer facilities.

What’s wrong with it taking up one of the channels? If music used a
channel, I could apply effects to it. Right now, there’s no way to
do that.

That being said, a bit of re-architecture might not be out of the
question heading into 1.3 (considering what started this line of
discussion :P). Having the option to use the music APIs on the regular
sound channels would be nice.

Wait, first you say it’s good that it doesn’t take a sound channel, and
then you say it would be nice if it did? confuzzled

mixer API could use a bit of a clean-up. The image library feels much
more coherent by comparison.

I’ve been poking around in that a bit over the weekend. I’m working to
see if I can’t revamp the mixer system to put music on channels and
make it possible to play multiple music streams at once.>----- Original Message ----

From: Matthew Orlando
Subject: Re: [SDL] SDL_mixer resource leak fixes -> RWops revamp
On Thu, Apr 14, 2011 at 3:52 PM, Mason Wheeler <@Mason_Wheeler> wrote:
From my experience with the RWops revamp, I have to agree that the

This can be done.

In DarkPlaces I parse the "cue " chunk from .wav files which specifies the loop point (so when it hits the end of the sound, it goes back to this point), unfortunately not many editors can write this
chunk.

And for .ogg someone added custom tags to music which specifies the sample position to loop to, and DarkPlaces looks for those tags.

That said, mod music has other nice features like custom commands which could enable gameplay synchronized to the music, or vice versa.

I’ve been told that OpenAL can’t do this sort of intro+loop effect… how strange.

P.S. Quake used the "cue " chunks in wav in the same way back in 1996 for its intro+loop sound effects for door opening/lift moving sounds and all the ambient sounds (swampy noises, torch crackle,
flickering fluorescent lights, etc), this is nothing new, a huge portion of its sound files had such looping.On 04/26/2011 10:41 AM, Mason Wheeler wrote:

No, they have different capabilities. Tracked (“MOD”) music, for example,
has the all-important capability to loop to an arbitrary section of the song,
which is crucial for video game music. Waveform formats simply can’t
do this.


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier

[…]

I’ve been told that OpenAL can’t do this sort of intro+loop effect… how
strange.
[…]

I’m not all that into OpenAL, though I did study it’s API when working on one
of my sound engines some time ago - but you can stream audio, right…? If so,
you certainly can do this, and much more - though it requires more than some
plain API calls, obviously.On Wednesday 27 April 2011, at 01.12.30, Forest Hale wrote:


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

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://consulting.olofson.net http://olofsonarcade.com |
’---------------------------------------------------------------------’