aboutsummaryrefslogtreecommitdiff
path: root/engines/queen/midiadlib.cpp
diff options
context:
space:
mode:
authorGregory Montoir2007-11-15 20:21:33 +0000
committerGregory Montoir2007-11-15 20:21:33 +0000
commitde750efced41c3b1b0040d418a215b9546f78dd6 (patch)
treec95ba26e6dd3aee6c8072d80caf2813176d14ef1 /engines/queen/midiadlib.cpp
parentb95a10201168a2b2bb59008822bcd3d8eb6c43fb (diff)
downloadscummvm-rg350-de750efced41c3b1b0040d418a215b9546f78dd6.tar.gz
scummvm-rg350-de750efced41c3b1b0040d418a215b9546f78dd6.tar.bz2
scummvm-rg350-de750efced41c3b1b0040d418a215b9546f78dd6.zip
added support for Adlib tracks
svn-id: r29509
Diffstat (limited to 'engines/queen/midiadlib.cpp')
-rw-r--r--engines/queen/midiadlib.cpp628
1 files changed, 628 insertions, 0 deletions
diff --git a/engines/queen/midiadlib.cpp b/engines/queen/midiadlib.cpp
new file mode 100644
index 0000000000..af68fc2435
--- /dev/null
+++ b/engines/queen/midiadlib.cpp
@@ -0,0 +1,628 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/endian.h"
+
+#include "sound/fmopl.h"
+#include "sound/softsynth/emumidi.h"
+
+namespace Queen {
+
+class AdlibMidiChannel;
+
+class AdlibMidiDriver : public MidiDriver_Emulated {
+public:
+
+ AdlibMidiDriver(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer) {}
+ ~AdlibMidiDriver() {}
+
+ // MidiDriver
+ int open();
+ void close();
+ void send(uint32 b);
+ void metaEvent(byte type, byte *data, uint16 length);
+ MidiChannel *allocateChannel() { return 0; }
+ MidiChannel *getPercussionChannel() { return 0; }
+
+ // AudioStream
+ bool isStereo() const { return false; }
+ int getRate() const { return _mixer->getOutputRate(); }
+
+ // MidiDriver_Emulated
+ void generateSamples(int16 *buf, int len);
+
+private:
+
+ void handleMidiEvent0x90_NoteOn(int channel, int param1, int param2);
+ void handleSequencerSpecificMetaEvent1(int channel, const uint8 *data);
+ void handleSequencerSpecificMetaEvent2(uint8 value);
+ void handleSequencerSpecificMetaEvent3(uint8 value);
+
+ void Adlib_Write(uint8 port, uint8 value);
+ void Adlib_SetupCard();
+ void Adlib_SetupChannels(int fl);
+ void Adlib_ResetAmpVibratoRhythm(int am, int vib, int kso);
+ void Adlib_ResetChannels();
+ void Adlib_SetAmpVibratoRhythm();
+ void Adlib_SetCSMKeyboardSplit();
+ void Adlib_SetNoteMul(int mul);
+ void Adlib_SetWaveformSelect(int fl);
+ void Adlib_SetPitchBend(int channel, int range);
+ void Adlib_PlayNote(int channel);
+ uint8 Adlib_PlayNoteHelper(int channel, int note1, int note2, int oct);
+ void Adlib_TurnNoteOff(int channel);
+ void Adlib_TurnNoteOn(int channel, int note);
+ void Adlib_SetupChannelFromSequence(int channel, const uint8 *src, int fl);
+ void Adlib_SetupChannel(int channel, const uint16 *src, int fl);
+ void Adlib_SetNoteVolume(int channel, int volume);
+ void Adlib_SetupChannelHelper(int channel);
+ void Adlib_SetChannel0x40(int channel);
+ void Adlib_SetChannel0xC0(int channel);
+ void Adlib_SetChannel0x60(int channel);
+ void Adlib_SetChannel0x80(int channel);
+ void Adlib_SetChannel0x20(int channel);
+ void Adlib_SetChannel0xE0(int channel);
+
+ FM_OPL *_opl;
+ int _midiNumberOfChannels;
+ int _adlibNoteMul;
+ int _adlibWaveformSelect;
+ int _adlibAMDepthEq48;
+ int _adlibVibratoDepthEq14;
+ int _adlibRhythmEnabled;
+ int _adlibKeyboardSplitOn;
+ int _adlibVibratoRhythm;
+ uint8 _midiChannelsFreqTable[9];
+ uint8 _adlibChannelsLevelKeyScalingTable[11];
+ uint8 _adlibSetupChannelSequence1[14 * 18];
+ uint16 _adlibSetupChannelSequence2[14];
+ int16 _midiChannelsNote2Table[9];
+ uint8 _midiChannelsNote1Table[9];
+ uint8 _midiChannelsOctTable[9];
+ uint16 _adlibChannelsVolume[11];
+ uint16 _adlibMetaSequenceData[28];
+
+ static const uint8 _adlibChannelsMappingTable1[];
+ static const uint8 _adlibChannelsNoFeedback[];
+ static const uint8 _adlibChannelsMappingTable2[];
+ static const uint8 _adlibChannelsMappingTable3[];
+ static const uint8 _adlibChannelsKeyScalingTable1[];
+ static const uint8 _adlibChannelsKeyScalingTable2[];
+ static const uint8 _adlibChannelsVolumeTable[];
+ static const uint8 _adlibInitSequenceData1[];
+ static const uint8 _adlibInitSequenceData2[];
+ static const uint8 _adlibInitSequenceData3[];
+ static const uint8 _adlibInitSequenceData4[];
+ static const uint8 _adlibInitSequenceData5[];
+ static const uint8 _adlibInitSequenceData6[];
+ static const uint8 _adlibInitSequenceData7[];
+ static const uint8 _adlibInitSequenceData8[];
+ static const int16 _midiChannelsNoteTable[];
+ static const int16 _midiNoteFreqTable[];
+};
+
+int AdlibMidiDriver::open() {
+ MidiDriver_Emulated::open();
+ _opl = makeAdlibOPL(getRate());
+ Adlib_SetupCard();
+ for (int i = 0; i < 11; ++i) {
+ _adlibChannelsVolume[i] = 0;
+ Adlib_SetNoteVolume(i, 0);
+ Adlib_TurnNoteOff(i);
+ }
+ _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, false, true);
+ return 0;
+}
+
+void AdlibMidiDriver::close() {
+ _mixer->stopHandle(_mixerSoundHandle);
+ OPLDestroy(_opl);
+}
+
+void AdlibMidiDriver::send(uint32 b) {
+ int channel = b & 15;
+ int cmd = (b >> 4) & 7;
+ int param1 = (b >> 8) & 255;
+ int param2 = (b >> 16) & 255;
+ switch (cmd) {
+ case 0:
+ Adlib_TurnNoteOff(channel);
+ break;
+ case 1:
+ handleMidiEvent0x90_NoteOn(channel, param1, param2);
+ break;
+ case 3:
+ break;
+ case 5:
+ Adlib_SetNoteVolume(channel, param1);
+ _adlibChannelsVolume[channel] = param1;
+ break;
+ case 6:
+ Adlib_SetPitchBend(channel, param1 | (param2 << 7));
+ break;
+ default:
+// warning("Unhandled cmd %d channel %d (0x%X)\n", cmd, channel, b);
+ break;
+ }
+}
+
+void AdlibMidiDriver::metaEvent(byte type, byte *data, uint16 length) {
+ int event = 0;
+ if (length > 4 && READ_BE_UINT32(data) == 0x3F00) {
+ event = data[4];
+ switch (event) {
+ case 1:
+ if (length == 34) {
+ handleSequencerSpecificMetaEvent1(data[5], data + 6);
+ return;
+ }
+ break;
+ case 2:
+ if (length == 6) {
+ handleSequencerSpecificMetaEvent2(data[5]);
+ return;
+ }
+ break;
+ case 3:
+ if (length == 6) {
+ handleSequencerSpecificMetaEvent3(data[5]);
+ return;
+ }
+ break;
+ }
+ }
+ warning("Unhandled meta event %d len %d", event, length);
+}
+
+void AdlibMidiDriver::generateSamples(int16 *data, int len) {
+ memset(data, 0, sizeof(int16) * len);
+ YM3812UpdateOne(_opl, data, len);
+}
+
+void AdlibMidiDriver::handleSequencerSpecificMetaEvent1(int channel, const uint8 *data) {
+ for (int i = 0; i < 28; ++i) {
+ _adlibMetaSequenceData[i] = data[i];
+ }
+ if (_midiNumberOfChannels > channel) {
+ const uint8 *p;
+ if (_adlibRhythmEnabled) {
+ p = &_adlibChannelsKeyScalingTable2[channel * 2];
+ } else {
+ p = &_adlibChannelsKeyScalingTable1[channel * 2];
+ }
+ Adlib_SetupChannel(p[0], _adlibMetaSequenceData, _adlibMetaSequenceData[26]);
+ if (p[1] != 255) {
+ Adlib_SetupChannel(p[1], _adlibMetaSequenceData + 13, _adlibMetaSequenceData[27]);
+ }
+ }
+}
+
+void AdlibMidiDriver::handleSequencerSpecificMetaEvent2(uint8 value) {
+ _adlibRhythmEnabled = value;
+ _midiNumberOfChannels = _adlibRhythmEnabled ? 11 : 9;
+ Adlib_SetAmpVibratoRhythm();
+}
+
+void AdlibMidiDriver::handleSequencerSpecificMetaEvent3(uint8 value) {
+ Adlib_SetNoteMul(value);
+}
+
+void AdlibMidiDriver::handleMidiEvent0x90_NoteOn(int channel, int param1, int param2) { // note, volume
+ if (param2 == 0) {
+ Adlib_TurnNoteOff(channel);
+ _adlibChannelsVolume[channel] = param2;
+ } else {
+ Adlib_SetNoteVolume(channel, param2);
+ _adlibChannelsVolume[channel] = param2;
+ Adlib_TurnNoteOff(channel);
+ Adlib_TurnNoteOn(channel, param1);
+ }
+}
+
+void AdlibMidiDriver::Adlib_Write(uint8 port, uint8 value) {
+ OPLWriteReg(_opl, port, value);
+}
+
+void AdlibMidiDriver::Adlib_SetupCard() {
+ for (int i = 1; i <= 0xF5; ++i) {
+ Adlib_Write(i, 0);
+ }
+ Adlib_Write(4, 6);
+ for (int i = 0; i < 9; ++i) {
+ _midiChannelsNote2Table[i] = 8192;
+ _midiChannelsOctTable[i] = 0;
+ _midiChannelsNote1Table[i] = 0;
+ _midiChannelsFreqTable[i] = 0;
+ }
+ memset(_adlibChannelsLevelKeyScalingTable, 127, 11);
+ Adlib_SetupChannels(0);
+ Adlib_ResetAmpVibratoRhythm(0, 0, 0);
+ Adlib_SetNoteMul(1);
+ Adlib_SetWaveformSelect(1);
+}
+
+void AdlibMidiDriver::Adlib_SetupChannels(int fl) {
+ if (fl != 0) {
+ _midiChannelsNote1Table[8] = 24;
+ _midiChannelsNote2Table[8] = 8192;
+ Adlib_PlayNote(8);
+ _midiChannelsNote1Table[7] = 31;
+ _midiChannelsNote2Table[7] = 8192;
+ Adlib_PlayNote(7);
+ }
+ _adlibRhythmEnabled = fl;
+ _midiNumberOfChannels = fl ? 11 : 9;
+ _adlibVibratoRhythm = 0;
+ _adlibAMDepthEq48 = 0;
+ _adlibVibratoDepthEq14 = 0;
+ _adlibKeyboardSplitOn = 0;
+ Adlib_ResetChannels();
+ Adlib_SetAmpVibratoRhythm();
+}
+
+void AdlibMidiDriver::Adlib_ResetAmpVibratoRhythm(int am, int vib, int kso) {
+ _adlibAMDepthEq48 = am;
+ _adlibVibratoDepthEq14 = vib;
+ _adlibKeyboardSplitOn = kso;
+ Adlib_SetAmpVibratoRhythm();
+ Adlib_SetCSMKeyboardSplit();
+}
+
+void AdlibMidiDriver::Adlib_ResetChannels() {
+ for (int i = 0; i < 18; ++i) {
+ Adlib_SetupChannelFromSequence(i, _adlibChannelsNoFeedback[i] ? _adlibInitSequenceData2 : _adlibInitSequenceData1, 0);
+ }
+ if (_adlibRhythmEnabled) {
+ Adlib_SetupChannelFromSequence(12, _adlibInitSequenceData3, 0);
+ Adlib_SetupChannelFromSequence(15, _adlibInitSequenceData4, 0);
+ Adlib_SetupChannelFromSequence(16, _adlibInitSequenceData5, 0);
+ Adlib_SetupChannelFromSequence(14, _adlibInitSequenceData6, 0);
+ Adlib_SetupChannelFromSequence(17, _adlibInitSequenceData7, 0);
+ Adlib_SetupChannelFromSequence(13, _adlibInitSequenceData8, 0);
+ }
+}
+
+void AdlibMidiDriver::Adlib_SetAmpVibratoRhythm() {
+ uint8 value = 0;
+ if (_adlibAMDepthEq48) {
+ value |= 0x80;
+ }
+ if (_adlibVibratoDepthEq14) {
+ value |= 0x40;
+ }
+ if (_adlibRhythmEnabled) {
+ value |= 0x20;
+ }
+ Adlib_Write(0xBD, value | _adlibVibratoRhythm);
+}
+
+void AdlibMidiDriver::Adlib_SetCSMKeyboardSplit() {
+ uint8 value = _adlibKeyboardSplitOn ? 0x40 : 0;
+ Adlib_Write(8, value);
+}
+
+void AdlibMidiDriver::Adlib_SetNoteMul(int mul) {
+ if (mul > 12) {
+ mul = 12;
+ } else if (mul < 1) {
+ mul = 1;
+ }
+ _adlibNoteMul = mul;
+}
+
+void AdlibMidiDriver::Adlib_SetWaveformSelect(int fl) {
+ _adlibWaveformSelect = fl ? 0x20 : 0;
+ for (int i = 0; i < 18; ++i) {
+ Adlib_Write(0xE0 + _adlibChannelsMappingTable1[i], 0);
+ }
+ Adlib_Write(1, _adlibWaveformSelect);
+}
+
+void AdlibMidiDriver::Adlib_SetPitchBend(int channel, int range) {
+ if ((_adlibRhythmEnabled && channel <= 6) || channel < 9) {
+ if (range > 16383) {
+ range = 16383;
+ }
+ _midiChannelsNote2Table[channel] = range;
+ Adlib_PlayNote(channel);
+ }
+}
+
+void AdlibMidiDriver::Adlib_PlayNote(int channel) {
+ _midiChannelsFreqTable[channel] = Adlib_PlayNoteHelper(channel, _midiChannelsNote1Table[channel], _midiChannelsNote2Table[channel], _midiChannelsOctTable[channel]);
+}
+
+uint8 AdlibMidiDriver::Adlib_PlayNoteHelper(int channel, int note1, int note2, int oct) {
+ int n = ((note2 * _midiChannelsNoteTable[channel]) >> 8) - 8192;
+ if (n != 0) {
+ n >>= 5;
+ n *= _adlibNoteMul;
+ }
+ n += (note1 << 8) + 8;
+ n >>= 4;
+ if (n < 0) {
+ n = 0;
+ } else if (n > 1535) {
+ n = 1535;
+ }
+ int index = (((n >> 4) % 12) << 4) | (n & 0xF);
+ int f = _midiNoteFreqTable[index];
+ int o = (n >> 4) / 12 - 1;
+ if (f < 0) {
+ ++o;
+ }
+ if (o < 0) {
+ ++o;
+ f >>= 1;
+ }
+ Adlib_Write(0xA0 + channel, f & 0xFF);
+ int value = ((f >> 8) & 3) | (o << 2) | oct;
+ Adlib_Write(0xB0 + channel, value);
+ return value;
+}
+
+void AdlibMidiDriver::Adlib_TurnNoteOff(int channel) {
+ if ((_adlibRhythmEnabled && channel <= 6) || channel < 9) {
+ _midiChannelsOctTable[channel] = 0;
+ _midiChannelsFreqTable[channel] &= ~0x20;
+ Adlib_Write(0xB0 + channel, _midiChannelsFreqTable[channel]);
+ } else if (_adlibRhythmEnabled && channel <= 10) {
+ _adlibVibratoRhythm &= ~(1 << (4 - (channel - 6)));
+ Adlib_SetAmpVibratoRhythm();
+ }
+}
+
+void AdlibMidiDriver::Adlib_TurnNoteOn(int channel, int note) {
+ note -= 12;
+ if (note < 0) {
+ note = 0;
+ }
+ if ((_adlibRhythmEnabled && channel <= 6) || channel < 9) {
+ _midiChannelsNote1Table[channel] = note;
+ _midiChannelsOctTable[channel] = 0x20;
+ Adlib_PlayNote(channel);
+ } else if (_adlibRhythmEnabled && channel <= 10) {
+ if (channel == 6) {
+ _midiChannelsNote1Table[6] = note;
+ Adlib_PlayNote(channel);
+ } else if (channel == 8 && _midiChannelsNote1Table[8] == note) {
+ _midiChannelsNote1Table[8] = note;
+ _midiChannelsNote1Table[7] = note + 7;
+ Adlib_PlayNote(8);
+ Adlib_PlayNote(7);
+ }
+ _adlibVibratoRhythm = 1 << (4 - (channel - 6));
+ Adlib_SetAmpVibratoRhythm();
+ }
+}
+
+void AdlibMidiDriver::Adlib_SetupChannelFromSequence(int channel, const uint8 *src, int fl) {
+ for (int i = 0; i < 13; ++i) {
+ _adlibSetupChannelSequence2[i] = src[i];
+ }
+ Adlib_SetupChannel(channel, _adlibSetupChannelSequence2, fl);
+}
+
+void AdlibMidiDriver::Adlib_SetupChannel(int channel, const uint16 *src, int fl) {
+ for (int i = 0; i < 13; ++i) {
+ _adlibSetupChannelSequence1[14 * channel + i] = src[i];
+ }
+ _adlibSetupChannelSequence1[14 * channel + 13] = fl & 3;
+ Adlib_SetupChannelHelper(channel);
+}
+
+void AdlibMidiDriver::Adlib_SetNoteVolume(int channel, int volume) {
+ if (_midiNumberOfChannels > channel) {
+ if (volume > 127) {
+ volume = 127;
+ }
+ _adlibChannelsLevelKeyScalingTable[channel] = volume;
+ const uint8 *p;
+ if (_adlibRhythmEnabled) {
+ p = &_adlibChannelsKeyScalingTable2[channel * 2];
+ } else {
+ p = &_adlibChannelsKeyScalingTable1[channel * 2];
+ }
+ Adlib_SetChannel0x40(p[0]);
+ if (p[1] != 255) {
+ Adlib_SetChannel0x40(p[1]);
+ }
+ }
+}
+
+void AdlibMidiDriver::Adlib_SetupChannelHelper(int channel) {
+ Adlib_SetAmpVibratoRhythm();
+ Adlib_SetCSMKeyboardSplit();
+ Adlib_SetChannel0x40(channel);
+ Adlib_SetChannel0xC0(channel);
+ Adlib_SetChannel0x60(channel);
+ Adlib_SetChannel0x80(channel);
+ Adlib_SetChannel0x20(channel);
+ Adlib_SetChannel0xE0(channel);
+}
+
+void AdlibMidiDriver::Adlib_SetChannel0x40(int channel) {
+ int index, value, fl;
+
+ if (_adlibRhythmEnabled) {
+ index = _adlibChannelsMappingTable3[channel];
+ } else {
+ index = _adlibChannelsMappingTable2[channel];
+ }
+ value = 63 - (_adlibSetupChannelSequence1[channel * 14 + 8] & 63);
+ fl = 0;
+ if (_adlibRhythmEnabled && index > 6) {
+ fl = -1;
+ }
+ if (_adlibChannelsNoFeedback[channel] || _adlibSetupChannelSequence1[channel * 14 + 12] == 0 || fl != 0) {
+ value = ((_adlibChannelsLevelKeyScalingTable[index] * value) + 64) >> 7;
+ }
+ value = (_adlibChannelsVolumeTable[index] * value * 2) >> 8;
+ if (value > 63) {
+ value = 63;
+ }
+ value = 63 - value;
+ value |= _adlibSetupChannelSequence1[channel * 14] << 6;
+ Adlib_Write(0x40 + _adlibChannelsMappingTable1[channel], value);
+}
+
+void AdlibMidiDriver::Adlib_SetChannel0xC0(int channel) {
+ if (_adlibChannelsNoFeedback[channel] == 0) {
+ const uint8 *p = &_adlibSetupChannelSequence1[channel * 14];
+ uint8 value = p[2] << 1;
+ if (p[12] == 0) {
+ value |= 1;
+ }
+ Adlib_Write(0xC0 + _adlibChannelsMappingTable2[channel], value);
+ }
+}
+
+void AdlibMidiDriver::Adlib_SetChannel0x60(int channel) {
+ const uint8 *p = &_adlibSetupChannelSequence1[channel * 14];
+ uint8 value = (p[3] << 4) | (p[6] & 15);
+ Adlib_Write(0x60 + _adlibChannelsMappingTable1[channel], value);
+}
+
+void AdlibMidiDriver::Adlib_SetChannel0x80(int channel) {
+ const uint8 *p = &_adlibSetupChannelSequence1[channel * 14];
+ uint8 value = (p[4] << 4) | (p[7] & 15);
+ Adlib_Write(0x80 + _adlibChannelsMappingTable1[channel], value);
+}
+
+void AdlibMidiDriver::Adlib_SetChannel0x20(int channel) {
+ const uint8 *p = &_adlibSetupChannelSequence1[channel * 14];
+ uint8 value = p[1] & 15;
+ if (p[9]) {
+ value |= 0x80;
+ }
+ if (p[10]) {
+ value |= 0x40;
+ }
+ if (p[5]) {
+ value |= 0x20;
+ }
+ if (p[11]) {
+ value |= 0x10;
+ }
+ Adlib_Write(0x20 + _adlibChannelsMappingTable1[channel], value);
+}
+
+void AdlibMidiDriver::Adlib_SetChannel0xE0(int channel) {
+ uint8 value = 0;
+ if (_adlibWaveformSelect) {
+ const uint8 *p = &_adlibSetupChannelSequence1[channel * 14];
+ value = p[13] & 3;
+ }
+ Adlib_Write(0xE0 + _adlibChannelsMappingTable1[channel], value);
+}
+
+const uint8 AdlibMidiDriver::_adlibChannelsMappingTable1[] = {
+ 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21
+};
+
+const uint8 AdlibMidiDriver::_adlibChannelsNoFeedback[] = {
+ 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1
+};
+
+const uint8 AdlibMidiDriver::_adlibChannelsMappingTable2[] = {
+ 0, 1, 2, 0, 1, 2, 3, 4, 5, 3, 4, 5, 6, 7, 8, 6, 7, 8
+};
+
+const uint8 AdlibMidiDriver::_adlibChannelsMappingTable3[] = {
+ 0, 1, 2, 0, 1, 2, 3, 4, 5, 3, 4, 5, 6, 10, 8, 6, 7, 9
+};
+
+const uint8 AdlibMidiDriver::_adlibChannelsKeyScalingTable1[] = {
+ 0, 3, 1, 4, 2, 5, 6, 9, 7, 10, 8, 11, 12, 15, 13, 16, 14, 17
+};
+
+const uint8 AdlibMidiDriver::_adlibChannelsKeyScalingTable2[] = {
+ 0, 3, 1, 4, 2, 5, 6, 9, 7, 10, 8, 11, 12, 15, 16, 255, 14, 255, 17, 255, 13, 255
+};
+
+const uint8 AdlibMidiDriver::_adlibChannelsVolumeTable[] = {
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
+};
+
+const uint8 AdlibMidiDriver::_adlibInitSequenceData1[] = {
+ 1, 1, 3, 15, 5, 0, 1, 3, 15, 0, 0, 0, 1, 0
+};
+
+const uint8 AdlibMidiDriver::_adlibInitSequenceData2[] = {
+ 0, 1, 1, 15, 7, 0, 2, 4, 0, 0, 0, 1, 0, 0
+};
+
+const uint8 AdlibMidiDriver::_adlibInitSequenceData3[] = {
+ 0, 0, 0, 10, 4, 0, 8, 12, 11, 0, 0, 0, 1, 0
+};
+
+const uint8 AdlibMidiDriver::_adlibInitSequenceData4[] = {
+ 0, 0, 0, 13, 4, 0, 6, 15, 0, 0, 0, 0, 1, 0
+};
+
+const uint8 AdlibMidiDriver::_adlibInitSequenceData5[] = {
+ 0, 12, 0, 15, 11, 0, 8, 5, 0, 0, 0, 0, 0, 0
+};
+
+const uint8 AdlibMidiDriver::_adlibInitSequenceData6[] = {
+ 0, 4, 0, 15, 11, 0, 7, 5, 0, 0, 0, 0, 0, 0
+};
+
+const uint8 AdlibMidiDriver::_adlibInitSequenceData7[] = {
+ 0, 1, 0, 15, 11, 0, 5, 5, 0, 0, 0, 0, 0, 0
+};
+
+const uint8 AdlibMidiDriver::_adlibInitSequenceData8[] = {
+ 0, 1, 0, 15, 11, 0, 7, 5, 0, 0, 0, 0, 0, 0
+};
+
+const int16 AdlibMidiDriver::_midiChannelsNoteTable[] = {
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256
+};
+
+const int16 AdlibMidiDriver::_midiNoteFreqTable[] = {
+ 690, 692, 695, 697, 700, 702, 705, 707, 710, 713, 715, 718,
+ 720, 723, 726, 728, 731, 733, 736, 739, 741, 744, 747, 749,
+ 752, 755, 758, 760, 763, 766, 769, 771, 774, 777, 780, 783,
+ 785, 788, 791, 794, 797, 800, 803, 806, 809, 811, 814, 817,
+ 820, 823, 826, 829, 832, 835, 838, 841, 844, 847, 850, 854,
+ 857, 860, 863, 866, 869, 872, 875, 879, 882, 885, 888, 891,
+ 895, 898, 901, 904, 908, 911, 914, 917, 921, 924, 927, 931,
+ 934, 937, 941, 944, 948, 951, 955, 958, 961, 965, 968, 972,
+ 975, 979, 983, 986, 990, 993, 997, 1000, 1004, 1008, 1011, 1015,
+ 1019, 1022, -511, -509, -507, -505, -504, -502, -500, -498, -496, -494,
+ -492, -490, -488, -486, -484, -482, -480, -479, -477, -475, -473, -471,
+ -469, -467, -465, -463, -460, -458, -456, -454, -452, -450, -448, -446,
+ -444, -442, -440, -438, -436, -433, -431, -429, -427, -425, -423, -420,
+ -418, -416, -414, -412, -409, -407, -405, -403, -401, -398, -396, -394,
+ -391, -389, -387, -385, -382, -380, -378, -375, -373, -371, -368, -366,
+ -363, -361, -359, -356, -354, -351, -349, -347, -344, -342, -339, -337
+};
+
+MidiDriver *C_Player_CreateAdlibMidiDriver(Audio::Mixer *mixer) {
+ return new AdlibMidiDriver(mixer);
+}
+
+} // End of namespace Queen