[Scummvm-git-logs] scummvm master -> 992887810a3bcd58ac86deb4dcd4beeb7086ba64

athrxx noreply at scummvm.org
Sat Dec 11 21:30:39 UTC 2021


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
992887810a KYRA: (LoK/Mac) - implement GMM volume settings


Commit: 992887810a3bcd58ac86deb4dcd4beeb7086ba64
    https://github.com/scummvm/scummvm/commit/992887810a3bcd58ac86deb4dcd4beeb7086ba64
Author: athrxx (athrxx at scummvm.org)
Date: 2021-12-11T22:28:57+01:00

Commit Message:
KYRA: (LoK/Mac) - implement GMM volume settings

( and some other minor improvements and fixes)

Changed paths:
    engines/kyra/sound/drivers/halestorm.cpp
    engines/kyra/sound/drivers/halestorm.h
    engines/kyra/sound/sound_mac_lok.cpp
    engines/kyra/sound/sound_mac_res.h


diff --git a/engines/kyra/sound/drivers/halestorm.cpp b/engines/kyra/sound/drivers/halestorm.cpp
index e49421b33f..7fab6e6c37 100644
--- a/engines/kyra/sound/drivers/halestorm.cpp
+++ b/engines/kyra/sound/drivers/halestorm.cpp
@@ -43,8 +43,7 @@ public:
 	void setVblCallback(CallbackProc *proc);
 	void clearBuffer();
 
-	void setMusicVolume(uint16 vol);
-	void setSoundEffectVolume(uint16 vol);
+	void setMasterVolume(Audio::Mixer::SoundType type, uint16 vol);
 
 	// AudioStream interface
 	int readBuffer(int16 *buffer, const int numSamples) override;
@@ -53,8 +52,8 @@ public:
 	bool endOfData() const override { return false; }
 
 private:
-	template<typename T> void generateData(T *dst, uint32 len);
-	void runVblTasl();
+	template<typename T> void generateData(T *dst, uint32 len, Audio::Mixer::SoundType);
+	void runVblTask();
 
 	HSLowLevelDriver *_drv;
 
@@ -63,14 +62,15 @@ private:
 	uint32 _vblCountDown;
 	uint32 _vblCountDownRem;
 
-	uint32 _volMusic;
-	uint32 _volSfx;
-
 	CallbackProc *_vblCbProc;
 
-	void *_buffStart;
-	const void *_buffEnd;
-	void *_buffPos;
+	struct SmpBuffer {
+		SmpBuffer() : start(0), pos(0), end(0), volume(0x10000) {}
+		void *start;
+		void *pos;
+		const void *end;
+		uint32 volume;
+	} _buffers[2];
 
 	const uint32 _intRate;
 	const uint32 _outputRate;
@@ -244,7 +244,7 @@ public:
 	HSAudioStream *init(uint32 scummVMOutputrate, bool output16bit);
 	int send(int cmd, ...);
 
-	template<typename T> void generateData(T *dst, uint32 len);
+	template<typename T> void generateData(T *dst, uint32 len, Audio::Mixer::SoundType type);
 
 private:
 	typedef Common::Functor1Mem<va_list&, int, HSLowLevelDriver> HSOpcode;
@@ -317,7 +317,7 @@ private:
 	HSSoundChannel *_chan;
 
 	void createTables();
-	void pcmNextTick();
+	void pcmNextTick(int chanFirst, int chanLast);
 	void pcmUpdateChannel(HSSoundChannel &chan);
 	template<typename T> void fillBuffer(T *dst);
 
@@ -525,21 +525,23 @@ private:
 
 HSAudioStream::HSAudioStream(HSLowLevelDriver *drv, uint32 scummVMOutputrate, uint32 deviceRate, uint32 feedBufferSize, bool output16Bit) : Audio::AudioStream(), _drv(drv),
 _outputRate(scummVMOutputrate), _intRate(deviceRate), _buffSize(feedBufferSize), _outputByteSize(output16Bit ? 2 : 1), _isStereo(false), _vblSmpQty(0), _vblSmpQtyRem(0),
-_vblCountDown(0), _vblCountDownRem(0), _buffPos(nullptr), _buffStart(nullptr), _buffEnd(nullptr), _rateConvCnt(0), _volMusic(0x10000), _volSfx(0x10000),
-_vblCbProc(nullptr) {
+_vblCountDown(0), _vblCountDownRem(0), _rateConvCnt(0), _vblCbProc(nullptr) {
 	assert(drv);
 	_vblSmpQty = scummVMOutputrate / 60;
 	_vblSmpQtyRem = scummVMOutputrate % 60;
 	_vblCountDown = _vblSmpQty;
 	_vblCountDownRem = 0;
 
-	_buffStart = new uint8[_buffSize * _outputByteSize];
-	_buffEnd = (uint8*)_buffStart + _buffSize * _outputByteSize;
+	for (int i = 0; i < 2; ++i) {
+		_buffers[i].start = new uint8[_buffSize * _outputByteSize];
+		_buffers[i].end = (uint8*)_buffers[i].start + _buffSize * _outputByteSize;
+	}
 	clearBuffer();
 }
 
 HSAudioStream::~HSAudioStream() {
-	delete[] (uint8*)_buffStart;
+	for (int i = 0; i < 2; ++i)
+		delete[] (uint8*)_buffers[i].start;
 }
 
 void HSAudioStream::setVblCallback(CallbackProc *proc) {
@@ -547,38 +549,50 @@ void HSAudioStream::setVblCallback(CallbackProc *proc) {
 }
 
 void HSAudioStream::clearBuffer() {
-	memset(_buffStart, _outputByteSize == 2 ? 0 : 0x80, _buffSize * _outputByteSize);
-	_buffPos = _buffStart;
-}
-
-void HSAudioStream::setMusicVolume(uint16 vol) {
-	_volMusic = vol * vol;
+	for (int i = 0; i < 2; ++i) {
+		memset(_buffers[i].start, _outputByteSize == 2 ? 0 : 0x80, _buffSize * _outputByteSize);
+		_buffers[i].pos = _buffers[i].start;
+	}
 }
 
-void HSAudioStream::setSoundEffectVolume(uint16 vol) {
-	_volSfx = vol * vol;
+void HSAudioStream::setMasterVolume(Audio::Mixer::SoundType type, uint16 vol) {
+	if (type == Audio::Mixer::kMusicSoundType || type == Audio::Mixer::kPlainSoundType)
+		_buffers[0].volume = vol * vol;
+	if (type == Audio::Mixer::kSFXSoundType || type == Audio::Mixer::kPlainSoundType)
+		_buffers[1].volume = vol * vol;
 }
 
 int HSAudioStream::readBuffer(int16 *buffer, const int numSamples) {
+	static const Audio::Mixer::SoundType stype[2] = {
+		Audio::Mixer::kMusicSoundType,
+		Audio::Mixer::kSFXSoundType
+	};
+
 	for (int i = _isStereo ? numSamples >> 1 : numSamples; i; --i) {
 		if (!--_vblCountDown) {
 			_vblCountDownRem += _vblSmpQtyRem;
 			_vblCountDown = _vblSmpQty + _vblCountDownRem / _vblSmpQty;
 			_vblCountDownRem %= _vblSmpQty;
-			runVblTasl();
+			runVblTask();
 		}
 
-		int32 smp = (int32)(((_outputByteSize == 2) ? *(int16*)_buffPos : *(uint8*)_buffPos - 0x80) * _volSfx);
+		int32 smp = 0;
+		for (int ii = 0; ii < 2; ++ii)
+			smp += (int32)(((_outputByteSize == 2) ? *(int16*)_buffers[ii].pos : *(uint8*)_buffers[ii].pos - 0x80) * _buffers[ii].volume);
+
 		_rateConvCnt += _intRate;
 		if (_rateConvCnt >= _outputRate) {
 			_rateConvCnt -= _outputRate;
-			_buffPos = (uint8*)_buffPos + _outputByteSize;
-			if (_buffPos == _buffEnd) {
-				_buffPos = _buffStart;
-				if (_outputByteSize == 2)
-					generateData<int16>((int16*)_buffPos, _buffSize);
-				else
-					generateData<uint8>((uint8*)_buffPos, _buffSize);
+
+			for (int ii = 0; ii < 2; ++ii) {
+				_buffers[ii].pos = (uint8*)_buffers[ii].pos + _outputByteSize;
+				if (_buffers[ii].pos == _buffers[ii].end) {
+					_buffers[ii].pos = _buffers[ii].start;
+					if (_outputByteSize == 2)
+						generateData<int16>((int16*)_buffers[ii].pos, _buffSize, stype[ii]);
+					else
+						generateData<uint8>((uint8*)_buffers[ii].pos, _buffSize, stype[ii]);
+				}
 			}
 		}
 
@@ -590,12 +604,12 @@ int HSAudioStream::readBuffer(int16 *buffer, const int numSamples) {
 	return numSamples;
 }
 
-template<typename T> void HSAudioStream::generateData(T *dst, uint32 len) {
+template<typename T> void HSAudioStream::generateData(T *dst, uint32 len, Audio::Mixer::SoundType type) {
 	if (_drv)
-		_drv->generateData<T>(dst, len);
+		_drv->generateData<T>(dst, len, type);
 }
 
-void HSAudioStream::runVblTasl() {
+void HSAudioStream::runVblTask() {
 	if (_vblCbProc && _vblCbProc->isValid())
 		(*_vblCbProc)();
 }
@@ -948,9 +962,20 @@ int HSLowLevelDriver::send(int cmd, ...) {
 	return res;
 }
 
-template<typename T> void HSLowLevelDriver::generateData(T *dst, uint32 len) {
-	pcmNextTick();
-	songNextTick();
+template<typename T> void HSLowLevelDriver::generateData(T *dst, uint32 len, Audio::Mixer::SoundType type) {
+	int first = 0;
+	int last = _song._numChanMusic + _song._numChanSfx;
+
+	if (type == Audio::Mixer::kMusicSoundType)
+		last = _song._numChanMusic;
+	else if (type == Audio::Mixer::kSFXSoundType)
+		first = _song._numChanMusic;
+	else if (type == Audio::Mixer::kSpeechSoundType)
+		error("HSLowLevelDriver::generateData(): Unsupported sound type 'kSpeechSoundType'");
+
+	pcmNextTick(first, last);
+	if (type != Audio::Mixer::kSFXSoundType)
+		songNextTick();
 	fillBuffer<T>(dst);
 }
 
@@ -1342,12 +1367,12 @@ void HSLowLevelDriver::createTables() {
 	}
 }
 
-void HSLowLevelDriver::pcmNextTick() {
+void HSLowLevelDriver::pcmNextTick(int chanFirst, int chanLast) {
 	int16 cnt = 0;
 	uint16 val = 0;
 	for (int i = 0; i < _song._numChanMusic + _song._numChanSfx; ++i) {
 		++cnt;
-		if (_chan[i].status >= 0)
+		if (i >= chanFirst && i < chanLast && _chan[i].status >= 0)
 			continue;
 		--cnt;
 		val += 0x80;
@@ -1362,7 +1387,7 @@ void HSLowLevelDriver::pcmNextTick() {
 		return;
 
 	for (int i = 0; i < _song._numChanMusic + _song._numChanSfx; ++i) {
-		if (_chan[i].status < 0)
+		if (i < chanFirst || i >= chanLast || _chan[i].status < 0)
 			continue;
 		pcmUpdateChannel(_chan[i]);
 	}
@@ -2040,8 +2065,8 @@ bool HSSoundSystem::init(bool hiQuality, uint8 interpolationMode, bool output16b
 	_voicestr = _driver->init(_mixer->getOutputRate(), output16bit);
 	if (!_voicestr)
 		return false;
-	_voicestr->setMusicVolume(_volumeMusic);
-	_voicestr->setSoundEffectVolume(_volumeSfx);
+	_voicestr->setMasterVolume(Audio::Mixer::kMusicSoundType, _volumeMusic);
+	_voicestr->setMasterVolume(Audio::Mixer::kSFXSoundType, _volumeSfx);
 
 	Common::StackLock lock(_mutex);
 	_vblTask = new HSAudioStream::CallbackProc(this, &HSSoundSystem::vblTaskProc);
@@ -2105,7 +2130,6 @@ int HSSoundSystem::changeSystemVoices(int numChanMusicTotal, int numChanMusicPol
 }
 
 void HSSoundSystem::startSoundEffect(int id, int rate) {
-	Common::StackLock lock(_mutex);
 	if (!_ready)
 		return;
 
@@ -2113,6 +2137,8 @@ void HSSoundSystem::startSoundEffect(int id, int rate) {
 	if (!slot)
 		return;
 
+	Common::StackLock lock(_mutex);
+
 	if (slot->reverse) {
 		reverseSamples(slot);
 		slot->reverse = false;
@@ -2122,7 +2148,6 @@ void HSSoundSystem::startSoundEffect(int id, int rate) {
 }
 
 void HSSoundSystem::enqueueSoundEffect(int id, int rate, int note) {
-	Common::StackLock lock(_mutex);
 	if (!_ready || !id || !rate || !note)
 		return;
 
@@ -2130,6 +2155,8 @@ void HSSoundSystem::enqueueSoundEffect(int id, int rate, int note) {
 	if (!s)
 		return;
 
+	Common::StackLock lock(_mutex);
+
 	assert(note > 21 && note < 80);
 	_sfxQueue.push(SfxQueueEntry(id, (s->rate >> 8) * _noteFreq[note - 22], rate * 60 / 1000));
 	_sfxDuration = 0;
@@ -2242,6 +2269,10 @@ int HSSoundSystem::doCommand(int cmd, va_list &arg) {
 		_driver->send(18, va_arg(arg, const HSSoundEffectVoice*));
 		break;
 
+	case 102:
+		res = _driver->send(20, va_arg(arg, const HSSoundEffectVoice*));
+		break;
+
 	case 103:
 		_isFading = false;
 		_driver->send(22);
@@ -2259,7 +2290,7 @@ void HSSoundSystem::setMusicVolume(int volume) {
 	Common::StackLock lock(_mutex);
 	if (!_ready)
 		return;
-	_voicestr->setMusicVolume(volume);
+	_voicestr->setMasterVolume(Audio::Mixer::kMusicSoundType, volume);
 }
 
 void HSSoundSystem::setSoundEffectVolume(int volume) {
@@ -2267,7 +2298,7 @@ void HSSoundSystem::setSoundEffectVolume(int volume) {
 	Common::StackLock lock(_mutex);
 	if (!_ready)
 		return;
-	_voicestr->setSoundEffectVolume(volume);
+	_voicestr->setMasterVolume(Audio::Mixer::kSFXSoundType, volume);
 }
 
 void HSSoundSystem::vblTaskProc() {
diff --git a/engines/kyra/sound/drivers/halestorm.h b/engines/kyra/sound/drivers/halestorm.h
index 4bbcfe6f42..20bfbcfa18 100644
--- a/engines/kyra/sound/drivers/halestorm.h
+++ b/engines/kyra/sound/drivers/halestorm.h
@@ -61,6 +61,18 @@ public:
 	void stopSoundEffect(int id);
 	void stopAllSoundEffects();
 
+	enum HSCommands {
+		kSongPlayOnce			= 0,
+		kSongPlayLoop			= 1,
+		kSongAbort				= 2,
+		kSongIsPlaying			= 3,
+		kSongFadeOut			= 10,
+		kSongFadeIn				= 11,
+		kSongFadeGetState		= 12,
+		kSongFadeReset			= 13,
+		kSetRateAndIntrplMode	= 14
+	};
+
 	int doCommand(int cmd, ...);
 
 	void setMusicVolume(int volume);
diff --git a/engines/kyra/sound/sound_mac_lok.cpp b/engines/kyra/sound/sound_mac_lok.cpp
index c8c59c3215..91f6922847 100644
--- a/engines/kyra/sound/sound_mac_lok.cpp
+++ b/engines/kyra/sound/sound_mac_lok.cpp
@@ -90,6 +90,7 @@ bool SoundMacRes::init() {
 }
 
 Common::SeekableReadStream *SoundMacRes::getResource(uint16 id, uint32 type) {
+	Common::StackLock lock(_mutex);
 	Common::SeekableReadStream *res = nullptr;
 
 	for (int i = 0; i < 2; ++i) {
@@ -101,6 +102,7 @@ Common::SeekableReadStream *SoundMacRes::getResource(uint16 id, uint32 type) {
 }
 
 bool SoundMacRes::setQuality(bool hi) {
+	Common::StackLock lock(_mutex);
 	Common::String s[2];
 	s[0] = hi ? "HQ_Music.res" : "LQ_Music.res";
 	s[1] = _kyraMacExe;
@@ -138,6 +140,9 @@ Sound::kType SoundMac::getMusicType() const {
 }
 
 bool SoundMac::init(bool hiQuality) {
+	if (_ready)
+		return true;
+
 	_res = new SoundMacRes(_vm);
 	if (!(_res && _res->init()))
 		return false;
@@ -149,7 +154,10 @@ bool SoundMac::init(bool hiQuality) {
 
 	setQuality(hiQuality);
 
-	return (_ready = true);
+	_ready = true;
+	updateVolumeSettings();
+
+	return true;
 }
 
 void SoundMac::selectAudioResourceSet(int set) {
@@ -179,10 +187,10 @@ void SoundMac::playTrack(uint8 track) {
 		beginFadeOut();
 		return;
 	} else if (_currentResourceSet == kMusicFinale && track == 2) {
-		_driver->doCommand(1, 0x12c);
+		_driver->doCommand(HalestormDriver::kSongPlayLoop, 0x12c);
 		return;
 	} else if (_currentResourceSet == kMusicFinale && track == 4) {
-		_driver->doCommand(1, 0x12d);
+		_driver->doCommand(HalestormDriver::kSongPlayLoop, 0x12d);
 		return;
 	} else {
 		track -= 11;
@@ -190,12 +198,12 @@ void SoundMac::playTrack(uint8 track) {
 		loop = _musicLoopTable[track];
 	}
 
-	_driver->doCommand(loop, _resIDMusic[track]);
+	_driver->doCommand(loop ? HalestormDriver::kSongPlayLoop : HalestormDriver::kSongPlayOnce, _resIDMusic[track]);
 }
 
 void SoundMac::haltTrack() {
 	if (_ready)
-		_driver->doCommand(2);
+		_driver->doCommand(HalestormDriver::kSongAbort);
 }
 
 void SoundMac::playSoundEffect(uint16 track, uint8) {
@@ -213,23 +221,18 @@ void SoundMac::playSoundEffect(uint16 track, uint8) {
 }
 
 bool SoundMac::isPlaying() const {
-	return _ready && _driver->doCommand(3);
+	return _ready && _driver->doCommand(HalestormDriver::kSongIsPlaying);
 }
 
 void SoundMac::beginFadeOut() {
 	if (!_ready)
 		return;
 
-	if (_currentResourceSet == kMusicIngame) {
-		haltTrack();
-		return;
-	}
-
-	_driver->doCommand(10, 30);
-	while (_driver->doCommand(12) >= 16)
+	_driver->doCommand(HalestormDriver::kSongFadeOut, 30);
+	while (_driver->doCommand(HalestormDriver::kSongFadeGetState) >= 16)
 		_vm->delay(8);
-	_driver->doCommand(2);
-	_driver->doCommand(11, 30);
+	_driver->doCommand(HalestormDriver::kSongAbort);
+	_driver->doCommand(HalestormDriver::kSongFadeReset, 256);
 }
 
 void SoundMac::updateVolumeSettings() {
@@ -252,7 +255,7 @@ void SoundMac::setQuality(bool hi) {
 	if (!(_driver && _res))
 		return;
 
-	_driver->doCommand(2);
+	_driver->doCommand(HalestormDriver::kSongAbort);
 	_driver->stopAllSoundEffects();
 	_driver->releaseSamples();
 
@@ -260,10 +263,10 @@ void SoundMac::setQuality(bool hi) {
 
 	if (hi) {
 		_driver->changeSystemVoices(7, 4, 1);
-		_driver->doCommand(14, 3);
+		_driver->doCommand(HalestormDriver::kSetRateAndIntrplMode, 3);
 	} else {
 		_driver->changeSystemVoices(4, 3, 1);
-		_driver->doCommand(14, 2);
+		_driver->doCommand(HalestormDriver::kSetRateAndIntrplMode, 2);
 	}
 
 	_driver->registerSamples(resIds, true);
diff --git a/engines/kyra/sound/sound_mac_res.h b/engines/kyra/sound/sound_mac_res.h
index b4dbf53483..89c8de5808 100644
--- a/engines/kyra/sound/sound_mac_res.h
+++ b/engines/kyra/sound/sound_mac_res.h
@@ -44,6 +44,7 @@ private:
 	Common::String _kyraMacExe;
 	Common::MacResManager *_resMan;
 	Common::Archive *_stuffItArchive;
+	Common::Mutex _mutex;
 };
 
 } // End of namespace Kyra




More information about the Scummvm-git-logs mailing list