diff options
| -rw-r--r-- | scumm/imuse_digi/dimuse.cpp | 111 | ||||
| -rw-r--r-- | scumm/imuse_digi/dimuse.h | 17 | ||||
| -rw-r--r-- | scumm/imuse_digi/dimuse_track.cpp | 35 | 
3 files changed, 153 insertions, 10 deletions
| diff --git a/scumm/imuse_digi/dimuse.cpp b/scumm/imuse_digi/dimuse.cpp index 1feefff637..58dddc8a07 100644 --- a/scumm/imuse_digi/dimuse.cpp +++ b/scumm/imuse_digi/dimuse.cpp @@ -78,10 +78,19 @@ void IMuseDigital::resetState() {  	_nextSeqToPlay = 0;  } -void IMuseDigital::pullDataForMixer(int32 pullSize, byte *mixerBuffer, AudioStream *stream) { -	Common::StackLock lock(_mutex, "IMuseDigital::pullDataForMixer()"); +#ifdef ENABLE_PULLMETHOD + +int IMuseDigital::pullProcCallback(void *refCon, CustomProcInputStream *stream, byte *mixerBuffer, int pullSize) { +	IMuseDigital *imuseDigital = (IMuseDigital *)refCon; +	return imuseDigital->pullProc(stream, mixerBuffer, pullSize); +} + +int IMuseDigital::pullProc(CustomProcInputStream *stream, byte *mixerBuffer, int pullSize) { +	Common::StackLock lock(_mutex, "IMuseDigital::pullProc()");  	for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {  		if (_track[l]->stream == stream) { +			_vm->_mixer->setChannelVolume(_track[l]->handle, _track[l]->mixerVol); +			_vm->_mixer->setChannelBalance(_track[l]->handle, _track[l]->mixerPan);  			int32 mixer_size = pullSize;  			byte *data = NULL;  			int32 result = 0, pos = 0; @@ -114,6 +123,10 @@ void IMuseDigital::pullDataForMixer(int32 pullSize, byte *mixerBuffer, AudioStre  							result &= ~2;  					}  				} else if (bits == 8) { +					memset(mixerBuffer, 0x80, pullSize);  +					_track[l]->toBeRemoved = true; +					return pullSize; +  					result = _sound->getDataFromRegion(_track[l]->soundHandle, _track[l]->curRegion, &data, _track[l]->regionOffset, mixer_size);  					if (_sound->getChannels(_track[l]->soundHandle) == 2) {  						result &= ~1; @@ -132,18 +145,103 @@ void IMuseDigital::pullDataForMixer(int32 pullSize, byte *mixerBuffer, AudioStre  				if (_sound->isEndOfRegion(_track[l]->soundHandle, _track[l]->curRegion)) {  					switchToNextRegion(l); -					if (_track[l]->toBeRemoved) -						break; +					if (_track[l]->toBeRemoved) { +						mixer_size -= result; +						return pullSize - mixer_size; +					}  				}  				mixer_size -= result;  				assert(mixer_size >= 0);  			} while (mixer_size != 0); -			return; +			return pullSize; +		} +	} +	error("IMuseDigital::pullProc() Can't match streams"); +} + +void IMuseDigital::callback() { +	Common::StackLock lock(_mutex, "IMuseDigital::callback()"); +	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; +				} +			} + +			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; +						} +					} +				} 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); +			} + +			int pan = (_track[l]->pan != 64) ? 2 * _track[l]->pan - 127 : 0; +			int vol = _track[l]->vol / 1000; + +			if (_track[l]->volGroupId == 1) +				vol = (vol * _volVoice) / 128; +			if (_track[l]->volGroupId == 2) +				vol = (vol * _volSfx) / 128; +			if (_track[l]->volGroupId == 3) +				vol = (vol * _volMusic) / 128; + +			_track[l]->mixerVol = vol; +			_track[l]->mixerPan = pan; + +			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); +					} +				} +			}  		}  	} -	error("IMuseDigital::pullDataForMixer() Can't match streams");  } +#else +  void IMuseDigital::callback() {  	Common::StackLock lock(_mutex, "IMuseDigital::callback()");  	int l = 0; @@ -287,6 +385,7 @@ void IMuseDigital::callback() {  		}  	}  } +#endif  void IMuseDigital::switchToNextRegion(int track) {  	if (track >= MAX_DIGITAL_TRACKS) { diff --git a/scumm/imuse_digi/dimuse.h b/scumm/imuse_digi/dimuse.h index 9c29f3180d..c49ff6bdf2 100644 --- a/scumm/imuse_digi/dimuse.h +++ b/scumm/imuse_digi/dimuse.h @@ -33,6 +33,10 @@  namespace Scumm { +// enable below for pullmethod data transfer from imuse to sound mixer, +// it's experimental and buggy +//#define ENABLE_PULLMETHOD +  #define MAX_DIGITAL_TRACKS 8  #define MAX_DIGITAL_FADETRACKS 8 @@ -63,12 +67,20 @@ private:  		int volGroupId;  		int iteration;  		int mod; +#ifndef ENABLE_PULLMETHOD  		int32 pullSize; +#endif  		int32 mixerFlags; +		int mixerVol; +		int mixerPan;  		ImuseDigiSndMgr::soundStruct *soundHandle;  		PlayingSoundHandle handle; +#ifndef ENABLE_PULLMETHOD  		AppendableAudioStream *stream; +#else +		CustomProcInputStream *stream; +#endif  		AudioStream *stream2;  		Track(); @@ -93,7 +105,10 @@ private:  	int _curMusicCue;  	static void timer_handler(void *refConf); -	void pullDataForMixer(int32 pullSize, byte *mixerBuffer, AudioStream *stream); +#ifdef ENABLE_PULLMETHOD +	static int pullProcCallback(void *refCon, CustomProcInputStream *stream, byte *mixerBuffer, int pullSize); +	int pullProc(CustomProcInputStream *stream, byte *mixerBuffer, int pullSize); +#endif  	void callback();  	void switchToNextRegion(int track);  	void allocSlot(int priority); diff --git a/scumm/imuse_digi/dimuse_track.cpp b/scumm/imuse_digi/dimuse_track.cpp index 8f70edabe3..ccac2296fd 100644 --- a/scumm/imuse_digi/dimuse_track.cpp +++ b/scumm/imuse_digi/dimuse_track.cpp @@ -58,9 +58,14 @@ void IMuseDigital::allocSlot(int priority) {  				}  			}  			assert(track_id != -1); +#ifndef ENABLE_PULLMETHOD  			_track[track_id]->stream->finish();  			_track[track_id]->stream = NULL;  			_vm->_mixer->stopHandle(_track[track_id]->handle); +#else +			_vm->_mixer->stopHandle(_track[track_id]->handle); +			_track[track_id]->stream = NULL; +#endif  			_sound->closeSound(_track[track_id]->soundHandle);  			_track[track_id]->used = false;  			assert(!_track[track_id]->handle.isActive()); @@ -98,6 +103,8 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,  			_track[l]->trackOffset = 0;  			_track[l]->mod = 0;  			_track[l]->mixerFlags = 0; +			_track[l]->mixerPan = 0; +			_track[l]->mixerVol = volume;  			_track[l]->toBeRemoved = false;  			int bits = 0, freq = 0, channels = 0; @@ -136,29 +143,42 @@ 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 = freq * channels; +#ifndef ENABLE_PULLMETHOD +				_track[l]->pullSize = _track[l]->iteration; +#endif  				if (channels == 2)  					_track[l]->mixerFlags = SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO;  				if ((bits == 12) || (bits == 16)) {  					_track[l]->mixerFlags |= SoundMixer::FLAG_16BITS; -					_track[l]->iteration = _track[l]->pullSize *= 2; +					_track[l]->iteration *= 2; +#ifndef ENABLE_PULLMETHOD +					_track[l]->pullSize = _track[l]->iteration; +#endif  				} else if (bits == 8) {  					_track[l]->mixerFlags |= SoundMixer::FLAG_UNSIGNED;  				} else  					error("IMuseDigital::startSound(): Can't handle %d bit samples", bits); +#ifndef ENABLE_PULLMETHOD  				_track[l]->pullSize /= 25;	// We want a "frame rate" of 25 audio blocks per second +#endif  			}  			if (input) {  				_track[l]->stream2 = input;  				_track[l]->stream = NULL; +				_track[l]->started = false;  			} else {  				_track[l]->stream2 = NULL; +#ifndef ENABLE_PULLMETHOD  				_track[l]->stream = makeAppendableAudioStream(freq, _track[l]->mixerFlags, 100000); +#else +				_track[l]->stream = new CustomProcInputStream(freq, _track[l]->mixerFlags, (CustomProcInputStream::CustomInputProc)pullProcCallback, this); +#endif  				_vm->_mixer->playInputStream(&_track[l]->handle, _track[l]->stream, false, _track[l]->vol / 1000, _track[l]->pan, -1); +				_track[l]->started = true;  			}  			_track[l]->used = true; @@ -276,8 +296,12 @@ int IMuseDigital::cloneToFadeOutTrack(int track, int fadeDelay, int killNormalTr  	_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; +#ifndef ENABLE_PULLMETHOD  	_track[track]->pullSize = _track[fadeTrack]->pullSize; +#endif  	_track[track]->used = _track[fadeTrack]->used;  	_track[track]->toBeRemoved = _track[fadeTrack]->toBeRemoved;  	_track[track]->started = _track[fadeTrack]->started; @@ -295,8 +319,13 @@ int IMuseDigital::cloneToFadeOutTrack(int track, int fadeDelay, int killNormalTr  		_track[track]->used = false;  	} else {  		_track[track]->soundHandle = _sound->cloneSound(_track[fadeTrack]->soundHandle); +#ifndef ENABLE_PULLMETHOD  		_track[track]->stream = makeAppendableAudioStream(_sound->getFreq(_track[track]->soundHandle), _track[track]->mixerFlags, 100000); +#else +		_track[track]->stream = new CustomProcInputStream(_sound->getFreq(_track[track]->soundHandle), _track[track]->mixerFlags, (CustomProcInputStream::CustomInputProc)pullProcCallback, this); +#endif  		_vm->_mixer->playInputStream(&_track[track]->handle, _track[track]->stream, false, _track[track]->vol / 1000, _track[track]->pan, -1); +		_track[track]->started = true;  	}  	return fadeTrack; | 
