[Scummvm-cvs-logs] CVS: scummvm/scumm/imuse_digi dimuse.cpp,1.45.2.4,1.45.2.5 dimuse.h,1.31.2.1,1.31.2.2 dimuse_bndmgr.cpp,1.14.2.2,1.14.2.3 dimuse_bndmgr.h,1.5.2.2,1.5.2.3 dimuse_codecs.cpp,1.3,1.3.2.1 dimuse_script.cpp,1.7.2.2,1.7.2.3 dimuse_sndmgr.cpp,1.26.2.3,1.26.2.4 dimuse_sndmgr.h,1.19.2.1,1.19.2.2 dimuse_track.cpp,1.17.2.2,1.17.2.3

Pawel Kolodziejski aquadran at users.sourceforge.net
Sat Jun 26 02:19:13 CEST 2004


Update of /cvsroot/scummvm/scummvm/scumm/imuse_digi
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12615/scummvm/scumm/imuse_digi

Modified Files:
      Tag: branch-0-6-0
	dimuse.cpp dimuse.h dimuse_bndmgr.cpp dimuse_bndmgr.h 
	dimuse_codecs.cpp dimuse_script.cpp dimuse_sndmgr.cpp 
	dimuse_sndmgr.h dimuse_track.cpp 
Log Message:
backported imuse digital and smush changes

Index: dimuse.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse.cpp,v
retrieving revision 1.45.2.4
retrieving revision 1.45.2.5
diff -u -d -r1.45.2.4 -r1.45.2.5
--- dimuse.cpp	3 May 2004 11:33:50 -0000	1.45.2.4
+++ dimuse.cpp	26 Jun 2004 09:18:29 -0000	1.45.2.5
@@ -41,7 +41,7 @@
 	imuseDigital->callback();
 }
 
-IMuseDigital::IMuseDigital(ScummEngine *scumm)
+IMuseDigital::IMuseDigital(ScummEngine *scumm, int fps)
 	: _vm(scumm) {
 	_mutex = g_system->create_mutex();
 	_pause = false;
@@ -49,16 +49,16 @@
 	_volVoice = 0;
 	_volSfx = 0;
 	_volMusic = 0;
+	_callbackFps = fps;
 	resetState();
 	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
 		_track[l] = new Track;
 		_track[l]->used = false;
 	}
-	_vm->_timer->installTimerProc(timer_handler, 1000000 / 25, this);
+	_vm->_timer->installTimerProc(timer_handler, 1000000 / _callbackFps, this);
 }
 
 IMuseDigital::~IMuseDigital() {
-	Common::StackLock lock(_mutex);
 	stopAllSounds();
 	_vm->_timer->removeTimerProc(timer_handler);
 	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
@@ -82,94 +82,73 @@
 
 void IMuseDigital::callback() {
 	Common::StackLock lock(_mutex);
-	int l = 0;
 
 	if (_pause || !_vm)
 		return;
 
-	for (l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
-		if (_track[l]->used) {
-			if (_track[l]->stream2) {
-				if (!_track[l]->handle.isActive() && _track[l]->started) {
-					debug(5, "IMuseDigital::callback() A: stopped sound: %d", _track[l]->soundId);
-					delete _track[l]->stream2;
-					_track[l]->stream2 = NULL;
-					_track[l]->used = false;
-					continue;
-				}
-			} else if (_track[l]->stream) {
-				if (_track[l]->toBeRemoved) {
-					debug(5, "IMuseDigital::callback() B: stopped sound: %d", _track[l]->soundId);
-					_track[l]->stream->finish();
-					_track[l]->stream = NULL;
-					_sound->closeSound(_track[l]->soundHandle);
-					_track[l]->soundHandle = NULL;
-					_track[l]->used = false;
-					continue;
-				}
+	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+		Track *track = _track[l];
+		if (track->used && !track->readyToRemove) {
+			if (track->toBeRemoved) {
+				track->readyToRemove = true;
+				continue;
 			}
 
-			if (_track[l]->volFadeUsed) {
-				if (_track[l]->volFadeStep < 0) {
-					if (_track[l]->vol > _track[l]->volFadeDest) {
-						_track[l]->vol += _track[l]->volFadeStep;
-						if (_track[l]->vol < _track[l]->volFadeDest) {
-							_track[l]->vol = _track[l]->volFadeDest;
-							_track[l]->volFadeUsed = false;
+			if (track->volFadeUsed) {
+				if (track->volFadeStep < 0) {
+					if (track->vol > track->volFadeDest) {
+						track->vol += track->volFadeStep;
+						if (track->vol < track->volFadeDest) {
+							track->vol = track->volFadeDest;
+							track->volFadeUsed = false;
 						}
-						if (_track[l]->vol == 0) {
-							_track[l]->toBeRemoved = true;
+						if (track->vol == 0) {
+							track->toBeRemoved = true;
 						}
 					}
-				} else if (_track[l]->volFadeStep > 0) {
-					if (_track[l]->vol < _track[l]->volFadeDest) {
-						_track[l]->vol += _track[l]->volFadeStep;
-						if (_track[l]->vol > _track[l]->volFadeDest) {
-							_track[l]->vol = _track[l]->volFadeDest;
-							_track[l]->volFadeUsed = false;
+				} else if (track->volFadeStep > 0) {
+					if (track->vol < track->volFadeDest) {
+						track->vol += track->volFadeStep;
+						if (track->vol > track->volFadeDest) {
+							track->vol = track->volFadeDest;
+							track->volFadeUsed = false;
 						}
 					}
 				}
-				debug(5, "Fade: sound(%d), Vol(%d)", _track[l]->soundId, _track[l]->vol / 1000);
+				debug(5, "Fade: sound(%d), Vol(%d)", track->soundId, track->vol / 1000);
 			}
 
-			int pan = (_track[l]->pan != 64) ? 2 * _track[l]->pan - 127 : 0;
-			int vol = _track[l]->vol / 1000;
+			int pan = (track->pan != 64) ? 2 * track->pan - 127 : 0;
+			int vol = track->vol / 1000;
 
-			if (_track[l]->volGroupId == 1)
+			if (track->volGroupId == 1)
 				vol = (vol * _volVoice) / 128;
-			if (_track[l]->volGroupId == 2)
+			if (track->volGroupId == 2)
 				vol = (vol * _volSfx) / 128;
-			if (_track[l]->volGroupId == 3)
+			if (track->volGroupId == 3)
 				vol = (vol * _volMusic) / 128;
 
-			if (_vm->_mixer->isReady()) {
-				if (_track[l]->stream2) {
-					if (!_track[l]->started) {
-						_track[l]->started = true;
-						_vm->_mixer->playInputStream(&_track[l]->handle, _track[l]->stream2, false, _track[l]->vol / 1000, _track[l]->pan, -1, false);
-					} else {
-						_vm->_mixer->setChannelVolume(_track[l]->handle, vol);
-						_vm->_mixer->setChannelBalance(_track[l]->handle, pan);
-					}
-					continue;
-				}
-			}
+			track->mixerVol = vol;
+			track->mixerPan = pan;
 
-			if (_track[l]->stream) {
+			if (track->stream) {
 				byte *data = NULL;
 				int32 result = 0;
 
-				if (_track[l]->curRegion == -1) {
+				if (track->curRegion == -1) {
 					switchToNextRegion(l);
-					if (_track[l]->toBeRemoved)
+					if (track->toBeRemoved)
 						continue;
 				}
 
-				int bits = _sound->getBits(_track[l]->soundHandle);
-				int channels = _sound->getChannels(_track[l]->soundHandle);
+				int bits = _sound->getBits(track->soundHandle);
+				int channels = _sound->getChannels(track->soundHandle);
 
-				int32 mixer_size = _track[l]->iteration / 25;
+				int32 mixer_size = track->iteration / _callbackFps;
+
+				if (track->stream->endOfData()) {
+					mixer_size *= 2;
+				}
 
 				if ((bits == 12) || (bits == 16)) {
 					if (channels == 1)
@@ -188,18 +167,18 @@
 					if (bits == 12) {
 						byte *ptr = NULL;
 
-						mixer_size += _track[l]->mod;
+						mixer_size += track->mod;
 						int mixer_size_12 = (mixer_size * 3) / 4;
 						int length = (mixer_size_12 / 3) * 4;
-						_track[l]->mod = mixer_size - length;
+						track->mod = mixer_size - length;
 
-						int32 offset = (_track[l]->regionOffset * 3) / 4;
-						int result2 = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &ptr, offset, mixer_size_12);
+						int32 offset = (track->regionOffset * 3) / 4;
+						int result2 = _sound->getDataFromRegion(track->soundHandle, track->curRegion, &ptr, offset, mixer_size_12);
 						result = BundleCodecs::decode12BitsSample(ptr, &data, result2);
 
 						free(ptr);
 					} else if (bits == 16) {
-						result = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &data, _track[l]->regionOffset, mixer_size);
+						result = _sound->getDataFromRegion(track->soundHandle, track->curRegion, &data, track->regionOffset, mixer_size);
 						if (channels == 1) {
 							result &= ~1;
 						}
@@ -207,7 +186,7 @@
 							result &= ~3;
 						}
 					} else if (bits == 8) {
-						result = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &data, _track[l]->regionOffset, mixer_size);
+						result = _sound->getDataFromRegion(track->soundHandle, track->curRegion, &data, track->regionOffset, mixer_size);
 						if (channels == 2) {
 							result &= ~1;
 						}
@@ -217,81 +196,94 @@
 						result = mixer_size;
 
 					if (_vm->_mixer->isReady()) {
-						_vm->_mixer->setChannelVolume(_track[l]->handle, vol);
-						_vm->_mixer->setChannelBalance(_track[l]->handle, pan);
-						_track[l]->stream->append(data, result);
-						_track[l]->regionOffset += result;
-						_track[l]->trackOffset += result;
+						_vm->_mixer->setChannelVolume(track->handle, vol);
+						_vm->_mixer->setChannelBalance(track->handle, pan);
+						track->stream->append(data, result);
+						track->regionOffset += result;
 						free(data);
 					}
 
-					if (_sound->isEndOfRegion(_track[l]->soundHandle, _track[l]->curRegion)) {
+					if (_sound->isEndOfRegion(track->soundHandle, track->curRegion)) {
 						switchToNextRegion(l);
-						if (_track[l]->toBeRemoved)
+						if (track->toBeRemoved)
 							break;
 					}
 					mixer_size -= result;
 					assert(mixer_size >= 0);
 				} while (mixer_size != 0);
+			} else if (track->stream2) {
+				if (_vm->_mixer->isReady()) {
+					if (!track->started) {
+						track->started = true;
+						_vm->_mixer->playInputStream(&track->handle, track->stream2, false, vol, pan, -1, false);
+					} else {
+						_vm->_mixer->setChannelVolume(track->handle, vol);
+						_vm->_mixer->setChannelBalance(track->handle, pan);
+					}
+				}
 			}
 		}
 	}
 }
 
-void IMuseDigital::switchToNextRegion(int track) {
-	debug(5, "switchToNextRegion(track:%d)", track);
+void IMuseDigital::switchToNextRegion(int trackId) {
+	debug(5, "switchToNextRegion(track:%d)", trackId);
 
-	if (track >= MAX_DIGITAL_TRACKS) {
-		_track[track]->toBeRemoved = true;
-		debug(5, "exit (fadetrack can't go next region) switchToNextRegion(track:%d)", track);
+	Track *track = _track[trackId];
+	if (trackId >= MAX_DIGITAL_TRACKS) {
+		track->toBeRemoved = true;
+		debug(5, "exit (fadetrack can't go next region) switchToNextRegion(trackId:%d)", trackId);
 		return;
 	}
 
-	int num_regions = _sound->getNumRegions(_track[track]->soundHandle);
+	int num_regions = _sound->getNumRegions(track->soundHandle);
 
-	if (++_track[track]->curRegion == num_regions) {
-		_track[track]->toBeRemoved = true;
-		debug(5, "exit (end of regions) switchToNextRegion(track:%d)", track);
+	if (++track->curRegion == num_regions) {
+		track->toBeRemoved = true;
+		debug(5, "exit (end of regions) switchToNextRegion(track:%d)", trackId);
 		return;
 	}
 
-	int jumpId = _sound->getJumpIdByRegionAndHookId(_track[track]->soundHandle, _track[track]->curRegion, _track[track]->curHookId);
+	ImuseDigiSndMgr::soundStruct *soundHandle = track->soundHandle;
+	int jumpId = _sound->getJumpIdByRegionAndHookId(soundHandle, track->curRegion, track->curHookId);
 	if (jumpId == -1)
-		jumpId = _sound->getJumpIdByRegionAndHookId(_track[track]->soundHandle, _track[track]->curRegion, 0);
+		jumpId = _sound->getJumpIdByRegionAndHookId(soundHandle, track->curRegion, 0);
 	if (jumpId != -1) {
-		int region = _sound->getRegionIdByJumpId(_track[track]->soundHandle, jumpId);
+		int region = _sound->getRegionIdByJumpId(soundHandle, jumpId);
 		assert(region != -1);
-		int sampleHookId = _sound->getJumpHookId(_track[track]->soundHandle, jumpId);
+		int sampleHookId = _sound->getJumpHookId(soundHandle, jumpId);
 		assert(sampleHookId != -1);
-		int fadeDelay = (60 * _sound->getJumpFade(_track[track]->soundHandle, jumpId)) / 1000;
+		int fadeDelay = (60 * _sound->getJumpFade(soundHandle, jumpId)) / 1000;
 		if (sampleHookId != 0) {
-			if (_track[track]->curHookId == sampleHookId) {
+			if (track->curHookId == sampleHookId) {
 				if (fadeDelay != 0) {
-					int fadeTrack = cloneToFadeOutTrack(track, fadeDelay, false);
-					_track[fadeTrack]->dataOffset = _sound->getRegionOffset(_track[fadeTrack]->soundHandle, _track[fadeTrack]->curRegion);
-					_track[fadeTrack]->regionOffset = 0;
-					debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", _track[fadeTrack]->soundId, _track[fadeTrack]->curRegion, _track[fadeTrack]->curHookId);
-					_track[fadeTrack]->curHookId = 0;
+					int fadeTrackId = cloneToFadeOutTrack(trackId, fadeDelay);
+					Track *fadeTrack = _track[fadeTrackId];
+					fadeTrack->dataOffset = _sound->getRegionOffset(fadeTrack->soundHandle, fadeTrack->curRegion);
+					fadeTrack->regionOffset = 0;
+					debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", fadeTrack->soundId, fadeTrack->curRegion, fadeTrack->curHookId);
+					fadeTrack->curHookId = 0;
 				}
-				_track[track]->curRegion = region;
-				debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", _track[track]->soundId, _track[track]->curRegion, _track[track]->curHookId);
-				_track[track]->curHookId = 0;
+				track->curRegion = region;
+				debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", track->soundId, track->curRegion, track->curHookId);
+				track->curHookId = 0;
 			}
 		} else {
 			if (fadeDelay != 0) {
-				int fadeTrack = cloneToFadeOutTrack(track, fadeDelay, false);
-				_track[fadeTrack]->dataOffset = _sound->getRegionOffset(_track[fadeTrack]->soundHandle, _track[fadeTrack]->curRegion);
-				_track[fadeTrack]->regionOffset = 0;
-				debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", _track[fadeTrack]->soundId, _track[fadeTrack]->curRegion, _track[fadeTrack]->curHookId);
+				int fadeTrackId = cloneToFadeOutTrack(trackId, fadeDelay);
+				Track *fadeTrack = _track[fadeTrackId];
+				fadeTrack->dataOffset = _sound->getRegionOffset(fadeTrack->soundHandle, fadeTrack->curRegion);
+				fadeTrack->regionOffset = 0;
+				debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", fadeTrack->soundId, fadeTrack->curRegion, fadeTrack->curHookId);
 			}
-			_track[track]->curRegion = region;
-			debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", _track[track]->soundId, _track[track]->curRegion, _track[track]->curHookId);
+			track->curRegion = region;
+			debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", track->soundId, track->curRegion, track->curHookId);
 		}
 	}
 
-	debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", _track[track]->soundId, _track[track]->curRegion, _track[track]->curHookId);
-	_track[track]->dataOffset = _sound->getRegionOffset(_track[track]->soundHandle, _track[track]->curRegion);
-	_track[track]->regionOffset = 0;
+	debug(5, "switchToNextRegion-sound(%d) select %d region, curHookId: %d", track->soundId, track->curRegion, track->curHookId);
+	track->dataOffset = _sound->getRegionOffset(soundHandle, track->curRegion);
+	track->regionOffset = 0;
 }
 
 } // End of namespace Scumm

Index: dimuse.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse.h,v
retrieving revision 1.31.2.1
retrieving revision 1.31.2.2
diff -u -d -r1.31.2.1 -r1.31.2.2
--- dimuse.h	2 May 2004 16:36:04 -0000	1.31.2.1
+++ dimuse.h	26 Jun 2004 09:18:29 -0000	1.31.2.2
@@ -43,6 +43,8 @@
 class IMuseDigital : public MusicEngine {
 private:
 
+	int _callbackFps;
+
 	struct Track {
 		int8 pan;			// pan
 		int32 vol;			// volume
@@ -55,11 +57,11 @@
 		char soundName[15];
 		bool used;
 		bool toBeRemoved;
+		bool readyToRemove;
 		bool started;
 		bool souStream;
 		int32 priority;
 		int32 regionOffset;
-		int32 trackOffset;
 		int32 dataOffset;
 		int32 curRegion;
 		int32 curHookId;
@@ -99,8 +101,8 @@
 
 	static void timer_handler(void *refConf);
 	void callback();
-	void switchToNextRegion(int track);
-	bool allocSlot(int priority);
+	void switchToNextRegion(int trackId);
+	int allocSlot(int priority);
 	void startSound(int soundId, const char *soundName, int soundType, int volGroupId, AudioStream *input, int hookId, int volume, int priority);
 	void selectVolumeGroup(int soundId, int volGroupId);
 
@@ -109,7 +111,7 @@
 
 	int getSoundIdByName(const char *soundName);
 	void fadeOutMusic(int fadeDelay);
-	int cloneToFadeOutTrack(int track, int fadeDelay, int killNormalTrack);
+	int cloneToFadeOutTrack(int trackId, int fadeDelay);
 
 	void setFtMusicState(int stateId);
 	void setFtMusicSequence(int seqId);
@@ -125,7 +127,7 @@
 	void playDigMusic(const char *songName, const imuseDigTable *table, int atribPos, bool sequence);
 
 public:
-	IMuseDigital(ScummEngine *scumm);
+	IMuseDigital(ScummEngine *scumm, int fps);
 	virtual ~IMuseDigital();
 
 	void startVoice(int soundId, AudioStream *input);
@@ -156,6 +158,7 @@
 	void pause(bool pause);
 	void parseScriptCmds(int a, int b, int c, int d, int e, int f, int g, int h);
 	void refreshScripts();
+	void flushTracks();
 	int getSoundStatus(int sound) const;
 	int32 getCurMusicPosInMs();
 	int32 getCurVoiceLipSyncWidth();

Index: dimuse_bndmgr.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_bndmgr.cpp,v
retrieving revision 1.14.2.2
retrieving revision 1.14.2.3
diff -u -d -r1.14.2.2 -r1.14.2.3
--- dimuse_bndmgr.cpp	2 May 2004 16:36:04 -0000	1.14.2.2
+++ dimuse_bndmgr.cpp	26 Jun 2004 09:18:29 -0000	1.14.2.3
@@ -104,7 +104,7 @@
 			name[z] = '\0';
 			strcpy(_budleDirCache[freeSlot].bundleTable[i].filename, name);
 			_budleDirCache[freeSlot].bundleTable[i].offset = file.readUint32BE();
-			_budleDirCache[freeSlot].bundleTable[i].size = file.readUint32BE();
+			file.seek(4, SEEK_CUR);
 		}
 		return freeSlot;
 	} else {
@@ -140,7 +140,7 @@
 	_bundleTable = _cache->getTable(filename, directory);
 	assert(_bundleTable);
 	_compTableLoaded = false;
-	_lastCacheOutputSize = 0;
+	_outputSize = 0;
 	_lastBlock = -1;
 
 	return true;
@@ -154,10 +154,14 @@
 		_numCompItems = 0;
 		_compTableLoaded = false;
 		_lastBlock = -1;
-		_lastCacheOutputSize = 0;
+		_outputSize = 0;
 		_curSample = -1;
 		free(_compTable);
 		_compTable = NULL;
+		if (_compInput) {
+			free(_compInput);
+			_compInput = NULL;
+		}
 	}
 }
 
@@ -167,7 +171,6 @@
 
 int32 BundleMgr::decompressSampleByIndex(int32 index, int32 offset, int32 size, byte **comp_final, int header_size, bool header_outside) {
 	int32 i, tag, num, final_size, output_size;
-	byte *comp_input, *comp_output;
 	int skip, first_block, last_block;
 	
 	if (index != -1)
@@ -182,8 +185,7 @@
 		_file.seek(_bundleTable[index].offset, SEEK_SET);
 		tag = _file.readUint32BE();
 		_numCompItems = num = _file.readUint32BE();
-		_file.readUint32BE();
-		_file.readUint32BE();
+		_file.seek(8, SEEK_CUR);
 
 		if (tag != MKID_BE('COMP')) {
 			warning("BundleMgr::decompressSampleByIndex() Compressed sound %d invalid (%s)", index, tag2str(tag));
@@ -191,23 +193,27 @@
 		}
 
 		_compTable = (CompTable *)malloc(sizeof(CompTable) * num);
+		int32 maxSize = 0;
 		for (i = 0; i < num; i++) {
 			_compTable[i].offset = _file.readUint32BE();
 			_compTable[i].size = _file.readUint32BE();
 			_compTable[i].codec = _file.readUint32BE();
-			_file.readUint32BE();
+			_file.seek(4, SEEK_CUR);
+			if (_compTable[i].size > maxSize)
+				maxSize = _compTable[i].size;
 		}
+		// CMI hack: one more byte at the end of input buffer
+		_compInput = (byte *)malloc(maxSize + 1);
 		_compTableLoaded = true;
 	}
 
 	first_block = (offset + header_size) / 0x2000;
 	last_block = (offset + size + header_size - 1) / 0x2000;
 
-	// workaround for bug when (offset + size + header_size - 1) is more one byte after sound resource
+	// case when (offset + size + header_size - 1) is more one byte after sound resource
 	if ((last_block >= _numCompItems) && (_numCompItems > 0))
 		last_block = _numCompItems - 1;
 
-	comp_output = (byte *)malloc(0x2000);
 	int32 blocks_final_size = 0x2000 * (1 + last_block - first_block);
 	*comp_final = (byte *)malloc(blocks_final_size);
 	final_size = 0;
@@ -215,26 +221,17 @@
 	skip = offset - (first_block * 0x2000) + header_size;
 
 	for (i = first_block; i <= last_block; i++) {
-		byte *curBuf;
 		if (_lastBlock != i) {
 			// CMI hack: one more zero byte at the end of input buffer
-			comp_input = (byte *)malloc(_compTable[i].size + 1);
-			comp_input[_compTable[i].size] = 0;
+			_compInput[_compTable[i].size] = 0;
 			_file.seek(_bundleTable[index].offset + _compTable[i].offset, SEEK_SET);
-			_file.read(comp_input, _compTable[i].size);
-
-			output_size = BundleCodecs::decompressCodec(_compTable[i].codec, comp_input, comp_output, _compTable[i].size);
-			assert(output_size <= 0x2000);
+			_file.read(_compInput, _compTable[i].size);
+			_outputSize = BundleCodecs::decompressCodec(_compTable[i].codec, _compInput, _compOutput, _compTable[i].size);
 			_lastBlock = i;
-			_lastCacheOutputSize = output_size;
-			memcpy(_blockChache, comp_output, output_size);
-			curBuf = comp_output;
-			free(comp_input);
-		} else {
-			output_size = _lastCacheOutputSize;
-			curBuf = _blockChache;
 		}
 
+		output_size = _outputSize;
+
 		if (header_outside) {
 			output_size -= skip;
 		} else {
@@ -247,16 +244,16 @@
 
 		assert(final_size + output_size <= blocks_final_size);
 
-		memcpy(*comp_final + final_size, curBuf + skip, output_size);
-
+		memcpy(*comp_final + final_size, _compOutput + skip, output_size);
 		final_size += output_size;
+
 		size -= output_size;
 		assert(size >= 0);
 		if (size == 0)
 			break;
+
 		skip = 0;
 	}
-	free(comp_output);
 
 	return final_size;
 }

Index: dimuse_bndmgr.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_bndmgr.h,v
retrieving revision 1.5.2.2
retrieving revision 1.5.2.3
diff -u -d -r1.5.2.2 -r1.5.2.3
--- dimuse_bndmgr.h	2 May 2004 16:36:04 -0000	1.5.2.2
+++ dimuse_bndmgr.h	26 Jun 2004 09:18:29 -0000	1.5.2.3
@@ -30,7 +30,6 @@
 public:
 	struct AudioTable {
 		char filename[13];
-		int32 size;
 		int32 offset;
 	};
 private:
@@ -63,15 +62,16 @@
 	BundleDirCache *_cache;
 	BundleDirCache::AudioTable *_bundleTable;
 	CompTable *_compTable;
-	int32 _numFiles;
-	int32 _numCompItems;
-	int32 _curSample;
+	int _numFiles;
+	int _numCompItems;
+	int _curSample;
 	File _file;
 	bool _compTableLoaded;
 	int _fileBundleId;
-	byte _blockChache[0x2000];
-	int32 _lastCacheOutputSize;
-	int32 _lastBlock;
+	byte _compOutput[0x2000];
+	byte *_compInput;
+	int _outputSize;
+	int _lastBlock;
 
 public:
 

Index: dimuse_codecs.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_codecs.cpp,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -d -r1.3 -r1.3.2.1
--- dimuse_codecs.cpp	8 Jan 2004 15:48:41 -0000	1.3
+++ dimuse_codecs.cpp	26 Jun 2004 09:18:29 -0000	1.3.2.1
@@ -194,7 +194,7 @@
 	int data, size, bit, bitsleft = 16, mask = READ_LE_UINT16(srcptr);
 	srcptr += 2;
 
-	while (1) {
+	for (;;) {
 		NextBit;
 		if (bit) {
 			*dstptr++ = *srcptr++;
@@ -269,22 +269,23 @@
 		memset(t_table, 0, output_size);
 
 		src = comp_output;
-		length = (output_size * 8) / 12;
+		length = (output_size << 3) / 12;
 		k = 0;
 		if (length > 0) {
 			c = -12;
 			s = 0;
 			j = 0;
 			do {
-				ptr = src + length + k / 2;
+				ptr = src + length + (k >> 1);
+				t_tmp2 = src[j];
 				if (k & 1) {
-					r = c / 8;
-					t_table[r + 2] = ((src[j] & 0x0f) << 4) | (ptr[1] >> 4);
-					t_table[r + 1] = (src[j] & 0xf0) | (t_table[r + 1]);
+					r = c >> 3;
+					t_table[r + 2] = ((t_tmp2 & 0x0f) << 4) | (ptr[1] >> 4);
+					t_table[r + 1] = (t_tmp2 & 0xf0) | (t_table[r + 1]);
 				} else {
-					r = s / 8;
-					t_table[r + 0] = ((src[j] & 0x0f) << 4) | (ptr[0] & 0x0f);
-					t_table[r + 1] = src[j] >> 4;
+					r = s >> 3;
+					t_table[r + 0] = ((t_tmp2 & 0x0f) << 4) | (ptr[0] & 0x0f);
+					t_table[r + 1] = t_tmp2 >> 4;
 				}
 				s += 12;
 				c += 12;
@@ -292,7 +293,7 @@
 				j++;
 			} while (k < length);
 		}
-		offset1 = ((length - 1) * 3) / 2;
+		offset1 = ((length - 1) * 3) >> 1;
 		t_table[offset1 + 1] = (t_table[offset1 + 1]) | (src[length - 1] & 0xf0);
 		memcpy(src, t_table, output_size);
 		free(t_table);
@@ -310,24 +311,25 @@
 		memset(t_table, 0, output_size);
 
 		src = comp_output;
-		length = (output_size * 8) / 12;
+		length = (output_size << 3) / 12;
 		k = 1;
 		c = 0;
 		s = 12;
-		t_table[0] = src[length] / 16;
+		t_table[0] = src[length] >> 4;
 		t = length + k;
 		j = 1;
 		if (t > k) {
 			do {
-				ptr = src + length + k / 2;
+				t_tmp1 = *(src + length + (k >> 1));
+				t_tmp2 = src[j - 1];
 				if (k & 1) {
-					r = c / 8;
-					t_table[r + 0] = (src[j - 1] & 0xf0) | t_table[r];
-					t_table[r + 1] = ((src[j - 1] & 0x0f) << 4) | (ptr[0] & 0x0f);
+					r = c >> 3;
+					t_table[r + 0] = (t_tmp2 & 0xf0) | t_table[r];
+					t_table[r + 1] = ((t_tmp2 & 0x0f) << 4) | (t_tmp1 & 0x0f);
 				} else {
-					r = s / 8;
-					t_table[r + 0] = src[j - 1] >> 4;
-					t_table[r - 1] = ((src[j - 1] & 0x0f) << 4) | (ptr[0] >> 4);
+					r = s >> 3;
+					t_table[r + 0] = t_tmp2 >> 4;
+					t_table[r - 1] = ((t_tmp2 & 0x0f) << 4) | (t_tmp1 >> 4);
 				}
 				s += 12;
 				c += 12;
@@ -351,7 +353,7 @@
 		memset(t_table, 0, output_size);
 
 		src = comp_output;
-		length = (output_size * 8) / 12;
+		length = (output_size << 3) / 12;
 		k = 0;
 		c = 0;
 		j = 0;
@@ -361,15 +363,16 @@
 		t = length - 1;
 		if (t > 0) {
 			do {
-				ptr = src + length + k / 2;
+				t_tmp1 = *(src + length + (k >> 1));
+				t_tmp2 = src[j];
 				if (k & 1) {
-					r = s / 8;
-					t_table[r + 2] = (src[j] & 0xf0) | *(t_table + r + 2);
-					t_table[r + 3] = ((src[j] & 0x0f) << 4) | (ptr[0] >> 4);
+					r = s >> 3;
+					t_table[r + 2] = (t_tmp2 & 0xf0) | t_table[r + 2];
+					t_table[r + 3] = ((t_tmp2 & 0x0f) << 4) | (t_tmp1 >> 4);
 				} else {
-					r = c / 8;
-					t_table[r + 2] = src[j] >> 4;
-					t_table[r + 1] = ((src[j] & 0x0f) << 4) | (ptr[0] & 0x0f);
+					r = c >> 3;
+					t_table[r + 2] = t_tmp2 >> 4;
+					t_table[r + 1] = ((t_tmp2 & 0x0f) << 4) | (t_tmp1 & 0x0f);
 				}
 				s += 12;
 				c += 12;
@@ -393,36 +396,33 @@
 		memcpy(t_table, p, output_size);
 
 		offset1 = output_size / 3;
-		offset2 = offset1 * 2;
+		offset2 = offset1 << 1;
 		offset3 = offset2;
 		src = comp_output;
-		do {
-			if (offset1 == 0)
-				break;
-			offset1--;
+
+		while (offset1--) {
 			offset2 -= 2;
 			offset3--;
 			t_table[offset2 + 0] = src[offset1];
 			t_table[offset2 + 1] = src[offset3];
-		} while (1);
+		}
 
 		src = comp_output;
-		length = (output_size * 8) / 12;
+		length = (output_size << 3) / 12;
 		k = 0;
 		if (length > 0) {
 			c = -12;
 			s = 0;
 			do {
-				j = length + k / 2;
+				j = length + (k >> 1);
+				t_tmp1 = t_table[k];
 				if (k & 1) {
-					r = c / 8;
-					t_tmp1 = t_table[k];
+					r = c >> 3;
 					t_tmp2 = t_table[j + 1];
 					src[r + 2] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 >> 4);
 					src[r + 1] = (src[r + 1]) | (t_tmp1 & 0xf0);
 				} else {
-					r = s / 8;
-					t_tmp1 = t_table[k];
+					r = s >> 3;
 					t_tmp2 = t_table[j];
 					src[r + 0] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
 					src[r + 1] = t_tmp1 >> 4;
@@ -432,7 +432,7 @@
 				k++;
 			} while (k < length);
 		}
-		offset1 = ((length - 1) * 3) / 2;
+		offset1 = ((length - 1) * 3) >> 1;
 		src[offset1 + 1] = (t_table[length] & 0xf0) | src[offset1 + 1];
 		free(t_table);
 		break;
@@ -449,40 +449,36 @@
 		memcpy(t_table, p, output_size);
 
 		offset1 = output_size / 3;
-		offset2 = offset1 * 2;
+		offset2 = offset1 << 1;
 		offset3 = offset2;
 		src = comp_output;
-		do {
-			if (offset1 == 0)
-				break;
-			offset1--;
+
+		while (offset1--) {
 			offset2 -= 2;
 			offset3--;
 			t_table[offset2 + 0] = src[offset1];
 			t_table[offset2 + 1] = src[offset3];
-		} while (1);
+		}
 
 		src = comp_output;
-		length = (output_size * 8) / 12;
+		length = (output_size << 3) / 12;
 		k = 1;
 		c = 0;
 		s = 12;
-		t_tmp1 = t_table[length] / 16;
+		t_tmp1 = t_table[length] >> 4;
 		src[0] = t_tmp1;
 		t = length + k;
 		if (t > k) {
 			do {
-				j = length + k / 2;
+				j = length + (k >> 1);
+				t_tmp1 = t_table[k - 1];
+				t_tmp2 = t_table[j];
 				if (k & 1) {
-					r = c / 8;
-					t_tmp1 = t_table[k - 1];
-					t_tmp2 = t_table[j];
+					r = c >> 3;
 					src[r + 0] = (src[r]) | (t_tmp1 & 0xf0);
 					src[r + 1] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
 				} else {
-					r = s / 8;
-					t_tmp1 = t_table[k - 1];
-					t_tmp2 = t_table[j];
+					r = s >> 3;
 					src[r + 0] = t_tmp1 >> 4;
 					src[r - 1] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 >> 4);
 				}
@@ -506,21 +502,19 @@
 		memcpy(t_table, p, output_size);
 
 		offset1 = output_size / 3;
-		offset2 = offset1 * 2;
+		offset2 = offset1 << 1;
 		offset3 = offset2;
 		src = comp_output;
-		do {
-			if (offset1 == 0)
-				break;
-			offset1--;
+
+		while (offset1--) {
 			offset2 -= 2;
 			offset3--;
 			t_table[offset2 + 0] = src[offset1];
 			t_table[offset2 + 1] = src[offset3];
-		} while (1);
+		}
 
 		src = comp_output;
-		length = (output_size * 8) / 12;
+		length = (output_size << 3) / 12;
 		k = 0;
 		c = 0;
 		s = -12;
@@ -529,17 +523,15 @@
 		t = length - 1;
 		if (t > 0) {
 			do {
-				j = length + k / 2;
+				j = length + (k >> 1);
+				t_tmp1 = t_table[k];
+				t_tmp2 = t_table[j];
 				if (k & 1) {
-					r = s / 8;
-					t_tmp1 = t_table[k];
-					t_tmp2 = t_table[j];
+					r = s >> 3;
 					src[r + 2] = (src[r + 2]) | (t_tmp1 & 0xf0);
 					src[r + 3] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 >> 4);
 				} else {
-					r = c / 8;
-					t_tmp1 = t_table[k];
-					t_tmp2 = t_table[j];
+					r = c >> 3;
 					src[r + 2] = t_tmp1 >> 4;
 					src[r + 1] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
 				}
@@ -592,8 +584,8 @@
 					left = 0x2000 - firstWord;
 					output_size = left;
 				} else {
-					left = 0x1000 - firstWord / 2;
-					output_size = left * 2;
+					left = 0x1000 - (firstWord >> 1);
+					output_size = left << 1;
 				}
 				output_size += firstWord;
 			} else {
@@ -621,38 +613,19 @@
 				}
 
 				left = origLeft;
-				destPos = l * 2;
+				destPos = l << 1;
 
 				if (channels == 2) {
 					if (l == 0)
 						left++;
-					left /= 2;
+					left >>= 1;
 				}
 
 				while (left--) {
 					curTableEntry = _destImcTable[curTablePos];
 					decompTable = (byte)(curTableEntry - 2);
 					bitMask = 2 << decompTable;
-					readPos = src + tableEntrySum / 8;
-					
-					// FIXME - it seems the decoder often reads exactly one byte too
-					// far - that is, it reads 2 bytes at once, and the second byte
-					// is just outside the buffer. However, it seems of these two bytes,
-					// only the upper one is actually used, so this should be fine.
-					// Still, I put this error message into place. If somebody one day
-					// encounters a situation where the second byte would be used, too,
-					// then this would indicate there is a bug in the decoder...
-					if (readPos + 1 >= comp_input + input_size) {
-						// OK an overflow... if it is more than one byte or if we
-						// need more than 8 bit of data -> error
-						if (readPos + 1 > comp_input + input_size ||
-						    curTableEntry + (tableEntrySum & 7) > 8) {
-							error("decompressCodec: input buffer overflow: %d bytes over (we need %d bits of data)",
-									(int)((readPos + 1) - (comp_input + input_size)) + 1,
-									curTableEntry + (tableEntrySum & 7)
-								);
-						}
-					}
+					readPos = src + (tableEntrySum >> 3);
 					readWord = (uint16)(READ_BE_UINT16(readPos) << (tableEntrySum & 7));
 					otherTablePos = (byte)(readWord >> (16 - curTableEntry));
 					tableEntrySum += curTableEntry;
@@ -682,7 +655,7 @@
 						curTablePos = 0;
 					imcTableEntry = imcTable[curTablePos];
 
-					destPos += channels * 2;
+					destPos += channels << 1;
 				}
 			}
 		}

Index: dimuse_script.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_script.cpp,v
retrieving revision 1.7.2.2
retrieving revision 1.7.2.3
diff -u -d -r1.7.2.2 -r1.7.2.3
--- dimuse_script.cpp	3 May 2004 11:32:49 -0000	1.7.2.2
+++ dimuse_script.cpp	26 Jun 2004 09:18:29 -0000	1.7.2.3
@@ -159,16 +159,45 @@
 	}
 }
 
+void 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 || (_vm->_insaneRunning && track->toBeRemoved))) {
+			if (track->stream) {
+				if (!track->stream->endOfStream()) {
+	 				track->stream->finish();
+	 			}
+				if (track->stream->endOfStream() || _vm->_insaneRunning) {
+					_vm->_mixer->stopHandle(track->handle);
+					delete track->stream;
+					track->stream = NULL;
+					_sound->closeSound(track->soundHandle);
+					track->soundHandle = NULL;
+					track->used = false;
+				}
+			} else if (track->stream2) {
+				_vm->_mixer->stopHandle(track->handle);
+				delete track->stream2;
+				track->stream2 = NULL;
+				track->used = false;
+			}
+		}
+	}
+}
+
 void IMuseDigital::refreshScripts() {
-	Common::StackLock lock(_mutex);
+	debug(5, "refreshScripts()");
 	bool found = false;
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+		Track *track = _track[l];
+		if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
 			found = true;
 		}
 	}
 
-	if ((!found) && (_curMusicSeq != 0)) {
+	if (!found && (_curMusicSeq != 0)) {
+		debug(5, "refreshScripts() Start Sequence");
 		parseScriptCmds(0x1001, 0, 0, 0, 0, 0, 0, 0);
 	}
 }
@@ -205,8 +234,9 @@
 	msPos /= 16;
 	if (msPos < 65536) {
 		for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-			if ((_track[l]->soundId == soundId) && _track[l]->used) {
-				_sound->getSyncSizeAndPtrById(_track[l]->soundHandle, syncId, sync_size, &sync_ptr);
+			Track *track = _track[l];
+			if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+				_sound->getSyncSizeAndPtrById(track->soundHandle, syncId, sync_size, &sync_ptr);
 				if ((sync_size != 0) && (sync_ptr != NULL)) {
 					sync_size /= 4;
 					while (sync_size--) {
@@ -231,8 +261,9 @@
 
 int32 IMuseDigital::getPosInMs(int soundId) {
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->soundId == soundId) && _track[l]->used) {
-			int32 pos = (5 * (_track[l]->dataOffset + _track[l]->regionOffset)) / (_track[l]->iteration / 200);
+		Track *track = _track[l];
+		if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+			int32 pos = (5 * (track->dataOffset + track->regionOffset)) / (track->iteration / 200);
 			return pos;
 		}
 	}
@@ -241,11 +272,14 @@
 }
 
 int IMuseDigital::getSoundStatus(int sound) const {
-	Common::StackLock lock(_mutex);
 	debug(5, "IMuseDigital::getSoundStatus(%d)", sound);
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->soundId == sound) && _track[l]->handle.isActive()) {
-			return 1;
+		Track *track = _track[l];
+		if (track->soundId == sound) {
+			if ((track->stream2 && track->handle.isActive()) ||
+				(track->stream && track->used)) {
+					return 1;
+			}
 		}
 	}
 
@@ -253,33 +287,22 @@
 }
 
 void IMuseDigital::stopSound(int soundId) {
-	Common::StackLock lock(_mutex);
 	debug(5, "IMuseDigital::stopSound(%d)", soundId);
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->soundId == soundId) && (_track[l]->used)) {
-			if (_track[l]->stream) {
-				_track[l]->stream->finish();
-				_track[l]->stream = NULL;
-				_vm->_mixer->stopHandle(_track[l]->handle);
-				_sound->closeSound(_track[l]->soundHandle);
-				_track[l]->soundHandle = NULL;
-			} else if (_track[l]->stream2) {
-				_vm->_mixer->stopHandle(_track[l]->handle);
-				delete _track[l]->stream2;
-				_track[l]->stream2 = NULL;
-			}
-			_track[l]->used = false;
+		Track *track = _track[l];
+		if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+			track->toBeRemoved = true;
 		}
 	}
 }
 
 int32 IMuseDigital::getCurMusicPosInMs() {
-	Common::StackLock lock(_mutex);
 	int soundId = -1;
 
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) {
-			soundId = _track[l]->soundId;
+		Track *track = _track[l];
+		if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+			soundId = track->soundId;
 		}
 	}
 
@@ -289,7 +312,6 @@
 }
 
 int32 IMuseDigital::getCurVoiceLipSyncWidth() {
-	Common::StackLock lock(_mutex);
 	int32 msPos = getPosInMs(kTalkSoundID) + 50;
 	int32 width = 0, height = 0;
 
@@ -299,7 +321,6 @@
 }
 
 int32 IMuseDigital::getCurVoiceLipSyncHeight() {
-	Common::StackLock lock(_mutex);
 	int32 msPos = getPosInMs(kTalkSoundID) + 50;
 	int32 width = 0, height = 0;
 
@@ -309,12 +330,12 @@
 }
 
 int32 IMuseDigital::getCurMusicLipSyncWidth(int syncId) {
-	Common::StackLock lock(_mutex);
 	int soundId = -1;
 
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC) && _track[l]->used) {
-			soundId = _track[l]->soundId;
+		Track *track = _track[l];
+		if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+			soundId = track->soundId;
 		}
 	}
 
@@ -327,12 +348,12 @@
 }
 
 int32 IMuseDigital::getCurMusicLipSyncHeight(int syncId) {
-	Common::StackLock lock(_mutex);
 	int soundId = -1;
 
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) {
-			soundId = _track[l]->soundId;
+		Track *track = _track[l];
+		if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+			soundId = track->soundId;
 		}
 	}
 
@@ -345,32 +366,29 @@
 }
 
 void IMuseDigital::stopAllSounds() {
-	Common::StackLock lock(_mutex);
 	debug(5, "IMuseDigital::stopAllSounds");
 
-	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
-		if (_track[l]->used) {
-			if (_track[l]->stream) {
-				_track[l]->stream->finish();
-				_track[l]->stream = NULL;
-				_vm->_mixer->stopHandle(_track[l]->handle);
-				_sound->closeSound(_track[l]->soundHandle);
-				_track[l]->soundHandle = NULL;
-			} else if (_track[l]->stream2) {
-				_vm->_mixer->stopHandle(_track[l]->handle);
-				delete _track[l]->stream2;
-				_track[l]->stream2 = NULL;
+	for(;;) {
+		bool foundNotRemoved = false;
+		for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+			Track *track = _track[l];
+			if (track->used) {
+				track->toBeRemoved = true;
+				foundNotRemoved = true;
 			}
-			_track[l]->used = false;
 		}
+		if (!foundNotRemoved)
+			break;
+		flushTracks();
+		_vm->_system->delay_msecs(50);
 	}
 }
 
 void IMuseDigital::pause(bool p) {
-	Common::StackLock lock(_mutex);
 	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
-		if (_track[l]->used) {
-			_vm->_mixer->pauseHandle(_track[l]->handle, p);
+		Track *track = _track[l];
+		if (track->used) {
+			_vm->_mixer->pauseHandle(track->handle, p);
 		}
 	}
 	_pause = p;

Index: dimuse_sndmgr.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_sndmgr.cpp,v
retrieving revision 1.26.2.3
retrieving revision 1.26.2.4
diff -u -d -r1.26.2.3 -r1.26.2.4
--- dimuse_sndmgr.cpp	2 May 2004 16:36:04 -0000	1.26.2.3
+++ dimuse_sndmgr.cpp	26 Jun 2004 09:18:29 -0000	1.26.2.4
@@ -79,7 +79,7 @@
 	} while (tag != MKID_BE('DATA'));
 }
 
-void ImuseDigiSndMgr::prepareSound(byte *ptr, int slot) {
+void ImuseDigiSndMgr::prepareSound(byte *ptr, soundStruct *sound) {
 	if (READ_UINT32(ptr) == MKID('Crea')) {
 		bool quit = false;
 		int len;
@@ -87,12 +87,11 @@
 		int32 offset = READ_LE_UINT16(ptr + 20);
 		int16 code = READ_LE_UINT16(ptr + 24);
 
-		_sounds[slot].region = (_region *)malloc(sizeof(_region) * 70);
-		_sounds[slot].jump = (_jump *)malloc(sizeof(_jump));
-		_sounds[slot].resPtr = ptr;
-		_vm->lock(rtSound, _sounds[slot].soundId);
-		_sounds[slot].bits = 8;
-		_sounds[slot].channels = 1;
+		sound->region = (_region *)malloc(sizeof(_region) * 70);
+		sound->jump = (_jump *)malloc(sizeof(_jump));
+		sound->resPtr = ptr;
+		sound->bits = 8;
+		sound->channels = 1;
 
 		while (!quit) {
 			len = READ_LE_UINT32(ptr + offset);
@@ -117,23 +116,23 @@
 					int time_constant = ptr[offset];
 					offset += 2;
 					len -= 2;
-					_sounds[slot].freq = getSampleRateFromVOCRate(time_constant);
-					_sounds[slot].region[_sounds[slot].numRegions].offset = offset;
-					_sounds[slot].region[_sounds[slot].numRegions].length = len;
-					_sounds[slot].numRegions++;
+					sound->freq = getSampleRateFromVOCRate(time_constant);
+					sound->region[sound->numRegions].offset = offset;
+					sound->region[sound->numRegions].length = len;
+					sound->numRegions++;
 				}
 				break;
 			case 6:	// begin of loop
-				_sounds[slot].jump[0].dest = offset + 8;
-				_sounds[slot].jump[0].hookId = 0;
-				_sounds[slot].jump[0].fadeDelay = 0;
+				sound->jump[0].dest = offset + 8;
+				sound->jump[0].hookId = 0;
+				sound->jump[0].fadeDelay = 0;
 				break;
 			case 7:	// end of loop
-				_sounds[slot].jump[0].offset = offset - 4;
-				_sounds[slot].numJumps++;
-				_sounds[slot].region[_sounds[slot].numRegions].offset = offset - 4;
-				_sounds[slot].region[_sounds[slot].numRegions].length = 0;
-				_sounds[slot].numRegions++;
+				sound->jump[0].offset = offset - 4;
+				sound->numJumps++;
+				sound->region[sound->numRegions].offset = offset - 4;
+				sound->region[sound->numRegions].length = 0;
+				sound->numRegions++;
 				break;
 			default:
 				error("Invalid code in VOC file : %d", code);
@@ -152,22 +151,22 @@
 		int curIndexJump = 0;
 		int curIndexSync = 0;
 
-		_sounds[slot].numRegions = 0;
-		_sounds[slot].numJumps = 0;
-		_sounds[slot].numSyncs = 0;
-		countElements(ptr, _sounds[slot].numRegions, _sounds[slot].numJumps, _sounds[slot].numSyncs);
-		_sounds[slot].region = (_region *)malloc(sizeof(_region) * _sounds[slot].numRegions);
-		_sounds[slot].jump = (_jump *)malloc(sizeof(_jump) * _sounds[slot].numJumps);
-		_sounds[slot].sync = (_sync *)malloc(sizeof(_sync) * _sounds[slot].numSyncs);
+		sound->numRegions = 0;
+		sound->numJumps = 0;
+		sound->numSyncs = 0;
+		countElements(ptr, sound->numRegions, sound->numJumps, sound->numSyncs);
+		sound->region = (_region *)malloc(sizeof(_region) * sound->numRegions);
+		sound->jump = (_jump *)malloc(sizeof(_jump) * sound->numJumps);
+		sound->sync = (_sync *)malloc(sizeof(_sync) * sound->numSyncs);
 
 		do {
 			tag = READ_BE_UINT32(ptr); ptr += 4;
 			switch(tag) {
 			case MKID_BE('FRMT'):
 				ptr += 12;
-				_sounds[slot].bits = READ_BE_UINT32(ptr); ptr += 4;
-				_sounds[slot].freq = READ_BE_UINT32(ptr); ptr += 4;
-				_sounds[slot].channels = READ_BE_UINT32(ptr); ptr += 4;
+				sound->bits = READ_BE_UINT32(ptr); ptr += 4;
+				sound->freq = READ_BE_UINT32(ptr); ptr += 4;
+				sound->channels = READ_BE_UINT32(ptr); ptr += 4;
 				break;
 			case MKID_BE('TEXT'):
 			case MKID_BE('STOP'):
@@ -175,23 +174,23 @@
 				break;
 			case MKID_BE('REGN'):
 				ptr += 4;
-				_sounds[slot].region[curIndexRegion].offset = READ_BE_UINT32(ptr); ptr += 4;
-				_sounds[slot].region[curIndexRegion].length = READ_BE_UINT32(ptr); ptr += 4;
+				sound->region[curIndexRegion].offset = READ_BE_UINT32(ptr); ptr += 4;
+				sound->region[curIndexRegion].length = READ_BE_UINT32(ptr); ptr += 4;
 				curIndexRegion++;
 				break;
 			case MKID_BE('JUMP'):
 				ptr += 4;
-				_sounds[slot].jump[curIndexJump].offset = READ_BE_UINT32(ptr); ptr += 4;
-				_sounds[slot].jump[curIndexJump].dest = READ_BE_UINT32(ptr); ptr += 4;
-				_sounds[slot].jump[curIndexJump].hookId = READ_BE_UINT32(ptr); ptr += 4;
-				_sounds[slot].jump[curIndexJump].fadeDelay = READ_BE_UINT32(ptr); ptr += 4;
+				sound->jump[curIndexJump].offset = READ_BE_UINT32(ptr); ptr += 4;
+				sound->jump[curIndexJump].dest = READ_BE_UINT32(ptr); ptr += 4;
+				sound->jump[curIndexJump].hookId = READ_BE_UINT32(ptr); ptr += 4;
+				sound->jump[curIndexJump].fadeDelay = READ_BE_UINT32(ptr); ptr += 4;
 				curIndexJump++;
 				break;
 			case MKID_BE('SYNC'):
 				size = READ_BE_UINT32(ptr); ptr += 4;
-				_sounds[slot].sync[curIndexSync].size = size;
-				_sounds[slot].sync[curIndexSync].ptr = (byte *)malloc(size);
-				memcpy(_sounds[slot].sync[curIndexSync].ptr, ptr, size);
+				sound->sync[curIndexSync].size = size;
+				sound->sync[curIndexSync].ptr = (byte *)malloc(size);
+				memcpy(sound->sync[curIndexSync].ptr, ptr, size);
 				curIndexSync++;
 				ptr += size;
 				break;
@@ -199,94 +198,100 @@
 				ptr += 4;
 				break;
 			default:
-				error("ImuseDigiSndMgr::prepareSound(%d/%s) Unknown sfx header '%s'", _sounds[slot].soundId, _sounds[slot].name, tag2str(tag));
+				error("ImuseDigiSndMgr::prepareSound(%d/%s) Unknown sfx header '%s'", sound->soundId, sound->name, tag2str(tag));
 			}
 		} while (tag != MKID_BE('DATA'));
-		_sounds[slot].offsetData =  ptr - s_ptr;
+		sound->offsetData =  ptr - s_ptr;
 	} else {
 		error("ImuseDigiSndMgr::prepareSound(): Unknown sound format");
 	}
 }
 
-int ImuseDigiSndMgr::allocSlot() {
+ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::allocSlot() {
 	for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
 		if (!_sounds[l].inUse) {
 			_sounds[l].inUse = true;
-			return l;
+			return &_sounds[l];
 		}
 	}
 
-	return -1;
+	return NULL;
 }
 
-bool ImuseDigiSndMgr::openMusicBundle(int slot) {
+bool ImuseDigiSndMgr::openMusicBundle(soundStruct *sound, int disk) {
 	bool result = false;
 
-	_sounds[slot].bundle = new BundleMgr(_cacheBundleDir);
+	sound->bundle = new BundleMgr(_cacheBundleDir);
 	if (_vm->_gameId == GID_CMI) {
 		if (_vm->_features & GF_DEMO) {
-			result = _sounds[slot].bundle->openFile("music.bun", _vm->getGameDataPath());
+			result = sound->bundle->openFile("music.bun", _vm->getGameDataPath());
 		} else {
 			char musicfile[20];
-			sprintf(musicfile, "musdisk%d.bun", _vm->VAR(_vm->VAR_CURRENTDISK));
-			if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
+			if (disk == -1)
+				sprintf(musicfile, "musdisk%d.bun", _vm->VAR(_vm->VAR_CURRENTDISK));
+			else
+				sprintf(musicfile, "musdisk%d.bun", disk);
+//			if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
 //				_vm->_imuseDigital->parseScriptCmds(0x1000, 0, 0, 0, 0, 0, 0, 0);
 //				_vm->_imuseDigital->parseScriptCmds(0x2000, 0, 0, 0, 0, 0, 0, 0);
 //				_vm->_imuseDigital->stopAllSounds();
-				_sounds[slot].bundle->closeFile();
-			}
+//				sound->bundle->closeFile();
+//			}
 
-			result = _sounds[slot].bundle->openFile(musicfile, _vm->getGameDataPath());
+			result = sound->bundle->openFile(musicfile, _vm->getGameDataPath());
 
 			if (result == false)
-				result = _sounds[slot].bundle->openFile("music.bun", _vm->getGameDataPath());
+				result = sound->bundle->openFile("music.bun", _vm->getGameDataPath());
 			_disk = (byte)_vm->VAR(_vm->VAR_CURRENTDISK);
 		}
 	} else if (_vm->_gameId == GID_DIG)
-		result = _sounds[slot].bundle->openFile("digmusic.bun", _vm->getGameDataPath());
+		result = sound->bundle->openFile("digmusic.bun", _vm->getGameDataPath());
 	else
 		error("ImuseDigiSndMgr::openMusicBundle() Don't know which bundle file to load");
 
 	return result;
 }
 
-bool ImuseDigiSndMgr::openVoiceBundle(int slot) {
+bool ImuseDigiSndMgr::openVoiceBundle(soundStruct *sound, int disk) {
 	bool result = false;
 
-	_sounds[slot].bundle = new BundleMgr(_cacheBundleDir);
+	sound->bundle = new BundleMgr(_cacheBundleDir);
 	if (_vm->_gameId == GID_CMI) {
 		if (_vm->_features & GF_DEMO) {
-			result = _sounds[slot].bundle->openFile("voice.bun", _vm->getGameDataPath());
+			result = sound->bundle->openFile("voice.bun", _vm->getGameDataPath());
 		} else {
 			char voxfile[20];
-			sprintf(voxfile, "voxdisk%d.bun", _vm->VAR(_vm->VAR_CURRENTDISK));
-			if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
+			if (disk == -1)
+				sprintf(voxfile, "voxdisk%d.bun", _vm->VAR(_vm->VAR_CURRENTDISK));
+			else
+				sprintf(voxfile, "voxdisk%d.bun", disk);
+//			if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
 //				_vm->_imuseDigital->parseScriptCmds(0x1000, 0, 0, 0, 0, 0, 0, 0);
 //				_vm->_imuseDigital->parseScriptCmds(0x2000, 0, 0, 0, 0, 0, 0, 0);
 //				_vm->_imuseDigital->stopAllSounds();
-				_sounds[slot].bundle->closeFile();
-			}
+//				sound->bundle->closeFile();
+//			}
 
-			result = _sounds[slot].bundle->openFile(voxfile, _vm->getGameDataPath());
+			result = sound->bundle->openFile(voxfile, _vm->getGameDataPath());
 
 			if (result == false)
-				result = _sounds[slot].bundle->openFile("voice.bun", _vm->getGameDataPath());
+				result = sound->bundle->openFile("voice.bun", _vm->getGameDataPath());
 			_disk = (byte)_vm->VAR(_vm->VAR_CURRENTDISK);
 		}
 	} else if (_vm->_gameId == GID_DIG)
-		result = _sounds[slot].bundle->openFile("digvoice.bun", _vm->getGameDataPath());
+		result = sound->bundle->openFile("digvoice.bun", _vm->getGameDataPath());
 	else
 		error("ImuseDigiSndMgr::openVoiceBundle() Don't know which bundle file to load");
 
 	return result;
 }
 
-ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const char *soundName, int soundType, int volGroupId) {
+ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const char *soundName, int soundType, int volGroupId, int disk) {
 	assert(soundId >= 0);
 	assert(soundType);
 
-	int slot = allocSlot();
-	if (slot == -1) {
+	soundStruct *sound = allocSlot();
+	if (!sound) {
 		error("ImuseDigiSndMgr::openSound() can't alloc free sound slot");
 	}
 
@@ -294,34 +299,39 @@
 	byte *ptr = NULL;
 
 	if (soundName[0] == 0) {
-		_sounds[slot].name[0] = 0;
+		sound->name[0] = 0;
 		if ((soundType == IMUSE_RESOURCE)) {
+			_vm->ensureResourceLoaded(rtSound, soundId);
+			_vm->lock(rtSound, soundId);
 			ptr = _vm->getResourceAddress(rtSound, soundId);
 			if (ptr == NULL) {
-				closeSound(&_sounds[slot]);
+				closeSound(sound);
 				return NULL;
 			}
-			_sounds[slot].resPtr = ptr;
-			_sounds[slot].soundId = soundId;
-			_sounds[slot].type = soundType;
-			_sounds[slot].volGroupId = volGroupId;
+			sound->resPtr = ptr;
+			sound->soundId = soundId;
+			sound->type = soundType;
+			sound->volGroupId = volGroupId;
 			result = true;
 		} else if (soundType == IMUSE_BUNDLE) {
 			bool header_outside = ((_vm->_gameId == GID_CMI) && !(_vm->_features & GF_DEMO));
 			if (volGroupId == IMUSE_VOLGRP_VOICE)
-				result = openVoiceBundle(slot);
+				result = openVoiceBundle(sound, disk);
 			else if (volGroupId == IMUSE_VOLGRP_MUSIC)
-				result = openMusicBundle(slot);
+				result = openMusicBundle(sound, disk);
 			else
 				error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);
 			if (!result) {
-				closeSound(&_sounds[slot]);
+				closeSound(sound);
 				return NULL;
 			}
-			_sounds[slot].bundle->decompressSampleByIndex(soundId, 0, 0x2000, &ptr, 0, header_outside);
-			_sounds[slot].soundId = soundId;
-			_sounds[slot].type = soundType;
-			_sounds[slot].volGroupId = volGroupId;
+			if (sound->bundle->decompressSampleByIndex(soundId, 0, 0x2000, &ptr, 0, header_outside) == 0) {
+				closeSound(sound);
+				return NULL;
+			}
+			sound->soundId = soundId;
+			sound->type = soundType;
+			sound->volGroupId = volGroupId;
 		} else {
 			error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);
 		}
@@ -329,20 +339,23 @@
 		if (soundType == IMUSE_BUNDLE) {
 			bool header_outside = ((_vm->_gameId == GID_CMI) && !(_vm->_features & GF_DEMO));
 			if (volGroupId == IMUSE_VOLGRP_VOICE)
-				result = openVoiceBundle(slot);
+				result = openVoiceBundle(sound, disk);
 			else if (volGroupId == IMUSE_VOLGRP_MUSIC)
-				result = openMusicBundle(slot);
+				result = openMusicBundle(sound, disk);
 			else
 				error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);
 			if (!result) {
-				closeSound(&_sounds[slot]);
+				closeSound(sound);
 				return NULL;
 			}
-			_sounds[slot].bundle->decompressSampleByName(soundName, 0, 0x2000, &ptr, header_outside);
-			strcpy(_sounds[slot].name, soundName);
-			_sounds[slot].soundId = soundId;
-			_sounds[slot].type = soundType;
-			_sounds[slot].volGroupId = volGroupId;
+			if (sound->bundle->decompressSampleByName(soundName, 0, 0x2000, &ptr, header_outside) == 0) {
+				closeSound(sound);
+				return NULL;
+			}
+			strcpy(sound->name, soundName);
+			sound->soundId = soundId;
+			sound->type = soundType;
+			sound->volGroupId = volGroupId;
 		} else {
 			error("ImuseDigiSndMgr::openSound() Don't know how load sound: %s", soundName);
 		}
@@ -350,11 +363,12 @@
 
 	if (result) {
 		if (ptr == NULL) {
-			closeSound(&_sounds[slot]);
+			closeSound(sound);
 			return NULL;
 		}
-		prepareSound(ptr, slot);
-		return &_sounds[slot];
+		sound->disk = _disk;
+		prepareSound(ptr, sound);
+		return sound;
 	}
 
 	return NULL;
@@ -363,8 +377,15 @@
 void ImuseDigiSndMgr::closeSound(soundStruct *soundHandle) {
 	assert(soundHandle && checkForProperHandle(soundHandle));
 
-	if (soundHandle->resPtr)
-		_vm->unlock(rtSound, soundHandle->soundId);
+	if (soundHandle->resPtr) {
+		bool found = false;
+		for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
+			if ((_sounds[l].soundId == soundHandle->soundId) && (&_sounds[l] != soundHandle))
+				found = true;
+		}
+		if (!found)
+			_vm->unlock(rtSound, soundHandle->soundId);
+	}
 
 	delete soundHandle->bundle;
 	for (int r = 0; r < soundHandle->numSyncs; r++)
@@ -378,7 +399,7 @@
 ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::cloneSound(soundStruct *soundHandle) {
 	assert(soundHandle && checkForProperHandle(soundHandle));
 
-	return openSound(soundHandle->soundId, soundHandle->name, soundHandle->type, soundHandle->volGroupId);
+	return openSound(soundHandle->soundId, soundHandle->name, soundHandle->type, soundHandle->volGroupId, soundHandle->disk);
 }
 
 bool ImuseDigiSndMgr::checkForProperHandle(soundStruct *soundHandle) {
@@ -431,8 +452,9 @@
 	debug(5, "getJumpIdByRegionAndHookId() region:%d, hookId:%d", region, hookId);
 	assert(soundHandle && checkForProperHandle(soundHandle));
 	assert(region >= 0 && region < soundHandle->numRegions);
+	int32 offset = soundHandle->region[region].offset;
 	for (int l = 0; l < soundHandle->numJumps; l++) {
-		if (soundHandle->jump[l].offset == soundHandle->region[region].offset) {
+		if (offset == soundHandle->jump[l].offset) {
 			if (soundHandle->jump[l].hookId == hookId)
 				return l;
 		}
@@ -457,8 +479,9 @@
 	debug(5, "getRegionIdByJumpId() jumpId:%d", jumpId);
 	assert(soundHandle && checkForProperHandle(soundHandle));
 	assert(jumpId >= 0 && jumpId < soundHandle->numJumps);
+	int32 dest = soundHandle->jump[jumpId].dest;
 	for (int l = 0; l < soundHandle->numRegions; l++) {
-		if (soundHandle->jump[jumpId].dest == soundHandle->region[l].offset) {
+		if (dest == soundHandle->region[l].offset) {
 			return l;
 		}
 	}

Index: dimuse_sndmgr.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_sndmgr.h,v
retrieving revision 1.19.2.1
retrieving revision 1.19.2.2
diff -u -d -r1.19.2.1 -r1.19.2.2
--- dimuse_sndmgr.h	2 May 2004 16:36:04 -0000	1.19.2.1
+++ dimuse_sndmgr.h	26 Jun 2004 09:18:29 -0000	1.19.2.2
@@ -34,7 +34,7 @@
 class ImuseDigiSndMgr {
 public:
 
-#define MAX_IMUSE_SOUNDS 10
+#define MAX_IMUSE_SOUNDS 16
 
 #define IMUSE_RESOURCE 1
 #define IMUSE_BUNDLE 2
@@ -83,6 +83,7 @@
 		BundleMgr *bundle;
 		int type;
 		int volGroupId;
+		int disk;
 	};
 
 private:
@@ -90,15 +91,15 @@
 	soundStruct _sounds[MAX_IMUSE_SOUNDS];
 
 	bool checkForProperHandle(soundStruct *soundHandle);
-	int allocSlot();
-	void prepareSound(byte *ptr, int slot);
+	soundStruct *allocSlot();
+	void prepareSound(byte *ptr, soundStruct *sound);
 
 	ScummEngine *_vm;
 	byte _disk;
 	BundleDirCache *_cacheBundleDir;
 
-	bool openMusicBundle(int slot);
-	bool openVoiceBundle(int slot);
+	bool openMusicBundle(soundStruct *sound, int disk);
+	bool openVoiceBundle(soundStruct *sound, int disk);
 
 	void countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs);
 
@@ -107,7 +108,7 @@
 	ImuseDigiSndMgr(ScummEngine *scumm);
 	~ImuseDigiSndMgr();
 
-	soundStruct *openSound(int32 soundId, const char *soundName, int soundType, int volGroupId);
+	soundStruct *openSound(int32 soundId, const char *soundName, int soundType, int volGroupId, int disk);
 	void closeSound(soundStruct *soundHandle);
 	soundStruct *cloneSound(soundStruct *soundHandle);
 

Index: dimuse_track.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_track.cpp,v
retrieving revision 1.17.2.2
retrieving revision 1.17.2.3
diff -u -d -r1.17.2.2 -r1.17.2.3
--- dimuse_track.cpp	3 May 2004 11:32:49 -0000	1.17.2.2
+++ dimuse_track.cpp	26 Jun 2004 09:18:29 -0000	1.17.2.3
@@ -32,107 +32,104 @@
 
 namespace Scumm {
 
-bool IMuseDigital::allocSlot(int priority) {
-	int l;
-	int lower_priority = 127;
-	bool found_free = false;
+int IMuseDigital::allocSlot(int priority) {
+	int l, lower_priority = 127;
+	int trackId = -1;
 
 	for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if (!_track[l]->used && !_track[l]->handle.isActive())
-			found_free = true;
+		if (!_track[l]->used) {
+			trackId = l;
+			break;
+		}
 	}
 
-	if (!found_free) {
+	if (trackId == -1) {
 		debug(5, "IMuseDigital::startSound(): All slots are full");
 		for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-			if (_track[l]->used && _track[l]->handle.isActive() &&
-					(lower_priority > _track[l]->priority) && (!_track[l]->stream2))
-				lower_priority = _track[l]->priority;
+			Track *track = _track[l];
+			if (track->used && !track->toBeRemoved &&
+					(lower_priority > track->priority) && !track->stream2)
+				lower_priority = track->priority;
 		}
 		if (lower_priority <= priority) {
-			int track_id = -1;
 			for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-				if (_track[l]->used && _track[l]->handle.isActive() &&
-						(lower_priority == _track[l]->priority) && (!_track[l]->stream2)) {
-					track_id = l;
+				Track *track = _track[l];
+				if (track->used && !track->toBeRemoved &&
+						(lower_priority == track->priority) && !track->stream2) {
+					trackId = l;
 				}
 			}
-			assert(track_id != -1);
-			_track[track_id]->stream->finish();
-			_track[track_id]->stream = NULL;
-			_vm->_mixer->stopHandle(_track[track_id]->handle);
-			_sound->closeSound(_track[track_id]->soundHandle);
-			_track[track_id]->soundHandle = NULL;
-			_track[track_id]->used = false;
-			assert(!_track[track_id]->handle.isActive());
-			debug(5, "IMuseDigital::startSound(): Removed sound %d from track %d", _track[track_id]->soundId, track_id);
+			assert(trackId != -1);
+			_track[trackId]->toBeRemoved = true;
+			debug(5, "IMuseDigital::startSound(): Removed sound %d from track %d", _track[trackId]->soundId, trackId);
 		} else {
 			debug(5, "IMuseDigital::startSound(): Priority sound too low");
-			return false;
+			return -1;
 		}
 	}
 
-	return true;
+	return trackId;
 }
 
 void IMuseDigital::startSound(int soundId, const char *soundName, int soundType, int volGroupId, AudioStream *input, int hookId, int volume, int priority) {
-	Common::StackLock lock(_mutex);
 	debug(5, "IMuseDigital::startSound(%d)", soundId);
-	int l;
 
-	if (!allocSlot(priority)) {
+	int l = allocSlot(priority);
+	if (l == -1) {
 		warning("IMuseDigital::startSound() Can't start sound - no free slots");
 		return;
 	}
 
-	for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if (!_track[l]->used && !_track[l]->handle.isActive()) {
-			_track[l]->pan = 64;
-			_track[l]->vol = volume * 1000;
-			_track[l]->volFadeDest = 0;
-			_track[l]->volFadeStep = 0;
-			_track[l]->volFadeDelay = 0;
-			_track[l]->volFadeUsed = false;
-			_track[l]->soundId = soundId;
-			_track[l]->started = false;
-			_track[l]->volGroupId = volGroupId;
-			_track[l]->curHookId = hookId;
-			_track[l]->priority = priority;
-			_track[l]->curRegion = -1;
-			_track[l]->dataOffset = 0;
-			_track[l]->regionOffset = 0;
-			_track[l]->trackOffset = 0;
-			_track[l]->mod = 0;
-			_track[l]->mixerFlags = 0;
-			_track[l]->mixerPan = 0;
-			_track[l]->mixerVol = volume;
-			_track[l]->toBeRemoved = false;
-			_track[l]->soundType = soundType;
+	Track *track = _track[l];
+	for (;;) {
+		flushTracks();
+		if (!track->used) {
+			track->pan = 64;
+			track->vol = volume * 1000;
+			track->volFadeDest = 0;
+			track->volFadeStep = 0;
+			track->volFadeDelay = 0;
+			track->volFadeUsed = false;
+			track->soundId = soundId;
+			track->started = false;
+			track->volGroupId = volGroupId;
+			track->curHookId = hookId;
+			track->priority = priority;
+			track->curRegion = -1;
+			track->dataOffset = 0;
+			track->regionOffset = 0;
+			track->mod = 0;
+			track->mixerFlags = 0;
+			track->mixerPan = 0;
+			track->mixerVol = volume;
+			track->toBeRemoved = false;
+			track->readyToRemove = false;
+			track->soundType = soundType;
 
 			int bits = 0, freq = 0, channels = 0;
 
 			if (input) {
-				_track[l]->iteration = 0;
-				_track[l]->souStream = true;
-				_track[l]->soundName[0] = 0;
+				track->iteration = 0;
+				track->souStream = true;
+				track->soundName[0] = 0;
 			} else {
-				_track[l]->souStream = false;
-				strcpy(_track[l]->soundName, soundName);
-				_track[l]->soundHandle = _sound->openSound(soundId, soundName, soundType, volGroupId);
+				track->souStream = false;
+				strcpy(track->soundName, soundName);
+				track->soundHandle = _sound->openSound(soundId, soundName, soundType, volGroupId, -1);
 
-				if (_track[l]->soundHandle == NULL)
+				if (track->soundHandle == NULL)
 					return;
 
-				bits = _sound->getBits(_track[l]->soundHandle);
-				channels = _sound->getChannels(_track[l]->soundHandle);
-				freq = _sound->getFreq(_track[l]->soundHandle);
+				bits = _sound->getBits(track->soundHandle);
+				channels = _sound->getChannels(track->soundHandle);
+				freq = _sound->getFreq(track->soundHandle);
 
 				if ((soundId == kTalkSoundID) && (soundType == IMUSE_BUNDLE)) {
 					if (_vm->_actorToPrintStrFor != 0xFF && _vm->_actorToPrintStrFor != 0) {
 						Actor *a = _vm->derefActor(_vm->_actorToPrintStrFor, "IMuseDigital::startSound");
 						freq = (freq * a->talkFrequency) / 256;
-						_track[l]->pan = a->talkPan;
-						_track[l]->vol = a->talkVolume * 1000;
+						track->pan = a->talkPan;
+						track->vol = a->talkVolume * 1000;
 					}
 				}
 
@@ -140,75 +137,86 @@
 				assert(channels == 1 || channels == 2);
 				assert(0 < freq && freq <= 65535);
 
-				_track[l]->iteration = freq * channels;
+				track->iteration = freq * channels;
 				if (channels == 2)
-					_track[l]->mixerFlags = SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO;
+					track->mixerFlags = SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO;
 
 				if ((bits == 12) || (bits == 16)) {
-					_track[l]->mixerFlags |= SoundMixer::FLAG_16BITS;
-					_track[l]->iteration *= 2;
+					track->mixerFlags |= SoundMixer::FLAG_16BITS;
+					track->iteration *= 2;
 				} else if (bits == 8) {
-					_track[l]->mixerFlags |= SoundMixer::FLAG_UNSIGNED;
+					track->mixerFlags |= SoundMixer::FLAG_UNSIGNED;
 				} else
 					error("IMuseDigital::startSound(): Can't handle %d bit samples", bits);
 			}
 
 			if (input) {
-				_track[l]->stream2 = input;
-				_track[l]->stream = NULL;
-				_track[l]->started = false;
+				track->stream2 = input;
+				track->stream = NULL;
+				track->started = false;
 			} else {
+				int pan = (track->pan != 64) ? 2 * track->pan - 127 : 0;
+				int vol = track->vol / 1000;
+
+				if (track->volGroupId == 1)
+					vol = (vol * _volVoice) / 128;
+				if (track->volGroupId == 2)
+					vol = (vol * _volSfx) / 128;
+				if (track->volGroupId == 3)
+					vol = (vol * _volMusic) / 128;
+
+				track->mixerPan = pan;
+				track->mixerVol = vol;
+
 				// setup 1 second stream wrapped buffer
-				int32 streamBufferSize = _track[l]->iteration;
-				_track[l]->stream2 = NULL;
-				_track[l]->stream = makeAppendableAudioStream(freq, _track[l]->mixerFlags, streamBufferSize);
-				_vm->_mixer->playInputStream(&_track[l]->handle, _track[l]->stream, false, _track[l]->vol / 1000, _track[l]->pan, -1);
-				_track[l]->started = true;
+				int32 streamBufferSize = track->iteration;
+				track->stream2 = NULL;
+				track->stream = makeAppendableAudioStream(freq, track->mixerFlags, streamBufferSize);
+				_vm->_mixer->playInputStream(&track->handle, track->stream, false, track->mixerVol, track->mixerPan, -1, false);
+				track->started = true;
 			}
 
-			_track[l]->used = true;
+			track->used = true;
 			return;
 		}
 	}
-
-	error("IMuseDigital::startSound(): We should never get here");
 }
 
 void IMuseDigital::setPriority(int soundId, int priority) {
-	Common::StackLock lock(_mutex);
 	debug(5, "IMuseDigital::setPriority(%d, %d)", soundId, priority);
-
 	assert ((priority >= 0) && (priority <= 127));
 
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->soundId == soundId) && _track[l]->used) {
-			_track[l]->priority = priority;
+		Track *track = _track[l];
+		if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+			track->priority = priority;
 		}
 	}
 }
 
 void IMuseDigital::setVolume(int soundId, int volume) {
-	Common::StackLock lock(_mutex);
 	debug(5, "IMuseDigital::setVolume(%d, %d)", soundId, volume);
+
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->soundId == soundId) && _track[l]->used) {
-			_track[l]->vol = volume * 1000;
+		Track *track = _track[l];
+		if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+			track->vol = volume * 1000;
 		}
 	}
 }
 
 void IMuseDigital::setPan(int soundId, int pan) {
-	Common::StackLock lock(_mutex);
 	debug(5, "IMuseDigital::setPan(%d, %d)", soundId, pan);
+
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->soundId == soundId) && _track[l]->used) {
-			_track[l]->pan = pan;
+		Track *track = _track[l];
+		if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+			track->pan = pan;
 		}
 	}
 }
 
 void IMuseDigital::selectVolumeGroup(int soundId, int volGroupId) {
-	Common::StackLock lock(_mutex);
 	debug(5, "IMuseDigital::setGroupVolume(%d, %d)", soundId, volGroupId);
 	assert((volGroupId >= 1) && (volGroupId <= 4));
 
@@ -216,8 +224,9 @@
 		volGroupId = 3;
 
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->soundId == soundId) && _track[l]->used) {
-			_track[l]->volGroupId = volGroupId;
+		Track *track = _track[l];
+		if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+			track->volGroupId = volGroupId;
 		}
 	}
 }
@@ -225,93 +234,87 @@
 void IMuseDigital::setFade(int soundId, int destVolume, int delay60HzTicks) {
 	Common::StackLock lock(_mutex);
 	debug(5, "IMuseDigital::setFade(%d, %d, %d)", soundId, destVolume, delay60HzTicks);
+
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->soundId == soundId) && _track[l]->used) {
-			_track[l]->volFadeDelay = delay60HzTicks;
-			_track[l]->volFadeDest = destVolume * 1000;
-			_track[l]->volFadeStep = (_track[l]->volFadeDest - _track[l]->vol) * 60 * 40 / (1000 * delay60HzTicks);
-			_track[l]->volFadeUsed = true;
+		Track *track = _track[l];
+		if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+			track->volFadeDelay = delay60HzTicks;
+			track->volFadeDest = destVolume * 1000;
+			track->volFadeStep = (track->volFadeDest - track->vol) * 60 * (1000 / _callbackFps) / (1000 * delay60HzTicks);
+			track->volFadeUsed = true;
 		}
 	}
 }
 
 void IMuseDigital::fadeOutMusic(int fadeDelay) {
-	Common::StackLock lock(_mutex);
 	debug(5, "IMuseDigital::fadeOutMusic");
 	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
-		if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) {
-			cloneToFadeOutTrack(l, fadeDelay, true);
+		Track *track = _track[l];
+		if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+			cloneToFadeOutTrack(l, fadeDelay);
+			track->toBeRemoved = true;
 		}
 	}
 }
 
-int IMuseDigital::cloneToFadeOutTrack(int track, int fadeDelay, int killNormalTrack) {
-	Common::StackLock lock(_mutex);
-	debug(5, "IMuseDigital::cloneToFadeOutTrack(%d, %d)", track, fadeDelay);
-	int fadeTrack = -1;
-
-	for (int l = MAX_DIGITAL_TRACKS; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
-		if (!_track[l]->used) {
-			fadeTrack = l;
-			break;
-		}
-	}
-	if (fadeTrack == -1)
-		error("IMuseDigital::cloneToFadeTrack() Can't find free fade track");
+int IMuseDigital::cloneToFadeOutTrack(int trackId, int fadeDelay) {
+	int fadeTrackId = -1;
+	Track *track;
+	Track *fadeTrack;
 
-	// swap track to fade track
-	Track *tmpTrack = _track[track];
-	_track[track] = _track[fadeTrack];
-	_track[fadeTrack] = tmpTrack;
+	debug(5, "IMuseDigital::cloneToFadeOutTrack(%d, %d)", trackId, fadeDelay);
 
-	// copy track params from swaped fade track to new track
-	_track[track]->pan = _track[fadeTrack]->pan;
-	_track[track]->vol = _track[fadeTrack]->vol;
-	_track[track]->volGroupId = _track[fadeTrack]->volGroupId;
-	_track[track]->volFadeDelay = _track[fadeTrack]->volFadeDelay;
-	_track[track]->volFadeDest = _track[fadeTrack]->volFadeDest;
-	_track[track]->volFadeStep = _track[fadeTrack]->volFadeStep;
-	_track[track]->volFadeUsed = _track[fadeTrack]->volFadeUsed;
-	_track[track]->priority = _track[fadeTrack]->priority;
-	_track[track]->soundId = _track[fadeTrack]->soundId;
-	_track[track]->dataOffset = _track[fadeTrack]->dataOffset;
-	_track[track]->regionOffset = _track[fadeTrack]->regionOffset;
-	_track[track]->trackOffset = _track[fadeTrack]->trackOffset;
-	_track[track]->curRegion = _track[fadeTrack]->curRegion;
-	_track[track]->curHookId = _track[fadeTrack]->curHookId;
-	_track[track]->iteration = _track[fadeTrack]->iteration;
-	_track[track]->mixerFlags = _track[fadeTrack]->mixerFlags;
-	_track[track]->mixerVol = _track[fadeTrack]->mixerVol;
-	_track[track]->mixerPan = _track[fadeTrack]->mixerPan;
-	_track[track]->mod = _track[fadeTrack]->mod;
-	_track[track]->used = _track[fadeTrack]->used;
-	_track[track]->toBeRemoved = _track[fadeTrack]->toBeRemoved;
-	_track[track]->souStream = _track[fadeTrack]->souStream;
-	_track[track]->started = _track[fadeTrack]->started;
-	_track[track]->stream2 = _track[fadeTrack]->stream2;
-	strcpy(_track[track]->soundName, _track[fadeTrack]->soundName);
-	_track[track]->soundType = _track[fadeTrack]->soundType;
+	{
+		Common::StackLock lock(_mutex);
+		for (int l = MAX_DIGITAL_TRACKS; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
+			if (!_track[l]->used) {
+				fadeTrackId = l;
+				break;
+			}
+		}
+		if (fadeTrackId == -1)
+			error("IMuseDigital::cloneTofadeTrackId() Can't find free fade track");
 
-	_track[track]->soundHandle = NULL;
-	_track[track]->stream = NULL;
+		track = _track[trackId];
+		fadeTrack = _track[fadeTrackId];
+		fadeTrack->pan = track->pan;
+		fadeTrack->vol = track->vol;
+		fadeTrack->volGroupId = track->volGroupId;
+		fadeTrack->priority = track->priority;
+		fadeTrack->soundId = track->soundId;
+		fadeTrack->dataOffset = track->dataOffset;
+		fadeTrack->regionOffset = track->regionOffset;
+		fadeTrack->curRegion = track->curRegion;
+		fadeTrack->curHookId = track->curHookId;
+		fadeTrack->iteration = track->iteration;
+		fadeTrack->mixerFlags = track->mixerFlags;
+		fadeTrack->mixerVol = track->mixerVol;
+		fadeTrack->mixerPan = track->mixerPan;
+		fadeTrack->mod = track->mod;
+		fadeTrack->toBeRemoved = track->toBeRemoved;
+		fadeTrack->readyToRemove = track->readyToRemove;
+		fadeTrack->souStream = track->souStream;
+		fadeTrack->started = track->started;
+		fadeTrack->stream2 = track->stream2;
+		strcpy(fadeTrack->soundName, track->soundName);
+		fadeTrack->soundType = track->soundType;
+		fadeTrack->soundHandle = _sound->cloneSound(track->soundHandle);
+		assert(fadeTrack->soundHandle);
+	}
 
-	_track[fadeTrack]->volFadeDelay = fadeDelay;
-	_track[fadeTrack]->volFadeDest = 0;
-	_track[fadeTrack]->volFadeStep = (_track[fadeTrack]->volFadeDest - _track[fadeTrack]->vol) * 60 * 40 / (1000 * fadeDelay);
-	_track[fadeTrack]->volFadeUsed = true;
+	fadeTrack->volFadeDelay = fadeDelay;
+	fadeTrack->volFadeDest = 0;
+	fadeTrack->volFadeStep = (fadeTrack->volFadeDest - fadeTrack->vol) * 60 * (1000 / _callbackFps) / (1000 * fadeDelay);
+	fadeTrack->volFadeUsed = true;
 
-	if (killNormalTrack) {
-		_track[track]->used = false;
-	} else {
-		_track[track]->soundHandle = _sound->cloneSound(_track[fadeTrack]->soundHandle);
-		// setup 1 second stream wrapped buffer
-		int32 streamBufferSize = _track[track]->iteration;
-		_track[track]->stream = makeAppendableAudioStream(_sound->getFreq(_track[track]->soundHandle), _track[track]->mixerFlags, streamBufferSize);
-		_vm->_mixer->playInputStream(&_track[track]->handle, _track[track]->stream, false, _track[track]->vol / 1000, _track[track]->pan, -1);
-		_track[track]->started = true;
-	}
+	// setup 1 second stream wrapped buffer
+	int32 streamBufferSize = fadeTrack->iteration;
+	fadeTrack->stream = makeAppendableAudioStream(_sound->getFreq(fadeTrack->soundHandle), fadeTrack->mixerFlags, streamBufferSize);
+	_vm->_mixer->playInputStream(&fadeTrack->handle, fadeTrack->stream, false, fadeTrack->vol / 1000, fadeTrack->pan, -1, false);
+	fadeTrack->started = true;
+	fadeTrack->used = true;
 
-	return fadeTrack;
+	return fadeTrackId;
 }
 
 } // End of namespace Scumm





More information about the Scummvm-git-logs mailing list