diff options
| author | Paweł Kołodziejski | 2004-04-11 14:48:50 +0000 | 
|---|---|---|
| committer | Paweł Kołodziejski | 2004-04-11 14:48:50 +0000 | 
| commit | def44acc6f03b3c752002f140e6accb74477e527 (patch) | |
| tree | 5f449975e39d0b6813c66f44bf1cdbced7512288 | |
| parent | 26c8f9340db3db6f7296053a8e67a31293cce73b (diff) | |
| download | scummvm-rg350-def44acc6f03b3c752002f140e6accb74477e527.tar.gz scummvm-rg350-def44acc6f03b3c752002f140e6accb74477e527.tar.bz2 scummvm-rg350-def44acc6f03b3c752002f140e6accb74477e527.zip | |
implemented 'fade buffers' stuff
svn-id: r13542
| -rw-r--r-- | TODO | 1 | ||||
| -rw-r--r-- | scumm/imuse_digi/dimuse.cpp | 181 | ||||
| -rw-r--r-- | scumm/imuse_digi/dimuse.h | 8 | ||||
| -rw-r--r-- | scumm/imuse_digi/dimuse_script.cpp | 62 | ||||
| -rw-r--r-- | scumm/imuse_digi/dimuse_sndmgr.cpp | 17 | ||||
| -rw-r--r-- | scumm/imuse_digi/dimuse_sndmgr.h | 5 | ||||
| -rw-r--r-- | scumm/imuse_digi/dimuse_track.cpp | 202 | 
7 files changed, 289 insertions, 187 deletions
| @@ -256,7 +256,6 @@ SCUMM  * Fix codec44 for nut fonts  * iMUSE Digital:    - Fix music code (done, but not tested yet) -  - Implement 'fade buffers' stuff, to handle fadeParam in JUMP opcode    - Implement pool method data transfer between imuse and sound mixer    - Add save/load code    - Add code for MP3 and Ogg Vorbis compressed datafiles diff --git a/scumm/imuse_digi/dimuse.cpp b/scumm/imuse_digi/dimuse.cpp index 86b955cd7c..7a1add676c 100644 --- a/scumm/imuse_digi/dimuse.cpp +++ b/scumm/imuse_digi/dimuse.cpp @@ -50,6 +50,10 @@ IMuseDigital::IMuseDigital(ScummEngine *scumm)  	_volSfx = 0;  	_volMusic = 0;  	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);  } @@ -59,6 +63,9 @@ IMuseDigital::~IMuseDigital() {  		Common::StackLock lock(_mutex, "IMuseDigital::~IMuseDigital()");  		_vm->_timer->removeTimerProc(timer_handler);  	} +	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) { +		delete _track[l]; +	}  	delete _sound;  	g_system->deleteMutex(_mutex);  } @@ -78,113 +85,114 @@ void IMuseDigital::callback() {  	if (_pause || !_vm)  		return; -	for (l = 0; l < MAX_DIGITAL_TRACKS;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; +	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].used = false; +			} 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;  				}  			} -			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[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[l].vol == 0) { -							_track[l].toBeRemoved = true; +						if (_track[l]->vol == 0) { +							_track[l]->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[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;  						}  					}  				} -				debug(5, "Fade: sound(%d), Vol(%d)", _track[l].soundId, _track[l].vol / 1000); +				debug(5, "Fade: sound(%d), Vol(%d)", _track[l]->soundId, _track[l]->vol / 1000);  			} -			int pan = (_track[l].pan != 64) ? 2 * _track[l].pan - 127 : 0; -			int vol = _track[l].vol / 1000; +			int pan = (_track[l]->pan != 64) ? 2 * _track[l]->pan - 127 : 0; +			int vol = _track[l]->vol / 1000; -			if (_track[l].volGroupId == 1) +			if (_track[l]->volGroupId == 1)  				vol = (vol * _volVoice) / 128; -			if (_track[l].volGroupId == 2) +			if (_track[l]->volGroupId == 2)  				vol = (vol * _volSfx) / 128; -			if (_track[l].volGroupId == 3) +			if (_track[l]->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); +				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); +						_vm->_mixer->setChannelVolume(_track[l]->handle, vol); +						_vm->_mixer->setChannelBalance(_track[l]->handle, pan);  					}  					continue;  				}  			} -			if (_track[l].stream) { -				int32 mixer_size = _track[l].pullSize; +			if (_track[l]->stream) { +				int32 mixer_size = _track[l]->pullSize;  				byte *data = NULL;  				int32 result = 0; -				if (_track[l].stream->endOfData()) { +				if (_track[l]->stream->endOfData()) {  					mixer_size *= 2;  				} -				if (_track[l].curRegion == -1) +				if (_track[l]->curRegion == -1)  					switchToNextRegion(l); -				int bits = _sound->getBits(_track[l].soundHandle); +				int bits = _sound->getBits(_track[l]->soundHandle);  				do {  					if (bits == 12) {  						byte *ptr = NULL; -						mixer_size += _track[l].mod; +						mixer_size += _track[l]->mod;  						int mixer_size_12 = (mixer_size * 3) / 4;  						int length = (mixer_size_12 / 3) * 4; -						_track[l].mod = mixer_size - length; +						_track[l]->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[l]->regionOffset * 3) / 4; +						int result2 = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->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); -						if (_sound->getChannels(_track[l].soundHandle) == 1) { +						result = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &data, _track[l]->regionOffset, mixer_size); +						if (_sound->getChannels(_track[l]->soundHandle) == 1) {  							result &= ~1;  						} -						if (_sound->getChannels(_track[l].soundHandle) == 2) { +						if (_sound->getChannels(_track[l]->soundHandle) == 2) {  							if (result & 2)  								result &= ~2;  						}  					} else if (bits == 8) { -						result = _sound->getDataFromRegion(_track[l].soundHandle, _track[l].curRegion, &data, _track[l].regionOffset, mixer_size); -						if (_sound->getChannels(_track[l].soundHandle) == 2) { +						result = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &data, _track[l]->regionOffset, mixer_size); +						if (_sound->getChannels(_track[l]->soundHandle) == 2) {  							result &= ~1;  						}  					} @@ -193,17 +201,17 @@ void IMuseDigital::callback() {  						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[l]->handle, vol); +						_vm->_mixer->setChannelBalance(_track[l]->handle, pan); +						_track[l]->stream->append(data, result); +						_track[l]->regionOffset += result; +						_track[l]->trackOffset += result;  						free(data);  					} -					if (_sound->isEndOfRegion(_track[l].soundHandle, _track[l].curRegion)) { +					if (_sound->isEndOfRegion(_track[l]->soundHandle, _track[l]->curRegion)) {  						switchToNextRegion(l); -						if (_track[l].toBeRemoved) +						if (_track[l]->toBeRemoved)  							break;  					}  					mixer_size -= result; @@ -215,36 +223,51 @@ void IMuseDigital::callback() {  }  void IMuseDigital::switchToNextRegion(int track) { -	int num_regions = _sound->getNumRegions(_track[track].soundHandle); +	if (track >= MAX_DIGITAL_TRACKS) { +		_track[track]->toBeRemoved = true; +		return; +	} + +	int num_regions = _sound->getNumRegions(_track[track]->soundHandle); -	if (++_track[track].curRegion == num_regions) { -		_track[track].toBeRemoved = true; +	if (++_track[track]->curRegion == num_regions) { +		_track[track]->toBeRemoved = true;  		return;  	} -	int jumpId = _sound->getJumpIdByRegionAndHookId(_track[track].soundHandle, _track[track].curRegion, _track[track].curHookId); +	int jumpId = _sound->getJumpIdByRegionAndHookId(_track[track]->soundHandle, _track[track]->curRegion, _track[track]->curHookId);  	if (jumpId == -1) -		jumpId = _sound->getJumpIdByRegionAndHookId(_track[track].soundHandle, _track[track].curRegion, 0); +		jumpId = _sound->getJumpIdByRegionAndHookId(_track[track]->soundHandle, _track[track]->curRegion, 0);  	if (jumpId != -1) { -		int region = _sound->getRegionIdByJumpId(_track[track].soundHandle, jumpId); +		int region = _sound->getRegionIdByJumpId(_track[track]->soundHandle, jumpId);  		assert(region != -1); -		int sampleHookId = _sound->getJumpHookId(_track[track].soundHandle, jumpId); +		int sampleHookId = _sound->getJumpHookId(_track[track]->soundHandle, jumpId);  		assert(sampleHookId != -1); +		int fadeDelay = (60 * _sound->getJumpFade(_track[track]->soundHandle, jumpId)) / 1000;  		if (sampleHookId != 0) { -			if (_track[track].curHookId == sampleHookId) { -				_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; +			if (_track[track]->curHookId == sampleHookId) { +				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[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[fadeTrack]->curHookId = 0;  			}  		} else { -			_track[track].curRegion = region; -			debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", _track[track].soundId, _track[track].curRegion, _track[track].curHookId); +			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[track]->curRegion = region; +			debug(5, "switchToNextRegion-sound(%d) jump to %d region, curHookId: %d", _track[track]->soundId, _track[track]->curRegion, _track[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[track]->soundId, _track[track]->curRegion, _track[track]->curHookId); +	_track[track]->dataOffset = _sound->getRegionOffset(_track[track]->soundHandle, _track[track]->curRegion); +	_track[track]->regionOffset = 0;  }  } // End of namespace Scumm diff --git a/scumm/imuse_digi/dimuse.h b/scumm/imuse_digi/dimuse.h index 61a4c8da4c..1e1763762a 100644 --- a/scumm/imuse_digi/dimuse.h +++ b/scumm/imuse_digi/dimuse.h @@ -34,6 +34,7 @@  namespace Scumm {  #define MAX_DIGITAL_TRACKS 8 +#define MAX_DIGITAL_FADETRACKS 8  struct imuseDigTable;  struct imuseComiTable; @@ -63,6 +64,8 @@ private:  		int iteration;  		int mod;  		int32 pullSize; +		int32 mixerFlags; +  		ImuseDigiSndMgr::soundStruct *soundHandle;  		PlayingSoundHandle handle;  		AppendableAudioStream *stream; @@ -71,7 +74,7 @@ private:  		Track();  	}; -	Track _track[MAX_DIGITAL_TRACKS]; +	Track *_track[MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS];  	OSystem::MutexRef _mutex;  	ScummEngine *_vm; @@ -94,12 +97,14 @@ private:  	void switchToNextRegion(int track);  	void 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);  	int32 getPosInMs(int soundId);  	void getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height);  	int getSoundIdByName(const char *soundName);  	void fadeOutMusic(int fadeDelay); +	int cloneToFadeOutTrack(int track, int fadeDelay, int killNormalTrack);  	void setFtMusicState(int stateId);  	void setFtMusicSequence(int seqId); @@ -139,7 +144,6 @@ public:  	void setVolume(int soundId, int volume);  	void setPan(int soundId, int pan);  	void setFade(int soundId, int destVolume, int delay60HzTicks); -	void selectVolumeGroup(int soundId, int volGroupId);  	void setMasterVolume(int vol) {}  	void stopSound(int soundId);  	void stopAllSounds() { stopAllSounds(false); } diff --git a/scumm/imuse_digi/dimuse_script.cpp b/scumm/imuse_digi/dimuse_script.cpp index fb26ce6120..abc0acc5f5 100644 --- a/scumm/imuse_digi/dimuse_script.cpp +++ b/scumm/imuse_digi/dimuse_script.cpp @@ -163,7 +163,7 @@ void IMuseDigital::refreshScripts() {  	Common::StackLock lock(_mutex, "IMuseDigital::refreshScripts()");  	bool found = false;  	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) { -		if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) { +		if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) {  			found = true;  		}  	} @@ -175,7 +175,7 @@ void IMuseDigital::refreshScripts() {  void IMuseDigital::startVoice(int soundId, AudioStream *input) {  	debug(5, "startVoiceStream(%d)", soundId); -	startSound(soundId, NULL, 0, IMUSE_VOLGRP_VOICE, input, 0, 127, 127); +	startSound(soundId, "", 0, IMUSE_VOLGRP_VOICE, input, 0, 127, 127);  }  void IMuseDigital::startVoice(int soundId, const char *soundName) { @@ -185,7 +185,7 @@ void IMuseDigital::startVoice(int soundId, const char *soundName) {  void IMuseDigital::startMusic(int soundId, int volume) {  	debug(5, "startMusicResource(%d)", soundId); -	startSound(soundId, NULL, IMUSE_RESOURCE, IMUSE_VOLGRP_MUSIC, NULL, 0, volume, 126); +	startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_MUSIC, NULL, 0, volume, 126);  }  void IMuseDigital::startMusic(const char *soundName, int soundId, int hookId, int volume) { @@ -195,7 +195,7 @@ void IMuseDigital::startMusic(const char *soundName, int soundId, int hookId, in  void IMuseDigital::startSfx(int soundId, int priority) {  	debug(5, "startSfx(%d)", soundId); -	startSound(soundId, NULL, IMUSE_RESOURCE, IMUSE_VOLGRP_SFX, NULL, 0, 127, priority); +	startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_SFX, NULL, 0, 127, priority);  }  void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height) { @@ -205,8 +205,8 @@ void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width  	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); +			if ((_track[l]->soundId == soundId) && _track[l]->used) { +				_sound->getSyncSizeAndPtrById(_track[l]->soundHandle, syncId, sync_size, &sync_ptr);  				if ((sync_size != 0) && (sync_ptr != NULL)) {  					sync_size /= 4;  					while (sync_size--) { @@ -231,8 +231,8 @@ void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width  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); +		if ((_track[l]->soundId == soundId) && (_track[l]->used)) { +			int32 pos = (5 * (_track[l]->dataOffset + _track[l]->regionOffset)) / (_track[l]->iteration / 200);  			return pos;  		}  	} @@ -244,7 +244,7 @@ int IMuseDigital::getSoundStatus(int sound) const {  	Common::StackLock lock(_mutex, "IMuseDigital::getSoundStatus()");  	debug(5, "IMuseDigital::getSoundStatus(%d)", sound);  	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) { -		if ((_track[l].soundId == sound) && _track[l].used) { +		if ((_track[l]->soundId == sound) && _track[l]->used) {  			return 1;  		}  	} @@ -256,12 +256,12 @@ void IMuseDigital::stopSound(int soundId) {  	Common::StackLock lock(_mutex, "IMuseDigital::stopSound()");  	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].toBeRemoved = true; +		if ((_track[l]->soundId == soundId) && _track[l]->used) { +			if (_track[l]->stream) { +				_track[l]->toBeRemoved = true;  			} -			else if (_track[l].stream2) -				_vm->_mixer->stopHandle(_track[l].handle); +			else if (_track[l]->stream2) +				_vm->_mixer->stopHandle(_track[l]->handle);  		}  	}  } @@ -271,8 +271,8 @@ int32 IMuseDigital::getCurMusicPosInMs() {  	int soundId = -1;  	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) { -		if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) { -			soundId = _track[l].soundId; +		if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) { +			soundId = _track[l]->soundId;  		}  	} @@ -306,8 +306,8 @@ int32 IMuseDigital::getCurMusicLipSyncWidth(int syncId) {  	int soundId = -1;  	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) { -		if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) { -			soundId = _track[l].soundId; +		if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) { +			soundId = _track[l]->soundId;  		}  	} @@ -324,8 +324,8 @@ int32 IMuseDigital::getCurMusicLipSyncHeight(int syncId) {  	int soundId = -1;  	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) { -		if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) { -			soundId = _track[l].soundId; +		if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) { +			soundId = _track[l]->soundId;  		}  	} @@ -341,12 +341,12 @@ void IMuseDigital::stopAllSounds(bool waitForStop) {  	debug(5, "IMuseDigital::stopAllSounds");  	{  		Common::StackLock lock(_mutex, "IMuseDigital::stopAllSounds()"); -		for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) { -			if (_track[l].used) { -				if (_track[l].stream) { -					_track[l].toBeRemoved = true; -				} else if (_track[l].stream2) -					_vm->_mixer->stopHandle(_track[l].handle); +		for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) { +			if (_track[l]->used) { +				if (_track[l]->stream) { +					_track[l]->toBeRemoved = true; +				} else if (_track[l]->stream2) +					_vm->_mixer->stopHandle(_track[l]->handle);  			}  		}  	} @@ -355,8 +355,8 @@ void IMuseDigital::stopAllSounds(bool waitForStop) {  		bool used;  		do {  			used = false; -			for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) { -				if (_track[l].used) +			for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) { +				if (_track[l]->used)  					used = true;  			}  			g_system->delay_msecs(10); @@ -366,9 +366,9 @@ void IMuseDigital::stopAllSounds(bool waitForStop) {  void IMuseDigital::pause(bool p) {  	Common::StackLock lock(_mutex, "IMuseDigital::pause()"); -	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) { -		if (_track[l].used) { -			_vm->_mixer->pauseHandle(_track[l].handle, p); +	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) { +		if (_track[l]->used) { +			_vm->_mixer->pauseHandle(_track[l]->handle, p);  		}  	}  	_pause = p; diff --git a/scumm/imuse_digi/dimuse_sndmgr.cpp b/scumm/imuse_digi/dimuse_sndmgr.cpp index 63d2d2c0f0..7664c08713 100644 --- a/scumm/imuse_digi/dimuse_sndmgr.cpp +++ b/scumm/imuse_digi/dimuse_sndmgr.cpp @@ -286,7 +286,8 @@ ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const ch  	bool result = false;  	byte *ptr = NULL; -	if (soundName == NULL) { +	if (soundName[0] == 0) { +		_sounds[slot].name[0] = 0;  		if ((soundType == IMUSE_RESOURCE)) {  			ptr = _vm->getResourceAddress(rtSound, soundId);  			if (ptr == NULL) { @@ -294,6 +295,9 @@ ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const ch  				return NULL;  			}  			_sounds[slot].resPtr = ptr; +			_sounds[slot].soundId = soundId; +			_sounds[slot].type = soundType; +			_sounds[slot].volGroupId = volGroupId;  			result = true;  		} else if (soundType == IMUSE_BUNDLE) {  			bool header_outside = ((_vm->_gameId == GID_CMI) && !(_vm->_features & GF_DEMO)); @@ -304,8 +308,9 @@ ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const ch  			else  				error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);  			_sounds[slot].bundle->decompressSampleByIndex(soundId, 0, 0x2000, &ptr, 0, header_outside); -			_sounds[slot].name[0] = 0;  			_sounds[slot].soundId = soundId; +			_sounds[slot].type = soundType; +			_sounds[slot].volGroupId = volGroupId;  		} else {  			error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);  		} @@ -321,6 +326,8 @@ ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const ch  			_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;  		} else {  			error("ImuseDigiSndMgr::openSound() Don't know how load sound: %s", soundName);  		} @@ -350,6 +357,12 @@ void ImuseDigiSndMgr::closeSound(soundStruct *soundHandle) {  	memset(soundHandle, 0, sizeof(soundStruct));  } +ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::cloneSound(soundStruct *soundHandle) { +	assert(soundHandle && checkForProperHandle(soundHandle)); + +	return openSound(soundHandle->soundId, soundHandle->name, soundHandle->type, soundHandle->volGroupId); +} +  bool ImuseDigiSndMgr::checkForProperHandle(soundStruct *soundHandle) {  	for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {  		if (soundHandle == &_sounds[l]) diff --git a/scumm/imuse_digi/dimuse_sndmgr.h b/scumm/imuse_digi/dimuse_sndmgr.h index c6055e5e0a..ba9f28b852 100644 --- a/scumm/imuse_digi/dimuse_sndmgr.h +++ b/scumm/imuse_digi/dimuse_sndmgr.h @@ -81,6 +81,8 @@ public:  		char name[15];  		int16 soundId;  		BundleMgr *bundle; +		int type; +		int volGroupId;  	};  private: @@ -105,8 +107,9 @@ public:  	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);  	void closeSound(soundStruct *soundHandle); +	soundStruct *cloneSound(soundStruct *soundHandle);  	int getFreq(soundStruct *soundHandle);  	int getBits(soundStruct *soundHandle); diff --git a/scumm/imuse_digi/dimuse_track.cpp b/scumm/imuse_digi/dimuse_track.cpp index be15e46fa9..8f70edabe3 100644 --- a/scumm/imuse_digi/dimuse_track.cpp +++ b/scumm/imuse_digi/dimuse_track.cpp @@ -38,33 +38,33 @@ void IMuseDigital::allocSlot(int priority) {  	bool found_free = false;  	for (l = 0; l < MAX_DIGITAL_TRACKS; l++) { -		if (!_track[l].used && !_track[l].handle.isActive()) +		if (!_track[l]->used && !_track[l]->handle.isActive())  			found_free = true;  	}  	if (!found_free) {  		warning("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; +			if (_track[l]->used && _track[l]->handle.isActive() && +					(lower_priority > _track[l]->priority) && (!_track[l]->stream2)) +				lower_priority = _track[l]->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)) { +				if (_track[l]->used && _track[l]->handle.isActive() && +						(lower_priority == _track[l]->priority) && (!_track[l]->stream2)) {  					track_id = 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].used = false; -			assert(!_track[track_id].handle.isActive()); -			warning("IMuseDigital::startSound(): Removed sound %d from track %d", _track[track_id].soundId, track_id); +			_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]->used = false; +			assert(!_track[track_id]->handle.isActive()); +			warning("IMuseDigital::startSound(): Removed sound %d from track %d", _track[track_id]->soundId, track_id);  		} else {  			warning("IMuseDigital::startSound(): Priority sound too low");  			return; @@ -80,46 +80,47 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,  	allocSlot(priority);  	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].toBeRemoved = false; - -			int bits = 0, freq = 0, channels = 0, mixerFlags = 0; +		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]->toBeRemoved = false; + +			int bits = 0, freq = 0, channels = 0;  			if (input) { -				_track[l].iteration = 1; // ? +				_track[l]->iteration = 1; // ?  				// Do nothing here, we already have an audio stream  			} else { -				_track[l].soundHandle = _sound->openSound(soundId, soundName, soundType, volGroupId); +				_track[l]->soundHandle = _sound->openSound(soundId, soundName, soundType, volGroupId); -				if (_track[l].soundHandle == NULL) +				if (_track[l]->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[l]->soundHandle); +				channels = _sound->getChannels(_track[l]->soundHandle); +				freq = _sound->getFreq(_track[l]->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[l]->pan = a->talkPan; +						_track[l]->vol = a->talkVolume * 1000;  					}  				} @@ -135,32 +136,32 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,  				// subclass).  				freq -= (freq % 25); -				_track[l].iteration = _track[l].pullSize = freq * channels; +				_track[l]->iteration = _track[l]->pullSize = freq * channels;  				if (channels == 2) -					mixerFlags = SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO; +					_track[l]->mixerFlags = SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO;  				if ((bits == 12) || (bits == 16)) { -					mixerFlags |= SoundMixer::FLAG_16BITS; -					_track[l].iteration = _track[l].pullSize *= 2; +					_track[l]->mixerFlags |= SoundMixer::FLAG_16BITS; +					_track[l]->iteration = _track[l]->pullSize *= 2;  				} else if (bits == 8) { -					mixerFlags |= SoundMixer::FLAG_UNSIGNED; +					_track[l]->mixerFlags |= SoundMixer::FLAG_UNSIGNED;  				} else  					error("IMuseDigital::startSound(): Can't handle %d bit samples", bits); -				_track[l].pullSize /= 25;	// We want a "frame rate" of 25 audio blocks per second +				_track[l]->pullSize /= 25;	// We want a "frame rate" of 25 audio blocks per second  			}  			if (input) { -				_track[l].stream2 = input; -				_track[l].stream = NULL; +				_track[l]->stream2 = input; +				_track[l]->stream = NULL;  			} else { -				_track[l].stream2 = NULL; -				_track[l].stream = makeAppendableAudioStream(freq, mixerFlags, 100000); -				_vm->_mixer->playInputStream(&_track[l].handle, _track[l].stream, false, _track[l].vol / 1000, _track[l].pan, -1); +				_track[l]->stream2 = NULL; +				_track[l]->stream = makeAppendableAudioStream(freq, _track[l]->mixerFlags, 100000); +				_vm->_mixer->playInputStream(&_track[l]->handle, _track[l]->stream, false, _track[l]->vol / 1000, _track[l]->pan, -1);  			} -			_track[l].used = true; +			_track[l]->used = true;  			return;  		}  	} @@ -175,8 +176,8 @@ void IMuseDigital::setPriority(int soundId, int 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; +		if ((_track[l]->soundId == soundId) && _track[l]->used) { +			_track[l]->priority = priority;  		}  	}  } @@ -185,8 +186,8 @@ void IMuseDigital::setVolume(int soundId, int volume) {  	Common::StackLock lock(_mutex, "IMuseDigital::setVolume()");  	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; +		if ((_track[l]->soundId == soundId) && _track[l]->used) { +			_track[l]->vol = volume * 1000;  		}  	}  } @@ -195,8 +196,8 @@ void IMuseDigital::setPan(int soundId, int pan) {  	Common::StackLock lock(_mutex, "IMuseDigital::setPan()");  	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; +		if ((_track[l]->soundId == soundId) && _track[l]->used) { +			_track[l]->pan = pan;  		}  	}  } @@ -210,8 +211,8 @@ void IMuseDigital::selectVolumeGroup(int soundId, int volGroupId) {  		volGroupId = 3;  	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) { -		if ((_track[l].soundId == soundId) && _track[l].used) { -			_track[l].volGroupId = volGroupId; +		if ((_track[l]->soundId == soundId) && _track[l]->used) { +			_track[l]->volGroupId = volGroupId;  		}  	}  } @@ -220,11 +221,11 @@ void IMuseDigital::setFade(int soundId, int destVolume, int delay60HzTicks) {  	Common::StackLock lock(_mutex, "IMuseDigital::setFade()");  	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; +		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;  		}  	}  } @@ -233,13 +234,72 @@ void IMuseDigital::fadeOutMusic(int fadeDelay) {  	Common::StackLock lock(_mutex, "IMuseDigital::fadeOutMusic()");  	debug(5, "IMuseDigital::fadeOutMusic");  	for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) { -		if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) { -			_track[l].volFadeDelay = fadeDelay; -			_track[l].volFadeDest = 0; -			_track[l].volFadeStep = (_track[l].volFadeDest - _track[l].vol) * 60 * 40 / (1000 * fadeDelay); -			_track[l].volFadeUsed = true; +		if ((_track[l]->used) && (_track[l]->volGroupId == IMUSE_VOLGRP_MUSIC)) { +			cloneToFadeOutTrack(l, fadeDelay, true);  		}  	}  } +int IMuseDigital::cloneToFadeOutTrack(int track, int fadeDelay, int killNormalTrack) { +	Common::StackLock lock(_mutex, "IMuseDigital::cloneToFadeOutTrack()"); +	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"); + +	// swap track to fade track +	Track *tmpTrack = _track[track]; +	_track[track] = _track[fadeTrack]; +	_track[fadeTrack] = tmpTrack; + +	// 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]->mod = _track[fadeTrack]->mod; +	_track[track]->pullSize = _track[fadeTrack]->pullSize; +	_track[track]->used = _track[fadeTrack]->used; +	_track[track]->toBeRemoved = _track[fadeTrack]->toBeRemoved; +	_track[track]->started = _track[fadeTrack]->started; +	_track[track]->stream2 = _track[fadeTrack]->stream2; + +	_track[track]->soundHandle = NULL; +	_track[track]->stream = NULL; + +	_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; + +	if (killNormalTrack) { +		_track[track]->used = false; +	} else { +		_track[track]->soundHandle = _sound->cloneSound(_track[fadeTrack]->soundHandle); +		_track[track]->stream = makeAppendableAudioStream(_sound->getFreq(_track[track]->soundHandle), _track[track]->mixerFlags, 100000); +		_vm->_mixer->playInputStream(&_track[track]->handle, _track[track]->stream, false, _track[track]->vol / 1000, _track[track]->pan, -1); +	} + +	return fadeTrack; +} +  } // End of namespace Scumm | 
