[Scummvm-devel] Recent Audio API changes
Johannes Schickel
lordhoto at scummvm.org
Sun Jan 10 20:07:39 CET 2010
Hi,
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
- AGOS
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
mail.
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