Ticket #8321: elapsed-time.diff

File elapsed-time.diff, 4.0 KB (added by eriktorbjorn, 16 years ago)

Patch against a January 6 CVS snapshot

  • scummvm/sound/mixer.cpp

    diff -ur ScummVM-cvs20040206/scummvm/sound/mixer.cpp ScummVM-cvs20040206+hack/scummvm/sound/mixer.cpp
    old new  
    4949        int8 _balance;
    5050        bool _paused;
    5151        int _id;
     52        uint32 _samplesConsumed;
     53        uint32 _samplesDecoded;
     54        uint32 _mixerTimeStamp;
    5255
    5356protected:
    5457        RateConverter *_converter;
     
    8386        int getId() const {
    8487                return _id;
    8588        }
     89        uint32 getElapsedTime();
    8690};
    8791
    8892class ChannelStream : public Channel {
     
    393397                _channels[index]->setBalance(balance);
    394398}
    395399
     400uint32 SoundMixer::getChannelElapsedTime(PlayingSoundHandle handle) {
     401        Common::StackLock lock(_mutex);
     402
     403        if (!handle.isActive())
     404                return 0;
     405
     406        int index = handle.getIndex();
     407
     408        if ((index < 0) || (index >= NUM_CHANNELS)) {
     409                warning("soundMixer::getChannelElapsedTime has invalid index %d", index);
     410                return 0;
     411        }
     412
     413        if (_channels[index])
     414                return _channels[index]->getElapsedTime();
     415
     416        warning("soundMixer::getChannelElapsedTime has no channel object for index %d", index);
     417        return 0;
     418}
     419
    396420void SoundMixer::pauseAll(bool paused) {
    397421        _paused = paused;
    398422}
     
    465489
    466490Channel::Channel(SoundMixer *mixer, PlayingSoundHandle *handle, bool isMusic, int id)
    467491        : _mixer(mixer), _handle(handle), _autofreeStream(true), _isMusic(isMusic),
    468           _volume(255), _balance(0), _paused(false), _id(id), _converter(0), _input(0) {
     492          _volume(255), _balance(0), _paused(false), _id(id), _samplesConsumed(0),
     493          _samplesDecoded(0), _mixerTimeStamp(0), _converter(0), _input(0) {
    469494        assert(mixer);
    470495}
    471496
    472497Channel::Channel(SoundMixer *mixer, PlayingSoundHandle *handle, AudioStream *input,
    473498                                bool autofreeStream, bool isMusic, bool reverseStereo, int id)
    474499        : _mixer(mixer), _handle(handle), _autofreeStream(autofreeStream), _isMusic(isMusic),
    475           _volume(255), _balance(0), _paused(false), _id(id), _converter(0), _input(input) {
     500          _volume(255), _balance(0), _paused(false), _id(id), _samplesConsumed(0),
     501          _samplesDecoded(0), _mixerTimeStamp(0), _converter(0), _input(input) {
    476502        assert(mixer);
    477503        assert(input);
    478504
     
    522548                        vol_r = vol / 255;
    523549                }
    524550
     551                _samplesConsumed = _samplesDecoded;
     552                _mixerTimeStamp = g_system->get_msecs();
     553
    525554                _converter->flow(*_input, data, len, vol_l, vol_r);
     555
     556                _samplesDecoded += len;
    526557        }
    527558}
    528559
     560uint32 Channel::getElapsedTime() {
     561        if (_mixerTimeStamp == 0)
     562                return 0;
     563
     564        // Convert the number of samples into a time duration. To avoid
     565        // overflow, this has to be done in a somewhat non-obvious way.
     566
     567        uint rate = _mixer->getOutputRate();
     568
     569        uint32 seconds = _samplesConsumed / rate;
     570        uint32 milliseconds = (1000 * (_samplesConsumed % rate)) / rate;
     571
     572        uint32 delta = g_system->get_msecs() - _mixerTimeStamp;
     573
     574        // In theory it would seem like a good idea to limit the approximation
     575        // so that it never exceeds the theoretical upper bound set by
     576        // _samplesDecoded. Meanwhile, back in the real world, doing so makes
     577        // the Broken Sword cutscenes noticeably jerkier. I guess the mixer
     578        // isn't invoked at the regular intervals that I first imagined.
     579
     580        // FIXME: This won't work if the sound is paused.
     581        return 1000 * seconds + milliseconds + delta;
     582}
     583
    529584ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle,
    530585                                                        uint rate, byte flags, uint32 buffer_size)
    531586        : Channel(mixer, handle, true) {
  • scummvm/sound/mixer.h

    diff -ur ScummVM-cvs20040206/scummvm/sound/mixer.h ScummVM-cvs20040206+hack/scummvm/sound/mixer.h
    old new  
    154154        /** set the channel balance for the given handle (-127 ... 0 ... 127) (left ... center ... right)*/
    155155        void setChannelBalance(PlayingSoundHandle handle, int8 balance);
    156156
     157        /** get approximation of for how long the channel has been playing */
     158        uint32 getChannelElapsedTime(PlayingSoundHandle handle);
     159
    157160        /** Check whether any SFX channel is active.*/
    158161        bool hasActiveSFXChannel();
    159162