AUDIO/MIDI: Fix Miles 3 AdLib pitch bend range
Miles 2 uses the default MT-32 pitch bend range of 12 semitones for its AdLib driver. Miles 3 switched to the default GM pitch bend range of 2 semitones for AdLib. ScummVM would always use the Miles 2 pitch bend range, which caused pitch bend for Miles 3 games to sound wrong on AdLib. To fix this, a property was added to the Miles AdLib driver to specify which Miles version to emulate. Depending on the value of this option, the correct default pitch bend range is set.
This commit is contained in:
parent
c0c5330986
commit
d73b19b9b3
4 changed files with 41 additions and 9 deletions
|
@ -86,6 +86,11 @@ namespace Audio {
|
||||||
// volume of 256, so use this by default.
|
// volume of 256, so use this by default.
|
||||||
#define MILES_DEFAULT_SOURCE_NEUTRAL_VOLUME 256
|
#define MILES_DEFAULT_SOURCE_NEUTRAL_VOLUME 256
|
||||||
|
|
||||||
|
enum MilesVersion {
|
||||||
|
MILES_VERSION_2 = 2,
|
||||||
|
MILES_VERSION_3
|
||||||
|
};
|
||||||
|
|
||||||
struct MilesMT32InstrumentEntry {
|
struct MilesMT32InstrumentEntry {
|
||||||
byte bankId;
|
byte bankId;
|
||||||
byte patchId;
|
byte patchId;
|
||||||
|
@ -118,11 +123,6 @@ public:
|
||||||
|
|
||||||
class MidiDriver_Miles_Midi : public MidiDriver_MT32GM, public MidiDriver_Miles_Xmidi_Timbres {
|
class MidiDriver_Miles_Midi : public MidiDriver_MT32GM, public MidiDriver_Miles_Xmidi_Timbres {
|
||||||
public:
|
public:
|
||||||
enum MilesVersion {
|
|
||||||
MILES_VERSION_2 = 2,
|
|
||||||
MILES_VERSION_3
|
|
||||||
};
|
|
||||||
|
|
||||||
MidiDriver_Miles_Midi(MusicType midiType, MilesMT32InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount);
|
MidiDriver_Miles_Midi(MusicType midiType, MilesMT32InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount);
|
||||||
~MidiDriver_Miles_Midi();
|
~MidiDriver_Miles_Midi();
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,8 @@ public:
|
||||||
void applySourceVolume(uint8 source) override;
|
void applySourceVolume(uint8 source) override;
|
||||||
void deinitSource(uint8 source) override;
|
void deinitSource(uint8 source) override;
|
||||||
|
|
||||||
|
uint32 property(int prop, uint32 param) override;
|
||||||
|
|
||||||
void setVolume(byte volume);
|
void setVolume(byte volume);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -146,6 +148,9 @@ private:
|
||||||
byte _modeVirtualFmVoicesCount;
|
byte _modeVirtualFmVoicesCount;
|
||||||
bool _modeStereo;
|
bool _modeStereo;
|
||||||
|
|
||||||
|
// the version of Miles AIL/MSS to emulate
|
||||||
|
MilesVersion _milesVersion;
|
||||||
|
|
||||||
// Structure to hold information about current status of MIDI Channels
|
// Structure to hold information about current status of MIDI Channels
|
||||||
struct MidiChannelEntry {
|
struct MidiChannelEntry {
|
||||||
byte currentPatchBank;
|
byte currentPatchBank;
|
||||||
|
@ -282,6 +287,9 @@ MidiDriver_Miles_AdLib::MidiDriver_Miles_AdLib(InstrumentEntry *instrumentTableP
|
||||||
_modePhysicalFmVoicesCount = 18;
|
_modePhysicalFmVoicesCount = 18;
|
||||||
_modeStereo = true;
|
_modeStereo = true;
|
||||||
|
|
||||||
|
// Default to Miles v2
|
||||||
|
_milesVersion = MILES_VERSION_2;
|
||||||
|
|
||||||
// Older Miles Audio drivers did not do a circular assign for physical FM-voices
|
// Older Miles Audio drivers did not do a circular assign for physical FM-voices
|
||||||
// Sherlock Holmes 2 used the circular assign
|
// Sherlock Holmes 2 used the circular assign
|
||||||
circularPhysicalAssignment = true;
|
circularPhysicalAssignment = true;
|
||||||
|
@ -349,9 +357,9 @@ void MidiDriver_Miles_AdLib::resetData() {
|
||||||
_midiChannels[midiChannel].currentVolumeExpression = 127;
|
_midiChannels[midiChannel].currentVolumeExpression = 127;
|
||||||
|
|
||||||
// Miles Audio 2: hardcoded pitch range as a global (not channel specific), set to 12
|
// Miles Audio 2: hardcoded pitch range as a global (not channel specific), set to 12
|
||||||
// Miles Audio 3: pitch range per MIDI channel
|
// Miles Audio 3: pitch range per MIDI channel; default 2 semitones
|
||||||
_midiChannels[midiChannel].currentPitchBender = MIDI_PITCH_BEND_DEFAULT;
|
_midiChannels[midiChannel].currentPitchBender = MIDI_PITCH_BEND_DEFAULT;
|
||||||
_midiChannels[midiChannel].currentPitchRange = 12;
|
_midiChannels[midiChannel].currentPitchRange = _milesVersion == MILES_VERSION_3 ? 2 : 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -448,6 +456,28 @@ void MidiDriver_Miles_AdLib::stopAllNotes(uint8 source, uint8 channel) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 MidiDriver_Miles_AdLib::property(int prop, uint32 param) {
|
||||||
|
switch (prop) {
|
||||||
|
case PROP_MILES_VERSION:
|
||||||
|
if (param == 0xFFFF)
|
||||||
|
return _milesVersion;
|
||||||
|
|
||||||
|
switch (param) {
|
||||||
|
case MILES_VERSION_3:
|
||||||
|
_milesVersion = MILES_VERSION_3;
|
||||||
|
break;
|
||||||
|
case MILES_VERSION_2:
|
||||||
|
default:
|
||||||
|
_milesVersion = MILES_VERSION_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return MidiDriver_Multisource::property(prop, param);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void MidiDriver_Miles_AdLib::applySourceVolume(uint8 source) {
|
void MidiDriver_Miles_AdLib::applySourceVolume(uint8 source) {
|
||||||
if (!(source == 0 || source == 0xFF))
|
if (!(source == 0 || source == 0xFF))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -81,6 +81,8 @@ Music::Music(SagaEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer), _par
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_driver = new MidiDriver_ADLIB_Multisource(OPL::Config::kOpl3);
|
_driver = new MidiDriver_ADLIB_Multisource(OPL::Config::kOpl3);
|
||||||
|
_driver->property(MidiDriver::PROP_MILES_VERSION, _vm->getGameId() == GID_ITE ?
|
||||||
|
Audio::MILES_VERSION_2 : Audio::MILES_VERSION_3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_MT32:
|
case MT_MT32:
|
||||||
|
@ -88,7 +90,7 @@ Music::Music(SagaEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer), _par
|
||||||
if (_vm->getPlatform() == Common::kPlatformDOS) {
|
if (_vm->getPlatform() == Common::kPlatformDOS) {
|
||||||
_driver = Audio::MidiDriver_Miles_MIDI_create(_musicType, "");
|
_driver = Audio::MidiDriver_Miles_MIDI_create(_musicType, "");
|
||||||
_driver->property(MidiDriver::PROP_MILES_VERSION, _vm->getGameId() == GID_ITE ?
|
_driver->property(MidiDriver::PROP_MILES_VERSION, _vm->getGameId() == GID_ITE ?
|
||||||
Audio::MidiDriver_Miles_Midi::MILES_VERSION_2 : Audio::MidiDriver_Miles_Midi::MILES_VERSION_3);
|
Audio::MILES_VERSION_2 : Audio::MILES_VERSION_3);
|
||||||
} else {
|
} else {
|
||||||
_driver = new MidiDriver_MT32GM(_musicType);
|
_driver = new MidiDriver_MT32GM(_musicType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,6 @@ Music::Music(hResContext *musicRes) : _musicContext(musicRes), _parser(0) {
|
||||||
case MT_MT32:
|
case MT_MT32:
|
||||||
case MT_GM:
|
case MT_GM:
|
||||||
_driver = Audio::MidiDriver_Miles_MIDI_create(_musicType, "");
|
_driver = Audio::MidiDriver_Miles_MIDI_create(_musicType, "");
|
||||||
_driver->property(MidiDriver::PROP_MILES_VERSION, Audio::MidiDriver_Miles_Midi::MILES_VERSION_3);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_driver = new MidiDriver_NULL_Multisource();
|
_driver = new MidiDriver_NULL_Multisource();
|
||||||
|
@ -68,6 +67,7 @@ Music::Music(hResContext *musicRes) : _musicContext(musicRes), _parser(0) {
|
||||||
|
|
||||||
if (_driver) {
|
if (_driver) {
|
||||||
_driver->property(MidiDriver::PROP_USER_VOLUME_SCALING, true);
|
_driver->property(MidiDriver::PROP_USER_VOLUME_SCALING, true);
|
||||||
|
_driver->property(MidiDriver::PROP_MILES_VERSION, Audio::MILES_VERSION_3);
|
||||||
if (_driver->open() != 0)
|
if (_driver->open() != 0)
|
||||||
error("Failed to open MIDI driver.");
|
error("Failed to open MIDI driver.");
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue