[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