diff options
author | Torbjörn Andersson | 2004-02-12 16:25:28 +0000 |
---|---|---|
committer | Torbjörn Andersson | 2004-02-12 16:25:28 +0000 |
commit | 9003dbbcb325cdf30b15822bc9bbf29c04884579 (patch) | |
tree | 88ae410ec521d585831864aab37b512474fa2951 | |
parent | 322266106124af70a0f1c1fb91f77766917c57e0 (diff) | |
download | scummvm-rg350-9003dbbcb325cdf30b15822bc9bbf29c04884579.tar.gz scummvm-rg350-9003dbbcb325cdf30b15822bc9bbf29c04884579.tar.bz2 scummvm-rg350-9003dbbcb325cdf30b15822bc9bbf29c04884579.zip |
With no comments from fingolfin, and a go-ahead from ender, I've committed
patch #892455 ("getElapsedTime() for sounds") despite its current
shortcomings. It should be good enough for the Broken Sword cutscenes
anyway, which is what I'll be looking at next.
svn-id: r12829
-rw-r--r-- | sound/mixer.cpp | 59 | ||||
-rw-r--r-- | sound/mixer.h | 3 |
2 files changed, 60 insertions, 2 deletions
diff --git a/sound/mixer.cpp b/sound/mixer.cpp index b31c2a6f25..af3bbc3156 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -49,6 +49,9 @@ private: int8 _balance; bool _paused; int _id; + uint32 _samplesConsumed; + uint32 _samplesDecoded; + uint32 _mixerTimeStamp; protected: RateConverter *_converter; @@ -83,6 +86,7 @@ public: int getId() const { return _id; } + uint32 getElapsedTime(); }; class ChannelStream : public Channel { @@ -393,6 +397,26 @@ void SoundMixer::setChannelBalance(PlayingSoundHandle handle, int8 balance) { _channels[index]->setBalance(balance); } +uint32 SoundMixer::getChannelElapsedTime(PlayingSoundHandle handle) { + Common::StackLock lock(_mutex); + + if (!handle.isActive()) + return 0; + + int index = handle.getIndex(); + + if ((index < 0) || (index >= NUM_CHANNELS)) { + warning("soundMixer::getChannelElapsedTime has invalid index %d", index); + return 0; + } + + if (_channels[index]) + return _channels[index]->getElapsedTime(); + + warning("soundMixer::getChannelElapsedTime has no channel object for index %d", index); + return 0; +} + void SoundMixer::pauseAll(bool paused) { _paused = paused; } @@ -465,14 +489,16 @@ void SoundMixer::setMusicVolume(int volume) { Channel::Channel(SoundMixer *mixer, PlayingSoundHandle *handle, bool isMusic, int id) : _mixer(mixer), _handle(handle), _autofreeStream(true), _isMusic(isMusic), - _volume(255), _balance(0), _paused(false), _id(id), _converter(0), _input(0) { + _volume(255), _balance(0), _paused(false), _id(id), _samplesConsumed(0), + _samplesDecoded(0), _mixerTimeStamp(0), _converter(0), _input(0) { assert(mixer); } Channel::Channel(SoundMixer *mixer, PlayingSoundHandle *handle, AudioStream *input, bool autofreeStream, bool isMusic, bool reverseStereo, int id) : _mixer(mixer), _handle(handle), _autofreeStream(autofreeStream), _isMusic(isMusic), - _volume(255), _balance(0), _paused(false), _id(id), _converter(0), _input(input) { + _volume(255), _balance(0), _paused(false), _id(id), _samplesConsumed(0), + _samplesDecoded(0), _mixerTimeStamp(0), _converter(0), _input(input) { assert(mixer); assert(input); @@ -522,10 +548,39 @@ void Channel::mix(int16 *data, uint len) { vol_r = vol / 255; } + _samplesConsumed = _samplesDecoded; + _mixerTimeStamp = g_system->get_msecs(); + _converter->flow(*_input, data, len, vol_l, vol_r); + + _samplesDecoded += len; } } +uint32 Channel::getElapsedTime() { + if (_mixerTimeStamp == 0) + return 0; + + // Convert the number of samples into a time duration. To avoid + // overflow, this has to be done in a somewhat non-obvious way. + + uint rate = _mixer->getOutputRate(); + + uint32 seconds = _samplesConsumed / rate; + uint32 milliseconds = (1000 * (_samplesConsumed % rate)) / rate; + + uint32 delta = g_system->get_msecs() - _mixerTimeStamp; + + // In theory it would seem like a good idea to limit the approximation + // so that it never exceeds the theoretical upper bound set by + // _samplesDecoded. Meanwhile, back in the real world, doing so makes + // the Broken Sword cutscenes noticeably jerkier. I guess the mixer + // isn't invoked at the regular intervals that I first imagined. + + // FIXME: This won't work very well if the sound is paused. + return 1000 * seconds + milliseconds + delta; +} + ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, uint rate, byte flags, uint32 buffer_size) : Channel(mixer, handle, true) { diff --git a/sound/mixer.h b/sound/mixer.h index 377d299ee7..3b26f0f763 100644 --- a/sound/mixer.h +++ b/sound/mixer.h @@ -154,6 +154,9 @@ public: /** set the channel balance for the given handle (-127 ... 0 ... 127) (left ... center ... right)*/ void setChannelBalance(PlayingSoundHandle handle, int8 balance); + /** get approximation of for how long the channel has been playing */ + uint32 getChannelElapsedTime(PlayingSoundHandle handle); + /** Check whether any SFX channel is active.*/ bool hasActiveSFXChannel(); |