[Scummvm-git-logs] scummvm master -> 3ef9ec5560ceaacfee7ce615ec99f2cdc020fd83

athrxx noreply at scummvm.org
Sun Sep 4 11:39:47 UTC 2022


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:
3ef9ec5560 SCUMM: (DOTT) - fix bug no. 13460 (Incorrect MIDI pitch bending)


Commit: 3ef9ec5560ceaacfee7ce615ec99f2cdc020fd83
    https://github.com/scummvm/scummvm/commit/3ef9ec5560ceaacfee7ce615ec99f2cdc020fd83
Author: athrxx (athrxx at scummvm.org)
Date: 2022-09-04T13:32:38+02:00

Commit Message:
SCUMM: (DOTT) - fix bug no. 13460 (Incorrect MIDI pitch bending)

(General Midi Part only)

The bug report says that the AdLib part is broken, too. I am not sure about that device. For GM it was very obvious, though...

Changed paths:
    engines/scumm/imuse/imuse.cpp
    engines/scumm/imuse/imuse_internal.h
    engines/scumm/imuse/imuse_part.cpp
    engines/scumm/imuse/imuse_player.cpp


diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp
index ecd29abdfbb..89224ab95fb 100644
--- a/engines/scumm/imuse/imuse.cpp
+++ b/engines/scumm/imuse/imuse.cpp
@@ -489,7 +489,10 @@ uint32 IMuseInternal::property(int prop, uint32 value) {
 		// GS Mode emulates MT-32 on a GS device, so _native_mt32 should always be true
 		if (_midi_native && _enable_gs) {
 			_native_mt32 = true;
-			initGM(_midi_native);
+			initGS(_midi_native);
+		} else {
+			// If GS is disabled we do the "normal" init from the original GM drivers.
+			initGM();
 		}
 		break;
 
@@ -1515,7 +1518,7 @@ void IMuseInternal::initMT32(MidiDriver *midi) {
 	_system->delayMillis(1000);
 }
 
-void IMuseInternal::initGM(MidiDriver *midi) {
+void IMuseInternal::initGS(MidiDriver *midi) {
 	byte buffer[12];
 	int i;
 
@@ -1623,6 +1626,31 @@ void IMuseInternal::initGM(MidiDriver *midi) {
 	}
 }
 
+void IMuseInternal::initGM() {
+	if (!_midi_native || _native_mt32 || _enable_gs || _isAmiga)
+		return;
+	// These are the init messages from the DOTT General Midi
+	// driver. This is the major part of the bug fix for bug
+	// no. 13460 ("DOTT: Incorrect MIDI pitch bending").
+	// Might be worthwhile to check if other GM drivers (like
+	// SAM) have the same values...
+	MidiDriver *m = _midi_native;
+	for (int i = 0; i < 16; ++i) {
+		m->send(0x0064B0 | i);
+		m->send(0x0065B0 | i);
+		m->send(0x1006B0 | i);
+		m->send(0x7F07B0 | i);
+		m->send(0x3F0AB0 | i);
+		m->send(0x4000E0 | i);
+		m->send(0x0001B0 | i);
+		m->send(0x0040B0 | i);
+		m->send(0x405BB0 | i);
+		m->send(0x005DB0 | i);
+		m->send(0x0000B0 | i);
+		m->send(0x007BB0 | i);
+	}
+}
+
 void IMuseInternal::init_queue() {
 	_queue_adding = false;
 	_queue_pos = 0;
diff --git a/engines/scumm/imuse/imuse_internal.h b/engines/scumm/imuse/imuse_internal.h
index 9289cc546bb..f5f46a0c7ee 100644
--- a/engines/scumm/imuse/imuse_internal.h
+++ b/engines/scumm/imuse/imuse_internal.h
@@ -218,8 +218,9 @@ protected:
 	HookDatas _hook;
 	ParameterFader _parameterFaders[4];
 
-	bool _isMT32;
 	bool _isMIDI;
+	bool _isMT32;
+	bool _isGM;
 	bool _supportsPercussion;
 
 protected:
@@ -275,6 +276,7 @@ public:
 	bool isFadingOut() const;
 	bool isMIDI() const { return _isMIDI; }
 	bool isMT32() const { return _isMT32; }
+	bool isGM() const { return _isGM; }
 	bool jump(uint track, uint beat, uint tick);
 	void onTimer();
 	void removePart(Part *part);
@@ -477,8 +479,9 @@ protected:
 	void handle_marker(uint id, byte data);
 	int get_channel_volume(uint a);
 	void initMidiDriver(TimerCallbackInfo *info);
-	void initGM(MidiDriver *midi);
+	void initGS(MidiDriver *midi);
 	void initMT32(MidiDriver *midi);
+	void initGM();
 	void init_players();
 	void init_parts();
 	void init_queue();
diff --git a/engines/scumm/imuse/imuse_part.cpp b/engines/scumm/imuse/imuse_part.cpp
index 641ddae9908..32d5893bc8e 100644
--- a/engines/scumm/imuse/imuse_part.cpp
+++ b/engines/scumm/imuse/imuse_part.cpp
@@ -194,7 +194,7 @@ void Part::pitchBendFactor(byte value) {
 		return;
 	pitchBend(0);
 	_pitchbend_factor = value;
-	if (_mc)
+	if (_mc && !(_player->isGM()))
 		_mc->pitchBendFactor(value);
 }
 
@@ -339,7 +339,8 @@ void Part::sendAll() {
 	if (!clearToTransmit())
 		return;
 
-	_mc->pitchBendFactor(_pitchbend_factor);
+	if (!_player->isGM())
+		_mc->pitchBendFactor(_pitchbend_factor);
 	sendTranspose();
 	sendPitchBend();
 	_mc->volume(_vol_eff);
@@ -371,7 +372,14 @@ void Part::sendPitchBend() {
 	// We send the transpose value separately for Amiga (which is more like the original handles this).
 	// Some rhythm instruments depend on this.
 	int8 transpose = _se->_isAmiga ? 0 : _transpose_eff;
-	_mc->pitchBend(clamp(bend + (_detune_eff * 64 / 12) + (transpose * 8192 / 12), -8192, 8191));
+
+	if (_player->isGM())
+		// This is the DOTT formula. Might not be exactly like this for SAM...
+		bend = ((clamp(((bend * _pitchbend_factor) >> 6) + _detune_eff + (transpose << 7), -2048, 2047) + 0x800) << 2) - 0x2000;
+	else
+		bend = clamp(bend + (_detune_eff * 64 / 12) + (transpose * 8192 / 12), -8192, 8191);
+
+	_mc->pitchBend(bend);
 }
 
 void Part::sendTranspose() {
diff --git a/engines/scumm/imuse/imuse_player.cpp b/engines/scumm/imuse/imuse_player.cpp
index a60a3cb1065..1fb0f842973 100644
--- a/engines/scumm/imuse/imuse_player.cpp
+++ b/engines/scumm/imuse/imuse_player.cpp
@@ -77,6 +77,7 @@ Player::Player() :
 	_speed(128),
 	_isMT32(false),
 	_isMIDI(false),
+	_isGM(false),
 	_supportsPercussion(false),
 	_se(nullptr),
 	_vol_chan(0),
@@ -107,6 +108,7 @@ bool Player::startSound(int sound, MidiDriver *midi) {
 	_isMT32 = _se->isMT32(sound);
 	_isMIDI = _se->isMIDI(sound);
 	_supportsPercussion = _se->supportsPercussion(sound);
+	_isGM = (_supportsPercussion && !_isMT32); // Unlike IMuseInternal::isMIDI(), IMuseInternal::supportsPercussion() really filters out all non-MIDI things...
 
 	_parts = nullptr;
 	_active = true;
@@ -1028,6 +1030,7 @@ void Player::fixAfterLoad() {
 		_isMT32 = _se->isMT32(_id);
 		_isMIDI = _se->isMIDI(_id);
 		_supportsPercussion = _se->supportsPercussion(_id);
+		_isGM = (_supportsPercussion && !_isMT32); // Unlike IMuseInternal::isMIDI(), IMuseInternal::supportsPercussion() really filters out all non-MIDI things...
 	}
 }
 




More information about the Scummvm-git-logs mailing list