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  */
22 
23 #include "common/debug.h"
24 #include "common/system.h"
25 
26 #include "audio/fmopl.h"
27 #include "audio/mpu401.h"
28 #include "audio/mididrv.h"
29 
30 namespace Parallaction {
31 
32 const uint kNumVoices = 9;
33 // adlib FM voices 0-5
34 const uint kNumMelodic = 6;
35 // adlib FM voice 6 and 7-8
36 const uint kNumPercussion = 5;
37 
38 // mask for maximum volume level
39 #define LEVEL_MASK 0x7f
40 
41 struct OPLOperator {
42 	uint8 characteristic; // amplitude modulation, vibrato, envelope, keyboard scaling, modulator frequency
43 	uint8 levels;
44 	uint8 attackDecay;
45 	uint8 sustainRelease;
46 	uint8 waveform;
47 };
48 
49 struct MelodicProgram {
50 	OPLOperator op[2];
51 	uint8 feedbackAlgo;
52 };
53 
54 struct PercussionNote {
55 	OPLOperator op[2];
56 	uint8 feedbackAlgo;
57 	uint8 percussion;
58 	uint8 valid;
59 	uint16 frequency;
60 	uint8 octave;
61 };
62 
63 static const MelodicProgram melodicPrograms[128] = {
64 	{{{   0x1, 0x51, 0xf2, 0xb2,  0x0 }, { 0x11,  0x0, 0xf2, 0xa2,  0x0 }},  0x0 },
65 	{{{  0xc2, 0x4b, 0xf1, 0x53,  0x0 }, { 0xd2,  0x0, 0xf2, 0x74,  0x0 }},  0x4 },
66 	{{{  0x81, 0x9d, 0xf2, 0x74,  0x0 }, { 0x13,  0x0, 0xf2, 0xf1,  0x0 }},  0x6 },
67 	{{{   0x3, 0x4f, 0xf1, 0x53,  0x0 }, { 0x17,  0x3, 0xf2, 0x74,  0x0 }},  0x6 },
68 	{{{  0xd1, 0x81, 0x81, 0x73,  0x2 }, { 0xd4,  0x0, 0xe1, 0x34,  0x0 }},  0x3 },
69 	{{{   0x1,  0x0, 0x94, 0xa6,  0x0 }, {  0x2,  0x0, 0x83, 0x26,  0x0 }},  0x1 },
70 	{{{  0xf3, 0x84, 0x81,  0x2,  0x1 }, { 0x55, 0x80, 0xdd,  0x3,  0x0 }},  0x4 },
71 	{{{   0x5, 0x8a, 0xf2, 0x26,  0x0 }, {  0x1, 0x80, 0xf3, 0x48,  0x0 }},  0x0 },
72 	{{{  0x32,  0x0, 0xb1, 0x14,  0x0 }, { 0x12,  0x0, 0xfd, 0x36,  0x0 }},  0x3 },
73 	{{{   0x1,  0x0, 0x82,  0xa,  0x2 }, {  0x2,  0x0, 0x85, 0x15,  0x0 }},  0x3 },
74 	{{{  0xd1,  0x1, 0x97, 0xaa,  0x0 }, {  0x4,  0xd, 0xf3, 0xa5,  0x1 }},  0x9 },
75 	{{{  0x17,  0x0, 0xf2, 0x62,  0x0 }, { 0x12,  0x0, 0xf2, 0x72,  0x0 }},  0x8 },
76 	{{{   0x6,  0x0, 0xff, 0xf4,  0x0 }, { 0xc4,  0x0, 0xf8, 0xb5,  0x0 }},  0xe },
77 	{{{  0xc0, 0x81, 0xf2, 0x13,  0x2 }, { 0xc0, 0xc1, 0xf3, 0x14,  0x2 }},  0xb },
78 	{{{  0x44, 0x53, 0xf5, 0x31,  0x0 }, { 0x60, 0x80, 0xfd, 0x22,  0x0 }},  0x6 },
79 	{{{  0xe0, 0x80, 0xf4, 0xf2,  0x0 }, { 0x61,  0x0, 0xf2,  0x6,  0x0 }},  0x8 },
80 	{{{  0xc1,  0x6, 0x83, 0x23,  0x0 }, { 0xc1,  0x4, 0xf0, 0x26,  0x0 }},  0x1 },
81 	{{{  0x26,  0x0, 0xf4, 0xb6,  0x0 }, { 0x21,  0x0, 0x81, 0x4b,  0x0 }},  0x1 },
82 	{{{  0x24, 0x80, 0xff,  0xf,  0x0 }, { 0x21, 0x80, 0xff,  0xf,  0x0 }},  0x1 },
83 	{{{  0x24, 0x4f, 0xf2,  0xb,  0x0 }, { 0x31,  0x0, 0x52,  0xb,  0x0 }},  0xb },
84 	{{{  0x31,  0x8, 0x81,  0xb,  0x0 }, { 0xa1, 0x80, 0x92, 0x3b,  0x0 }},  0x0 },
85 	{{{  0x70, 0xc5, 0x52, 0x11,  0x1 }, { 0x71, 0x80, 0x31, 0xfe,  0x1 }},  0x0 },
86 	{{{  0x51, 0x88, 0x10, 0xf0,  0x0 }, { 0x42, 0x83, 0x40, 0xfc,  0x0 }},  0x8 },
87 	{{{  0xf0, 0xd9, 0x81,  0x3,  0x0 }, { 0xb1, 0x80, 0xf1,  0x5,  0x0 }},  0xa },
88 	{{{  0x21, 0x4f, 0xf1, 0x31,  0x0 }, {  0x2, 0x80, 0xc3, 0x45,  0x0 }},  0x0 },
89 	{{{   0x7, 0x8f, 0x9c, 0x33,  0x1 }, {  0x1, 0x80, 0x8a, 0x13,  0x0 }},  0x0 },
90 	{{{  0x21, 0x40, 0xf1, 0x31,  0x0 }, {  0x6, 0x80, 0xf4, 0x44,  0x0 }},  0x0 },
91 	{{{  0x21, 0x40, 0xf1, 0x31,  0x3 }, { 0x81,  0x0, 0xf4, 0x44,  0x2 }},  0x2 },
92 	{{{  0x11, 0x8d, 0xfd, 0x11,  0x0 }, { 0x11, 0x80, 0xfd, 0x11,  0x0 }},  0x8 },
93 	{{{  0xf0,  0x1, 0x97, 0x17,  0x0 }, { 0x21,  0xd, 0xf1, 0x18,  0x0 }},  0x8 },
94 	{{{  0xf1,  0x1, 0x97, 0x17,  0x0 }, { 0x21,  0xd, 0xf1, 0x18,  0x0 }},  0x8 },
95 	{{{  0xcd, 0x9e, 0x55, 0xd1,  0x0 }, { 0xd1,  0x0, 0xf2, 0x71,  0x0 }},  0xe },
96 	{{{   0x1,  0x0, 0xf2, 0x88,  0x0 }, {  0x1,  0x0, 0xf5, 0x88,  0x0 }},  0x1 },
97 	{{{  0x30,  0xd, 0xf2, 0xef,  0x0 }, { 0x21,  0x0, 0xf5, 0x78,  0x0 }},  0x6 },
98 	{{{   0x0, 0x10, 0xf4, 0xd9,  0x0 }, {  0x0,  0x0, 0xf5, 0xd7,  0x0 }},  0x4 },
99 	{{{   0x1, 0x4c, 0xf2, 0x50,  0x0 }, {  0x1, 0x40, 0xd2, 0x59,  0x0 }},  0x8 },
100 	{{{  0x20, 0x11, 0xe2, 0x8a,  0x0 }, { 0x20,  0x0, 0xe4, 0xa8,  0x0 }},  0xa },
101 	{{{  0x21, 0x40, 0x7b,  0x4,  0x1 }, { 0x21,  0x0, 0x75, 0x72,  0x0 }},  0x2 },
102 	{{{  0x31,  0xd, 0xf2, 0xef,  0x0 }, { 0x21,  0x0, 0xf5, 0x78,  0x0 }},  0xa },
103 	{{{   0x1,  0xc, 0xf5, 0x2f,  0x1 }, {  0x0, 0x80, 0xf5, 0x5c,  0x0 }},  0x0 },
104 	{{{  0xb0, 0x1c, 0x81,  0x3,  0x2 }, { 0x20,  0x0, 0x54, 0x67,  0x2 }},  0xe },
105 	{{{   0x1,  0x0, 0xf1, 0x65,  0x0 }, {  0x1, 0x80, 0xa3, 0xa8,  0x2 }},  0x1 },
106 	{{{  0xe1, 0x4f, 0xc1, 0xd3,  0x2 }, { 0x21,  0x0, 0x32, 0x74,  0x1 }},  0x0 },
107 	{{{   0x2,  0x0, 0xf6, 0x16,  0x0 }, { 0x12,  0x0, 0xf2, 0xf8,  0x0 }},  0x1 },
108 	{{{  0xe0, 0x63, 0xf8, 0xf3,  0x0 }, { 0x70, 0x80, 0xf7, 0xf3,  0x0 }},  0x4 },
109 	{{{   0x1,  0x6, 0xf3, 0xff,  0x0 }, {  0x8,  0x0, 0xf7, 0xff,  0x0 }},  0x4 },
110 	{{{  0x21, 0x16, 0xb0, 0x81,  0x1 }, { 0x22,  0x0, 0xb3, 0x13,  0x1 }},  0xc },
111 	{{{   0x1, 0x4f, 0xf0, 0xff,  0x0 }, { 0x30,  0x0, 0x90,  0xf,  0x0 }},  0x6 },
112 	{{{   0x0, 0x10, 0xf1, 0xf2,  0x2 }, {  0x1,  0x0, 0xf1, 0xf2,  0x3 }},  0x0 },
113 	{{{   0x1, 0x4f, 0xf1, 0x50,  0x0 }, { 0x21, 0x80, 0xa3,  0x5,  0x3 }},  0x6 },
114 	{{{  0xb1,  0x3, 0x55,  0x3,  0x0 }, { 0xb1,  0x3,  0x8,  0xa,  0x0 }},  0x9 },
115 	{{{  0x22,  0x0, 0xa9, 0x34,  0x1 }, {  0x1,  0x0, 0xa2, 0x42,  0x2 }},  0x2 },
116 	{{{  0xa0, 0xdc, 0x81, 0x31,  0x3 }, { 0xb1, 0x80, 0xf1,  0x1,  0x3 }},  0x0 },
117 	{{{   0x1, 0x4f, 0xf1, 0x50,  0x0 }, { 0x21, 0x80, 0xa3,  0x5,  0x3 }},  0x6 },
118 	{{{  0xf1, 0x80, 0xa0, 0x72,  0x0 }, { 0x74,  0x0, 0x90, 0x22,  0x0 }},  0x9 },
119 	{{{  0xe1, 0x13, 0x71, 0xae,  0x0 }, { 0xe1,  0x0, 0xf0, 0xfc,  0x1 }},  0xa },
120 	{{{  0x31, 0x1c, 0x41,  0xb,  0x0 }, { 0xa1, 0x80, 0x92, 0x3b,  0x0 }},  0xe },
121 	{{{  0x71, 0x1c, 0x41, 0x1f,  0x0 }, { 0xa1, 0x80, 0x92, 0x3b,  0x0 }},  0xe },
122 	{{{  0x21, 0x1c, 0x53, 0x1d,  0x0 }, { 0xa1, 0x80, 0x52, 0x3b,  0x0 }},  0xc },
123 	{{{  0x21, 0x1d, 0xa4, 0xae,  0x1 }, { 0x21,  0x0, 0xb1, 0x9e,  0x0 }},  0xc },
124 	{{{  0xe1, 0x16, 0x71, 0xae,  0x0 }, { 0xe1,  0x0, 0x81, 0x9e,  0x0 }},  0xa },
125 	{{{  0xe1, 0x15, 0x71, 0xae,  0x0 }, { 0xe2,  0x0, 0x81, 0x9e,  0x0 }},  0xe },
126 	{{{  0x21, 0x16, 0x71, 0xae,  0x0 }, { 0x21,  0x0, 0x81, 0x9e,  0x0 }},  0xe },
127 	{{{  0x71, 0x1c, 0x41, 0x1f,  0x0 }, { 0xa1, 0x80, 0x92, 0x3b,  0x0 }},  0xe },
128 	{{{  0x21, 0x4f, 0x81, 0x53,  0x0 }, { 0x32,  0x0, 0x22, 0x2c,  0x0 }},  0xa },
129 	{{{  0x22, 0x4f, 0x81, 0x53,  0x0 }, { 0x32,  0x0, 0x22, 0x2c,  0x0 }},  0xa },
130 	{{{  0x23, 0x4f, 0x81, 0x53,  0x0 }, { 0x34,  0x0, 0x22, 0x2c,  0x0 }},  0xa },
131 	{{{  0xe1, 0x16, 0x71, 0xae,  0x0 }, { 0xe1,  0x0, 0x81, 0x9e,  0x0 }},  0xa },
132 	{{{  0x71, 0xc5, 0x6e, 0x17,  0x0 }, { 0x22,  0x5, 0x8b,  0xe,  0x0 }},  0x2 },
133 	{{{  0xe6, 0x27, 0x70,  0xf,  0x1 }, { 0xe3,  0x0, 0x60, 0x9f,  0x0 }},  0xa },
134 	{{{  0x30, 0xc8, 0xd5, 0x19,  0x0 }, { 0xb1, 0x80, 0x61, 0x1b,  0x0 }},  0xc },
135 	{{{  0x32, 0x9a, 0x51, 0x1b,  0x0 }, { 0xa1, 0x82, 0xa2, 0x3b,  0x0 }},  0xc },
136 	{{{  0xad,  0x3, 0x74, 0x29,  0x0 }, { 0xa2, 0x82, 0x73, 0x29,  0x0 }},  0x7 },
137 	{{{  0x21, 0x83, 0x74, 0x17,  0x0 }, { 0x62, 0x8d, 0x65, 0x17,  0x0 }},  0x7 },
138 	{{{  0x94,  0xb, 0x85, 0xff,  0x1 }, { 0x13,  0x0, 0x74, 0xff,  0x0 }},  0xc },
139 	{{{  0x74, 0x87, 0xa4,  0x2,  0x0 }, { 0xd6, 0x80, 0x45, 0x42,  0x0 }},  0x2 },
140 	{{{  0xb3, 0x85, 0x76, 0x21,  0x1 }, { 0x20,  0x0, 0x3d, 0xc1,  0x0 }},  0x6 },
141 	{{{  0x17, 0x4f, 0xf2, 0x61,  0x0 }, { 0x12,  0x8, 0xf1, 0xb4,  0x0 }},  0x8 },
142 	{{{  0x4f, 0x86, 0x65,  0x1,  0x0 }, { 0x1f,  0x0, 0x32, 0x74,  0x0 }},  0x4 },
143 	{{{  0xe1, 0x23, 0x71, 0xae,  0x0 }, { 0xe4,  0x0, 0x82, 0x9e,  0x0 }},  0xa },
144 	{{{  0x11, 0x86, 0xf2, 0xbd,  0x0 }, {  0x4, 0x80, 0xa0, 0x9b,  0x1 }},  0x8 },
145 	{{{  0x20, 0x90, 0xf5, 0x9e,  0x2 }, { 0x11,  0x0, 0xf4, 0x5b,  0x3 }},  0xc },
146 	{{{  0xf0, 0x80, 0x34, 0xe4,  0x0 }, { 0x7e,  0x0, 0xa2,  0x6,  0x0 }},  0x8 },
147 	{{{  0x90,  0xf, 0xff,  0x1,  0x3 }, {  0x0,  0x0, 0x1f,  0x1,  0x0 }},  0xe },
148 	{{{   0x1, 0x4f, 0xf0, 0xff,  0x0 }, { 0x33,  0x0, 0x90,  0xf,  0x0 }},  0x6 },
149 	{{{  0x1e,  0x0, 0x1f,  0xf,  0x0 }, { 0x10,  0x0, 0x1f, 0x7f,  0x0 }},  0x0 },
150 	{{{  0xbe,  0x0, 0xf1,  0x1,  0x3 }, { 0x31,  0x0, 0xf1,  0x1,  0x0 }},  0x4 },
151 	{{{  0xbe,  0x0, 0xf1,  0x1,  0x3 }, { 0x31,  0x0, 0xf1,  0x1,  0x0 }},  0x4 },
152 	{{{  0x93,  0x6, 0xc1,  0x4,  0x1 }, { 0x82,  0x0, 0x51,  0x9,  0x0 }},  0x6 },
153 	{{{  0xa0,  0x0, 0x96, 0x33,  0x0 }, { 0x20,  0x0, 0x55, 0x2b,  0x0 }},  0x6 },
154 	{{{   0x0, 0xc0, 0xff,  0x5,  0x0 }, {  0x0,  0x0, 0xff,  0x5,  0x3 }},  0x0 },
155 	{{{   0x4,  0x8, 0xf8,  0x7,  0x0 }, {  0x1,  0x0, 0x82, 0x74,  0x0 }},  0x8 },
156 	{{{   0x0,  0x0, 0x2f,  0x5,  0x0 }, { 0x20,  0x0, 0xff,  0x5,  0x3 }},  0xa },
157 	{{{  0x93,  0x0, 0xf7,  0x7,  0x2 }, {  0x0,  0x0, 0xf7,  0x7,  0x0 }},  0xa },
158 	{{{   0x0, 0x40, 0x80, 0x7a,  0x0 }, { 0xc4,  0x0, 0xc0, 0x7e,  0x0 }},  0x8 },
159 	{{{  0x90, 0x80, 0x55, 0xf5,  0x0 }, {  0x0,  0x0, 0x55, 0xf5,  0x0 }},  0x8 },
160 	{{{  0xe1, 0x80, 0x34, 0xe4,  0x0 }, { 0x69,  0x0, 0xf2,  0x6,  0x0 }},  0x8 },
161 	{{{   0x3,  0x2, 0xf0, 0xff,  0x3 }, { 0x11, 0x80, 0xf0, 0xff,  0x2 }},  0x2 },
162 	{{{  0x1e,  0x0, 0x1f,  0xf,  0x0 }, { 0x10,  0x0, 0x1f, 0x7f,  0x0 }},  0x0 },
163 	{{{   0x0,  0x0, 0x2f,  0x1,  0x0 }, {  0x0,  0x0, 0xff,  0x1,  0x0 }},  0x4 },
164 	{{{  0xbe,  0x0, 0xf1,  0x1,  0x3 }, { 0x31,  0x0, 0xf1,  0x1,  0x0 }},  0x4 },
165 	{{{  0x93, 0x85, 0x3f,  0x6,  0x1 }, {  0x0,  0x0, 0x5f,  0x7,  0x0 }},  0x6 },
166 	{{{   0x6,  0x0, 0xa0, 0xf0,  0x0 }, { 0x44,  0x0, 0xc5, 0x75,  0x0 }},  0xe },
167 	{{{  0x60,  0x0, 0x10, 0x81,  0x0 }, { 0x20, 0x8c, 0x12, 0x91,  0x0 }},  0xe },
168 	{{{   0x1, 0x40, 0xf1, 0x53,  0x0 }, {  0x8, 0x40, 0xf1, 0x53,  0x0 }},  0x0 },
169 	{{{  0x31,  0x0, 0x56, 0x31,  0x0 }, { 0x16,  0x0, 0x7d, 0x41,  0x0 }},  0x0 },
170 	{{{   0x0, 0x10, 0xf2, 0x72,  0x0 }, { 0x13,  0x0, 0xf2, 0x72,  0x0 }},  0xc },
171 	{{{  0x10,  0x0, 0x75, 0x93,  0x1 }, {  0x1,  0x0, 0xf5, 0x82,  0x1 }},  0x0 },
172 	{{{   0x0,  0x0, 0xf6, 0xff,  0x2 }, {  0x0,  0x0, 0xf6, 0xff,  0x0 }},  0x8 },
173 	{{{  0x30,  0x0, 0xff, 0xa0,  0x3 }, { 0x63,  0x0, 0x65,  0xb,  0x2 }},  0x0 },
174 	{{{  0x2a,  0x0, 0xf6, 0x87,  0x0 }, { 0x2b,  0x0, 0x76, 0x25,  0x0 }},  0x0 },
175 	{{{  0x85,  0x0, 0xb8, 0x84,  0x0 }, { 0x43,  0x0, 0xe5, 0x8f,  0x0 }},  0x6 },
176 	{{{   0x7, 0x4f, 0xf2, 0x60,  0x0 }, { 0x12,  0x0, 0xf2, 0x72,  0x0 }},  0x8 },
177 	{{{   0x5, 0x40, 0xb3, 0xd3,  0x0 }, { 0x86, 0x80, 0xf2, 0x24,  0x0 }},  0x2 },
178 	{{{  0xd0,  0x0, 0x11, 0xcf,  0x0 }, { 0xd1,  0x0, 0xf4, 0xe8,  0x3 }},  0x0 },
179 	{{{   0x5, 0x4e, 0xda, 0x25,  0x2 }, {  0x1,  0x0, 0xf9, 0x15,  0x0 }},  0xa },
180 	{{{   0x3,  0x0, 0x8f,  0x7,  0x2 }, {  0x2,  0x0, 0xff,  0x6,  0x0 }},  0x0 },
181 	{{{  0x13,  0x0, 0x8f,  0x7,  0x2 }, {  0x2,  0x0, 0xf9,  0x5,  0x0 }},  0x0 },
182 	{{{  0xf0,  0x1, 0x97, 0x17,  0x0 }, { 0x21,  0xd, 0xf1, 0x18,  0x0 }},  0x8 },
183 	{{{  0xf1, 0x41, 0x11, 0x11,  0x0 }, { 0xf1, 0x41, 0x11, 0x11,  0x0 }},  0x2 },
184 	{{{  0x13,  0x0, 0x8f,  0x7,  0x2 }, {  0x2,  0x0, 0xff,  0x6,  0x0 }},  0x0 },
185 	{{{   0x1,  0x0, 0x2f,  0x1,  0x0 }, {  0x1,  0x0, 0xaf,  0x1,  0x3 }},  0xf },
186 	{{{   0x1,  0x6, 0xf3, 0xff,  0x0 }, {  0x8,  0x0, 0xf7, 0xff,  0x0 }},  0x4 },
187 	{{{  0xc0, 0x4f, 0xf1,  0x3,  0x0 }, { 0xbe,  0xc, 0x10,  0x1,  0x0 }},  0x2 },
188 	{{{   0x0,  0x2, 0xf0, 0xff,  0x0 }, { 0x11, 0x80, 0xf0, 0xff,  0x0 }},  0x6 },
189 	{{{  0x81, 0x47, 0xf1, 0x83,  0x0 }, { 0xa2,  0x4, 0x91, 0x86,  0x0 }},  0x6 },
190 	{{{  0xf0, 0xc0, 0xff, 0xff,  0x3 }, { 0xe5,  0x0, 0xfb, 0xf0,  0x0 }},  0xe },
191 	{{{   0x0,  0x2, 0xf0, 0xff,  0x0 }, { 0x11, 0x80, 0xf0, 0xff,  0x0 }},  0x6 }
192 };
193 
194 static const PercussionNote percussionNotes[47] = {
195 	{{{  0x0,  0xb, 0xa8, 0x38,  0x0 }, {  0x0,  0x0, 0xd6, 0x49,  0x0 }},  0x0,  0x4,  0x1,   0x97,  0x4 },
196 	{{{ 0xc0, 0xc0, 0xf8, 0x3f,  0x2 }, { 0xc0,  0x0, 0xf6, 0x8e,  0x0 }},  0x0,  0x4,  0x1,   0xf7,  0x4 },
197 	{{{ 0xc0, 0x80, 0xc9, 0xab,  0x0 }, { 0xeb, 0x40, 0xb5, 0xf6,  0x0 }},  0x1,  0x3,  0x1,   0x6a,  0x6 },
198 	{{{  0xc,  0x0, 0xd8, 0xa6,  0x0 }, {  0x0,  0x0, 0xd6, 0x4f,  0x0 }},  0x1,  0x3,  0x1,   0x6c,  0x5 },
199 	{{{  0x1,  0x0, 0xe2, 0xd2,  0x0 }, {  0x3, 0x41, 0x8f, 0x48, 0x49 }},  0xc,  0x4,  0x1,   0x2f,  0x5 },
200 	{{{  0x0,  0x0, 0xc8, 0x58,  0x3 }, {  0x0,  0x0, 0xf6, 0x4f,  0x0 }},  0x9,  0x3,  0x1,  0x108,  0x4 },
201 	{{{  0x1,  0x0, 0xff,  0x5,  0x0 }, { 0xf2, 0xff, 0xe0, 0x50, 0x52 }}, 0x5d,  0x2,  0x1,   0x9f,  0x5 },
202 	{{{  0xe,  0x9, 0xb9, 0x47,  0x0 }, { 0xeb, 0x40, 0xf5, 0xe6,  0x0 }},  0x0,  0x0,  0x1,   0x82,  0x6 },
203 	{{{  0x0,  0x0, 0xd6, 0x83,  0x0 }, { 0xd6, 0xd7, 0xe0, 0x41, 0x5e }}, 0x4a,  0x2,  0x1,   0xc7,  0x5 },
204 	{{{  0x1,  0x9, 0x89, 0x67,  0x0 }, { 0xd6, 0xd7, 0xe0, 0x41, 0x5e }}, 0x4a,  0x0,  0x1,   0x80,  0x6 },
205 	{{{  0x1,  0x0, 0xd6, 0x96,  0x0 }, { 0xd6, 0xd7, 0xe0, 0x41, 0x5e }}, 0x4a,  0x2,  0x1,   0xed,  0x5 },
206 	{{{  0x0,  0x9, 0xa9, 0x55,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x1,   0x82,  0x6 },
207 	{{{  0x2,  0x0, 0xc6, 0x96,  0x0 }, { 0xe0,  0x0, 0xe0, 0x40,  0x0 }},  0x1,  0x2,  0x1,  0x123,  0x5 },
208 	{{{  0x5,  0x0, 0xf6, 0x56,  0x0 }, { 0xf7, 0xff, 0xb3, 0x90, 0x4f }},  0x1,  0x2,  0x1,  0x15b,  0x5 },
209 	{{{  0x1,  0x0, 0xf7, 0x14,  0x0 }, { 0xf7, 0xff, 0x36, 0x90, 0x79 }}, 0xe7,  0x1,  0x1,  0x1ac,  0x5 },
210 	{{{  0x0,  0x0, 0xf6, 0x56,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x1,  0x2,  0x1,  0x18b,  0x5 },
211 	{{{  0x0, 0x83, 0xfb,  0x5,  0x0 }, { 0xf7, 0x41, 0x39, 0x90, 0x79 }},  0x1,  0x1,  0x1,   0xc8,  0x5 },
212 	{{{  0x0,  0x0, 0xff,  0x5,  0x0 }, { 0xf7, 0xff, 0x36, 0x90, 0x79 }}, 0xe7,  0x1,  0x1,   0xf9,  0x5 },
213 	{{{  0x1,  0x0, 0xa0,  0x5,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x2,  0x1,  0x27a,  0x6 },
214 	{{{  0x0,  0x5, 0xf3,  0x6,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x2,  0x1,  0x108,  0x7 },
215 	{{{  0x1,  0x0, 0xf9, 0x34,  0x0 }, { 0xf7, 0xff, 0x36, 0x90, 0x79 }}, 0xe7,  0x1,  0x1,  0x147,  0x4 },
216 	{{{  0x0,  0x0, 0xf7, 0x16,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x2,  0x1,  0x120,  0x6 },
217 	{{{  0x1,  0x0, 0xff,  0x5,  0x0 }, { 0xf7, 0xff, 0x36, 0x90, 0x79 }}, 0xe7,  0x1,  0x1,   0x42,  0x6 },
218 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
219 	{{{  0x1,  0x0, 0xff,  0x5,  0x0 }, { 0xf7, 0xff, 0x36, 0x90, 0x79 }}, 0xe7,  0x1,  0x1,   0x6d,  0x5 },
220 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
221 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
222 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
223 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
224 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
225 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
226 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
227 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
228 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
229 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
230 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
231 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
232 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
233 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
234 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
235 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
236 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
237 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
238 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
239 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
240 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 },
241 	{{{  0x0,  0x0,  0x0,  0x0,  0x0 }, {  0x0,  0x0,  0x0,  0x0,  0x0 }},  0x0,  0x0,  0x0,  0x3fc,  0x4 }
242 };
243 
244 const uint16 melodicFrequencies[36] = {
245 	 0x55,   0x5a,   0x60,   0x66,   0x6c,   0x72,   0x79,   0x80,   0x88,
246 	 0x90,   0x99,   0xa1,   0xab,   0xb5,   0xc0,   0xcc,   0xd8,   0xe5,
247 	 0xf2,  0x101,  0x110,  0x120,  0x132,  0x143,  0x156,  0x16b,  0x181,
248 	0x198,  0x1b0,  0x1ca,  0x1e5,  0x202,  0x220,  0x241,  0x263,  0x286
249 };
250 
251 class AdLibDriver;
252 
253 class AdLibChannel : public MidiChannel_MPU401 {
254 public:
255 	void reset();
256 
257 	uint8 _program;
258 	uint8 _volume;
259 	uint8 _pedal;
260 };
261 
262 struct MelodicVoice {
263 	bool _used;
264 	uint8 _channel;
265 	uint8 _program;
266 
267 	uint8 _key;
268 	uint32 _timestamp;
269 	uint16 _frequency;
270 	int8 _octave;
271 };
272 
273 class AdLibDriver : public MidiDriver {
274 public:
AdLibDriver(Audio::Mixer * mixer)275 	AdLibDriver(Audio::Mixer *mixer) {
276 		for (uint i = 0; i < 16; ++i)
277 			_channels[i].init(this, i);
278 
279 		_isOpen = false;
280 
281 		_opl = NULL;
282 		memset(_voices, 0, sizeof(_voices));
283 
284 		_lastVoice = 0;
285 		_percussionMask = 0;
286 
287 		_adlibTimerProc = NULL;
288 		_adlibTimerParam = NULL;
289 	}
290 
291 	int open() override;
292 	void close() override;
293 	void send(uint32 b) override;
294 	MidiChannel *allocateChannel() override;
getPercussionChannel()295 	MidiChannel *getPercussionChannel() override { return &_channels[9]; }
isOpen() const296 	bool isOpen() const override { return _isOpen; }
getBaseTempo()297 	uint32 getBaseTempo() override { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
298 
setTimerCallback(void * timerParam,Common::TimerManager::TimerProc timerProc)299 	void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) override {
300 		_adlibTimerProc = timerProc;
301 		_adlibTimerParam = timerParam;
302 	}
303 
304 protected:
305 	OPL::OPL *_opl;
306 	AdLibChannel _channels[16];
307 	MelodicVoice _voices[kNumMelodic];
308 	uint8 _notesPerPercussion[kNumPercussion];
309 
310 	uint _lastVoice;
311 
312 	uint8 _percussionMask;
313 
314 	void noteOff(uint8 channel, uint8 note);
315 	void noteOn(uint8 channel, uint8 note, uint8 velocity);
316 	void allNotesOff();
317 	void setModulationWheel(uint8 channel, uint8 value);
318 	void setFootController(uint8 channel, uint8 value);
319 	void setVolume(uint8 channel, uint8 value);
320 	void setPitchBend(uint8 channel, int16 value);
321 
322 	void playNote(uint8 voice, uint8 octave, uint16 frequency);
323 
324 	void programOperatorSimple(uint8 offset, const OPLOperator &op);
325 	void programOperator(uint8 offset, const OPLOperator &op);
326 	void setOperatorLevel(uint8 offset, const OPLOperator &op, uint8 velocity, uint8 channel, bool forceVolume);
327 
328 	void setupPercussion(const PercussionNote &note);
329 	void playPercussion(uint8 channel, const PercussionNote &note, uint8 velocity);
330 
331 	void programMelodicVoice(uint8 voice, uint8 program);
332 	void playMelodicNote(uint8 voice, uint8 channel, uint8 note, uint8 velocity);
333 	void muteMelodicVoice(uint8 voice);
334 
335 	void initVoices();
336 
337 private:
338 	void onTimer();
339 
340 	Common::TimerManager::TimerProc _adlibTimerProc;
341 	void *_adlibTimerParam;
342 	bool _isOpen;
343 };
344 
createAdLibDriver()345 MidiDriver *createAdLibDriver() {
346 	return new AdLibDriver(g_system->getMixer());
347 }
348 
reset()349 void AdLibChannel::reset() {
350 	_program = 0;
351 	_volume = 127;
352 	_pedal = 0;
353 }
354 
355 /*
356 	bit 7 - Clear:  AM depth is 1 dB
357 	bit 6 - Clear:  Vibrato depth is 7 cent
358 	bit 5 - Set:    Rhythm enabled  (6 melodic voices)
359 	bit 4 - Bass drum off
360 	bit 3 - Snare drum off
361 	bit 2 - Tom tom off
362 	bit 1 - Cymbal off
363 	bit 0 - Hi Hat off
364 */
365 const uint8 kDefaultPercussionMask = 0x20;
366 
open()367 int AdLibDriver::open() {
368 	if (_isOpen)
369 		return MERR_ALREADY_OPEN;
370 
371 	_isOpen = true;
372 
373 	_opl = OPL::Config::create();
374 	_opl->init();
375 	_opl->writeReg(0x1, 0x20); // set bit 5 (enable all waveforms)
376 
377 	// Reset the OPL registers.
378 	for (uint i = 0; i < kNumVoices; ++i) {
379 		_opl->writeReg(0xA0 + i, 0); // frequency
380 		_opl->writeReg(0xB0 + i, 0); // key on
381 		_opl->writeReg(0xC0 + i, 0); // feedback
382 	}
383 	_opl->writeReg(0xBD, kDefaultPercussionMask);
384 
385 	initVoices();
386 
387 	_opl->start(new Common::Functor0Mem<void, AdLibDriver>(this, &AdLibDriver::onTimer));
388 	return 0;
389 }
390 
close()391 void AdLibDriver::close() {
392 	if (!_isOpen)
393 		return;
394 
395 	_isOpen = false;
396 
397 	delete _opl;
398 }
399 
send(uint32 b)400 void AdLibDriver::send(uint32 b) {
401 	uint channel = b & 0xf;
402 	uint cmd = (b >> 4) & 0xf;
403 	uint param1 = (b >> 8) & 0xff;
404 	uint param2 = (b >> 16) & 0xff;
405 
406 	switch (cmd) {
407 	case 8:
408 		noteOff(channel, param1);
409 		break;
410 	case 9:
411 		// TODO: map volume?
412 		noteOn(channel, param1, param2);
413 		break;
414 	case 11:
415 		// controller change
416 		switch (param1) {
417 		case 1:
418 			setModulationWheel(channel, param2);
419 			break;
420 		case 4:
421 			setFootController(channel, param2);
422 			break;
423 		case 7:
424 			setVolume(channel, param2);
425 			break;
426 		case 123:
427 			// all notes off
428 			allNotesOff();
429 			break;
430 		default:
431 			break;
432 		}
433 		break;
434 	case 12:
435 		// program change
436 		_channels[channel]._program = param1;
437 		break;
438 	case 14:
439 		setPitchBend(channel, (param1 | (param2 << 7)) - 0x2000);
440 		break;
441 	default:
442 		break;
443 	}
444 }
445 
noteOff(uint8 channel,uint8 note)446 void AdLibDriver::noteOff(uint8 channel, uint8 note) {
447 	if (channel == 9) {
448 		if (note < 35 || note > 81)
449 			return;
450 
451 		_percussionMask &= ~(1 << percussionNotes[note - 35].percussion);
452 		_opl->writeReg(0xBD, _percussionMask);
453 		return;
454 	}
455 
456 	for (int i = kNumMelodic - 1; i >= 0; --i) {
457 		if (_voices[i]._channel != channel)
458 			continue;
459 		if (_voices[i]._key != note)
460 			continue;
461 		muteMelodicVoice(i);
462 		_voices[i]._used = false;
463 		return;
464 	}
465 
466 	//debug(1, "failed to find voice off for channel %d, note %d", channel, note);
467 }
468 
noteOn(uint8 channel,uint8 note,uint8 velocity)469 void AdLibDriver::noteOn(uint8 channel, uint8 note, uint8 velocity) {
470 	if (channel == 9) {
471 		if (note < 35 || note > 81)
472 			return;
473 
474 		const PercussionNote &info = percussionNotes[note - 35];
475 		if (!info.valid)
476 			return;
477 
478 		if (note != _notesPerPercussion[info.percussion]) {
479 			setupPercussion(info);
480 			_notesPerPercussion[info.percussion] = note;
481 		}
482 
483 		playPercussion(channel, info, velocity);
484 		return;
485 	}
486 
487 	if (velocity == 0) {
488 		noteOff(channel, note);
489 		return;
490 	}
491 
492 	// We want to play a note on a melodic (voice) channel.
493 
494 	// First, look for a voice playing the same note with the same program.
495 	for (uint i = 0; i < kNumMelodic; ++i) {
496 		if (_voices[i]._channel != channel || _voices[i]._key != note)
497 			continue;
498 		if (_voices[i]._program != _channels[channel]._program)
499 			continue;
500 		muteMelodicVoice(i);
501 		playMelodicNote(i, channel, note, velocity);
502 		return;
503 	}
504 
505 	// The loops below try to start at _lastVoice and find a voice to use.
506 	// They ignore _lastVoice itself, and update _lastVoice if they succeed.
507 
508 	// Then, try finding a melodic voice with the same program.
509 	for (uint i = (_lastVoice + 1) % kNumMelodic; i != _lastVoice; i = (i + 1) % kNumMelodic) {
510 		if (_voices[i]._used)
511 			continue;
512 		if (_voices[i]._program != _channels[channel]._program)
513 			continue;
514 		playMelodicNote(i, channel, note, velocity);
515 		_lastVoice = i;
516 		return;
517 	}
518 
519 	// Then, try finding a free melodic voice of any kind.
520 	for (uint i = (_lastVoice + 1) % kNumMelodic; i != _lastVoice; i = (i + 1) % kNumMelodic) {
521 		if (_voices[i]._used)
522 			continue;
523 		programMelodicVoice(i, _channels[channel]._program);
524 		playMelodicNote(i, channel, note, velocity);
525 		_lastVoice = i;
526 		return;
527 	}
528 
529 	// Then just try finding a melodic voice with the same program,
530 	// and steal it.
531 	for (uint i = (_lastVoice + 1) % kNumMelodic; i != _lastVoice; i = (i + 1) % kNumMelodic) {
532 		if (_voices[i]._program != _channels[channel]._program)
533 			continue;
534 		muteMelodicVoice(i);
535 		playMelodicNote(i, channel, note, velocity);
536 		_lastVoice = i;
537 		return;
538 	}
539 
540 	// Finally, just take control of the channel used least recently.
541 	uint voiceId = 0;
542 	uint32 bestTimestamp = 0xffffffff;
543 	for (uint i = 0; i < kNumMelodic; ++i)
544 		if (bestTimestamp > _voices[i]._timestamp) {
545 			voiceId = i;
546 			bestTimestamp = _voices[i]._timestamp;
547 		}
548 
549 	//debug(1, "ran out of voices for channel %d, note %d, program %d: reused voice %d", channel, note, _channels[channel]._program, voiceId);
550 	programMelodicVoice(voiceId, _channels[channel]._program);
551 	playMelodicNote(voiceId, channel, note, velocity);
552 	_lastVoice = voiceId;
553 }
554 
555 // TODO: this doesn't match original
allNotesOff()556 void AdLibDriver::allNotesOff() {
557 	for (uint i = 0; i < kNumMelodic; ++i) {
558 		muteMelodicVoice(i);
559 		_voices[i]._used = false;
560 	}
561 
562 	_percussionMask = kDefaultPercussionMask;
563 	_opl->writeReg(0xBD, kDefaultPercussionMask);
564 }
565 
setModulationWheel(uint8 channel,uint8 value)566 void AdLibDriver::setModulationWheel(uint8 channel, uint8 value) {
567 	if (value >= 64)
568 		_percussionMask |= 0x80;
569 	else
570 		_percussionMask &= 0x7f;
571 
572 	_opl->writeReg(0xBD, _percussionMask);
573 }
574 
setFootController(uint8 channel,uint8 value)575 void AdLibDriver::setFootController(uint8 channel, uint8 value) {
576 	_channels[channel]._pedal = (value >= 64);
577 }
578 
setVolume(uint8 channel,uint8 value)579 void AdLibDriver::setVolume(uint8 channel, uint8 value) {
580 	_channels[channel]._volume = value;
581 }
582 
setPitchBend(uint8 channel,int16 value)583 void AdLibDriver::setPitchBend(uint8 channel, int16 value) {
584 	for (uint i = 0; i < kNumMelodic; ++i) {
585 		if (_voices[i]._channel != channel || !_voices[i]._used)
586 			continue;
587 
588 		// index into frequency table
589 		uint f = 12 + (_voices[i]._key % 12);
590 
591 		int16 bendAmount = value;
592 		if (bendAmount > 0) {
593 			// bend up two semitones
594 			bendAmount *= (melodicFrequencies[f + 2] - melodicFrequencies[f]);
595 		} else {
596 			// bend down two semitones
597 			bendAmount *= (melodicFrequencies[f] - melodicFrequencies[f - 2]);
598 		}
599 		bendAmount /= 0x2000;
600 		bendAmount += melodicFrequencies[f]; // add the base frequency
601 		playNote(i, _voices[i]._octave, bendAmount);
602 		_voices[i]._timestamp = g_system->getMillis();
603 	}
604 }
605 
playNote(uint8 voice,uint8 octave,uint16 frequency)606 void AdLibDriver::playNote(uint8 voice, uint8 octave, uint16 frequency) {
607 	/* Percussions are always fed keyOn = 0 even to set the note, as they are activated using the
608 	   BD register instead. I wonder if they can just be fed the same value as melodic voice and
609 	   be done with it. */
610 	uint8 keyOn = (voice < kNumMelodic) ? 0x20 : 0;
611 
612 	// key on, octave, high 2 bits of frequency
613 	_opl->writeReg(0xB0 + voice, keyOn | ((octave & 7) << 2) | ((frequency >> 8) & 3));
614 	// low 8 bits of frequency
615 	_opl->writeReg(0xA0 + voice, frequency & 0xff);
616 }
617 
programOperatorSimple(uint8 offset,const OPLOperator & op)618 void AdLibDriver::programOperatorSimple(uint8 offset, const OPLOperator &op) {
619 	_opl->writeReg(0x40 + offset, op.levels & LEVEL_MASK);
620 	_opl->writeReg(0x60 + offset, op.attackDecay);
621 	_opl->writeReg(0x80 + offset, op.sustainRelease);
622 }
623 
programOperator(uint8 offset,const OPLOperator & op)624 void AdLibDriver::programOperator(uint8 offset, const OPLOperator &op) {
625 	_opl->writeReg(0x20 + offset, op.characteristic);
626 	_opl->writeReg(0x60 + offset, op.attackDecay);
627 	_opl->writeReg(0x80 + offset, op.sustainRelease);
628 	_opl->writeReg(0xE0 + offset, op.waveform);
629 	_opl->writeReg(0x40 + offset, op.levels);
630 }
631 
632 const uint16 adlibLogVolume[] = {
633 	0, 37, 58, 73, 85, 95, 103, 110, 116, 121, 127, 131, 135, 139, 143, 146,
634 	149, 153, 155, 158, 161, 163, 165, 168, 170, 172, 174, 176, 178, 179, 181, 183,
635 	184, 186, 188, 189, 191, 192, 193, 195, 196, 197, 198, 200, 201, 202, 203, 204,
636 	205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 219,
637 	220, 221, 222, 223, 223, 224, 225, 226, 226, 227, 228, 228, 229, 230, 231, 231,
638 	232, 233, 233, 234, 234, 235, 236, 236, 237, 237, 238, 239, 239, 240, 240, 241,
639 	241, 242, 242, 243, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249,
640 	249, 250, 250, 251, 251, 252, 252, 253, 253, 253, 254, 254, 255, 255, 256, 256,
641 	256
642 };
643 
setOperatorLevel(uint8 offset,const OPLOperator & op,uint8 velocity,uint8 channel,bool forceVolume)644 void AdLibDriver::setOperatorLevel(uint8 offset, const OPLOperator &op, uint8 velocity, uint8 channel, bool forceVolume) {
645 	uint8 programLevel = LEVEL_MASK;
646 	if (!forceVolume)
647 		programLevel -= (op.levels & LEVEL_MASK);
648 
649 	uint32 noteLevel = adlibLogVolume[velocity];
650 	uint32 channelLevel = adlibLogVolume[_channels[channel]._volume];
651 	// programLevel comes from the static data and is probably already in the correct logarithmic scale
652 	uint32 finalLevel = LEVEL_MASK - ((noteLevel * channelLevel * programLevel) >> 16);
653 
654 	// high 2 bits are scaling level, the rest is (inversed) volume
655 	_opl->writeReg(0x40 + offset, (op.levels & 0xc0) | (finalLevel & 0x3f));
656 }
657 
658 const uint8 operatorOffsetsForPercussion[] = {
659 	0x11, // hi-hat
660 	0x15, // cymbal
661 	0x12, // tom tom
662 	0x14  // snare drum
663 };
664 
setupPercussion(const PercussionNote & note)665 void AdLibDriver::setupPercussion(const PercussionNote &note) {
666 	if (note.percussion < 4) {
667 		// simple percussion (1 operator)
668 
669 		// turn off relevant percussion
670 		_percussionMask &= ~(1 << note.percussion);
671 		_opl->writeReg(0xBD, _percussionMask);
672 
673 		programOperatorSimple(operatorOffsetsForPercussion[note.percussion], note.op[0]);
674 		return;
675 	}
676 
677 	// bass drum (2 operators)
678 
679 	// turn off bass drum
680 	_percussionMask &= ~(0x10);
681 	_opl->writeReg(0xBD, _percussionMask);
682 
683 	programOperator(0x10, note.op[0]);
684 	programOperator(0x13, note.op[1]);
685 
686 	_opl->writeReg(0xC0 + 6, note.feedbackAlgo);
687 }
688 
playPercussion(uint8 channel,const PercussionNote & note,uint8 velocity)689 void AdLibDriver::playPercussion(uint8 channel, const PercussionNote &note, uint8 velocity) {
690 	if (note.percussion < 4) {
691 		// simple percussion (1 operator)
692 
693 		// turn off relevant percussion
694 		_percussionMask &= ~(1 << note.percussion);
695 		_opl->writeReg(0xBD, _percussionMask);
696 
697 		setOperatorLevel(operatorOffsetsForPercussion[note.percussion], note.op[0], velocity, channel, true);
698 
699 		if (note.percussion == 2) {
700 			// tom tom
701 			playNote(8, note.octave, note.frequency);
702 		} else if (note.percussion == 3) {
703 			// snare drum
704 			playNote(7, note.octave, note.frequency);
705 		}
706 
707 		// turn on relevant percussion
708 		_percussionMask |= (1 << note.percussion);
709 		_opl->writeReg(0xBD, _percussionMask);
710 		return;
711 	}
712 
713 	// turn off bass drum
714 	_percussionMask &= ~(0x10);
715 	_opl->writeReg(0xBD, _percussionMask);
716 
717 	if (note.feedbackAlgo & 1) {
718 		// operators 1 and 2 in additive synthesis
719 		setOperatorLevel(0x10, note.op[0], velocity, channel, true);
720 		setOperatorLevel(0x13, note.op[1], velocity, channel, true);
721 	} else {
722 		// operator 2 is modulating operator 1
723 		setOperatorLevel(0x13, note.op[1], velocity, channel, true);
724 	}
725 
726 	playNote(6, note.octave, note.frequency);
727 
728 	// turn on bass drum
729 	_percussionMask |= 0x10;
730 	_opl->writeReg(0xBD, _percussionMask);
731 }
732 
733 const uint8 offset1ForMelodic[kNumVoices] = { 0x0,  0x1,  0x2,  0x8,  0x9,  0xa, 0x10, 0x11, 0x12 };
734 const uint8 offset2ForMelodic[kNumVoices] = { 0x3,  0x4,  0x5,  0xb,  0xc,  0xd, 0x13, 0x14, 0x15 };
735 
programMelodicVoice(uint8 voice,uint8 program)736 void AdLibDriver::programMelodicVoice(uint8 voice, uint8 program) {
737 	assert(program < 128);
738 	assert(voice < kNumMelodic);
739 
740 	const MelodicProgram &info = melodicPrograms[program];
741 	uint8 offset1 = offset1ForMelodic[voice];
742 	uint8 offset2 = offset2ForMelodic[voice];
743 
744 	// Start at lowest volume.
745 	_opl->writeReg(0x40 + offset1, LEVEL_MASK);
746 	_opl->writeReg(0x40 + offset2, LEVEL_MASK);
747 
748 	muteMelodicVoice(voice);
749 
750 	programOperator(offset1, info.op[0]);
751 	programOperator(offset2, info.op[1]);
752 
753 	_opl->writeReg(0xC0 + voice, info.feedbackAlgo);
754 }
755 
playMelodicNote(uint8 voice,uint8 channel,uint8 note,uint8 velocity)756 void AdLibDriver::playMelodicNote(uint8 voice, uint8 channel, uint8 note, uint8 velocity) {
757 	assert(voice < kNumMelodic);
758 
759 	uint8 octave = note / 12;
760 	uint8 f = 12 + (note % 12);
761 
762 	if (octave > 7)
763 		octave = 7;
764 
765 	const MelodicProgram &info = melodicPrograms[_channels[channel]._program];
766 	uint8 offset1 = offset1ForMelodic[voice];
767 	uint8 offset2 = offset2ForMelodic[voice];
768 
769 	if (info.feedbackAlgo & 1) {
770 		setOperatorLevel(offset1, info.op[0], velocity, channel, false);
771 		setOperatorLevel(offset2, info.op[1], velocity, channel, false);
772 	} else {
773 		setOperatorLevel(offset2, info.op[1], velocity, channel, true);
774 	}
775 
776 	playNote(voice, octave, melodicFrequencies[f]);
777 
778 	_voices[voice]._program = _channels[channel]._program;
779 	_voices[voice]._key = note;
780 	_voices[voice]._channel = channel;
781 	_voices[voice]._timestamp = g_system->getMillis();
782 	_voices[voice]._frequency = melodicFrequencies[f];
783 	_voices[voice]._octave = octave;
784 	_voices[voice]._used = true;
785 }
786 
muteMelodicVoice(uint8 voice)787 void AdLibDriver::muteMelodicVoice(uint8 voice) {
788 	_opl->writeReg(0xB0 + voice, 0 | ((_voices[voice]._octave & 7) << 2) | ((_voices[voice]._frequency >> 8) & 3));
789 }
790 
allocateChannel()791 MidiChannel *AdLibDriver::allocateChannel() {
792 	for (uint i = 0; i < 16; ++i) {
793 		if (i == 9)
794 			continue;
795 
796 		if (_channels[i].allocate())
797 			return &_channels[i];
798 	}
799 
800 	return NULL;
801 }
802 
onTimer()803 void AdLibDriver::onTimer() {
804 	if (_adlibTimerProc)
805 		(*_adlibTimerProc)(_adlibTimerParam);
806 }
807 
initVoices()808 void AdLibDriver::initVoices() {
809 	_percussionMask = kDefaultPercussionMask;
810 	_opl->writeReg(0xBD, _percussionMask);
811 
812 	for (uint i = 0; i < 16; ++i)
813 		_channels[i].reset();
814 
815 	for (uint i = 0; i < kNumMelodic; ++i) {
816 		_voices[i]._key = 0xff;
817 		_voices[i]._program = 0xff;
818 		_voices[i]._channel = 0xff;
819 		_voices[i]._timestamp = 0;
820 		_voices[i]._frequency = 0;
821 		_voices[i]._octave = 0;
822 		_voices[i]._used = false;
823 	}
824 
825 	for (uint i = 0; i < kNumPercussion; ++i)
826 		_notesPerPercussion[i] = 0xff;
827 
828 	_lastVoice = 0;
829 }
830 
831 } // namespace Parallaction
832