[Scummvm-devel] Recent Audio API changes

Johannes Schickel lordhoto at scummvm.org
Sun Jan 10 20:07:39 CET 2010


as some of you might have noticed Max and me are currently reworking 
some parts of the Audio API. This includes two things: Looping of the 
AudioStreams and the use of Timestamp.

Since Max worked almost exclusively on Timestamp I will leave it to him 
to explain the motivation behind it.

As some of you might know that looping of AudioStreams in the past had 
been more or less a very annoying situation. Only some Streams did 
feature looping, others not at all. This resulted in two different things:

1) People started to convert some codec implementations to have looping 
code, that means: code duplication.
2) People worked around this and implemented their own looping, for 
example by just reloading the stream, when it finished playback.

Both are not too nice and should be hopefully obsolete with the latest 
AudioStream API changes.

To achieve the same possibilities as with the old code, the new code 
introduces some new interfaces:

- RewindableAudioStream:

    This is an AudioStream, which can be rewinded to its initial position.

    Note: many common (if not all) audio streams, which allow this, have 
been converted to implement this interface.

- SeekableAudioStream:

    This is an AudioStream, which features the same as 
RewindableAudioStream, but additionally offers to seek at any given 
point in the AudioStream.

Additionally there are the following classes to allow looping:

- LoopingAudioStream:

    This object takes an RewindableAudioStream and plays it a given 
amount of loops from start to end. It additionally offers to query how 
many iterations have already been done.

For convenience some additional wrappers have been made to ease the use 
of the new looping features:
makeLoopingAudioStream (both inside audiostream.h and hopefully well 
enough documented).

There are some new less used (and currently it's not decided whether 
they stay forever) objects too:

- SubLoopingAudioStream:

    This allows looping of a nested part of an SeekableAudioStream, but 
always starts playback at the beginning.

    This is currently used to implement same looping possibilities as 
LinearMemoryStream's old looping did. It is also used directly in SAGA, 
to fix some sound track (I hope I converted that correctly, can someone 
familiar with SAGA check that please?).

- SubSeekableAudioStream:

    This is an object much like SeekableSubReadStream, i.e. it allows to 
limit the range of a SeekableAudioStream. This is currently exclusively 
used in the AudioCD code.

If you really need to use one of those directly in your code, please 
drop me a mail before doing so.

Also note that some old factory functions are now considered deprecated:

- makeLinearInputStream using a "loopStart" and "loopEnd" parameter.
- makeLinearDiskStream using a "loopStart" and "loopEnd" parameter.

Apart for the new makeLinearInputStream and makeLinearDiskStream 
factories Audio::Mixer::FLAG_LOOP is no longer a valid input, i.e. it 
will be silently ignored.

Hopefully that was enough of a short overview to get the basic idea 
behind the new code. For user documentation the doxygen comments inside 
audiostream.h should be used.

Now that the new code is "good enough" engine authors might start to 
migrate to it, in case they did implement manual looping code in their 
engines. I currently know that at least the following engines seem to 
implement custom looping:

- Sword1
- Sword2

Maybe other engines might benefit from the new code too. That should be 
at best checked by their maintainers (or any other active developer).

Below only comments about the above listed engines follow, when you're 
not interested in their development you might just skip the rest of the 

For SWORD1 and SWORD2: eriktorbjorn, do you have any idea whether it's 
possible to replace the music looping code with the new common 
functionality? If so, do you need any help? If not, any reason why you 
think it's not possible?

For AGOS: Kirben, I am not sure whether I get the code right, but it 
seems you implement a custom looping, which might first play sound and 
then (possibly) loop another one after that? That looks like it could be 
achieved by using LoopableAudioStream in combination with 
QueueingAudioStream. Maybe there's an easier way to implement that, 
though. Any ideas whether it should be possible to convert AGOS to use 
the new code? If so, do you need any help? If not, any reason why you 
think it's not possible?

I'm fine with answering those questions in private mail too. (Though 
please CC at least Max).

// Johannes

More information about the Scummvm-devel mailing list