diff options
| author | Max Horn | 2008-01-01 11:27:29 +0000 | 
|---|---|---|
| committer | Max Horn | 2008-01-01 11:27:29 +0000 | 
| commit | 305f60e0dbefa3861f5ca3614a2b930aca8afc2c (patch) | |
| tree | fe546c9f565ff4c9a999158e97a4e6af107a8d0f | |
| parent | a8d3967f63f51c77b8a934ec05b09803185afa12 (diff) | |
| download | scummvm-rg350-305f60e0dbefa3861f5ca3614a2b930aca8afc2c.tar.gz scummvm-rg350-305f60e0dbefa3861f5ca3614a2b930aca8afc2c.tar.bz2 scummvm-rg350-305f60e0dbefa3861f5ca3614a2b930aca8afc2c.zip | |
Patch #1839861 (Possible workaround for bugs related to cloneToFadeOutTrack): Fixes bug #1848399 and apparently also #1527274 & #1763227
svn-id: r30111
| -rw-r--r-- | engines/scumm/imuse_digi/dimuse.cpp | 16 | ||||
| -rw-r--r-- | engines/scumm/imuse_digi/dimuse.h | 3 | ||||
| -rw-r--r-- | engines/scumm/imuse_digi/dimuse_script.cpp | 49 | ||||
| -rw-r--r-- | engines/scumm/imuse_digi/dimuse_track.cpp | 45 | 
4 files changed, 63 insertions, 50 deletions
| diff --git a/engines/scumm/imuse_digi/dimuse.cpp b/engines/scumm/imuse_digi/dimuse.cpp index 776b840145..dba7e921b8 100644 --- a/engines/scumm/imuse_digi/dimuse.cpp +++ b/engines/scumm/imuse_digi/dimuse.cpp @@ -158,7 +158,6 @@ void IMuseDigital::saveOrLoad(Serializer *ser) {  		if (!ser->isSaving()) {  			if (!track->used)  				continue; -			track->readyToRemove = false;  			if ((track->toBeRemoved) || (track->souStreamUsed) || (track->curRegion == -1)) {  				track->streamSou= NULL;  				track->stream = NULL; @@ -231,9 +230,10 @@ void IMuseDigital::callback() {  	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {  		Track *track = _track[l]; -		if (track->used && !track->readyToRemove) { +		if (track->used) { +			// Remove tracks if necessary  			if (track->toBeRemoved) { -				track->readyToRemove = true; +				flushTrack(track);  				continue;  			} @@ -249,7 +249,9 @@ void IMuseDigital::callback() {  							track->volFadeUsed = false;  						}  						if (track->vol == 0) { -							track->toBeRemoved = true; +							// Fade out complete -> remove this track +							flushTrack(track); +							continue;  						}  					}  				} else if (track->volFadeStep > 0) { @@ -357,6 +359,8 @@ void IMuseDigital::callback() {  				} while (feedSize != 0);  			} else if (track->streamSou) {  				if (_mixer->isReady()) { +					// FIXME: Can't we replace track->mixerStreamRunning by +					// _mixer->isSoundHandleActive(track->mixChanHandle) ?  					if (!track->mixerStreamRunning) {  						track->mixerStreamRunning = true;  						_mixer->playInputStream(type, &track->mixChanHandle, track->streamSou, -1, vol, pan, false); @@ -375,7 +379,7 @@ void IMuseDigital::switchToNextRegion(Track *track) {  	debug(5, "switchToNextRegion(track:%d)", track->trackId);  	if (track->trackId >= MAX_DIGITAL_TRACKS) { -		track->toBeRemoved = true; +		flushTrack(track);  		debug(5, "exit (fadetrack can't go next region) switchToNextRegion(trackId:%d)", track->trackId);  		return;  	} @@ -383,7 +387,7 @@ void IMuseDigital::switchToNextRegion(Track *track) {  	int num_regions = _sound->getNumRegions(track->soundDesc);  	if (++track->curRegion == num_regions) { -		track->toBeRemoved = true; +		flushTrack(track);  		debug(5, "exit (end of regions) switchToNextRegion(track:%d)", track->trackId);  		return;  	} diff --git a/engines/scumm/imuse_digi/dimuse.h b/engines/scumm/imuse_digi/dimuse.h index f4a8a7467c..d6aa6d271f 100644 --- a/engines/scumm/imuse_digi/dimuse.h +++ b/engines/scumm/imuse_digi/dimuse.h @@ -83,7 +83,6 @@ private:  		char soundName[15]; // sound name but also filename of sound in bundle data  		bool used;			// flag mean that track is used  		bool toBeRemoved;   // flag mean that track need to be free -		bool readyToRemove; // flag mean that track is ready to stop  		bool mixerStreamRunning;	// flag mean sound mixer's stream is running  		bool souStreamUsed;	// flag mean that track use stream from sou file  		bool sndDataExtComp;// flag mean that sound data is compressed by scummvm tools @@ -152,6 +151,8 @@ private:  	void setDigMusicSequence(int seqId);  	void playDigMusic(const char *songName, const imuseDigTable *table, int attribPos, bool sequence); +	void flushTrack(Track *track); +  public:  	IMuseDigital(ScummEngine_v7 *scumm, Audio::Mixer *mixer, int fps);  	virtual ~IMuseDigital(); diff --git a/engines/scumm/imuse_digi/dimuse_script.cpp b/engines/scumm/imuse_digi/dimuse_script.cpp index b9ba72bb93..b9e242e529 100644 --- a/engines/scumm/imuse_digi/dimuse_script.cpp +++ b/engines/scumm/imuse_digi/dimuse_script.cpp @@ -163,32 +163,37 @@ void IMuseDigital::parseScriptCmds(int cmd, int b, int c, int d, int e, int f, i  	}  } +void IMuseDigital::flushTrack(Track *track) { +	track->toBeRemoved = true; +	if (track->stream) { +		// Finalize the appendable stream +		track->stream->finish(); +		// There might still be some data left in the buffers of the +		// appendable stream. We play it nice and wait till all of it +		// played. +		if (track->stream->endOfStream()) { +			_mixer->stopHandle(track->mixChanHandle); +			delete track->stream; +			track->stream = NULL; +			_sound->closeSound(track->soundDesc); +			track->soundDesc = NULL; +			track->used = false; +		} +	} else if (track->streamSou) { +		_mixer->stopHandle(track->mixChanHandle); +		delete track->streamSou; +		track->streamSou = NULL; +		track->used = false; +	} +} +  void IMuseDigital::flushTracks() {  	Common::StackLock lock(_mutex, "IMuseDigital::flushTracks()");  	debug(5, "flushTracks()");  	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {  		Track *track = _track[l]; -		if (track->used && track->readyToRemove) { -			if (track->stream) { -				// Finalize the appendable stream - 				track->stream->finish(); - 				// There might still be some data left in the buffers of the - 				// appendable stream. We play it nice and wait till all of it - 				// played. -				if (track->stream->endOfStream()) { -					_mixer->stopHandle(track->mixChanHandle); -					delete track->stream; -					track->stream = NULL; -					_sound->closeSound(track->soundDesc); -					track->soundDesc = NULL; -					track->used = false; -				} -			} else if (track->streamSou) { -				_mixer->stopHandle(track->mixChanHandle); -				delete track->streamSou; -				track->streamSou = NULL; -				track->used = false; -			} +		if (track->used && track->toBeRemoved) { +			flushTrack(track);  		}  	}  } @@ -288,7 +293,7 @@ int IMuseDigital::getSoundStatus(int sound) const {  		Track *track = _track[l];  		if (track->soundId == sound) {  			if ((track->streamSou && _mixer->isSoundHandleActive(track->mixChanHandle)) || -				(track->stream && track->used && !track->readyToRemove)) { +				(track->stream && !track->stream->endOfStream())) {  					return 1;  			}  		} diff --git a/engines/scumm/imuse_digi/dimuse_track.cpp b/engines/scumm/imuse_digi/dimuse_track.cpp index 1a9d59a214..faaae470e7 100644 --- a/engines/scumm/imuse_digi/dimuse_track.cpp +++ b/engines/scumm/imuse_digi/dimuse_track.cpp @@ -59,7 +59,22 @@ int IMuseDigital::allocSlot(int priority) {  		}  		if (lowest_priority <= priority) {  			assert(trackId != -1); -			_track[trackId]->toBeRemoved = true; +			Track *track = _track[trackId]; +			while (1) { +				if (!track->used) { +					break; +				} +				// The designated track is not yet available. So, we call flushTrack() +				// to get it processed (and thus made ready for us). Since the actual +				// processing is done by another thread, we also call parseEvents to +				// give it some time (and to avoid busy waiting/looping). +				flushTrack(track); +				_mutex.unlock(); +		#ifndef __PLAYSTATION2__ +				_vm->parseEvents(); +		#endif +				_mutex.lock(); +			}  			debug(5, "IMuseDigital::allocSlot(): Removed sound %d from track %d", _track[trackId]->soundId, trackId);  		} else {  			debug(5, "IMuseDigital::allocSlot(): Priority sound too low"); @@ -71,6 +86,7 @@ int IMuseDigital::allocSlot(int priority) {  }  void IMuseDigital::startSound(int soundId, const char *soundName, int soundType, int volGroupId, Audio::AudioStream *input, int hookId, int volume, int priority) { +	Common::StackLock lock(_mutex, "IMuseDigital::startSound()");  	debug(5, "IMuseDigital::startSound(%d)", soundId);  	int l = allocSlot(priority); @@ -80,21 +96,6 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,  	}  	Track *track = _track[l]; -	while (1) { -		_mutex.lock(); -		if (!track->used) { -			break; -		} -		// The designated track is not yet available. So, we call flushTracks() -		// to get it processed (and thus made ready for us). Since the actual -		// processing is done by another thread, we also call parseEvents to -		// give it some time (and to avoid busy waiting/looping). -		flushTracks(); -		_mutex.unlock(); -#ifndef __PLAYSTATION2__ -		_vm->parseEvents(); -#endif -	}  	track->pan = 64;  	track->vol = volume * 1000; @@ -113,7 +114,6 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,  	track->dataMod12Bit = 0;  	track->mixerFlags = 0;  	track->toBeRemoved = false; -	track->readyToRemove = false;  	track->soundType = soundType;  	int bits = 0, freq = 0, channels = 0; @@ -191,7 +191,6 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,  	}  	track->used = true; -	_mutex.unlock();  }  void IMuseDigital::setPriority(int soundId, int priority) { @@ -309,7 +308,7 @@ void IMuseDigital::fadeOutMusic(int fadeDelay) {  		Track *track = _track[l];  		if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {  			cloneToFadeOutTrack(track, fadeDelay); -			track->toBeRemoved = true; +			flushTrack(track);  		}  	}  } @@ -319,9 +318,14 @@ IMuseDigital::Track *IMuseDigital::cloneToFadeOutTrack(Track *track, int fadeDel  	Track *fadeTrack = 0;  	debug(0, "IMuseDigital::cloneToFadeOutTrack(%d, %d)", track->trackId, fadeDelay); +	 +	if (track->toBeRemoved) { +		error("IMuseDigital::cloneToFadeOutTrack: Tried to clone a track to be removed"); +		return NULL; +	}  	if (_track[track->trackId + MAX_DIGITAL_TRACKS]->used) { -		warning("IMuseDigital::cloneToFadeOutTrack: Not free fade track"); +		warning("IMuseDigital::cloneToFadeOutTrack: No free fade track");  		return NULL;  	} @@ -360,7 +364,6 @@ IMuseDigital::Track *IMuseDigital::cloneToFadeOutTrack(Track *track, int fadeDel  	}  	fadeTrack->stream = Audio::makeAppendableAudioStream(_sound->getFreq(fadeTrack->soundDesc), makeMixerFlags(fadeTrack->mixerFlags));  	_mixer->playInputStream(type, &fadeTrack->mixChanHandle, fadeTrack->stream, -1, fadeTrack->vol / 1000, fadeTrack->pan, false); -  	fadeTrack->mixerStreamRunning = true;  	fadeTrack->used = true; | 
