aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scumm/imuse_digi.cpp6
-rw-r--r--scumm/smush/smush_mixer.cpp6
-rw-r--r--scumm/smush/smush_player.cpp11
-rw-r--r--scumm/sound.cpp6
-rw-r--r--sound/mixer.cpp34
-rw-r--r--sound/mixer.h11
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();