~ubuntu-branches/ubuntu/raring/scummvm/raring

« back to all changes in this revision

Viewing changes to audio/softsynth/adlib.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Moritz Muehlenhoff
  • Date: 2011-05-25 19:02:23 UTC
  • mto: (21.1.2 sid)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: james.westby@ubuntu.com-20110525190223-fiqm0oaec714xk31
Tags: upstream-1.3.0
ImportĀ upstreamĀ versionĀ 1.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ScummVM - Graphic Adventure Engine
 
2
 *
 
3
 * ScummVM is the legal property of its developers, whose names
 
4
 * are too numerous to list here. Please refer to the COPYRIGHT
 
5
 * file distributed with this source distribution.
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License
 
9
 * as published by the Free Software Foundation; either version 2
 
10
 * of the License, or (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
20
 *
 
21
 * $URL$
 
22
 * $Id$
 
23
 */
 
24
 
 
25
#include "audio/softsynth/emumidi.h"
 
26
#include "common/debug.h"
 
27
#include "common/error.h"
 
28
#include "common/scummsys.h"
 
29
#include "common/system.h"
 
30
#include "common/textconsole.h"
 
31
#include "common/types.h"
 
32
#include "common/util.h"
 
33
#include "audio/fmopl.h"
 
34
#include "audio/musicplugin.h"
 
35
#include "common/translation.h"
 
36
 
 
37
#ifdef DEBUG_ADLIB
 
38
static int tick;
 
39
#endif
 
40
 
 
41
class MidiDriver_ADLIB;
 
42
struct AdLibVoice;
 
43
 
 
44
// We use packing for the following two structs, because the code
 
45
// does simply copy them over from byte streams, without any
 
46
// serialization. Check AdLibPart::sysEx_customInstrument for an
 
47
// example of this.
 
48
//
 
49
// It might be very well possible, that none of the compilers we support
 
50
// add any padding bytes at all, since the structs contain only variables
 
51
// of the type 'byte'. But better safe than sorry.
 
52
#include "common/pack-start.h"
 
53
struct InstrumentExtra {
 
54
        byte a, b, c, d, e, f, g, h;
 
55
} PACKED_STRUCT;
 
56
 
 
57
struct AdLibInstrument {
 
58
        byte mod_characteristic;
 
59
        byte mod_scalingOutputLevel;
 
60
        byte mod_attackDecay;
 
61
        byte mod_sustainRelease;
 
62
        byte mod_waveformSelect;
 
63
        byte car_characteristic;
 
64
        byte car_scalingOutputLevel;
 
65
        byte car_attackDecay;
 
66
        byte car_sustainRelease;
 
67
        byte car_waveformSelect;
 
68
        byte feedback;
 
69
        byte flags_a;
 
70
        InstrumentExtra extra_a;
 
71
        byte flags_b;
 
72
        InstrumentExtra extra_b;
 
73
        byte duration;
 
74
 
 
75
        AdLibInstrument() { memset(this, 0, sizeof(AdLibInstrument)); }
 
76
} PACKED_STRUCT;
 
77
#include "common/pack-end.h"
 
78
 
 
79
class AdLibPart : public MidiChannel {
 
80
        friend class MidiDriver_ADLIB;
 
81
 
 
82
protected:
 
83
//      AdLibPart *_prev, *_next;
 
84
        AdLibVoice *_voice;
 
85
        int16 _pitchbend;
 
86
        byte _pitchbend_factor;
 
87
        int8 _transpose_eff;
 
88
        byte _vol_eff;
 
89
        int8 _detune_eff;
 
90
        byte _modwheel;
 
91
        bool _pedal;
 
92
        byte _program;
 
93
        byte _pri_eff;
 
94
        AdLibInstrument _part_instr;
 
95
 
 
96
protected:
 
97
        MidiDriver_ADLIB *_owner;
 
98
        bool _allocated;
 
99
        byte _channel;
 
100
 
 
101
        void init(MidiDriver_ADLIB *owner, byte channel);
 
102
        void allocate() { _allocated = true; }
 
103
 
 
104
public:
 
105
        AdLibPart() {
 
106
                _voice = 0;
 
107
                _pitchbend = 0;
 
108
                _pitchbend_factor = 2;
 
109
                _transpose_eff = 0;
 
110
                _vol_eff = 0;
 
111
                _detune_eff = 0;
 
112
                _modwheel = 0;
 
113
                _pedal = 0;
 
114
                _program = 0;
 
115
                _pri_eff = 0;
 
116
 
 
117
                _owner = 0;
 
118
                _allocated = false;
 
119
                _channel = 0;
 
120
        }
 
121
 
 
122
        MidiDriver *device();
 
123
        byte getNumber() { return _channel; }
 
124
        void release() { _allocated = false; }
 
125
 
 
126
        void send(uint32 b);
 
127
 
 
128
        // Regular messages
 
129
        void noteOff(byte note);
 
130
        void noteOn(byte note, byte velocity);
 
131
        void programChange(byte program);
 
132
        void pitchBend(int16 bend);
 
133
 
 
134
        // Control Change messages
 
135
        void controlChange(byte control, byte value);
 
136
        void modulationWheel(byte value);
 
137
        void volume(byte value);
 
138
        void panPosition(byte value) { return; } // Not supported
 
139
        void pitchBendFactor(byte value);
 
140
        void detune(byte value);
 
141
        void priority(byte value);
 
142
        void sustain(bool value);
 
143
        void effectLevel(byte value) { return; } // Not supported
 
144
        void chorusLevel(byte value) { return; } // Not supported
 
145
        void allNotesOff();
 
146
 
 
147
        // SysEx messages
 
148
        void sysEx_customInstrument(uint32 type, const byte *instr);
 
149
};
 
150
 
 
151
// FYI (Jamieson630)
 
152
// It is assumed that any invocation to AdLibPercussionChannel
 
153
// will be done through the MidiChannel base class as opposed to the
 
154
// AdLibPart base class. If this were NOT the case, all the functions
 
155
// listed below would need to be virtual in AdLibPart as well as MidiChannel.
 
156
class AdLibPercussionChannel : public AdLibPart {
 
157
        friend class MidiDriver_ADLIB;
 
158
 
 
159
protected:
 
160
        void init(MidiDriver_ADLIB *owner, byte channel);
 
161
 
 
162
public:
 
163
        ~AdLibPercussionChannel();
 
164
 
 
165
        void noteOff(byte note);
 
166
        void noteOn(byte note, byte velocity);
 
167
        void programChange(byte program) { }
 
168
        void pitchBend(int16 bend) { }
 
169
 
 
170
        // Control Change messages
 
171
        void modulationWheel(byte value) { }
 
172
        void pitchBendFactor(byte value) { }
 
173
        void detune(byte value) { }
 
174
        void priority(byte value) { }
 
175
        void sustain(bool value) { }
 
176
 
 
177
        // SysEx messages
 
178
        void sysEx_customInstrument(uint32 type, const byte *instr);
 
179
 
 
180
private:
 
181
        byte _notes[256];
 
182
        AdLibInstrument *_customInstruments[256];
 
183
};
 
184
 
 
185
struct Struct10 {
 
186
        byte active;
 
187
        int16 cur_val;
 
188
        int16 count;
 
189
        uint16 max_value;
 
190
        int16 start_value;
 
191
        byte loop;
 
192
        byte table_a[4];
 
193
        byte table_b[4];
 
194
        int8 unk3;
 
195
        int8 modwheel;
 
196
        int8 modwheel_last;
 
197
        uint16 speed_lo_max;
 
198
        uint16 num_steps;
 
199
        int16 speed_hi;
 
200
        int8 direction;
 
201
        uint16 speed_lo;
 
202
        uint16 speed_lo_counter;
 
203
};
 
204
 
 
205
struct Struct11 {
 
206
        int16 modify_val;
 
207
        byte param, flag0x40, flag0x10;
 
208
        Struct10 *s10;
 
209
};
 
210
 
 
211
struct AdLibVoice {
 
212
        AdLibPart *_part;
 
213
        AdLibVoice *_next, *_prev;
 
214
        byte _waitforpedal;
 
215
        byte _note;
 
216
        byte _channel;
 
217
        byte _twochan;
 
218
        byte _vol_1, _vol_2;
 
219
        int16 _duration;
 
220
 
 
221
        Struct10 _s10a;
 
222
        Struct11 _s11a;
 
223
        Struct10 _s10b;
 
224
        Struct11 _s11b;
 
225
 
 
226
        AdLibVoice() { memset(this, 0, sizeof(AdLibVoice)); }
 
227
};
 
228
 
 
229
struct AdLibSetParams {
 
230
        byte a, b, c, d;
 
231
};
 
232
 
 
233
static const byte channel_mappings[9] = {
 
234
        0, 1, 2, 8,
 
235
        9, 10, 16, 17,
 
236
        18
 
237
};
 
238
 
 
239
static const byte channel_mappings_2[9] = {
 
240
        3, 4, 5, 11,
 
241
        12, 13, 19, 20,
 
242
        21
 
243
};
 
244
 
 
245
static const AdLibSetParams adlib_setparam_table[] = {
 
246
        {0x40, 0, 63, 63},  // level
 
247
        {0xE0, 2, 0, 0},    // unused
 
248
        {0x40, 6, 192, 0},  // level key scaling
 
249
        {0x20, 0, 15, 0},   // modulator frequency multiple
 
250
        {0x60, 4, 240, 15}, // attack rate
 
251
        {0x60, 0, 15, 15},  // decay rate
 
252
        {0x80, 4, 240, 15}, // sustain level
 
253
        {0x80, 0, 15, 15},  // release rate
 
254
        {0xE0, 0, 3, 0},    // waveformSelect select
 
255
        {0x20, 7, 128, 0},  // amp mod
 
256
        {0x20, 6, 64, 0},   // vib
 
257
        {0x20, 5, 32, 0},   // eg typ
 
258
        {0x20, 4, 16, 0},   // ksr
 
259
        {0xC0, 0, 1, 0},    // decay alg
 
260
        {0xC0, 1, 14, 0}    // feedback
 
261
};
 
262
 
 
263
static const byte param_table_1[16] = {
 
264
        29, 28, 27, 0,
 
265
        3, 4, 7, 8,
 
266
        13, 16, 17, 20,
 
267
        21, 30, 31, 0
 
268
};
 
269
 
 
270
static const uint16 maxval_table[16] = {
 
271
        0x2FF, 0x1F, 0x7, 0x3F,
 
272
        0x0F, 0x0F, 0x0F, 0x3,
 
273
        0x3F, 0x0F, 0x0F, 0x0F,
 
274
        0x3, 0x3E, 0x1F, 0
 
275
};
 
276
 
 
277
static const uint16 num_steps_table[] = {
 
278
        1, 2, 4, 5,
 
279
        6, 7, 8, 9,
 
280
        10, 12, 14, 16,
 
281
        18, 21, 24, 30,
 
282
        36, 50, 64, 82,
 
283
        100, 136, 160, 192,
 
284
        240, 276, 340, 460,
 
285
        600, 860, 1200, 1600
 
286
};
 
287
 
 
288
static const byte note_to_f_num[] = {
 
289
        90, 91, 92, 92, 93, 94, 94, 95,
 
290
        96, 96, 97, 98, 98, 99, 100, 101,
 
291
        101, 102, 103, 104, 104, 105, 106, 107,
 
292
        107, 108, 109, 110, 111, 111, 112, 113,
 
293
        114, 115, 115, 116, 117, 118, 119, 120,
 
294
        121, 121, 122, 123, 124, 125, 126, 127,
 
295
        128, 129, 130, 131, 132, 132, 133, 134,
 
296
        135, 136, 137, 138, 139, 140, 141, 142,
 
297
        143, 145, 146, 147, 148, 149, 150, 151,
 
298
        152, 153, 154, 155, 157, 158, 159, 160,
 
299
        161, 162, 163, 165, 166, 167, 168, 169,
 
300
        171, 172, 173, 174, 176, 177, 178, 180,
 
301
        181, 182, 184, 185, 186, 188, 189, 190,
 
302
        192, 193, 194, 196, 197, 199, 200, 202,
 
303
        203, 205, 206, 208, 209, 211, 212, 214,
 
304
        215, 217, 218, 220, 222, 223, 225, 226,
 
305
        228, 230, 231, 233, 235, 236, 238, 240,
 
306
        242, 243, 245, 247, 249, 251, 252, 254
 
307
};
 
308
 
 
309
static const byte map_gm_to_fm[128][30] = {
 
310
        // 0x00
 
311
{ 0xC2, 0xC5, 0x2B, 0x99, 0x58, 0xC2, 0x1F, 0x1E, 0xC8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x23 },
 
312
{ 0x22, 0x53, 0x0E, 0x8A, 0x30, 0x14, 0x06, 0x1D, 0x7A, 0x5C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
313
{ 0x06, 0x00, 0x1C, 0x79, 0x40, 0x02, 0x00, 0x4B, 0x79, 0x58, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
314
{ 0xC2, 0x89, 0x2A, 0x89, 0x49, 0xC2, 0x16, 0x1C, 0xB8, 0x7C, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x23 },
 
315
{ 0xC2, 0x17, 0x3D, 0x6A, 0x00, 0xC4, 0x2E, 0x2D, 0xC9, 0x20, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
316
{ 0x06, 0x1E, 0x1C, 0x99, 0x00, 0x02, 0x3A, 0x4C, 0x79, 0x00, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
317
{ 0x84, 0x40, 0x3B, 0x5A, 0x6F, 0x81, 0x0E, 0x3B, 0x5A, 0x7F, 0x0B, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
318
{ 0x84, 0x40, 0x3B, 0x5A, 0x63, 0x81, 0x00, 0x3B, 0x5A, 0x7F, 0x01, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
319
{ 0x8C, 0x80, 0x05, 0xEA, 0x59, 0x82, 0x0A, 0x3C, 0xAA, 0x64, 0x07, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
320
{ 0x85, 0x40, 0x0D, 0xEC, 0x71, 0x84, 0x58, 0x3E, 0xCB, 0x7C, 0x01, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
321
{ 0x8A, 0xC0, 0x0C, 0xDC, 0x50, 0x88, 0x58, 0x3D, 0xDA, 0x7C, 0x01, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
322
{ 0xC9, 0x40, 0x2B, 0x78, 0x42, 0xC2, 0x04, 0x4C, 0x8A, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x1A },
 
323
{ 0x2A, 0x0E, 0x17, 0x89, 0x28, 0x22, 0x0C, 0x1B, 0x09, 0x70, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
324
{ 0xE7, 0x9B, 0x08, 0x08, 0x26, 0xE2, 0x06, 0x0A, 0x08, 0x70, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
325
{ 0xC5, 0x05, 0x00, 0xFC, 0x40, 0x84, 0x00, 0x00, 0xDC, 0x50, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
326
{ 0x86, 0x40, 0x5D, 0x5A, 0x41, 0x81, 0x00, 0x0B, 0x5A, 0x7F, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
327
        // 0x10
 
328
{ 0xED, 0x00, 0x7B, 0xC8, 0x40, 0xE1, 0x99, 0x4A, 0xE9, 0x7E, 0x07, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
329
{ 0xE8, 0x4F, 0x3A, 0xD7, 0x7C, 0xE2, 0x97, 0x49, 0xF9, 0x7D, 0x05, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
330
{ 0xE1, 0x10, 0x2F, 0xF7, 0x7D, 0xF3, 0x45, 0x8F, 0xC7, 0x62, 0x07, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
331
{ 0x01, 0x8C, 0x9F, 0xDA, 0x70, 0xE4, 0x50, 0x9F, 0xDA, 0x6A, 0x09, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
332
{ 0x08, 0xD5, 0x9D, 0xA5, 0x45, 0xE2, 0x3F, 0x9F, 0xD6, 0x49, 0x07, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
333
{ 0xE5, 0x0F, 0x7D, 0xB8, 0x2E, 0xA2, 0x0F, 0x7C, 0xC7, 0x61, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
334
{ 0xF2, 0x2A, 0x9F, 0xDB, 0x01, 0xE1, 0x04, 0x8F, 0xD7, 0x62, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
335
{ 0xE4, 0x88, 0x9C, 0x50, 0x64, 0xE2, 0x18, 0x70, 0xC4, 0x7C, 0x0B, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
336
{ 0x02, 0xA3, 0x0D, 0xDA, 0x01, 0xC2, 0x35, 0x5D, 0x58, 0x00, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x18 },
 
337
{ 0x42, 0x55, 0x3E, 0xEB, 0x24, 0xD4, 0x08, 0x0D, 0xA9, 0x71, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x18 },
 
338
{ 0xC2, 0x00, 0x2B, 0x17, 0x51, 0xC2, 0x1E, 0x4D, 0x97, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x19 },
 
339
{ 0xC6, 0x01, 0x2D, 0xA7, 0x44, 0xC2, 0x06, 0x0E, 0xA7, 0x79, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
340
{ 0xC2, 0x0C, 0x06, 0x06, 0x55, 0xC2, 0x3F, 0x09, 0x86, 0x7D, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0A },
 
341
{ 0xC2, 0x2E, 0x4F, 0x77, 0x00, 0xC4, 0x08, 0x0E, 0x98, 0x59, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
342
{ 0xC2, 0x30, 0x4F, 0xCA, 0x01, 0xC4, 0x0D, 0x0E, 0xB8, 0x7F, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
343
{ 0xC4, 0x29, 0x4F, 0xCA, 0x03, 0xC8, 0x0D, 0x0C, 0xB7, 0x7D, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0B },
 
344
        // 0x20
 
345
{ 0xC2, 0x40, 0x3C, 0x96, 0x58, 0xC4, 0xDE, 0x0E, 0xC7, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x20 },
 
346
{ 0x31, 0x13, 0x2D, 0xD7, 0x3C, 0xE2, 0x18, 0x2E, 0xB8, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
347
{ 0x22, 0x86, 0x0D, 0xD7, 0x50, 0xE4, 0x18, 0x5E, 0xB8, 0x7C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x28 },
 
348
{ 0xF2, 0x0A, 0x0D, 0xD7, 0x40, 0xE4, 0x1F, 0x5E, 0xB8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
349
{ 0xF2, 0x09, 0x4B, 0xD6, 0x48, 0xE4, 0x1F, 0x1C, 0xB8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x28 },
 
350
{ 0x62, 0x11, 0x0C, 0xE6, 0x3C, 0xE4, 0x1F, 0x0C, 0xC8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
351
{ 0xE2, 0x12, 0x3D, 0xE6, 0x34, 0xE4, 0x1F, 0x7D, 0xB8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
352
{ 0xE2, 0x13, 0x3D, 0xE6, 0x34, 0xE4, 0x1F, 0x5D, 0xB8, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
353
{ 0xA2, 0x40, 0x5D, 0xBA, 0x3F, 0xE2, 0x00, 0x8F, 0xD8, 0x79, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
354
{ 0xE2, 0x40, 0x3D, 0xDA, 0x3B, 0xE1, 0x00, 0x7E, 0xD8, 0x7A, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
355
{ 0x62, 0x00, 0x6D, 0xFA, 0x5D, 0xE2, 0x00, 0x8F, 0xC8, 0x79, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
356
{ 0xE1, 0x00, 0x4E, 0xDB, 0x4A, 0xE3, 0x18, 0x6F, 0xE9, 0x7E, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
357
{ 0xE1, 0x00, 0x4E, 0xDB, 0x66, 0xE2, 0x00, 0x7F, 0xE9, 0x7E, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
358
{ 0x02, 0x0F, 0x66, 0xAA, 0x51, 0x02, 0x64, 0x29, 0xF9, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 },
 
359
{ 0x16, 0x4A, 0x04, 0xBA, 0x39, 0xC2, 0x58, 0x2D, 0xCA, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 },
 
360
{ 0x02, 0x00, 0x01, 0x7A, 0x79, 0x02, 0x3F, 0x28, 0xEA, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
361
        // 0x30
 
362
{ 0x62, 0x53, 0x9C, 0xBA, 0x31, 0x62, 0x5B, 0xAD, 0xC9, 0x55, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
363
{ 0xF2, 0x40, 0x6E, 0xDA, 0x49, 0xE2, 0x13, 0x8F, 0xF9, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
364
{ 0xE2, 0x40, 0x8F, 0xFA, 0x50, 0xF2, 0x04, 0x7F, 0xFA, 0x7D, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
365
{ 0xE4, 0xA0, 0xCE, 0x5B, 0x02, 0xE2, 0x32, 0x7F, 0xFB, 0x3D, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
366
{ 0xE6, 0x80, 0x9C, 0x99, 0x42, 0xE2, 0x04, 0x7D, 0x78, 0x60, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
367
{ 0xEA, 0xA0, 0xAC, 0x67, 0x02, 0xE2, 0x00, 0x7C, 0x7A, 0x7C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
368
{ 0xE7, 0x94, 0xAD, 0xB7, 0x03, 0xE2, 0x00, 0x7C, 0xBA, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
369
{ 0xC3, 0x3F, 0x4B, 0xE9, 0x7E, 0xC1, 0x3F, 0x9B, 0xF9, 0x7F, 0x0B, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x06 },
 
370
{ 0xB2, 0x20, 0xAD, 0xE9, 0x00, 0x62, 0x05, 0x8F, 0xC8, 0x68, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
371
{ 0xF2, 0x00, 0x8F, 0xFB, 0x50, 0xF6, 0x47, 0x8F, 0xE9, 0x68, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
372
{ 0xF2, 0x00, 0xAF, 0x88, 0x58, 0xF2, 0x54, 0x6E, 0xC9, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
373
{ 0xF2, 0x2A, 0x9F, 0x98, 0x01, 0xE2, 0x84, 0x4E, 0x78, 0x6C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
374
{ 0xE2, 0x02, 0x9F, 0xB8, 0x48, 0x22, 0x89, 0x9F, 0xE8, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
375
{ 0xE2, 0x2A, 0x7F, 0xB8, 0x01, 0xE4, 0x00, 0x0D, 0xC5, 0x7C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
376
{ 0xE4, 0x28, 0x8E, 0xE8, 0x01, 0xF2, 0x00, 0x4D, 0xD6, 0x7D, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
377
{ 0x62, 0x23, 0x8F, 0xEA, 0x00, 0xF2, 0x00, 0x5E, 0xD9, 0x7C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
378
        // 0x40
 
379
{ 0xB4, 0x26, 0x6E, 0x98, 0x01, 0x62, 0x00, 0x7D, 0xC8, 0x7D, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
380
{ 0xE2, 0x2E, 0x20, 0xD9, 0x01, 0xF2, 0x0F, 0x90, 0xF8, 0x78, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
381
{ 0xE4, 0x28, 0x7E, 0xF8, 0x01, 0xE2, 0x23, 0x8E, 0xE8, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
382
{ 0xB8, 0x28, 0x9E, 0x98, 0x01, 0x62, 0x00, 0x3D, 0xC8, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
383
{ 0x62, 0x00, 0x8E, 0xC9, 0x3D, 0xE6, 0x00, 0x7E, 0xD8, 0x68, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
384
{ 0xE2, 0x00, 0x5F, 0xF9, 0x48, 0xE6, 0x98, 0x8F, 0xF8, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
385
{ 0x62, 0x0C, 0x6E, 0xD8, 0x3D, 0x2A, 0x06, 0x7D, 0xD8, 0x58, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
386
{ 0xE4, 0x00, 0x7E, 0x89, 0x38, 0xE6, 0x84, 0x80, 0xF8, 0x68, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
387
{ 0xE4, 0x80, 0x6C, 0xD9, 0x30, 0xE2, 0x00, 0x8D, 0xC8, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
388
{ 0xE2, 0x80, 0x88, 0x48, 0x40, 0xE2, 0x0A, 0x7D, 0xA8, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
389
{ 0xE4, 0x00, 0x77, 0xC5, 0x54, 0xE2, 0x00, 0x9E, 0xD7, 0x70, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
390
{ 0xE4, 0x80, 0x86, 0xB9, 0x64, 0xE2, 0x05, 0x9F, 0xD7, 0x78, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
391
{ 0xE2, 0x00, 0x68, 0x68, 0x56, 0xE2, 0x08, 0x9B, 0xB3, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
392
{ 0xE4, 0x00, 0xA6, 0x87, 0x41, 0xE2, 0x0A, 0x7E, 0xC9, 0x7C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
393
{ 0xE4, 0x80, 0x9A, 0xB8, 0x48, 0xE2, 0x00, 0x9E, 0xF9, 0x60, 0x09, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
394
{ 0xE2, 0x80, 0x8E, 0x64, 0x68, 0xE2, 0x28, 0x6F, 0x73, 0x7C, 0x01, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
395
        // 0x50
 
396
{ 0xE8, 0x00, 0x7D, 0x99, 0x54, 0xE6, 0x80, 0x80, 0xF8, 0x7C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
397
{ 0xE6, 0x00, 0x9F, 0xB9, 0x6D, 0xE1, 0x00, 0x8F, 0xC8, 0x7D, 0x02, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
398
{ 0xE4, 0x00, 0x09, 0x68, 0x4A, 0xE2, 0x2B, 0x9E, 0xF3, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
399
{ 0xC4, 0x00, 0x99, 0xE8, 0x3B, 0xE2, 0x25, 0x6F, 0x93, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
400
{ 0xE6, 0x00, 0x6F, 0xDA, 0x69, 0xE2, 0x05, 0x2F, 0xD8, 0x6A, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
401
{ 0xEC, 0x60, 0x9D, 0xC7, 0x00, 0xE2, 0x21, 0x7F, 0xC9, 0x7C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
402
{ 0xE3, 0x00, 0x0F, 0xF7, 0x7D, 0xE1, 0x3F, 0x0F, 0xA7, 0x01, 0x0D, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
403
{ 0xE4, 0xA9, 0x0F, 0xA8, 0x02, 0xE2, 0x3C, 0x5F, 0xDA, 0x3C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
404
{ 0xE8, 0x40, 0x0D, 0x89, 0x7D, 0xE2, 0x17, 0x7E, 0xD9, 0x7C, 0x07, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
405
{ 0xE1, 0x00, 0xDF, 0x8A, 0x56, 0xE2, 0x5E, 0xCF, 0xBA, 0x7E, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
406
{ 0xE2, 0x00, 0x0B, 0x68, 0x60, 0xE2, 0x01, 0x9E, 0xB8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
407
{ 0xEA, 0x00, 0xAE, 0xAB, 0x49, 0xE2, 0x00, 0xAE, 0xBA, 0x6C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
408
{ 0xEB, 0x80, 0x8C, 0xCB, 0x3A, 0xE2, 0x86, 0xAF, 0xCA, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
409
{ 0xE5, 0x40, 0xDB, 0x3B, 0x3C, 0xE2, 0x80, 0xBE, 0xCA, 0x71, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
410
{ 0xE4, 0x00, 0x9E, 0xAA, 0x3D, 0xE1, 0x43, 0x0F, 0xBA, 0x7E, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
411
{ 0xE7, 0x40, 0xEC, 0xCA, 0x44, 0xE2, 0x03, 0xBF, 0xBA, 0x66, 0x02, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
412
        // 0x60
 
413
{ 0xEA, 0x00, 0x68, 0xB8, 0x48, 0xE2, 0x0A, 0x8E, 0xB8, 0x7C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
414
{ 0x61, 0x00, 0xBE, 0x99, 0x7E, 0xE3, 0x40, 0xCF, 0xCA, 0x7D, 0x09, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
415
{ 0xCD, 0x00, 0x0B, 0x00, 0x48, 0xC2, 0x58, 0x0C, 0x00, 0x7C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x1C },
 
416
{ 0xE2, 0x00, 0x0E, 0x00, 0x52, 0xE2, 0x58, 0x5F, 0xD0, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
417
{ 0xCC, 0x00, 0x7D, 0xDA, 0x40, 0xC2, 0x00, 0x5E, 0x9B, 0x58, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
418
{ 0xE9, 0xC0, 0xEE, 0xD8, 0x43, 0xE2, 0x05, 0xDD, 0xAA, 0x70, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
419
{ 0xDA, 0x00, 0x8F, 0xAC, 0x4A, 0x22, 0x05, 0x8D, 0x8A, 0x75, 0x02, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
420
{ 0x62, 0x8A, 0xCB, 0x7A, 0x74, 0xE6, 0x56, 0xAF, 0xDB, 0x70, 0x02, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
421
{ 0xC2, 0x41, 0xAC, 0x5B, 0x5B, 0xC2, 0x80, 0x0D, 0xCB, 0x7D, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x12 },
 
422
{ 0x75, 0x00, 0x0E, 0xCB, 0x5A, 0xE2, 0x1E, 0x0A, 0xC9, 0x7D, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x10 },
 
423
{ 0x41, 0x00, 0x0E, 0xEA, 0x53, 0xC2, 0x00, 0x08, 0xCA, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x07 },
 
424
{ 0xC1, 0x40, 0x0C, 0x59, 0x6A, 0xC2, 0x80, 0x3C, 0xAB, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0D },
 
425
{ 0x4B, 0x00, 0x0A, 0xF5, 0x61, 0xC2, 0x19, 0x0C, 0xE9, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x07 },
 
426
{ 0x62, 0x00, 0x7F, 0xD8, 0x54, 0xEA, 0x00, 0x8F, 0xD8, 0x7D, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
427
{ 0xE1, 0x00, 0x7F, 0xD9, 0x56, 0xE1, 0x00, 0x8F, 0xD8, 0x7E, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
428
{ 0xE1, 0x00, 0x7F, 0xD9, 0x56, 0xE1, 0x00, 0x8F, 0xD8, 0x7E, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
429
        // 0x70
 
430
{ 0xCF, 0x40, 0x09, 0xEA, 0x54, 0xC4, 0x00, 0x0C, 0xDB, 0x64, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
431
{ 0xCF, 0x40, 0x0C, 0xAA, 0x54, 0xC4, 0x00, 0x18, 0xF9, 0x64, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
432
{ 0xC9, 0x0E, 0x88, 0xD9, 0x3E, 0xC2, 0x08, 0x1A, 0xEA, 0x6C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 },
 
433
{ 0x03, 0x00, 0x15, 0x00, 0x64, 0x02, 0x00, 0x08, 0x00, 0x7C, 0x09, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
434
{ 0x01, 0x00, 0x47, 0xD7, 0x6C, 0x01, 0x3F, 0x0C, 0xFB, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 },
 
435
{ 0x00, 0x00, 0x36, 0x67, 0x7C, 0x01, 0x3F, 0x0E, 0xFA, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 },
 
436
{ 0x02, 0x00, 0x36, 0x68, 0x7C, 0x01, 0x3F, 0x0E, 0xFA, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 },
 
437
{ 0xCB, 0x00, 0xAF, 0x00, 0x7E, 0xC0, 0x00, 0xC0, 0x06, 0x7F, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0F },
 
438
{ 0x05, 0x0D, 0x80, 0xA6, 0x7F, 0x0B, 0x38, 0xA9, 0xD8, 0x00, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 },
 
439
{ 0x0F, 0x00, 0x90, 0xFA, 0x68, 0x06, 0x00, 0xA7, 0x39, 0x54, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x06 },
 
440
{ 0xC9, 0x15, 0xDD, 0xFF, 0x7C, 0x00, 0x00, 0xE7, 0xFC, 0x6C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x38 },
 
441
{ 0x48, 0x3C, 0x30, 0xF6, 0x03, 0x0A, 0x38, 0x97, 0xE8, 0x00, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 },
 
442
{ 0x07, 0x80, 0x0B, 0xC8, 0x65, 0x02, 0x3F, 0x0C, 0xEA, 0x7C, 0x0F, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 },
 
443
{ 0x00, 0x21, 0x66, 0x40, 0x03, 0x00, 0x3F, 0x47, 0x00, 0x00, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
444
{ 0x08, 0x00, 0x0B, 0x3C, 0x7C, 0x08, 0x3F, 0x06, 0xF3, 0x00, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
445
{ 0x00, 0x3F, 0x4C, 0xFB, 0x00, 0x00, 0x3F, 0x0A, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 }
 
446
};
 
447
 
 
448
static byte gm_percussion_to_fm[39][30] = {
 
449
{ 0x1A, 0x3F, 0x15, 0x05, 0x7C, 0x02, 0x21, 0x2B, 0xE4, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x06 },
 
450
{ 0x11, 0x12, 0x04, 0x07, 0x7C, 0x02, 0x23, 0x0B, 0xE5, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 },
 
451
{ 0x0A, 0x3F, 0x0B, 0x01, 0x7C, 0x1F, 0x1C, 0x46, 0xD0, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x01 },
 
452
{ 0x00, 0x3F, 0x0F, 0x00, 0x7C, 0x10, 0x12, 0x07, 0x00, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
453
{ 0x0F, 0x3F, 0x0B, 0x00, 0x7C, 0x1F, 0x0F, 0x19, 0xD0, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
454
{ 0x00, 0x3F, 0x1F, 0x00, 0x7E, 0x1F, 0x16, 0x07, 0x00, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 },
 
455
{ 0x12, 0x3F, 0x05, 0x06, 0x7C, 0x03, 0x1F, 0x4A, 0xD9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 },
 
456
{ 0xCF, 0x7F, 0x08, 0xFF, 0x7E, 0x00, 0xC7, 0x2D, 0xF7, 0x73, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
457
{ 0x12, 0x3F, 0x05, 0x06, 0x7C, 0x43, 0x21, 0x0C, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 },
 
458
{ 0xCF, 0x7F, 0x08, 0xCF, 0x7E, 0x00, 0x45, 0x2A, 0xF8, 0x4B, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0C },
 
459
{ 0x12, 0x3F, 0x06, 0x17, 0x7C, 0x03, 0x27, 0x0B, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 },
 
460
{ 0xCF, 0x7F, 0x08, 0xCD, 0x7E, 0x00, 0x40, 0x1A, 0x69, 0x63, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0C },
 
461
{ 0x13, 0x3F, 0x05, 0x06, 0x7C, 0x03, 0x17, 0x0A, 0xD9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 },
 
462
{ 0x15, 0x3F, 0x05, 0x06, 0x7C, 0x03, 0x21, 0x0C, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 },
 
463
{ 0xCF, 0x3F, 0x2B, 0xFB, 0x7E, 0xC0, 0x1E, 0x1A, 0xCA, 0x7F, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x10 },
 
464
{ 0x17, 0x3F, 0x04, 0x09, 0x7C, 0x03, 0x22, 0x0D, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 },
 
465
{ 0xCF, 0x3F, 0x0F, 0x5E, 0x7C, 0xC6, 0x13, 0x00, 0xCA, 0x7F, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 },
 
466
{ 0xCF, 0x3F, 0x7E, 0x9D, 0x7C, 0xC8, 0xC0, 0x0A, 0xBA, 0x74, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x06 },
 
467
{ 0xCF, 0x3F, 0x4D, 0x9F, 0x7C, 0xC6, 0x00, 0x08, 0xDA, 0x5B, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 },
 
468
{ 0xCF, 0x3F, 0x5D, 0xAA, 0x7A, 0xC0, 0xA4, 0x67, 0x99, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
469
{ 0xCF, 0x3F, 0x4A, 0xFD, 0x7C, 0xCF, 0x00, 0x59, 0xEA, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
470
{ 0x0F, 0x18, 0x0A, 0xFA, 0x57, 0x06, 0x07, 0x06, 0x39, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
471
{ 0xCF, 0x3F, 0x2B, 0xFC, 0x7C, 0xCC, 0xC6, 0x0B, 0xEA, 0x7F, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x10 },
 
472
{ 0x05, 0x1A, 0x04, 0x00, 0x7C, 0x12, 0x10, 0x0C, 0xEA, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x07 },
 
473
{ 0x04, 0x19, 0x04, 0x00, 0x7C, 0x12, 0x10, 0x2C, 0xEA, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 },
 
474
{ 0x04, 0x0A, 0x04, 0x00, 0x6C, 0x01, 0x07, 0x0D, 0xFA, 0x74, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x07 },
 
475
{ 0x15, 0x14, 0x05, 0x00, 0x7D, 0x01, 0x07, 0x5C, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 },
 
476
{ 0x10, 0x10, 0x05, 0x08, 0x7C, 0x01, 0x08, 0x0D, 0xEA, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 },
 
477
{ 0x11, 0x00, 0x06, 0x87, 0x7F, 0x02, 0x40, 0x09, 0x59, 0x68, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x08 },
 
478
{ 0x13, 0x26, 0x04, 0x6A, 0x7F, 0x01, 0x00, 0x08, 0x5A, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x08 },
 
479
{ 0xCF, 0x4E, 0x0C, 0xAA, 0x50, 0xC4, 0x00, 0x18, 0xF9, 0x54, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
480
{ 0xCF, 0x4E, 0x0C, 0xAA, 0x50, 0xC3, 0x00, 0x18, 0xF8, 0x54, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
481
{ 0xCB, 0x3F, 0x8F, 0x00, 0x7E, 0xC5, 0x00, 0x98, 0xD6, 0x5F, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0D },
 
482
{ 0x0C, 0x18, 0x87, 0xB3, 0x7F, 0x19, 0x10, 0x55, 0x75, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
483
{ 0x05, 0x11, 0x15, 0x00, 0x64, 0x02, 0x08, 0x08, 0x00, 0x5C, 0x09, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
484
{ 0x04, 0x08, 0x15, 0x00, 0x48, 0x01, 0x08, 0x08, 0x00, 0x60, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 },
 
485
{ 0xDA, 0x00, 0x53, 0x30, 0x68, 0x07, 0x1E, 0x49, 0xC4, 0x7E, 0x03, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 },
 
486
{ 0x1C, 0x00, 0x07, 0xBC, 0x6C, 0x0C, 0x14, 0x0B, 0x6A, 0x7E, 0x0B, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 },
 
487
{ 0x0A, 0x0E, 0x7F, 0x00, 0x7D, 0x13, 0x20, 0x28, 0x03, 0x7C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }
 
488
};
 
489
 
 
490
static const byte gm_percussion_lookup[128] = {
 
491
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 
492
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 
493
        0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
 
494
        0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0xFF, 0xFF, 0x17, 0x18, 0x19, 0x1A,
 
495
        0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x21, 0x22, 0x23, 0xFF, 0xFF,
 
496
        0x24, 0x25, 0xFF, 0xFF, 0xFF, 0x26, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 
497
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 
498
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 
499
};
 
500
 
 
501
static byte lookup_table[64][32];
 
502
 
 
503
static const byte volume_table[] = {
 
504
        0, 4, 7, 11,
 
505
        13, 16, 18, 20,
 
506
        22, 24, 26, 27,
 
507
        29, 30, 31, 33,
 
508
        34, 35, 36, 37,
 
509
        38, 39, 40, 41,
 
510
        42, 43, 44, 44,
 
511
        45, 46, 47, 47,
 
512
        48, 49, 49, 50,
 
513
        51, 51, 52, 53,
 
514
        53, 54, 54, 55,
 
515
        55, 56, 56, 57,
 
516
        57, 58, 58, 59,
 
517
        59, 60, 60, 60,
 
518
        61, 61, 62, 62,
 
519
        62, 63, 63, 63
 
520
};
 
521
 
 
522
static int lookup_volume(int a, int b) {
 
523
        if (b == 0)
 
524
                return 0;
 
525
 
 
526
        if (b == 31)
 
527
                return a;
 
528
 
 
529
        if (a < -63 || a > 63) {
 
530
                return b * (a + 1) >> 5;
 
531
        }
 
532
 
 
533
        if (b < 0) {
 
534
                if (a < 0) {
 
535
                        return lookup_table[-a][-b];
 
536
                } else {
 
537
                        return -lookup_table[a][-b];
 
538
                }
 
539
        } else {
 
540
                if (a < 0) {
 
541
                        return -lookup_table[-a][b];
 
542
                } else {
 
543
                        return lookup_table[a][b];
 
544
                }
 
545
        }
 
546
}
 
547
 
 
548
static void create_lookup_table() {
 
549
        int i, j;
 
550
        int sum;
 
551
 
 
552
        for (i = 0; i < 64; i++) {
 
553
                sum = i;
 
554
                for (j = 0; j < 32; j++) {
 
555
                        lookup_table[i][j] = sum >> 5;
 
556
                        sum += i;
 
557
                }
 
558
        }
 
559
        for (i = 0; i < 64; i++)
 
560
                lookup_table[i][0] = 0;
 
561
}
 
562
 
 
563
////////////////////////////////////////
 
564
//
 
565
// AdLib MIDI driver
 
566
//
 
567
////////////////////////////////////////
 
568
 
 
569
class MidiDriver_ADLIB : public MidiDriver_Emulated {
 
570
        friend class AdLibPart;
 
571
        friend class AdLibPercussionChannel;
 
572
 
 
573
public:
 
574
        MidiDriver_ADLIB(Audio::Mixer *mixer);
 
575
 
 
576
        int open();
 
577
        void close();
 
578
        void send(uint32 b);
 
579
        void send(byte channel, uint32 b); // Supports higher than channel 15
 
580
        uint32 property(int prop, uint32 param);
 
581
 
 
582
        void setPitchBendRange(byte channel, uint range);
 
583
        void sysEx_customInstrument(byte channel, uint32 type, const byte *instr);
 
584
 
 
585
        MidiChannel *allocateChannel();
 
586
        MidiChannel *getPercussionChannel() { return &_percussion; } // Percussion partially supported
 
587
 
 
588
 
 
589
        // AudioStream API
 
590
        bool isStereo() const { return false; }
 
591
        int getRate() const { return _mixer->getOutputRate(); }
 
592
 
 
593
private:
 
594
        bool _scummSmallHeader; // FIXME: This flag controls a special mode for SCUMM V3 games
 
595
 
 
596
        FM_OPL *_opl;
 
597
        byte *_adlib_reg_cache;
 
598
 
 
599
        int _adlib_timer_counter;
 
600
 
 
601
        uint16 channel_table_2[9];
 
602
        int _voice_index;
 
603
        int _timer_p;
 
604
        int _timer_q;
 
605
        uint16 curnote_table[9];
 
606
        AdLibVoice _voices[9];
 
607
        AdLibPart _parts[32];
 
608
        AdLibPercussionChannel _percussion;
 
609
 
 
610
        void generateSamples(int16 *buf, int len);
 
611
        void onTimer();
 
612
        void part_key_on(AdLibPart *part, AdLibInstrument *instr, byte note, byte velocity);
 
613
        void part_key_off(AdLibPart *part, byte note);
 
614
 
 
615
        void adlib_key_off(int chan);
 
616
        void adlib_note_on(int chan, byte note, int mod);
 
617
        void adlib_note_on_ex(int chan, byte note, int mod);
 
618
        int adlib_get_reg_value_param(int chan, byte data);
 
619
        void adlib_setup_channel(int chan, AdLibInstrument * instr, byte vol_1, byte vol_2);
 
620
        byte adlib_get_reg_value(byte reg) {
 
621
                return _adlib_reg_cache[reg];
 
622
        }
 
623
        void adlib_set_param(int channel, byte param, int value);
 
624
        void adlib_key_onoff(int channel);
 
625
        void adlib_write(byte reg, byte value);
 
626
        void adlib_playnote(int channel, int note);
 
627
 
 
628
        AdLibVoice *allocate_voice(byte pri);
 
629
 
 
630
        void mc_off(AdLibVoice * voice);
 
631
 
 
632
        static void link_mc(AdLibPart *part, AdLibVoice *voice);
 
633
        void mc_inc_stuff(AdLibVoice *voice, Struct10 * s10, Struct11 * s11);
 
634
        void mc_init_stuff(AdLibVoice *voice, Struct10 * s10, Struct11 * s11, byte flags,
 
635
                                                InstrumentExtra * ie);
 
636
 
 
637
        void struct10_init(Struct10 * s10, InstrumentExtra * ie);
 
638
        static byte struct10_ontimer(Struct10 * s10, Struct11 * s11);
 
639
        static void struct10_setup(Struct10 * s10);
 
640
        static int random_nr(int a);
 
641
        void mc_key_on(AdLibVoice *voice, AdLibInstrument *instr, byte note, byte velocity);
 
642
};
 
643
 
 
644
// MidiChannel method implementations
 
645
 
 
646
void AdLibPart::init(MidiDriver_ADLIB *owner, byte channel) {
 
647
        _owner = owner;
 
648
        _channel = channel;
 
649
        _pri_eff = 127;
 
650
        programChange(0);
 
651
}
 
652
 
 
653
MidiDriver *AdLibPart::device() {
 
654
        return _owner;
 
655
}
 
656
 
 
657
void AdLibPart::send(uint32 b) {
 
658
        _owner->send(_channel, b);
 
659
}
 
660
 
 
661
void AdLibPart::noteOff(byte note) {
 
662
#ifdef DEBUG_ADLIB
 
663
        debug(6, "%10d: noteOff(%d)", tick, note);
 
664
#endif
 
665
        _owner->part_key_off(this, note);
 
666
}
 
667
 
 
668
void AdLibPart::noteOn(byte note, byte velocity) {
 
669
#ifdef DEBUG_ADLIB
 
670
        debug(6, "%10d: noteOn(%d,%d)", tick, note, velocity);
 
671
#endif
 
672
        _owner->part_key_on(this, &_part_instr, note, velocity);
 
673
}
 
674
 
 
675
void AdLibPart::programChange(byte program) {
 
676
        if (program > 127)
 
677
                return;
 
678
 
 
679
        uint i;
 
680
        uint count = 0;
 
681
        for (i = 0; i < ARRAYSIZE(map_gm_to_fm[0]); ++i)
 
682
                count += map_gm_to_fm[program][i];
 
683
        if (!count)
 
684
                warning("No AdLib instrument defined for GM program %d", (int) program);
 
685
        _program = program;
 
686
        memcpy(&_part_instr, &map_gm_to_fm[program], sizeof(AdLibInstrument));
 
687
}
 
688
 
 
689
void AdLibPart::pitchBend(int16 bend) {
 
690
        AdLibVoice *voice;
 
691
 
 
692
        _pitchbend = bend;
 
693
        for (voice = _voice; voice; voice = voice->_next) {
 
694
                _owner->adlib_note_on(voice->_channel, voice->_note + _transpose_eff,
 
695
                                                (_pitchbend * _pitchbend_factor >> 6) + _detune_eff);
 
696
        }
 
697
}
 
698
 
 
699
void AdLibPart::controlChange(byte control, byte value) {
 
700
        switch (control) {
 
701
        case 0:
 
702
        case 32:
 
703
                break; // Bank select. Not supported
 
704
        case 1:   modulationWheel(value); break;
 
705
        case 7:   volume(value); break;
 
706
        case 10:  break; // Pan position. Not supported.
 
707
        case 16:  pitchBendFactor(value); break;
 
708
        case 17:  detune(value); break;
 
709
        case 18:  priority(value); break;
 
710
        case 64:  sustain(value > 0); break;
 
711
        case 91:  break; // Effects level. Not supported.
 
712
        case 93:  break; // Chorus level. Not supported.
 
713
        case 119: break; // Unknown, used in Simon the Sorcerer 2
 
714
        case 121: // reset all controllers
 
715
                modulationWheel(0);
 
716
                pitchBendFactor(0);
 
717
                detune(0);
 
718
                sustain(0);
 
719
                break;
 
720
        case 123: allNotesOff(); break;
 
721
        default:
 
722
                warning("AdLib: Unknown control change message %d (%d)", (int) control, (int)value);
 
723
        }
 
724
}
 
725
 
 
726
void AdLibPart::modulationWheel(byte value) {
 
727
        AdLibVoice *voice;
 
728
 
 
729
        _modwheel = value;
 
730
        for (voice = _voice; voice; voice = voice->_next) {
 
731
                if (voice->_s10a.active && voice->_s11a.flag0x40)
 
732
                        voice->_s10a.modwheel = _modwheel >> 2;
 
733
                if (voice->_s10b.active && voice->_s11b.flag0x40)
 
734
                        voice->_s10b.modwheel = _modwheel >> 2;
 
735
        }
 
736
}
 
737
 
 
738
void AdLibPart::volume(byte value) {
 
739
        AdLibVoice *voice;
 
740
 
 
741
        _vol_eff = value;
 
742
        for (voice = _voice; voice; voice = voice->_next) {
 
743
                _owner->adlib_set_param(voice->_channel, 0, volume_table[lookup_table[voice->_vol_2][_vol_eff >> 2]]);
 
744
                if (voice->_twochan) {
 
745
                        _owner->adlib_set_param(voice->_channel, 13, volume_table[lookup_table[voice->_vol_1][_vol_eff >> 2]]);
 
746
                }
 
747
        }
 
748
}
 
749
 
 
750
void AdLibPart::pitchBendFactor(byte value) {
 
751
        AdLibVoice *voice;
 
752
 
 
753
        _pitchbend_factor = value;
 
754
        for (voice = _voice; voice; voice = voice->_next) {
 
755
                _owner->adlib_note_on(voice->_channel, voice->_note + _transpose_eff,
 
756
                                                        (_pitchbend * _pitchbend_factor >> 6) + _detune_eff);
 
757
        }
 
758
}
 
759
 
 
760
void AdLibPart::detune(byte value) {
 
761
        AdLibVoice *voice;
 
762
 
 
763
        _detune_eff = value;
 
764
        for (voice = _voice; voice; voice = voice->_next) {
 
765
                _owner->adlib_note_on(voice->_channel, voice->_note + _transpose_eff,
 
766
                                                (_pitchbend * _pitchbend_factor >> 6) + _detune_eff);
 
767
        }
 
768
}
 
769
 
 
770
void AdLibPart::priority(byte value) {
 
771
        _pri_eff = value;
 
772
}
 
773
 
 
774
void AdLibPart::sustain(bool value) {
 
775
        AdLibVoice *voice;
 
776
 
 
777
        _pedal = value;
 
778
        if (!value) {
 
779
                for (voice = _voice; voice; voice = voice->_next) {
 
780
                        if (voice->_waitforpedal)
 
781
                                _owner->mc_off(voice);
 
782
                }
 
783
        }
 
784
}
 
785
 
 
786
void AdLibPart::allNotesOff() {
 
787
        while (_voice)
 
788
                _owner->mc_off(_voice);
 
789
}
 
790
 
 
791
void AdLibPart::sysEx_customInstrument(uint32 type, const byte *instr) {
 
792
        if (type == 'ADL ') {
 
793
                AdLibInstrument *i = &_part_instr;
 
794
                memcpy(i, instr, sizeof(AdLibInstrument));
 
795
        }
 
796
}
 
797
 
 
798
// MidiChannel method implementations for percussion
 
799
 
 
800
AdLibPercussionChannel::~AdLibPercussionChannel() {
 
801
        for (int i = 0; i < ARRAYSIZE(_customInstruments); ++i) {
 
802
                delete _customInstruments[i];
 
803
        }
 
804
}
 
805
 
 
806
void AdLibPercussionChannel::init(MidiDriver_ADLIB *owner, byte channel) {
 
807
        AdLibPart::init(owner, channel);
 
808
        _pri_eff = 0;
 
809
        _vol_eff = 127;
 
810
 
 
811
        // Initialize the custom instruments data
 
812
        memset(_notes, 0, sizeof(_notes));
 
813
        memset(_customInstruments, 0, sizeof(_customInstruments));
 
814
}
 
815
 
 
816
void AdLibPercussionChannel::noteOff(byte note) {
 
817
        // Jamieson630: Unless I run into a specific instrument that
 
818
        // may require a key off, I'm going to ignore this message.
 
819
        // The rationale is that a percussion instrument should
 
820
        // fade out of its own accord, and the AdLib instrument
 
821
        // definitions used should follow this rule. Since
 
822
        // percussion voices are allocated at the lowest priority
 
823
        // anyway, we know that "hanging" percussion sounds will
 
824
        // not prevent later musical instruments (or even other
 
825
        // percussion sounds) from playing.
 
826
/*
 
827
        _owner->part_key_off(this, note);
 
828
*/
 
829
}
 
830
 
 
831
void AdLibPercussionChannel::noteOn(byte note, byte velocity) {
 
832
        AdLibInstrument *inst = NULL;
 
833
 
 
834
        // The custom instruments have priority over the default mapping
 
835
        inst = _customInstruments[note];
 
836
        if (inst)
 
837
                note = _notes[note];
 
838
 
 
839
        if (!inst) {
 
840
                // Use the default GM to FM mapping as a fallback as a fallback
 
841
                byte key = gm_percussion_lookup[note];
 
842
                if (key != 0xFF)
 
843
                        inst = (AdLibInstrument *)&gm_percussion_to_fm[key];
 
844
        }
 
845
 
 
846
        if (!inst) {
 
847
                debug(2, "No instrument FM definition for GM percussion key %d", (int)note);
 
848
                return;
 
849
        }
 
850
 
 
851
        _owner->part_key_on(this, inst, note, velocity);
 
852
}
 
853
 
 
854
void AdLibPercussionChannel::sysEx_customInstrument(uint32 type, const byte *instr) {
 
855
        if (type == 'ADLP') {
 
856
                byte note = instr[0];
 
857
                _notes[note] = instr[1];
 
858
 
 
859
                // Allocate memory for the new instruments
 
860
                if (!_customInstruments[note]) {
 
861
                        _customInstruments[note] = new AdLibInstrument;
 
862
                }
 
863
 
 
864
                // Save the new instrument data
 
865
                _customInstruments[note]->mod_characteristic     = instr[2];
 
866
                _customInstruments[note]->mod_scalingOutputLevel = instr[3];
 
867
                _customInstruments[note]->mod_attackDecay        = instr[4];
 
868
                _customInstruments[note]->mod_sustainRelease     = instr[5];
 
869
                _customInstruments[note]->mod_waveformSelect     = instr[6];
 
870
                _customInstruments[note]->car_characteristic     = instr[7];
 
871
                _customInstruments[note]->car_scalingOutputLevel = instr[8];
 
872
                _customInstruments[note]->car_attackDecay        = instr[9];
 
873
                _customInstruments[note]->car_sustainRelease     = instr[10];
 
874
                _customInstruments[note]->car_waveformSelect     = instr[11];
 
875
                _customInstruments[note]->feedback               = instr[12];
 
876
        }
 
877
}
 
878
 
 
879
// MidiDriver method implementations
 
880
 
 
881
MidiDriver_ADLIB::MidiDriver_ADLIB(Audio::Mixer *mixer)
 
882
        : MidiDriver_Emulated(mixer) {
 
883
        uint i;
 
884
 
 
885
        _scummSmallHeader = false;
 
886
 
 
887
        _adlib_reg_cache = 0;
 
888
 
 
889
        _adlib_timer_counter = 0;
 
890
        _voice_index = 0;
 
891
        for (i = 0; i < ARRAYSIZE(curnote_table); ++i) {
 
892
                curnote_table[i] = 0;
 
893
        }
 
894
 
 
895
        for (i = 0; i < ARRAYSIZE(_parts); ++i) {
 
896
                _parts[i].init(this, i + ((i >= 9) ? 1 : 0));
 
897
        }
 
898
        _percussion.init(this, 9);
 
899
        _timer_p = 0xD69;
 
900
        _timer_q = 0x411B;
 
901
}
 
902
 
 
903
int MidiDriver_ADLIB::open() {
 
904
        if (_isOpen)
 
905
                return MERR_ALREADY_OPEN;
 
906
 
 
907
        MidiDriver_Emulated::open();
 
908
 
 
909
        int i;
 
910
        AdLibVoice *voice;
 
911
 
 
912
        for (i = 0, voice = _voices; i != ARRAYSIZE(_voices); i++, voice++) {
 
913
                voice->_channel = i;
 
914
                voice->_s11a.s10 = &voice->_s10b;
 
915
                voice->_s11b.s10 = &voice->_s10a;
 
916
        }
 
917
 
 
918
        _adlib_reg_cache = (byte *)calloc(256, 1);
 
919
 
 
920
        _opl = makeAdLibOPL(getRate());
 
921
 
 
922
        adlib_write(1, 0x20);
 
923
        adlib_write(8, 0x40);
 
924
        adlib_write(0xBD, 0x00);
 
925
        create_lookup_table();
 
926
 
 
927
        _mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
 
928
 
 
929
        return 0;
 
930
}
 
931
 
 
932
void MidiDriver_ADLIB::close() {
 
933
        if (!_isOpen)
 
934
                return;
 
935
        _isOpen = false;
 
936
 
 
937
        _mixer->stopHandle(_mixerSoundHandle);
 
938
 
 
939
        uint i;
 
940
        for (i = 0; i < ARRAYSIZE(_voices); ++i) {
 
941
                if (_voices[i]._part)
 
942
                        mc_off(&_voices[i]);
 
943
        }
 
944
 
 
945
        // Turn off the OPL emulation
 
946
        OPLDestroy(_opl);
 
947
//      YM3812Shutdown();
 
948
 
 
949
        free(_adlib_reg_cache);
 
950
}
 
951
 
 
952
void MidiDriver_ADLIB::send(uint32 b) {
 
953
        send(b & 0xF, b & 0xFFFFFFF0);
 
954
}
 
955
 
 
956
void MidiDriver_ADLIB::send(byte chan, uint32 b) {
 
957
        //byte param3 = (byte) ((b >> 24) & 0xFF);
 
958
        byte param2 = (byte) ((b >> 16) & 0xFF);
 
959
        byte param1 = (byte) ((b >>  8) & 0xFF);
 
960
        byte cmd    = (byte) (b & 0xF0);
 
961
 
 
962
        AdLibPart *part;
 
963
        if (chan == 9)
 
964
                part = &_percussion;
 
965
        else
 
966
                part = &_parts[chan];
 
967
 
 
968
        switch (cmd) {
 
969
        case 0x80:// Note Off
 
970
                part->noteOff(param1);
 
971
                break;
 
972
        case 0x90: // Note On
 
973
                part->noteOn(param1, param2);
 
974
                break;
 
975
        case 0xA0: // Aftertouch
 
976
                break; // Not supported.
 
977
        case 0xB0: // Control Change
 
978
                part->controlChange(param1, param2);
 
979
                break;
 
980
        case 0xC0: // Program Change
 
981
                part->programChange(param1);
 
982
                break;
 
983
        case 0xD0: // Channel Pressure
 
984
                break; // Not supported.
 
985
        case 0xE0: // Pitch Bend
 
986
                part->pitchBend((param1 | (param2 << 7)) - 0x2000);
 
987
                break;
 
988
        case 0xF0: // SysEx
 
989
                // We should never get here! SysEx information has to be
 
990
                // sent via high-level semantic methods.
 
991
                warning("MidiDriver_ADLIB: Receiving SysEx command on a send() call");
 
992
                break;
 
993
 
 
994
        default:
 
995
                warning("MidiDriver_ADLIB: Unknown send() command 0x%02X", cmd);
 
996
        }
 
997
}
 
998
 
 
999
uint32 MidiDriver_ADLIB::property(int prop, uint32 param) {
 
1000
        switch (prop) {
 
1001
                case PROP_OLD_ADLIB: // Older games used a different operator volume algorithm
 
1002
                        _scummSmallHeader = (param > 0);
 
1003
                        if (_scummSmallHeader) {
 
1004
                                _timer_p = 473;
 
1005
                                _timer_q = 1000;
 
1006
                        } else {
 
1007
                                _timer_p = 0xD69;
 
1008
                                _timer_q = 0x411B;
 
1009
                        }
 
1010
                        return 1;
 
1011
        }
 
1012
 
 
1013
        return 0;
 
1014
}
 
1015
 
 
1016
void MidiDriver_ADLIB::setPitchBendRange(byte channel, uint range) {
 
1017
        AdLibVoice *voice;
 
1018
        AdLibPart *part = &_parts[channel];
 
1019
 
 
1020
        part->_pitchbend_factor = range;
 
1021
        for (voice = part->_voice; voice; voice = voice->_next) {
 
1022
                adlib_note_on(voice->_channel, voice->_note + part->_transpose_eff,
 
1023
                                        (part->_pitchbend * part->_pitchbend_factor >> 6) + part->_detune_eff);
 
1024
        }
 
1025
}
 
1026
 
 
1027
void MidiDriver_ADLIB::sysEx_customInstrument(byte channel, uint32 type, const byte *instr) {
 
1028
        _parts[channel].sysEx_customInstrument(type, instr);
 
1029
}
 
1030
 
 
1031
MidiChannel *MidiDriver_ADLIB::allocateChannel() {
 
1032
        AdLibPart *part;
 
1033
        uint i;
 
1034
 
 
1035
        for (i = 0; i < ARRAYSIZE(_parts); ++i) {
 
1036
                part = &_parts[i];
 
1037
                if (!part->_allocated) {
 
1038
                        part->allocate();
 
1039
                        return part;
 
1040
                }
 
1041
        }
 
1042
        return NULL;
 
1043
}
 
1044
 
 
1045
// All the code brought over from IMuseAdLib
 
1046
 
 
1047
void MidiDriver_ADLIB::adlib_write(byte reg, byte value) {
 
1048
        if (_adlib_reg_cache[reg] == value)
 
1049
                return;
 
1050
#ifdef DEBUG_ADLIB
 
1051
        debug(6, "%10d: adlib_write[%x] = %x", tick, reg, value);
 
1052
#endif
 
1053
        _adlib_reg_cache[reg] = value;
 
1054
 
 
1055
        OPLWriteReg(_opl, reg, value);
 
1056
}
 
1057
 
 
1058
void MidiDriver_ADLIB::generateSamples(int16 *data, int len) {
 
1059
        memset(data, 0, sizeof(int16) * len);
 
1060
        YM3812UpdateOne(_opl, data, len);
 
1061
}
 
1062
 
 
1063
void MidiDriver_ADLIB::onTimer() {
 
1064
        AdLibVoice *voice;
 
1065
        int i;
 
1066
 
 
1067
        _adlib_timer_counter += _timer_p;
 
1068
        while (_adlib_timer_counter >= _timer_q) {
 
1069
                _adlib_timer_counter -= _timer_q;
 
1070
#ifdef DEBUG_ADLIB
 
1071
                tick++;
 
1072
#endif
 
1073
                voice = _voices;
 
1074
                for (i = 0; i != ARRAYSIZE(_voices); i++, voice++) {
 
1075
                        if (!voice->_part)
 
1076
                                continue;
 
1077
                        if (voice->_duration && (voice->_duration -= 0x11) <= 0) {
 
1078
                                mc_off(voice);
 
1079
                                return;
 
1080
                        }
 
1081
                        if (voice->_s10a.active) {
 
1082
                                mc_inc_stuff(voice, &voice->_s10a, &voice->_s11a);
 
1083
                        }
 
1084
                        if (voice->_s10b.active) {
 
1085
                                mc_inc_stuff(voice, &voice->_s10b, &voice->_s11b);
 
1086
                        }
 
1087
                }
 
1088
        }
 
1089
}
 
1090
 
 
1091
void MidiDriver_ADLIB::mc_off(AdLibVoice *voice) {
 
1092
        AdLibVoice *tmp;
 
1093
 
 
1094
        adlib_key_off(voice->_channel);
 
1095
 
 
1096
        tmp = voice->_prev;
 
1097
 
 
1098
        if (voice->_next)
 
1099
                voice->_next->_prev = tmp;
 
1100
        if (tmp)
 
1101
                tmp->_next = voice->_next;
 
1102
        else
 
1103
                voice->_part->_voice = voice->_next;
 
1104
        voice->_part = NULL;
 
1105
}
 
1106
 
 
1107
void MidiDriver_ADLIB::mc_inc_stuff(AdLibVoice *voice, Struct10 *s10, Struct11 *s11) {
 
1108
        byte code;
 
1109
        AdLibPart *part = voice->_part;
 
1110
 
 
1111
        code = struct10_ontimer(s10, s11);
 
1112
 
 
1113
        if (code & 1) {
 
1114
                switch (s11->param) {
 
1115
                case 0:
 
1116
                        voice->_vol_2 = s10->start_value + s11->modify_val;
 
1117
                        if (!_scummSmallHeader) {
 
1118
                                adlib_set_param(voice->_channel, 0,
 
1119
                                                                                                volume_table[lookup_table[voice->_vol_2]
 
1120
                                                                                                                                                 [part->_vol_eff >> 2]]);
 
1121
                        } else {
 
1122
                                adlib_set_param(voice->_channel, 0, voice->_vol_2);
 
1123
                        }
 
1124
                        break;
 
1125
                case 13:
 
1126
                        voice->_vol_1 = s10->start_value + s11->modify_val;
 
1127
                        if (voice->_twochan && !_scummSmallHeader) {
 
1128
                                adlib_set_param(voice->_channel, 13,
 
1129
                                                                                                volume_table[lookup_table[voice->_vol_1]
 
1130
                                                                                                [part->_vol_eff >> 2]]);
 
1131
                        } else {
 
1132
                                adlib_set_param(voice->_channel, 13, voice->_vol_1);
 
1133
                        }
 
1134
                        break;
 
1135
                case 30:
 
1136
                        s11->s10->modwheel = (char)s11->modify_val;
 
1137
                        break;
 
1138
                case 31:
 
1139
                        s11->s10->unk3 = (char)s11->modify_val;
 
1140
                        break;
 
1141
                default:
 
1142
                        adlib_set_param(voice->_channel, s11->param,
 
1143
                                                        s10->start_value + s11->modify_val);
 
1144
                        break;
 
1145
                }
 
1146
        }
 
1147
 
 
1148
        if (code & 2 && s11->flag0x10)
 
1149
                adlib_key_onoff(voice->_channel);
 
1150
}
 
1151
 
 
1152
void MidiDriver_ADLIB::adlib_key_off(int chan){
 
1153
        byte reg = chan + 0xB0;
 
1154
        adlib_write(reg, adlib_get_reg_value(reg) & ~0x20);
 
1155
}
 
1156
 
 
1157
byte MidiDriver_ADLIB::struct10_ontimer(Struct10 *s10, Struct11 *s11) {
 
1158
        byte result = 0;
 
1159
        int i;
 
1160
 
 
1161
        if (s10->count && (s10->count -= 17) <= 0) {
 
1162
                s10->active = 0;
 
1163
                return 0;
 
1164
        }
 
1165
 
 
1166
        i = s10->cur_val + s10->speed_hi;
 
1167
        s10->speed_lo_counter += s10->speed_lo;
 
1168
        if (s10->speed_lo_counter >= s10->speed_lo_max) {
 
1169
                s10->speed_lo_counter -= s10->speed_lo_max;
 
1170
                i += s10->direction;
 
1171
        }
 
1172
        if (s10->cur_val != i || s10->modwheel != s10->modwheel_last) {
 
1173
                s10->cur_val = i;
 
1174
                s10->modwheel_last = s10->modwheel;
 
1175
                i = lookup_volume(i, s10->modwheel_last);
 
1176
                if (i != s11->modify_val) {
 
1177
                        s11->modify_val = i;
 
1178
                        result = 1;
 
1179
                }
 
1180
        }
 
1181
 
 
1182
        if (!--s10->num_steps) {
 
1183
                s10->active++;
 
1184
                if (s10->active > 4) {
 
1185
                        if (s10->loop) {
 
1186
                                s10->active = 1;
 
1187
                                result |= 2;
 
1188
                                struct10_setup(s10);
 
1189
                        } else {
 
1190
                                s10->active = 0;
 
1191
                        }
 
1192
                } else {
 
1193
                        struct10_setup(s10);
 
1194
                }
 
1195
        }
 
1196
 
 
1197
        return result;
 
1198
}
 
1199
 
 
1200
void MidiDriver_ADLIB::adlib_set_param(int channel, byte param, int value) {
 
1201
        const AdLibSetParams *as;
 
1202
        byte reg;
 
1203
 
 
1204
        assert(channel >= 0 && channel < 9);
 
1205
 
 
1206
        if (param <= 12) {
 
1207
                reg = channel_mappings_2[channel];
 
1208
        } else if (param <= 25) {
 
1209
                param -= 13;
 
1210
                reg = channel_mappings[channel];
 
1211
        } else if (param <= 27) {
 
1212
                param -= 13;
 
1213
                reg = channel;
 
1214
        } else if (param == 28 || param == 29) {
 
1215
                if (param == 28)
 
1216
                        value -= 15;
 
1217
                else
 
1218
                        value -= 383;
 
1219
                value <<= 4;
 
1220
                channel_table_2[channel] = value;
 
1221
                adlib_playnote(channel, curnote_table[channel] + value);
 
1222
                return;
 
1223
        } else {
 
1224
                return;
 
1225
        }
 
1226
 
 
1227
        as = &adlib_setparam_table[param];
 
1228
        if (as->d)
 
1229
                value = as->d - value;
 
1230
        reg += as->a;
 
1231
        adlib_write(reg, (adlib_get_reg_value(reg) & ~as->c) | (((byte)value) << as->b));
 
1232
}
 
1233
 
 
1234
void MidiDriver_ADLIB::adlib_key_onoff(int channel) {
 
1235
        byte val;
 
1236
        byte reg = channel + 0xB0;
 
1237
        assert(channel >= 0 && channel < 9);
 
1238
 
 
1239
        val = adlib_get_reg_value(reg);
 
1240
        adlib_write(reg, val & ~0x20);
 
1241
        adlib_write(reg, val | 0x20);
 
1242
}
 
1243
 
 
1244
void MidiDriver_ADLIB::struct10_setup(Struct10 *s10) {
 
1245
        int b, c, d, e, f, g, h;
 
1246
        byte t;
 
1247
 
 
1248
        b = s10->unk3;
 
1249
        f = s10->active - 1;
 
1250
 
 
1251
        t = s10->table_a[f];
 
1252
        e = num_steps_table[lookup_table[t & 0x7F][b]];
 
1253
        if (t & 0x80) {
 
1254
                e = random_nr(e);
 
1255
        }
 
1256
        if (e == 0)
 
1257
                e++;
 
1258
 
 
1259
        s10->num_steps = s10->speed_lo_max = e;
 
1260
 
 
1261
        if (f != 2) {
 
1262
                c = s10->max_value;
 
1263
                g = s10->start_value;
 
1264
                t = s10->table_b[f];
 
1265
                d = lookup_volume(c, (t & 0x7F) - 31);
 
1266
                if (t & 0x80) {
 
1267
                        d = random_nr(d);
 
1268
                }
 
1269
                if (d + g > c) {
 
1270
                        h = c - g;
 
1271
                } else {
 
1272
                        h = d;
 
1273
                        if (d + g < 0)
 
1274
                                h = -g;
 
1275
                }
 
1276
                h -= s10->cur_val;
 
1277
        } else {
 
1278
                h = 0;
 
1279
        }
 
1280
 
 
1281
        s10->speed_hi = h / e;
 
1282
        if (h < 0) {
 
1283
                h = -h;
 
1284
                s10->direction = -1;
 
1285
        } else {
 
1286
                s10->direction = 1;
 
1287
        }
 
1288
 
 
1289
        s10->speed_lo = h % e;
 
1290
        s10->speed_lo_counter = 0;
 
1291
}
 
1292
 
 
1293
void MidiDriver_ADLIB::adlib_playnote(int channel, int note) {
 
1294
        byte old, oct, notex;
 
1295
        int note2;
 
1296
        int i;
 
1297
 
 
1298
        note2 = (note >> 7) - 4;
 
1299
        note2 = (note2 < 128) ? note2 : 0;
 
1300
 
 
1301
        oct = (note2 / 12);
 
1302
        if (oct > 7)
 
1303
                oct = 7 << 2;
 
1304
        else
 
1305
                oct <<= 2;
 
1306
        notex = note2 % 12 + 3;
 
1307
 
 
1308
        old = adlib_get_reg_value(channel + 0xB0);
 
1309
        if (old & 0x20) {
 
1310
                old &= ~0x20;
 
1311
                if (oct > old) {
 
1312
                        if (notex < 6) {
 
1313
                                notex += 12;
 
1314
                                oct -= 4;
 
1315
                        }
 
1316
                } else if (oct < old) {
 
1317
                        if (notex > 11) {
 
1318
                                notex -= 12;
 
1319
                                oct += 4;
 
1320
                        }
 
1321
                }
 
1322
        }
 
1323
 
 
1324
        i = (notex << 3) + ((note >> 4) & 0x7);
 
1325
        adlib_write(channel + 0xA0, note_to_f_num[i]);
 
1326
        adlib_write(channel + 0xB0, oct | 0x20);
 
1327
}
 
1328
 
 
1329
int MidiDriver_ADLIB::random_nr(int a) {
 
1330
        static byte _rand_seed = 1;
 
1331
        if (_rand_seed & 1) {
 
1332
                _rand_seed >>= 1;
 
1333
                _rand_seed ^= 0xB8;
 
1334
        } else {
 
1335
                _rand_seed >>= 1;
 
1336
        }
 
1337
        return _rand_seed * a >> 8;
 
1338
}
 
1339
 
 
1340
void MidiDriver_ADLIB::part_key_off(AdLibPart *part, byte note) {
 
1341
        AdLibVoice *voice;
 
1342
 
 
1343
        for (voice = part->_voice; voice; voice = voice->_next) {
 
1344
                if (voice->_note == note) {
 
1345
                        if (part->_pedal)
 
1346
                                voice->_waitforpedal = true;
 
1347
                        else
 
1348
                                mc_off(voice);
 
1349
                }
 
1350
        }
 
1351
}
 
1352
 
 
1353
void MidiDriver_ADLIB::part_key_on(AdLibPart *part, AdLibInstrument *instr, byte note, byte velocity) {
 
1354
        AdLibVoice *voice;
 
1355
 
 
1356
        voice = allocate_voice(part->_pri_eff);
 
1357
        if (!voice)
 
1358
                return;
 
1359
 
 
1360
        link_mc(part, voice);
 
1361
        mc_key_on(voice, instr, note, velocity);
 
1362
}
 
1363
 
 
1364
AdLibVoice *MidiDriver_ADLIB::allocate_voice(byte pri) {
 
1365
        AdLibVoice *ac, *best = NULL;
 
1366
        int i;
 
1367
 
 
1368
        for (i = 0; i < 9; i++) {
 
1369
                if (++_voice_index >= 9)
 
1370
                        _voice_index = 0;
 
1371
                ac = &_voices[_voice_index];
 
1372
                if (!ac->_part)
 
1373
                        return ac;
 
1374
                if (!ac->_next) {
 
1375
                        if (ac->_part->_pri_eff <= pri) {
 
1376
                                pri = ac->_part->_pri_eff;
 
1377
                                best = ac;
 
1378
                        }
 
1379
                }
 
1380
        }
 
1381
 
 
1382
        /* SCUMM V3 games don't have note priorities, first comes wins. */
 
1383
        if (_scummSmallHeader)
 
1384
                return NULL;
 
1385
 
 
1386
        if (best)
 
1387
                mc_off(best);
 
1388
        return best;
 
1389
}
 
1390
 
 
1391
void MidiDriver_ADLIB::link_mc(AdLibPart *part, AdLibVoice *voice) {
 
1392
        voice->_part = part;
 
1393
        voice->_next = (AdLibVoice *)part->_voice;
 
1394
        part->_voice = voice;
 
1395
        voice->_prev = NULL;
 
1396
 
 
1397
        if (voice->_next)
 
1398
                voice->_next->_prev = voice;
 
1399
}
 
1400
 
 
1401
void MidiDriver_ADLIB::mc_key_on(AdLibVoice *voice, AdLibInstrument *instr, byte note, byte velocity) {
 
1402
        AdLibPart *part = voice->_part;
 
1403
        int c;
 
1404
        byte vol_1, vol_2;
 
1405
 
 
1406
        voice->_twochan = instr->feedback & 1;
 
1407
        voice->_note = note;
 
1408
        voice->_waitforpedal = false;
 
1409
        voice->_duration = instr->duration;
 
1410
        if (voice->_duration != 0)
 
1411
                voice->_duration *= 63;
 
1412
 
 
1413
        if (!_scummSmallHeader)
 
1414
                vol_1 = (instr->mod_scalingOutputLevel & 0x3F) + lookup_table[velocity >> 1][instr->mod_waveformSelect >> 2];
 
1415
        else
 
1416
                vol_1 = 0x3f - (instr->mod_scalingOutputLevel & 0x3F);
 
1417
        if (vol_1 > 0x3F)
 
1418
                vol_1 = 0x3F;
 
1419
        voice->_vol_1 = vol_1;
 
1420
 
 
1421
        if (!_scummSmallHeader)
 
1422
                vol_2 = (instr->car_scalingOutputLevel & 0x3F) + lookup_table[velocity >> 1][instr->car_waveformSelect >> 2];
 
1423
        else
 
1424
                vol_2 = 0x3f - (instr->car_scalingOutputLevel & 0x3F);
 
1425
        if (vol_2 > 0x3F)
 
1426
                vol_2 = 0x3F;
 
1427
        voice->_vol_2 = vol_2;
 
1428
 
 
1429
        c = part->_vol_eff >> 2;
 
1430
 
 
1431
        if (!_scummSmallHeader) {
 
1432
                vol_2 = volume_table[lookup_table[vol_2][c]];
 
1433
                if (voice->_twochan)
 
1434
                        vol_1 = volume_table[lookup_table[vol_1][c]];
 
1435
        }
 
1436
 
 
1437
        adlib_setup_channel(voice->_channel, instr, vol_1, vol_2);
 
1438
        adlib_note_on_ex(voice->_channel, part->_transpose_eff + note, part->_detune_eff + (part->_pitchbend * part->_pitchbend_factor >> 6));
 
1439
 
 
1440
        if (instr->flags_a & 0x80) {
 
1441
                mc_init_stuff(voice, &voice->_s10a, &voice->_s11a, instr->flags_a, &instr->extra_a);
 
1442
        } else {
 
1443
                voice->_s10a.active = 0;
 
1444
        }
 
1445
 
 
1446
        if (instr->flags_b & 0x80) {
 
1447
                mc_init_stuff(voice, &voice->_s10b, &voice->_s11b, instr->flags_b, &instr->extra_b);
 
1448
        } else {
 
1449
                voice->_s10b.active = 0;
 
1450
        }
 
1451
}
 
1452
 
 
1453
void MidiDriver_ADLIB::adlib_setup_channel(int chan, AdLibInstrument *instr, byte vol_1, byte vol_2) {
 
1454
        byte channel;
 
1455
 
 
1456
        assert(chan >= 0 && chan < 9);
 
1457
 
 
1458
        channel = channel_mappings[chan];
 
1459
        adlib_write(channel + 0x20, instr->mod_characteristic);
 
1460
        adlib_write(channel + 0x40, (instr->mod_scalingOutputLevel | 0x3F) - vol_1 );
 
1461
        adlib_write(channel + 0x60, 0xff & (~instr->mod_attackDecay));
 
1462
        adlib_write(channel + 0x80, 0xff & (~instr->mod_sustainRelease));
 
1463
        adlib_write(channel + 0xE0, instr->mod_waveformSelect);
 
1464
 
 
1465
        channel = channel_mappings_2[chan];
 
1466
        adlib_write(channel + 0x20, instr->car_characteristic);
 
1467
        adlib_write(channel + 0x40, (instr->car_scalingOutputLevel | 0x3F) - vol_2 );
 
1468
        adlib_write(channel + 0x60, 0xff & (~instr->car_attackDecay));
 
1469
        adlib_write(channel + 0x80, 0xff & (~instr->car_sustainRelease));
 
1470
        adlib_write(channel + 0xE0, instr->car_waveformSelect);
 
1471
 
 
1472
        adlib_write((byte)chan + 0xC0, instr->feedback);
 
1473
}
 
1474
 
 
1475
void MidiDriver_ADLIB::adlib_note_on_ex(int chan, byte note, int mod)
 
1476
{
 
1477
        int code;
 
1478
        assert(chan >= 0 && chan < 9);
 
1479
        code = (note << 7) + mod;
 
1480
        curnote_table[chan] = code;
 
1481
        channel_table_2[chan] = 0;
 
1482
        adlib_playnote(chan, code);
 
1483
}
 
1484
 
 
1485
void MidiDriver_ADLIB::mc_init_stuff(AdLibVoice *voice, Struct10 * s10,
 
1486
                                                                        Struct11 * s11, byte flags, InstrumentExtra * ie) {
 
1487
        AdLibPart *part = voice->_part;
 
1488
        s11->modify_val = 0;
 
1489
        s11->flag0x40 = flags & 0x40;
 
1490
        s10->loop = flags & 0x20;
 
1491
        s11->flag0x10 = flags & 0x10;
 
1492
        s11->param = param_table_1[flags & 0xF];
 
1493
        s10->max_value = maxval_table[flags & 0xF];
 
1494
        s10->unk3 = 31;
 
1495
        if (s11->flag0x40) {
 
1496
                s10->modwheel = part->_modwheel >> 2;
 
1497
        } else {
 
1498
                s10->modwheel = 31;
 
1499
        }
 
1500
 
 
1501
        switch (s11->param) {
 
1502
        case 0:
 
1503
                s10->start_value = voice->_vol_2;
 
1504
                break;
 
1505
        case 13:
 
1506
                s10->start_value = voice->_vol_1;
 
1507
                break;
 
1508
        case 30:
 
1509
                s10->start_value = 31;
 
1510
                s11->s10->modwheel = 0;
 
1511
                break;
 
1512
        case 31:
 
1513
                s10->start_value = 0;
 
1514
                s11->s10->unk3 = 0;
 
1515
                break;
 
1516
        default:
 
1517
                s10->start_value = adlib_get_reg_value_param(voice->_channel, s11->param);
 
1518
        }
 
1519
 
 
1520
        struct10_init(s10, ie);
 
1521
}
 
1522
 
 
1523
void MidiDriver_ADLIB::struct10_init(Struct10 *s10, InstrumentExtra *ie) {
 
1524
        s10->active = 1;
 
1525
        if (!_scummSmallHeader) {
 
1526
                s10->cur_val = 0;
 
1527
        } else {
 
1528
                s10->cur_val = s10->start_value;
 
1529
                s10->start_value = 0;
 
1530
        }
 
1531
        s10->modwheel_last = 31;
 
1532
        s10->count = ie->a;
 
1533
        if (s10->count)
 
1534
                s10->count *= 63;
 
1535
        s10->table_a[0] = ie->b;
 
1536
        s10->table_a[1] = ie->d;
 
1537
        s10->table_a[2] = ie->f;
 
1538
        s10->table_a[3] = ie->g;
 
1539
 
 
1540
        s10->table_b[0] = ie->c;
 
1541
        s10->table_b[1] = ie->e;
 
1542
        s10->table_b[2] = 0;
 
1543
        s10->table_b[3] = ie->h;
 
1544
 
 
1545
        struct10_setup(s10);
 
1546
}
 
1547
 
 
1548
int MidiDriver_ADLIB::adlib_get_reg_value_param(int chan, byte param) {
 
1549
        const AdLibSetParams *as;
 
1550
        byte val;
 
1551
        byte channel;
 
1552
 
 
1553
        assert(chan >= 0 && chan < 9);
 
1554
 
 
1555
        if (param <= 12) {
 
1556
                channel = channel_mappings_2[chan];
 
1557
        } else if (param <= 25) {
 
1558
                param -= 13;
 
1559
                channel = channel_mappings[chan];
 
1560
        } else if (param <= 27) {
 
1561
                param -= 13;
 
1562
                channel = chan;
 
1563
        } else if (param == 28) {
 
1564
                return 0xF;
 
1565
        } else if (param == 29) {
 
1566
                return 0x17F;
 
1567
        } else {
 
1568
                return 0;
 
1569
        }
 
1570
 
 
1571
        as = &adlib_setparam_table[param];
 
1572
        val = adlib_get_reg_value(channel + as->a);
 
1573
        val &= as->c;
 
1574
        val >>= as->b;
 
1575
        if (as->d)
 
1576
                val = as->d - val;
 
1577
 
 
1578
        return val;
 
1579
}
 
1580
 
 
1581
void MidiDriver_ADLIB::adlib_note_on(int chan, byte note, int mod) {
 
1582
        int code;
 
1583
        assert(chan >= 0 && chan < 9);
 
1584
        code = (note << 7) + mod;
 
1585
        curnote_table[chan] = code;
 
1586
        adlib_playnote(chan, (int16) channel_table_2[chan] + code);
 
1587
}
 
1588
 
 
1589
 
 
1590
// Plugin interface
 
1591
 
 
1592
class AdLibEmuMusicPlugin : public MusicPluginObject {
 
1593
public:
 
1594
        const char *getName() const {
 
1595
                return _s("AdLib Emulator");
 
1596
        }
 
1597
 
 
1598
        const char *getId() const {
 
1599
                return "adlib";
 
1600
        }
 
1601
 
 
1602
        MusicDevices getDevices() const;
 
1603
        Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
 
1604
};
 
1605
 
 
1606
MusicDevices AdLibEmuMusicPlugin::getDevices() const {
 
1607
        MusicDevices devices;
 
1608
        devices.push_back(MusicDevice(this, "", MT_ADLIB));
 
1609
        return devices;
 
1610
}
 
1611
 
 
1612
Common::Error AdLibEmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
 
1613
        *mididriver = new MidiDriver_ADLIB(g_system->getMixer());
 
1614
 
 
1615
        return Common::kNoError;
 
1616
}
 
1617
 
 
1618
//#if PLUGIN_ENABLED_DYNAMIC(ADLIB)
 
1619
        //REGISTER_PLUGIN_DYNAMIC(ADLIB, PLUGIN_TYPE_MUSIC, AdLibEmuMusicPlugin);
 
1620
//#else
 
1621
        REGISTER_PLUGIN_STATIC(ADLIB, PLUGIN_TYPE_MUSIC, AdLibEmuMusicPlugin);
 
1622
//#endif