diff -ur ScummVM-cvs20040206/scummvm/sound/mixer.cpp ScummVM-cvs20040206+hack/scummvm/sound/mixer.cpp
old
|
new
|
|
49 | 49 | int8 _balance; |
50 | 50 | bool _paused; |
51 | 51 | int _id; |
| 52 | uint32 _samplesConsumed; |
| 53 | uint32 _samplesDecoded; |
| 54 | uint32 _mixerTimeStamp; |
52 | 55 | |
53 | 56 | protected: |
54 | 57 | RateConverter *_converter; |
… |
… |
|
83 | 86 | int getId() const { |
84 | 87 | return _id; |
85 | 88 | } |
| 89 | uint32 getElapsedTime(); |
86 | 90 | }; |
87 | 91 | |
88 | 92 | class ChannelStream : public Channel { |
… |
… |
|
393 | 397 | _channels[index]->setBalance(balance); |
394 | 398 | } |
395 | 399 | |
| 400 | uint32 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 | |
396 | 420 | void SoundMixer::pauseAll(bool paused) { |
397 | 421 | _paused = paused; |
398 | 422 | } |
… |
… |
|
465 | 489 | |
466 | 490 | Channel::Channel(SoundMixer *mixer, PlayingSoundHandle *handle, bool isMusic, int id) |
467 | 491 | : _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) { |
469 | 494 | assert(mixer); |
470 | 495 | } |
471 | 496 | |
472 | 497 | Channel::Channel(SoundMixer *mixer, PlayingSoundHandle *handle, AudioStream *input, |
473 | 498 | bool autofreeStream, bool isMusic, bool reverseStereo, int id) |
474 | 499 | : _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) { |
476 | 502 | assert(mixer); |
477 | 503 | assert(input); |
478 | 504 | |
… |
… |
|
522 | 548 | vol_r = vol / 255; |
523 | 549 | } |
524 | 550 | |
| 551 | _samplesConsumed = _samplesDecoded; |
| 552 | _mixerTimeStamp = g_system->get_msecs(); |
| 553 | |
525 | 554 | _converter->flow(*_input, data, len, vol_l, vol_r); |
| 555 | |
| 556 | _samplesDecoded += len; |
526 | 557 | } |
527 | 558 | } |
528 | 559 | |
| 560 | uint32 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 | |
529 | 584 | ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, |
530 | 585 | uint rate, byte flags, uint32 buffer_size) |
531 | 586 | : Channel(mixer, handle, true) { |
diff -ur ScummVM-cvs20040206/scummvm/sound/mixer.h ScummVM-cvs20040206+hack/scummvm/sound/mixer.h
old
|
new
|
|
154 | 154 | /** set the channel balance for the given handle (-127 ... 0 ... 127) (left ... center ... right)*/ |
155 | 155 | void setChannelBalance(PlayingSoundHandle handle, int8 balance); |
156 | 156 | |
| 157 | /** get approximation of for how long the channel has been playing */ |
| 158 | uint32 getChannelElapsedTime(PlayingSoundHandle handle); |
| 159 | |
157 | 160 | /** Check whether any SFX channel is active.*/ |
158 | 161 | bool hasActiveSFXChannel(); |
159 | 162 | |