[Scummvm-git-logs] scummvm master -> d165b1dc93582f43f08bbea54a2f3969d626b08e

athrxx noreply at scummvm.org
Sun Dec 15 15:04:15 UTC 2024


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

Summary:
89f6c1c83b SCUMM: (IMS/Mac) - fix orginal instrument glitch
d165b1dc93 SCUMM: (IMS/Mac) - fix DOTT music volume


Commit: 89f6c1c83b4aa9929a82a50f0593857287ea73f5
    https://github.com/scummvm/scummvm/commit/89f6c1c83b4aa9929a82a50f0593857287ea73f5
Author: athrxx (athrxx at scummvm.org)
Date: 2024-12-15T15:22:31+01:00

Commit Message:
SCUMM: (IMS/Mac) - fix orginal instrument glitch

(SAM final credits track)

Changed paths:
    engines/scumm/imuse/drivers/macintosh.cpp


diff --git a/engines/scumm/imuse/drivers/macintosh.cpp b/engines/scumm/imuse/drivers/macintosh.cpp
index a866152dc7b..b2c5c6e3270 100644
--- a/engines/scumm/imuse/drivers/macintosh.cpp
+++ b/engines/scumm/imuse/drivers/macintosh.cpp
@@ -41,7 +41,7 @@ enum : byte {
 struct ChanControlNode;
 struct DeviceChannel {
 	DeviceChannel(const uint32 *pitchtable) : pitchTable(pitchtable), frequency(0), phase(0), end(nullptr), pos(nullptr), smpBuffStart(nullptr),
-		smpBuffEnd(nullptr), loopStart(nullptr), loopEnd(nullptr), pitch(0), mute(true), release(false), instr(nullptr),
+		smpBuffEnd(nullptr), loopStart(nullptr), loopEnd(nullptr), pitch(0), mute(true), release(false), instr(nullptr), rhtm(false),
 		prog(0), baseFreq(0), note(0), volumeL(0), volumeR(0), rate(0), totalLevelL(0), totalLevelR(0), node(nullptr), prev(nullptr), next(nullptr) {}
 	~DeviceChannel() {}
 
@@ -64,6 +64,7 @@ struct DeviceChannel {
 	uint32 rate;
 	uint16 prog;
 	byte note;
+	bool rhtm;
 	bool mute;
 	bool release;
 	const ChanControlNode *node;
@@ -318,7 +319,7 @@ void DeviceChannel::recalcFrequency() {
 	int cpos = (pitch >> 7) + 60 - baseFreq;
 	if (cpos < 0)
 		frequency = (uint32)-1;
-	else if (pitch & 0x7F)
+	else if ((pitch & 0x7F) && cpos < 0x7F)
 		frequency = pitchTable[cpos] + (((pitchTable[cpos + 1] - pitchTable[cpos]) * (pitch & 0x7F)) >> 7);
 	else
 		frequency = pitchTable[cpos];
@@ -456,6 +457,11 @@ void IMSMacSoundSystem::noteOn(const ChanControlNode *node) {
 
 	debug(6, "NOTE ON: ims part %d, chan node %d, note %d, instr id %d (%s)", node->in ? node->in->getNumber() : node->number, node->number, node->note, node->prog, c->instr.get()->name());
 
+	// SAMNMAX: This is a workaround to fix a hanging note in the final credits track. The issue is present in the original game,too.
+	bool fixHangingNote = (c->instr.get()->id() == 321 && c->note == 40);
+	if (fixHangingNote)
+		debug(7, "%s:() Triggered hanging note workaround.", __FUNCTION__);
+
 	recalcVolume(c);
 
 	const MacLowLevelPCMDriver::PCMSound *s = c->instr.get()->data();
@@ -463,7 +469,7 @@ void IMSMacSoundSystem::noteOn(const ChanControlNode *node) {
 	c->rate = s->rate;
 	c->smpBuffStart = s->data.get();
 	c->smpBuffEnd = c->smpBuffStart + s->len;
-	if ((_version == 0 && (int32)s->loopst >= (int32)s->loopend - 12) || (_version > 0 && (!s->loopst || !s->loopend || node->rhythmPart || (int32)s->loopst > (int32)s->len - 10))) {
+	if ((_version == 0 && (int32)s->loopst >= (int32)s->loopend - 12) || (_version > 0 && (fixHangingNote || !s->loopst || !s->loopend || node->rhythmPart || (int32)s->loopst > (int32)s->len - 10))) {
 		c->loopStart = nullptr;
 		c->loopEnd = c->smpBuffEnd;
 	} else {
@@ -603,8 +609,8 @@ void IMSMacSoundSystem::dblBuffCallback(MacLowLevelPCMDriver::DoubleBuffer *dblB
 			*t++ += a1[*c.pos];
 			if (_stereo)
 				*t++ += a2[*c.pos];
+			}
 		}
-	}
 
 	const int16 *s = _mixBuffer16Bit;
 	sil <<= 7;
@@ -861,8 +867,8 @@ bool NewMacSoundSystem::loadInstruments(const char *const *fileNames, int numFil
 		if (ins->sndRes[0] != nullptr)
 			memset(ins->noteSmplsMapping, 0, 128);
 
-		int8 numRanges = CLIP<int8>(b[13], 0, 7);
-		assert(sz >= 16 + (uint)numRanges * 8);
+		byte numRanges = CLIP<int8>(b[13], 0, 7);
+		assert(sz >= 16 + numRanges * 8);
 
 		for (int ii = 0; ii < numRanges; ++ii) {
 			ins->sndRes.push_back(getSndResource(READ_BE_INT16(b + 16 + ii * 8)));
@@ -884,7 +890,7 @@ bool NewMacSoundSystem::loadInstruments(const char *const *fileNames, int numFil
 Common::SharedPtr<MacSndResource> NewMacSoundSystem::getNoteRangeSndResource(uint16 id, byte note) {
 	assert(note < 128);
 	Common::SharedPtr<MacSndResource> res;
-	for (Common::Array<Common::SharedPtr<Instrument> >::iterator it = _instruments.begin(); res == nullptr && it != _instruments.end(); ++it) {
+	for (Common::Array<Common::SharedPtr<Instrument> >::const_iterator it = _instruments.begin(); res == nullptr && it != _instruments.end(); ++it) {
 		uint16 cid = (*it)->id;
 		if (cid == id)
 			res = (*it)->sndRes[(*it)->noteSmplsMapping[note]];
@@ -894,9 +900,10 @@ Common::SharedPtr<MacSndResource> NewMacSoundSystem::getNoteRangeSndResource(uin
 
 void NewMacSoundSystem::setInstrument(DeviceChannel *chan) {
 	assert(chan && chan->node);
-	if (chan->instr == nullptr || (!chan->node->rhythmPart && chan->prog != chan->node->prog) || chan->note != chan->node->note) {
+	if (chan->instr == nullptr || chan->node->rhythmPart != chan->rhtm || (!chan->node->rhythmPart && chan->prog != chan->node->prog) || chan->note != chan->node->note) {
 		chan->note = chan->node->note;
-		chan->prog = chan->node->prog;
+		chan->prog = chan->node->rhythmPart ? 0 : chan->node->prog;
+		chan->rhtm = chan->node->rhythmPart;
 		chan->instr = chan->node->rhythmPart ? getSndResource(6000 + chan->note) : getNoteRangeSndResource(chan->prog, chan->note);
 	}
 }
@@ -1074,6 +1081,7 @@ void IMuseChannel_Macintosh::noteOn(byte note, byte velocity)  {
 			node->in = this;
 			node->prio = _prio;
 		}
+		node->prog = 0;
 		node->volume = _volume * 6 / 7;
 		node->rhythmPart = true;
 	}


Commit: d165b1dc93582f43f08bbea54a2f3969d626b08e
    https://github.com/scummvm/scummvm/commit/d165b1dc93582f43f08bbea54a2f3969d626b08e
Author: athrxx (athrxx at scummvm.org)
Date: 2024-12-15T15:22:35+01:00

Commit Message:
SCUMM: (IMS/Mac) - fix DOTT music volume

(and other minor adjustments)

The DOTT Mac imuse driver always sets master
volume to max. The SAMNMAX driver does not
have a hack like this.

Changed paths:
    engines/scumm/imuse/drivers/macintosh.cpp
    engines/scumm/imuse/imuse.cpp
    engines/scumm/players/mac_sound_lowlevel.h
    engines/scumm/players/player_mac_new.cpp
    engines/scumm/vars.cpp


diff --git a/engines/scumm/imuse/drivers/macintosh.cpp b/engines/scumm/imuse/drivers/macintosh.cpp
index b2c5c6e3270..aa5ab88f31f 100644
--- a/engines/scumm/imuse/drivers/macintosh.cpp
+++ b/engines/scumm/imuse/drivers/macintosh.cpp
@@ -388,13 +388,27 @@ bool IMSMacSoundSystem::init(const char *const *instrFileNames, int numInstrFile
 	int16 *d1 = &_mixTable[m];
 	int16 *d2 = &_mixTable[m - 1];
 
-	byte base = _internal16Bit? 0 : 128;
-	uint16 ml = _internal16Bit ? _numChannels : 1;
-	uint16 sv = _stereo ? 2 : 1;
-	for (uint32 i = 0; i < m; ++i) {
-		int val = (((((i * (m - _numChannels)) << 7) >> 1) / (((_numChannels >> 1) - 1) * i + m - _numChannels) + base) * ml * sv) >> 7;
-		*d1++ = base + val;
-		*d2-- = base -val - 1;
+	if (_version == 0) {
+		byte sh = _internal16Bit ? 5 : 0;
+		byte div = _internal16Bit ? 1 : _numChannels;
+		byte base = _internal16Bit? 0 : 128;
+		for (uint32 i = 0; i < m; ++i) {
+			uint16 val = (i << sh) / div;
+			*d1++ = base + val;
+			*d2-- = base - val - 1;
+		}
+	} else if (_internal16Bit) {
+		for (uint32 i = 0; i < m; ++i) {
+			uint16 val = (((i * _numChannels * 127) << 6) / (((_numChannels >> 1) - 1) * i + _numChannels * 127)) << 1;
+			*d1++ = val;
+			*d2-- = -val - 1;
+		}
+	} else {
+		for (uint32 i = 0; i < m; ++i) {
+			uint16 val = ((((i * _numChannels * 127) << 7) >> 1) / (((_numChannels >> 1) - 1) * i + _numChannels * 127) + 128) >> 7;
+			*d1++ = (byte)(128 + val);
+			*d2-- = (byte)(128 - val - 1);
+		}
 	}
 
 	_macstr = new MacPlayerAudioStream(this, _mixer->getOutputRate(), _stereo, false, internal16Bit);
@@ -412,9 +426,14 @@ bool IMSMacSoundSystem::init(const char *const *instrFileNames, int numInstrFile
 	// Only MI2 and FOA have MIDI sound effects. Also, the later versions use a different update method.
 	if (_version == 0) {
 		_macstr->addVolumeGroup(Audio::Mixer::kSFXSoundType);
-		_macstr->setVblCallback(&_vblTskProc);
+		_macstr->setVblCallback(&_vblTskProc);		
 	}
 
+	// The stream will by default expect 8-bit data and scale that to 16-bit. Or at least only low amplitude 16-bit data that only needs minor adjustment.
+	// For full range 16-bit input, we need some post-process downscaling, otherwise the application of the ScummVM global volume setting will cause overflows.
+	if (internal16Bit)
+		_macstr->scaleVolume(0, 5);
+
 	_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, _macstr, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
 
 	return true;
@@ -609,8 +628,8 @@ void IMSMacSoundSystem::dblBuffCallback(MacLowLevelPCMDriver::DoubleBuffer *dblB
 			*t++ += a1[*c.pos];
 			if (_stereo)
 				*t++ += a2[*c.pos];
-			}
 		}
+	}
 
 	const int16 *s = _mixBuffer16Bit;
 	sil <<= 7;
@@ -820,7 +839,7 @@ NewMacSoundSystem::~NewMacSoundSystem() {
 
 bool NewMacSoundSystem::start() {
 	_musicChan = _sdrv->createChannel(Audio::Mixer::kMusicSoundType, MacLowLevelPCMDriver::kSampledSynth, _stereo ? 0xCC : 0x8C, nullptr);
-	return _musicChan ? _sdrv->playDoubleBuffer(_musicChan, _stereo ? 2 : 1, _internal16Bit ? 16 : 8, 0x56220000, &_dbCbProc, _internal16Bit ? _numChannels : 1) : false;
+	return _musicChan ? _sdrv->playDoubleBuffer(_musicChan, _stereo ? 2 : 1, _internal16Bit ? 16 : 8, 0x56220000, &_dbCbProc,  _internal16Bit ? _numChannels : 1) : false;
 }
 
 bool NewMacSoundSystem::loadInstruments(const char *const *fileNames, int numFileNames) {
@@ -868,7 +887,7 @@ bool NewMacSoundSystem::loadInstruments(const char *const *fileNames, int numFil
 			memset(ins->noteSmplsMapping, 0, 128);
 
 		byte numRanges = CLIP<int8>(b[13], 0, 7);
-		assert(sz >= 16 + numRanges * 8);
+		assert(sz >= 16u + numRanges * 8u);
 
 		for (int ii = 0; ii < numRanges; ++ii) {
 			ins->sndRes.push_back(getSndResource(READ_BE_INT16(b + 16 + ii * 8)));
@@ -1109,13 +1128,11 @@ void IMuseChannel_Macintosh::controlChange(byte control, byte value)  {
 		dataEntry(value);
 		break;
 	case 7:
-	case 10:
-		if (control == 7)
-			_volume = value;
-		else
-			_panPos = value;
+	case 10: {
+		byte &param = (control == 7) ? _volume : _panPos;
+		param = value;
 		updateVolume();
-		break;
+		} break;
 	case 17:
 		if (_version == 2)
 			_polyphony = value;
diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp
index 7f2d936d88c..7276ca4fa4d 100644
--- a/engines/scumm/imuse/imuse.cpp
+++ b/engines/scumm/imuse/imuse.cpp
@@ -48,7 +48,7 @@ IMuseInternal::IMuseInternal(ScummEngine *vm, MidiDriverFlags sndType, bool nati
 	_vm(vm),
 	_native_mt32(nativeMT32),
 	_newSystem(vm && vm->_game.id == GID_SAMNMAX),
-	_dynamicChanAllocation(vm && (vm->_game.id != GID_MONKEY2 && vm->_game.id != GID_INDY4)), // For the non-iMuse games that (unfortunately) run on this player we need to pretend we're on the more modern version
+	_dynamicChanAllocation(vm && vm->_game.id != GID_MONKEY2 && vm->_game.id != GID_INDY4), // For the non-iMuse games that (unfortunately) run on this player we need to pretend we're on the more modern version
 	_midi_adlib(nullptr),
 	_midi_native(nullptr),
 	_sysex(nullptr),
@@ -1228,7 +1228,8 @@ int IMuseInternal::query_queue(int param) {
 }
 
 int IMuseInternal::setImuseMasterVolume(uint vol) {
-	if (vol > 255)
+	// The DOTT Macintosh driver ignores the vol argument and always sets the volume to max.
+	if (vol > 255 || (_soundType == MDT_MACINTOSH && _game_id == GID_TENTACLE))
 		vol = 255;
 	if (_master_volume == vol)
 		return 0;
diff --git a/engines/scumm/players/mac_sound_lowlevel.h b/engines/scumm/players/mac_sound_lowlevel.h
index 2ab09f36ed9..d20267695d5 100644
--- a/engines/scumm/players/mac_sound_lowlevel.h
+++ b/engines/scumm/players/mac_sound_lowlevel.h
@@ -188,7 +188,7 @@ public:
 	void initBuffers(uint32 feedBufferSize);
 	void initDrivers();
 	void addVolumeGroup(Audio::Mixer::SoundType type);
-	void scaleVolume(uint scale) { _scale = scale; }
+	void scaleVolume(uint upscale, uint downscale) { _upscale = upscale; _downscale = downscale; }
 	typedef Common::Functor0Mem<void, VblTaskClientDriver> CallbackProc;
 	void setVblCallback(const CallbackProc *proc);
 	void clearBuffer();
@@ -207,7 +207,8 @@ private:
 
 	VblTaskClientDriver *_drv;
 	int _numGroups;
-	uint16 _scale;
+	uint16 _upscale;
+	uint16 _downscale;
 
 	uint32 _vblSmpQty;
 	uint32 _vblSmpQtyRem;
diff --git a/engines/scumm/players/player_mac_new.cpp b/engines/scumm/players/player_mac_new.cpp
index 901c270dc95..3c0fe60599f 100644
--- a/engines/scumm/players/player_mac_new.cpp
+++ b/engines/scumm/players/player_mac_new.cpp
@@ -176,7 +176,7 @@ uint32 fixMul(uint32 fx1, uint32 fx2) {
 
 MacPlayerAudioStream::MacPlayerAudioStream(VblTaskClientDriver *drv, uint32 scummVMOutputrate, bool stereo, bool interpolate, bool internal16Bit) : Audio::AudioStream(), _drv(drv),
 	_vblSmpQty(0), _vblSmpQtyRem(0), _frameSize((stereo ? 2 : 1) * (internal16Bit ? 2 : 1)), _vblCountDown(0), _vblCountDownRem(0), _outputRate(scummVMOutputrate),
-		_vblCbProc(nullptr), _numGroups(1), _isStereo(stereo), _interp(interpolate), _smpInternalSize(internal16Bit ? 2 : 1), _scale(1) {
+		_vblCbProc(nullptr), _numGroups(1), _isStereo(stereo), _interp(interpolate), _smpInternalSize(internal16Bit ? 2 : 1), _upscale(0), _downscale(0) {
 	assert(_drv);
 	_buffers = new SmpBuffer[2];
 	_vblSmpQty = (_outputRate << 16) / VBL_UPDATE_RATE;
@@ -287,14 +287,14 @@ int MacPlayerAudioStream::readBuffer(int16 *buffer, const int numSamples) {
 			int diff = smpN - _buffers[ii].lastL;
 			if (diff && _buffers[ii].rateConvAcc && interp)
 				diff = (diff * _buffers[ii].rateConvAcc) >> RATECNV_BIT_PRECSN;
-			smpL += (int32)((_buffers[ii].lastL + diff) * (_buffers[ii].volume * _scale / numch));
+			smpL += (int32)((_buffers[ii].lastL + diff) * ((_buffers[ii].volume << _upscale) / numch));
 
 			if (_isStereo) {
 				smpN = _smpInternalSize == 2 ? *reinterpret_cast<int16*>(&_buffers[ii].pos[2]) : _buffers[ii].pos[1];
 				diff = smpN - _buffers[ii].lastR;
 				if (diff && _buffers[ii].rateConvAcc && interp)
 					diff = (diff * _buffers[ii].rateConvAcc) >> RATECNV_BIT_PRECSN;
-				smpR += (int32)((_buffers[ii].lastR + diff) * (_buffers[ii].volume * _scale / numch));
+				smpR += (int32)((_buffers[ii].lastR + diff) * ((_buffers[ii].volume << _upscale) / numch));
 			}
 		}
 
@@ -331,9 +331,9 @@ int MacPlayerAudioStream::readBuffer(int16 *buffer, const int numSamples) {
 			}
 		}
 
-		*buffer++ = CLIP<int32>((smpL / _numGroups) >> 2, -32768, 32767);
+		*buffer++ = CLIP<int32>((smpL / _numGroups) >> (2 + _downscale), -32768, 32767);
 		if (_isStereo)
-			*buffer++ = CLIP<int32>((smpR / _numGroups) >> 2, -32768, 32767);
+			*buffer++ = CLIP<int32>((smpR / _numGroups) >> (2 + _downscale), -32768, 32767);
 	}
 	return numSamples;
 }
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 634daccffbd..1389fd0d21a 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -857,23 +857,29 @@ void ScummEngine::setSoundCardVarToCurrentConfig() {
 	if (VAR_SOUNDCARD == 0xFF)
 		return;
 
+	switch (_sound->_musicType) {
+	case MDT_MACINTOSH:
+		switch (_game.id) {
+		case GID_INDY3:
+			VAR(VAR_SOUNDCARD) = (ConfMan.hasKey("mac_v3_low_quality_music") && ConfMan.getBool("mac_v3_low_quality_music")) ? 10 : 11;
+			break;
+		case GID_LOOM:
+			VAR(VAR_SOUNDCARD) = (ConfMan.hasKey("mac_snd_quality") && ConfMan.getInt("mac_snd_quality") > 0 && ConfMan.getInt("mac_snd_quality") < 4) ? 10 : 11;
+			break;
+		case GID_MONKEY:
+			VAR(VAR_SOUNDCARD) = 0xFFFF;
+			break;
+		default:
+			VAR(VAR_SOUNDCARD) = (_game.version >= 6) ? 0 : 4; 
+			break;
+		}
+		break;
 	// VAR_SOUNDCARD modes
 	// 0 PC Speaker
 	// 1 Tandy
 	// 2 CMS
 	// 3 AdLib
 	// 4 Roland
-	switch (_sound->_musicType) {
-	case MDT_MACINTOSH:
-		if (_game.id == GID_INDY3)
-			VAR(VAR_SOUNDCARD) = (ConfMan.hasKey("mac_v3_low_quality_music") && ConfMan.getBool("mac_v3_low_quality_music")) ? 10 : 11;
-		else if (_game.id == GID_LOOM)
-			VAR(VAR_SOUNDCARD) = (ConfMan.hasKey("mac_snd_quality") && ConfMan.getInt("mac_snd_quality") > 0 && ConfMan.getInt("mac_snd_quality") < 4) ? 10 : 11;
-		else if (_game.id == GID_MONKEY)
-			VAR(VAR_SOUNDCARD) = 0xffff;
-		else // GID_MONKEY2 || GID_INDY4
-			VAR(VAR_SOUNDCARD) = 4;
-		break;
 	case MDT_NONE:
 	case MDT_PCSPK:
 		VAR(VAR_SOUNDCARD) = 0;




More information about the Scummvm-git-logs mailing list