aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kiewitz2015-07-02 13:17:21 +0200
committerMartin Kiewitz2015-07-02 13:17:21 +0200
commit903309fbb7ce5c9dbc66c988169ac109def20e16 (patch)
treeee5c8f8bf676dcd5cbe6397616cdb3291d56722e
parent50d9fb24d32ba0722b52b2e021568db2fdda4ac9 (diff)
downloadscummvm-rg350-903309fbb7ce5c9dbc66c988169ac109def20e16.tar.gz
scummvm-rg350-903309fbb7ce5c9dbc66c988169ac109def20e16.tar.bz2
scummvm-rg350-903309fbb7ce5c9dbc66c988169ac109def20e16.zip
AUDIO: Miles Audio AdLib: implement sustain
fixes broken music in Return To Zork (demo) also added comments about those special cases (useful for testing)
-rw-r--r--audio/miles_adlib.cpp23
1 files changed, 21 insertions, 2 deletions
diff --git a/audio/miles_adlib.cpp b/audio/miles_adlib.cpp
index 6697122492..a48aba304c 100644
--- a/audio/miles_adlib.cpp
+++ b/audio/miles_adlib.cpp
@@ -34,6 +34,10 @@ namespace Audio {
// Miles Audio AdLib/OPL3 driver
//
// TODO: currently missing: OPL3 4-op voices
+//
+// Special cases (great for testing):
+// - sustain feature is used by Return To Zork (demo) right at the start
+// - sherlock holmes 2 does lots of priority sorts right at the start of the intro
#define MILES_ADLIB_VIRTUAL_FMVOICES_COUNT_MAX 20
#define MILES_ADLIB_PHYSICAL_FMVOICES_COUNT_MAX 18
@@ -255,6 +259,8 @@ private:
void releaseFmVoice(byte virtualFmVoice);
+ void releaseSustain(byte midiChannel);
+
void updatePhysicalFmVoice(byte virtualFmVoice, bool keyOn, uint16 registerUpdateFlags);
void controlChange(byte midiChannel, byte controllerNumber, byte controllerValue);
@@ -692,6 +698,19 @@ void MidiDriver_Miles_AdLib::releaseFmVoice(byte virtualFmVoice) {
_midiChannels[midiChannel].currentActiveVoicesCount--;
}
+void MidiDriver_Miles_AdLib::releaseSustain(byte midiChannel) {
+ // Search through all virtual FM-Voices for currently sustained notes and call noteOff on them
+ for (byte virtualFmVoice = 0; virtualFmVoice < _modeVirtualFmVoicesCount; virtualFmVoice++) {
+ if (_virtualFmVoices[virtualFmVoice].inUse) {
+ if ((_virtualFmVoices[virtualFmVoice].actualMidiChannel == midiChannel) && (_virtualFmVoices[virtualFmVoice].sustained)) {
+ // is currently sustained
+ // so do a noteOff (which will check current sustain controller)
+ noteOff(midiChannel, _virtualFmVoices[virtualFmVoice].currentOriginalMidiNote);
+ }
+ }
+ }
+}
+
void MidiDriver_Miles_AdLib::updatePhysicalFmVoice(byte virtualFmVoice, bool keyOn, uint16 registerUpdateFlags) {
byte midiChannel = _virtualFmVoices[virtualFmVoice].actualMidiChannel;
@@ -937,7 +956,7 @@ void MidiDriver_Miles_AdLib::controlChange(byte midiChannel, byte controllerNumb
case MILES_CONTROLLER_SUSTAIN:
_midiChannels[midiChannel].currentSustain = controllerValue;
if (controllerValue < 64) {
- // release sustain TODO
+ releaseSustain(midiChannel);
}
break;
@@ -948,7 +967,7 @@ void MidiDriver_Miles_AdLib::controlChange(byte midiChannel, byte controllerNumb
case MILES_CONTROLLER_RESET_ALL:
_midiChannels[midiChannel].currentSustain = 0;
- // release sustain TODO
+ releaseSustain(midiChannel);
_midiChannels[midiChannel].currentModulation = 0;
_midiChannels[midiChannel].currentVolumeExpression = 127;
_midiChannels[midiChannel].currentPitchBender = MILES_PITCHBENDER_DEFAULT;