diff options
-rw-r--r-- | scumm/imuse_digi.cpp | 6 | ||||
-rw-r--r-- | scumm/smush/smush_mixer.cpp | 6 | ||||
-rw-r--r-- | scumm/smush/smush_player.cpp | 11 | ||||
-rw-r--r-- | scumm/sound.cpp | 6 | ||||
-rw-r--r-- | sound/mixer.cpp | 34 | ||||
-rw-r--r-- | sound/mixer.h | 11 |
6 files changed, 54 insertions, 20 deletions
diff --git a/scumm/imuse_digi.cpp b/scumm/imuse_digi.cpp index f31db2272b..fdfcc73eff 100644 --- a/scumm/imuse_digi.cpp +++ b/scumm/imuse_digi.cpp @@ -715,7 +715,7 @@ void IMuseDigital::handler() { if (_channel[l]._used) { if (_channel[l]._toBeRemoved == true) { if (_channel[l]._mixerChannel != -1) { - _scumm->_mixer->stop(_channel[l]._mixerChannel); + _scumm->_mixer->endStream(_channel[l]._mixerChannel); _channel[l]._mixerChannel = -1; } if (_scumm->_mixer->_channels[l] == NULL) { @@ -824,10 +824,10 @@ void IMuseDigital::handler() { if (_scumm->_silentDigitalImuse == false) { if (_channel[l]._mixerChannel == -1) { - _channel[l]._mixerChannel = _scumm->_mixer->playStream(buf, mixer_size, + _channel[l]._mixerChannel = _scumm->_mixer->newStream(buf, mixer_size, _channel[l]._freq, _channel[l]._mixerFlags, 100000); } else { - _scumm->_mixer->append(_channel[l]._mixerChannel, buf, mixer_size); + _scumm->_mixer->appendStream(_channel[l]._mixerChannel, buf, mixer_size); } } free(buf); diff --git a/scumm/smush/smush_mixer.cpp b/scumm/smush/smush_mixer.cpp index 9f74b5252d..3de25e95d1 100644 --- a/scumm/smush/smush_mixer.cpp +++ b/scumm/smush/smush_mixer.cpp @@ -109,6 +109,8 @@ bool SmushMixer::handleFrame() { delete _channels[i].chan; _channels[i].id = -1; _channels[i].chan = NULL; + if (_channels[i].mixer_index != -1) + _mixer->endStream(_channels[i].mixer_index); } else { int32 rate; bool stereo, is_short; @@ -135,9 +137,9 @@ bool SmushMixer::handleFrame() { if (_silentMixer == false) { if (_channels[i].mixer_index == -1) { - _channels[i].mixer_index = _mixer->playStream(data, size, rate, flags, 2000000); + _channels[i].mixer_index = _mixer->newStream(data, size, rate, flags, 2000000); } else { - _mixer->append(_channels[i].mixer_index, data, size); + _mixer->appendStream(_channels[i].mixer_index, data, size); } } free(data); diff --git a/scumm/smush/smush_player.cpp b/scumm/smush/smush_player.cpp index d27a92f1c6..c3e9c829c7 100644 --- a/scumm/smush/smush_player.cpp +++ b/scumm/smush/smush_player.cpp @@ -223,7 +223,7 @@ SmushPlayer::SmushPlayer(Scumm *scumm, int speed, bool subtitles) { _storeFrame = false; _width = 0; _height = 0; - _IACTchannel = -1, + _IACTchannel = -1; _IACTpos = 0; _soundFrequency = 22050; _speed = speed; @@ -283,6 +283,11 @@ void SmushPlayer::deinit() { delete _base; _base = NULL; } + + if (_IACTchannel != -1) { + _scumm->_mixer->stop(_IACTchannel); + _IACTchannel = -1; + } _scumm->_insaneState = false; _scumm->abortCutscene(); @@ -451,10 +456,10 @@ void SmushPlayer::handleImuseAction(Chunk &b) { } while (--count); if (_IACTchannel == -1) { - _IACTchannel = _scumm->_mixer->playStream(output_data, 0x1000, 22050, + _IACTchannel = _scumm->_mixer->newStream(output_data, 0x1000, 22050, SoundMixer::FLAG_STEREO | SoundMixer::FLAG_16BITS, 200000); } else { - _scumm->_mixer->append(_IACTchannel, output_data, 0x1000); + _scumm->_mixer->appendStream(_IACTchannel, output_data, 0x1000); } bsize -= len; diff --git a/scumm/sound.cpp b/scumm/sound.cpp index 5eaf0beedc..3d6ea2a222 100644 --- a/scumm/sound.cpp +++ b/scumm/sound.cpp @@ -1170,16 +1170,16 @@ void Sound::bundleMusicHandler(Scumm *scumm) { final_size = _outputMixerSize; memcpy(buffer, ptr, _outputMixerSize); } else { - warning("Sound::bundleMusicHandler TODO: more playStream options..."); + warning("Sound::bundleMusicHandler TODO: more newStream options..."); return; } _bundleMusicPosition += final_size; if (_bundleMusicTrack == -1) { - _bundleMusicTrack = _scumm->_mixer->playStream(buffer, final_size, rate, + _bundleMusicTrack = _scumm->_mixer->newStream(buffer, final_size, rate, SoundMixer::FLAG_16BITS | SoundMixer::FLAG_STEREO, 300000); } else { - _scumm->_mixer->append(_bundleMusicTrack, buffer, final_size); + _scumm->_mixer->appendStream(_bundleMusicTrack, buffer, final_size); } free(buffer); } diff --git a/sound/mixer.cpp b/sound/mixer.cpp index bf2fd544b3..9f862ce65c 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -73,6 +73,7 @@ class ChannelStream : public Channel { uint32 _bufferSize; uint32 _rate; byte _flags; + bool _finished; public: ChannelStream(SoundMixer *mixer, void *sound, uint32 size, uint rate, byte flags, int32 buffer_size); @@ -83,6 +84,7 @@ public: bool isMusicChannel() { return true; } + void finish() { _finished = true; } }; #ifdef USE_MAD @@ -170,18 +172,30 @@ SoundMixer::~SoundMixer() { _syst->delete_mutex(_mutex); } -int SoundMixer::append(int index, void *sound, uint32 size) { +void SoundMixer::appendStream(int index, void *sound, uint32 size) { _syst->lock_mutex(_mutex); - Channel *chan = _channels[index]; + ChannelStream *chan = dynamic_cast<ChannelStream *>(_channels[index]); if (!chan) { - error("Trying to stream to a nonexistant streamer : %d", index); + error("Trying to append to a nonexistant stream %d", index); } else { - dynamic_cast<ChannelStream *>(chan)->append(sound, size); + chan->append(sound, size); + } + + _syst->unlock_mutex(_mutex); +} + +void SoundMixer::endStream(int index) { + _syst->lock_mutex(_mutex); + + ChannelStream *chan = dynamic_cast<ChannelStream *>(_channels[index]); + if (!chan) { + error("Trying to end a nonexistant streamer : %d", index); + } else { + chan->finish(); } _syst->unlock_mutex(_mutex); - return 1; } int SoundMixer::insertChannel(PlayingSoundHandle *handle, Channel *chan) { @@ -209,7 +223,7 @@ int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, ui return insertChannel(handle, new ChannelRaw(this, sound, size, rate, flags, id)); } -int SoundMixer::playStream(void *sound, uint32 size, uint rate, byte flags, int32 buffer_size) { +int SoundMixer::newStream(void *sound, uint32 size, uint rate, byte flags, int32 buffer_size) { return insertChannel(NULL, new ChannelStream(this, sound, size, rate, flags, buffer_size)); } @@ -717,6 +731,7 @@ ChannelStream::ChannelStream(SoundMixer *mixer, void *sound, uint32 size, uint r _pos = _ptr; _fpPos = 0; _fpSpeed = (1 << 16) * rate / mixer->_outputRate; + _finished = false; // adjust the magnitude to prevent division error while (size & 0xFFFF0000) @@ -757,6 +772,13 @@ void ChannelStream::mix(int16 *data, uint len) { const int16 *vol_tab = _mixer->_volumeTable; if (_pos == _endOfData) { + // Normally, the stream stays around even if all its data is used up. + // This is in case more data is streamed into it. To make the stream + // go away, one can either stop() it (which takes effect immediately, + // ignoring any remaining sound data), or finish() it, which means + // it will finish playing before it terminates itself. + if (_finished) + destroy(); return; } diff --git a/sound/mixer.h b/sound/mixer.h index bced868538..16e94f3326 100644 --- a/sound/mixer.h +++ b/sound/mixer.h @@ -86,7 +86,6 @@ public: FLAG_LOOP = 1 << 5 // loop the audio }; int playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id = -1); - int playStream(void *sound, uint32 size, uint rate, byte flags, int32 buffer_size); #ifdef USE_MAD int playMP3(PlayingSoundHandle *handle, void *sound, uint32 size, byte flags); int playMP3CDTrack(PlayingSoundHandle *handle, File *file, mad_timer_t duration); @@ -110,8 +109,14 @@ public: /** stop playing a specific sound */ void stopID(int id); - /** append to existing sound */ - int append(int index, void * sound, uint32 size); + /** Start a new stream. */ + int newStream(void *sound, uint32 size, uint rate, byte flags, int32 buffer_size); + + /** Append to an existing stream. */ + void appendStream(int index, void * sound, uint32 size); + + /** Mark a stream as finished - it will play all its remaining data, then stop. */ + void endStream(int index); /** Check whether any SFX channel is active.*/ bool hasActiveSFXChannel(); |