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 "ultima/nuvie/sound/adplug/opl_class.h"
24 #include "common/scummsys.h"
25
26 namespace Ultima {
27 namespace Nuvie {
28
29 #ifndef PI
30 #define PI 3.14159265358979323846
31 #endif
32
33 #ifdef _MSC_VER
34 # define INLINE __inline
35 #elif defined(__GNUC__)
36 # define INLINE inline
37 #else
38 # define INLINE
39 #endif
40
41 /* output final shift */
42 #if (OPL_SAMPLE_BITS==16)
43 #define FINAL_SH (0)
44 #define MAXOUT (+32767)
45 #define MINOUT (-32768)
46 #else
47 #define FINAL_SH (8)
48 #define MAXOUT (+127)
49 #define MINOUT (-128)
50 #endif
51
52
53 #define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */
54 #define EG_SH 16 /* 16.16 fixed point (EG timing) */
55 #define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */
56 #define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */
57
58 #define FREQ_MASK ((1<<FREQ_SH)-1)
59
60 /* envelope output entries */
61 #define ENV_BITS 10
62 #define ENV_LEN (1<<ENV_BITS)
63 #define ENV_STEP (128.0/ENV_LEN)
64
65 #define MAX_ATT_INDEX ((1<<(ENV_BITS-1))-1) /*511*/
66 #define MIN_ATT_INDEX (0)
67
68
69
70
71
72
73
74 /* register number to channel number , slot offset */
75 #define SLOT1 0
76 #define SLOT2 1
77
78 /* Envelope Generator phases */
79
80 #define EG_ATT 4
81 #define EG_DEC 3
82 #define EG_SUS 2
83 #define EG_REL 1
84 #define EG_OFF 0
85
86 #define OPL_TYPE_WAVESEL 0x01 /* waveform select */
87 #define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */
88 #define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */
89 #define OPL_TYPE_IO 0x08 /* I/O port */
90
91 /* ---------- Generic interface section ---------- */
92 #define OPL_TYPE_YM3526 (0)
93 #define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
94 #define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO)
95
96
97 /* mapping of register number (offset) to slot number used by the emulator */
98 static const int slot_array[32] = {
99 0, 2, 4, 1, 3, 5, -1, -1,
100 6, 8, 10, 7, 9, 11, -1, -1,
101 12, 14, 16, 13, 15, 17, -1, -1,
102 -1, -1, -1, -1, -1, -1, -1, -1
103 };
104
105 /* key scale level */
106 /* table is 3dB/octave , DV converts this into 6dB/octave */
107 /* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */
108 #define DV (0.1875/2.0)
109 static const uint32 ksl_tab[8 * 16] = {
110 /* OCT 0 */
111 (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
112 (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
113 (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
114 (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
115 /* OCT 1 */
116 (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
117 (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
118 (uint32)(0.000 / DV), (uint32)(0.750 / DV), (uint32)(1.125 / DV), (uint32)(1.500 / DV),
119 (uint32)(1.875 / DV), (uint32)(2.250 / DV), (uint32)(2.625 / DV), (uint32)(3.000 / DV),
120 /* OCT 2 */
121 (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
122 (uint32)(0.000 / DV), (uint32)(1.125 / DV), (uint32)(1.875 / DV), (uint32)(2.625 / DV),
123 (uint32)(3.000 / DV), (uint32)(3.750 / DV), (uint32)(4.125 / DV), (uint32)(4.500 / DV),
124 (uint32)(4.875 / DV), (uint32)(5.250 / DV), (uint32)(5.625 / DV), (uint32)(6.000 / DV),
125 /* OCT 3 */
126 (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(1.875 / DV),
127 (uint32)(3.000 / DV), (uint32)(4.125 / DV), (uint32)(4.875 / DV), (uint32)(5.625 / DV),
128 (uint32)(6.000 / DV), (uint32)(6.750 / DV), (uint32)(7.125 / DV), (uint32)(7.500 / DV),
129 (uint32)(7.875 / DV), (uint32)(8.250 / DV), (uint32)(8.625 / DV), (uint32)(9.000 / DV),
130 /* OCT 4 */
131 (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(3.000 / DV), (uint32)(4.875 / DV),
132 (uint32)(6.000 / DV), (uint32)(7.125 / DV), (uint32)(7.875 / DV), (uint32)(8.625 / DV),
133 (uint32)(9.000 / DV), (uint32)(9.750 / DV), (uint32)(10.125 / DV), (uint32)(10.500 / DV),
134 (uint32)(10.875 / DV), (uint32)(11.250 / DV), (uint32)(11.625 / DV), (uint32)(12.000 / DV),
135 /* OCT 5 */
136 (uint32)(0.000 / DV), (uint32)(3.000 / DV), (uint32)(6.000 / DV), (uint32)(7.875 / DV),
137 (uint32)(9.000 / DV), (uint32)(10.125 / DV), (uint32)(10.875 / DV), (uint32)(11.625 / DV),
138 (uint32)(12.000 / DV), (uint32)(12.750 / DV), (uint32)(13.125 / DV), (uint32)(13.500 / DV),
139 (uint32)(13.875 / DV), (uint32)(14.250 / DV), (uint32)(14.625 / DV), (uint32)(15.000 / DV),
140 /* OCT 6 */
141 (uint32)(0.000 / DV), (uint32)(6.000 / DV), (uint32)(9.000 / DV), (uint32)(10.875 / DV),
142 (uint32)(12.000 / DV), (uint32)(13.125 / DV), (uint32)(13.875 / DV), (uint32)(14.625 / DV),
143 (uint32)(15.000 / DV), (uint32)(15.750 / DV), (uint32)(16.125 / DV), (uint32)(16.500 / DV),
144 (uint32)(16.875 / DV), (uint32)(17.250 / DV), (uint32)(17.625 / DV), (uint32)(18.000 / DV),
145 /* OCT 7 */
146 (uint32)(0.000 / DV), (uint32)(9.000 / DV), (uint32)(12.000 / DV), (uint32)(13.875 / DV),
147 (uint32)(15.000 / DV), (uint32)(16.125 / DV), (uint32)(16.875 / DV), (uint32)(17.625 / DV),
148 (uint32)(18.000 / DV), (uint32)(18.750 / DV), (uint32)(19.125 / DV), (uint32)(19.500 / DV),
149 (uint32)(19.875 / DV), (uint32)(20.250 / DV), (uint32)(20.625 / DV), (uint32)(21.000 / DV)
150
151 };
152 #undef DV
153
154 /* sustain level table (3dB per step) */
155 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
156 #define SC(db) (uint32) ( db * (2.0/ENV_STEP) )
157 static const uint32 sl_tab[16] = {
158 SC(0), SC(1), SC(2), SC(3), SC(4), SC(5), SC(6), SC(7),
159 SC(8), SC(9), SC(10), SC(11), SC(12), SC(13), SC(14), SC(31)
160 };
161 #undef SC
162
163
164 #define RATE_STEPS (8)
165 static const unsigned char eg_inc[15 * RATE_STEPS] = {
166
167 /*cycle:0 1 2 3 4 5 6 7*/
168
169 /* 0 */ 0, 1, 0, 1, 0, 1, 0, 1, /* rates 00..12 0 (increment by 0 or 1) */
170 /* 1 */ 0, 1, 0, 1, 1, 1, 0, 1, /* rates 00..12 1 */
171 /* 2 */ 0, 1, 1, 1, 0, 1, 1, 1, /* rates 00..12 2 */
172 /* 3 */ 0, 1, 1, 1, 1, 1, 1, 1, /* rates 00..12 3 */
173
174 /* 4 */ 1, 1, 1, 1, 1, 1, 1, 1, /* rate 13 0 (increment by 1) */
175 /* 5 */ 1, 1, 1, 2, 1, 1, 1, 2, /* rate 13 1 */
176 /* 6 */ 1, 2, 1, 2, 1, 2, 1, 2, /* rate 13 2 */
177 /* 7 */ 1, 2, 2, 2, 1, 2, 2, 2, /* rate 13 3 */
178
179 /* 8 */ 2, 2, 2, 2, 2, 2, 2, 2, /* rate 14 0 (increment by 2) */
180 /* 9 */ 2, 2, 2, 4, 2, 2, 2, 4, /* rate 14 1 */
181 /*10 */ 2, 4, 2, 4, 2, 4, 2, 4, /* rate 14 2 */
182 /*11 */ 2, 4, 4, 4, 2, 4, 4, 4, /* rate 14 3 */
183
184 /*12 */ 4, 4, 4, 4, 4, 4, 4, 4, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 4) */
185 /*13 */ 8, 8, 8, 8, 8, 8, 8, 8, /* rates 15 2, 15 3 for attack */
186 /*14 */ 0, 0, 0, 0, 0, 0, 0, 0, /* infinity rates for attack and decay(s) */
187 };
188
189
190 #define O(a) (a*RATE_STEPS)
191
192 /*note that there is no O(13) in this table - it's directly in the code */
193 static const unsigned char eg_rate_select[16 + 64 + 16] = { /* Envelope Generator rates (16 + 64 rates + 16 RKS) */
194 /* 16 dummy (infinite time) rates */
195 O(14), O(14), O(14), O(14), O(14), O(14), O(14), O(14),
196 O(14), O(14), O(14), O(14), O(14), O(14), O(14), O(14),
197
198 /* rates 00-12 */
199 O(0), O(1), O(2), O(3),
200 O(0), O(1), O(2), O(3),
201 O(0), O(1), O(2), O(3),
202 O(0), O(1), O(2), O(3),
203 O(0), O(1), O(2), O(3),
204 O(0), O(1), O(2), O(3),
205 O(0), O(1), O(2), O(3),
206 O(0), O(1), O(2), O(3),
207 O(0), O(1), O(2), O(3),
208 O(0), O(1), O(2), O(3),
209 O(0), O(1), O(2), O(3),
210 O(0), O(1), O(2), O(3),
211 O(0), O(1), O(2), O(3),
212
213 /* rate 13 */
214 O(4), O(5), O(6), O(7),
215
216 /* rate 14 */
217 O(8), O(9), O(10), O(11),
218
219 /* rate 15 */
220 O(12), O(12), O(12), O(12),
221
222 /* 16 dummy rates (same as 15 3) */
223 O(12), O(12), O(12), O(12), O(12), O(12), O(12), O(12),
224 O(12), O(12), O(12), O(12), O(12), O(12), O(12), O(12),
225
226 };
227 #undef O
228
229 //rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
230 //shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
231 //mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0
232
233 #define O(a) (a*1)
234 static const unsigned char eg_rate_shift[16 + 64 + 16] = { /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */
235 /* 16 infinite time rates */
236 O(0), O(0), O(0), O(0), O(0), O(0), O(0), O(0),
237 O(0), O(0), O(0), O(0), O(0), O(0), O(0), O(0),
238
239 /* rates 00-12 */
240 O(12), O(12), O(12), O(12),
241 O(11), O(11), O(11), O(11),
242 O(10), O(10), O(10), O(10),
243 O(9), O(9), O(9), O(9),
244 O(8), O(8), O(8), O(8),
245 O(7), O(7), O(7), O(7),
246 O(6), O(6), O(6), O(6),
247 O(5), O(5), O(5), O(5),
248 O(4), O(4), O(4), O(4),
249 O(3), O(3), O(3), O(3),
250 O(2), O(2), O(2), O(2),
251 O(1), O(1), O(1), O(1),
252 O(0), O(0), O(0), O(0),
253
254 /* rate 13 */
255 O(0), O(0), O(0), O(0),
256
257 /* rate 14 */
258 O(0), O(0), O(0), O(0),
259
260 /* rate 15 */
261 O(0), O(0), O(0), O(0),
262
263 /* 16 dummy rates (same as 15 3) */
264 O(0), O(0), O(0), O(0), O(0), O(0), O(0), O(0),
265 O(0), O(0), O(0), O(0), O(0), O(0), O(0), O(0),
266
267 };
268 #undef O
269
270
271 /* multiple table */
272 #define ML 2
273 static const uint8 mul_tab[16] = {
274 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */
275 (uint8)(0.50 * ML), (uint8)(0.00 * ML), (uint8)(0.00 * ML), (uint8)(0.00 * ML), (uint8)(4.00 * ML), (uint8)(0.00 * ML), (uint8)(6.00 * ML), (uint8)(7.00 * ML),
276 (uint8)(8.00 * ML), (uint8)(9.00 * ML), (uint8)(10.00 * ML), (uint8)(10.00 * ML), (uint8)(12.00 * ML), (uint8)(12.00 * ML), (uint8)(15.00 * ML), (uint8)(15.00 * ML)
277 };
278 #undef ML
279
280
281
282 #define ENV_QUIET (TL_TAB_LEN>>4)
283
284
285
286
287 /* LFO Amplitude Modulation table (verified on real YM3812)
288 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples
289
290 Length: 210 elements.
291
292 Each of the elements has to be repeated
293 exactly 64 times (on 64 consecutive samples).
294 The whole table takes: 64 * 210 = 13440 samples.
295
296 When AM = 1 data is used directly
297 When AM = 0 data is divided by 4 before being used (loosing precision is important)
298 */
299
300 #define LFO_AM_TAB_ELEMENTS 210
301
302 static const uint8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = {
303 0, 0, 0, 0, 0, 0, 0,
304 1, 1, 1, 1,
305 2, 2, 2, 2,
306 3, 3, 3, 3,
307 4, 4, 4, 4,
308 5, 5, 5, 5,
309 6, 6, 6, 6,
310 7, 7, 7, 7,
311 8, 8, 8, 8,
312 9, 9, 9, 9,
313 10, 10, 10, 10,
314 11, 11, 11, 11,
315 12, 12, 12, 12,
316 13, 13, 13, 13,
317 14, 14, 14, 14,
318 15, 15, 15, 15,
319 16, 16, 16, 16,
320 17, 17, 17, 17,
321 18, 18, 18, 18,
322 19, 19, 19, 19,
323 20, 20, 20, 20,
324 21, 21, 21, 21,
325 22, 22, 22, 22,
326 23, 23, 23, 23,
327 24, 24, 24, 24,
328 25, 25, 25, 25,
329 26, 26, 26,
330 25, 25, 25, 25,
331 24, 24, 24, 24,
332 23, 23, 23, 23,
333 22, 22, 22, 22,
334 21, 21, 21, 21,
335 20, 20, 20, 20,
336 19, 19, 19, 19,
337 18, 18, 18, 18,
338 17, 17, 17, 17,
339 16, 16, 16, 16,
340 15, 15, 15, 15,
341 14, 14, 14, 14,
342 13, 13, 13, 13,
343 12, 12, 12, 12,
344 11, 11, 11, 11,
345 10, 10, 10, 10,
346 9, 9, 9, 9,
347 8, 8, 8, 8,
348 7, 7, 7, 7,
349 6, 6, 6, 6,
350 5, 5, 5, 5,
351 4, 4, 4, 4,
352 3, 3, 3, 3,
353 2, 2, 2, 2,
354 1, 1, 1, 1
355 };
356
357 /* LFO Phase Modulation table (verified on real YM3812) */
358 static const int8 lfo_pm_table[8 * 8 * 2] = {
359
360 /* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */
361 0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/
362 0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/
363
364 /* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */
365 0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/
366 1, 0, 0, 0, -1, 0, 0, 0, /*LFO PM depth = 1*/
367
368 /* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */
369 1, 0, 0, 0, -1, 0, 0, 0, /*LFO PM depth = 0*/
370 2, 1, 0, -1, -2, -1, 0, 1, /*LFO PM depth = 1*/
371
372 /* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */
373 1, 0, 0, 0, -1, 0, 0, 0, /*LFO PM depth = 0*/
374 3, 1, 0, -1, -3, -1, 0, 1, /*LFO PM depth = 1*/
375
376 /* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */
377 2, 1, 0, -1, -2, -1, 0, 1, /*LFO PM depth = 0*/
378 4, 2, 0, -2, -4, -2, 0, 2, /*LFO PM depth = 1*/
379
380 /* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */
381 2, 1, 0, -1, -2, -1, 0, 1, /*LFO PM depth = 0*/
382 5, 2, 0, -2, -5, -2, 0, 2, /*LFO PM depth = 1*/
383
384 /* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */
385 3, 1, 0, -1, -3, -1, 0, 1, /*LFO PM depth = 0*/
386 6, 3, 0, -3, -6, -3, 0, 3, /*LFO PM depth = 1*/
387
388 /* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */
389 3, 1, 0, -1, -3, -1, 0, 1, /*LFO PM depth = 0*/
390 7, 3, 0, -3, -7, -3, 0, 3 /*LFO PM depth = 1*/
391 };
392
393
OplClass(int rate,bool bit16,bool usestereo)394 OplClass::OplClass(int rate, bool bit16, bool usestereo)
395 : use16bit(bit16), stereo(usestereo), oplRate(rate) {
396 YM3812NumChips = 0;
397 num_lock = 0;
398 cur_chip = NULL;
399 YM3812Init(1, 3579545, rate);
400 }
401
update(short * buf,int samples)402 void OplClass::update(short *buf, int samples) {
403 int i;
404
405 if (use16bit) {
406 YM3812UpdateOne(0, buf, samples);
407
408 if (stereo)
409 for (i = samples - 1; i >= 0; i--) {
410 buf[i * 2] = buf[i];
411 buf[i * 2 + 1] = buf[i];
412 }
413 } else {
414 short *tempbuf = new short[stereo ? samples * 2 : samples];
415 YM3812UpdateOne(0, tempbuf, samples);
416
417 if (stereo)
418 for (i = samples - 1; i >= 0; i--) {
419 tempbuf[i * 2] = tempbuf[i];
420 tempbuf[i * 2 + 1] = tempbuf[i];
421 }
422
423 for (i = 0; i < (stereo ? samples * 2 : samples); i++)
424 ((char *)buf)[i] = (tempbuf[i] >> 8) ^ 0x80;
425
426 delete [] tempbuf;
427 }
428 }
429
write(int reg,int val)430 void OplClass::write(int reg, int val) {
431 YM3812Write(0, 0, reg);
432 YM3812Write(0, 1, val);
433 }
434
init()435 void OplClass::init() {
436 YM3812ResetChip(0);
437 }
438
limit(int val,int max,int min)439 INLINE int limit(int val, int max, int min) {
440 if (val > max)
441 val = max;
442 else if (val < min)
443 val = min;
444
445 return val;
446 }
447
448
449 /* status set and IRQ handling */
OPL_STATUS_SET(FM_OPL * OPL,int flag)450 INLINE void OPL_STATUS_SET(FM_OPL *OPL, int flag) {
451 /* set status flag */
452 OPL->status |= flag;
453 if (!(OPL->status & 0x80)) {
454 if (OPL->status & OPL->statusmask) {
455 /* IRQ on */
456 OPL->status |= 0x80;
457 /* callback user interrupt handler (IRQ is OFF to ON) */
458 if (OPL->IRQHandler)(OPL->IRQHandler)(OPL->IRQParam, 1);
459 }
460 }
461 }
462
463 /* status reset and IRQ handling */
OPL_STATUS_RESET(FM_OPL * OPL,int flag)464 INLINE void OPL_STATUS_RESET(FM_OPL *OPL, int flag) {
465 /* reset status flag */
466 OPL->status &= ~flag;
467 if ((OPL->status & 0x80)) {
468 if (!(OPL->status & OPL->statusmask)) {
469 OPL->status &= 0x7f;
470 /* callback user interrupt handler (IRQ is ON to OFF) */
471 if (OPL->IRQHandler)(OPL->IRQHandler)(OPL->IRQParam, 0);
472 }
473 }
474 }
475
476 /* IRQ mask set */
OPL_STATUSMASK_SET(FM_OPL * OPL,int flag)477 INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL, int flag) {
478 OPL->statusmask = flag;
479 /* IRQ handling check */
480 OPL_STATUS_SET(OPL, 0);
481 OPL_STATUS_RESET(OPL, 0);
482 }
483
484
485 /* advance LFO to next sample */
advance_lfo(FM_OPL * OPL)486 INLINE void OplClass::advance_lfo(FM_OPL *OPL) {
487 uint8 tmp;
488
489 /* LFO */
490 OPL->lfo_am_cnt += OPL->lfo_am_inc;
491 if (OPL->lfo_am_cnt >= (uint32)(LFO_AM_TAB_ELEMENTS << LFO_SH)) /* lfo_am_table is 210 elements long */
492 OPL->lfo_am_cnt -= (uint32)(LFO_AM_TAB_ELEMENTS << LFO_SH);
493
494 tmp = lfo_am_table[ OPL->lfo_am_cnt >> LFO_SH ];
495
496 if (OPL->lfo_am_depth)
497 LFO_AM = tmp;
498 else
499 LFO_AM = tmp >> 2;
500
501 OPL->lfo_pm_cnt += OPL->lfo_pm_inc;
502 LFO_PM = ((OPL->lfo_pm_cnt >> LFO_SH) & 7) | OPL->lfo_pm_depth_range;
503 }
504
505 /* advance to next sample */
advancex(FM_OPL * OPL)506 INLINE void OplClass::advancex(FM_OPL *OPL) {
507 OPL_CH *CH;
508 OPL_SLOT *op;
509 int i;
510
511 OPL->eg_timer += OPL->eg_timer_add;
512
513 while (OPL->eg_timer >= OPL->eg_timer_overflow) {
514 OPL->eg_timer -= OPL->eg_timer_overflow;
515
516 OPL->eg_cnt++;
517
518 for (i = 0; i < 9 * 2; i++) {
519 CH = &OPL->P_CH[i / 2];
520 op = &CH->SLOT[i & 1];
521
522 /* Envelope Generator */
523 switch (op->state) {
524 case EG_ATT: { /* attack phase */
525
526 if (!(OPL->eg_cnt & ((1 << op->eg_sh_ar) - 1))) {
527 op->volume += (~op->volume *
528 (eg_inc[op->eg_sel_ar + ((OPL->eg_cnt >> op->eg_sh_ar) & 7)])
529 ) >> 3;
530
531 if (op->volume <= MIN_ATT_INDEX) {
532 op->volume = MIN_ATT_INDEX;
533 op->state = EG_DEC;
534 }
535
536 }
537
538 }
539 break;
540
541 case EG_DEC: /* decay phase */
542 if (!(OPL->eg_cnt & ((1 << op->eg_sh_dr) - 1))) {
543 op->volume += eg_inc[op->eg_sel_dr + ((OPL->eg_cnt >> op->eg_sh_dr) & 7)];
544
545 if (op->volume >= (int32)op->sl)
546 op->state = EG_SUS;
547
548 }
549 break;
550
551 case EG_SUS: /* sustain phase */
552
553 /* this is important behaviour:
554 one can change percusive/non-percussive modes on the fly and
555 the chip will remain in sustain phase - verified on real YM3812 */
556
557 if (op->eg_type) { /* non-percussive mode */
558 /* do nothing */
559 } else { /* percussive mode */
560 /* during sustain phase chip adds Release Rate (in percussive mode) */
561 if (!(OPL->eg_cnt & ((1 << op->eg_sh_rr) - 1))) {
562 op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt >> op->eg_sh_rr) & 7)];
563
564 if (op->volume >= MAX_ATT_INDEX)
565 op->volume = MAX_ATT_INDEX;
566 }
567 /* else do nothing in sustain phase */
568 }
569 break;
570
571 case EG_REL: /* release phase */
572 if (!(OPL->eg_cnt & ((1 << op->eg_sh_rr) - 1))) {
573 op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt >> op->eg_sh_rr) & 7)];
574
575 if (op->volume >= MAX_ATT_INDEX) {
576 op->volume = MAX_ATT_INDEX;
577 op->state = EG_OFF;
578 }
579
580 }
581 break;
582
583 default:
584 break;
585 }
586 }
587 }
588
589 for (i = 0; i < 9 * 2; i++) {
590 CH = &OPL->P_CH[i / 2];
591 op = &CH->SLOT[i & 1];
592
593 /* Phase Generator */
594 if (op->vib) {
595 uint8 block;
596 unsigned int block_fnum = CH->block_fnum;
597
598 unsigned int fnum_lfo = (block_fnum & 0x0380) >> 7;
599
600 signed int lfo_fn_table_index_offset = lfo_pm_table[LFO_PM + 16 * fnum_lfo ];
601
602 if (lfo_fn_table_index_offset) { /* LFO phase modulation active */
603 block_fnum += lfo_fn_table_index_offset;
604 block = (block_fnum & 0x1c00) >> 10;
605 op->Cnt += (OPL->fn_tab[block_fnum & 0x03ff] >> (7 - block)) * op->mul; //ok
606 } else { /* LFO phase modulation = zero */
607 op->Cnt += op->Incr;
608 }
609 } else { /* LFO phase modulation disabled for this operator */
610 op->Cnt += op->Incr;
611 }
612 }
613
614 /* The Noise Generator of the YM3812 is 23-bit shift register.
615 * Period is equal to 2^23-2 samples.
616 * Register works at sampling frequency of the chip, so output
617 * can change on every sample.
618 *
619 * Output of the register and input to the bit 22 is:
620 * bit0 XOR bit14 XOR bit15 XOR bit22
621 *
622 * Simply use bit 22 as the noise output.
623 */
624
625 OPL->noise_p += OPL->noise_f;
626 i = OPL->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */
627 OPL->noise_p &= FREQ_MASK;
628 while (i) {
629 /*
630 uint32 j;
631 j = ( (OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22) ) & 1;
632 OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1);
633 */
634
635 /*
636 Instead of doing all the logic operations above, we
637 use a trick here (and use bit 0 as the noise output).
638 The difference is only that the noise bit changes one
639 step ahead. This doesn't matter since we don't know
640 what is real state of the noise_rng after the reset.
641 */
642
643 if (OPL->noise_rng & 1) OPL->noise_rng ^= 0x800302;
644 OPL->noise_rng >>= 1;
645
646 i--;
647 }
648 }
649
650
op_calc(uint32 phase,unsigned int env,signed int pm,unsigned int wave_tab)651 INLINE signed int OplClass::op_calc(uint32 phase, unsigned int env, signed int pm, unsigned int wave_tab) {
652 uint32 p;
653
654 p = (env << 4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm << 16))) >> FREQ_SH) & SIN_MASK) ];
655
656 if (p >= TL_TAB_LEN)
657 return 0;
658 return tl_tab[p];
659 }
660
op_calc1(uint32 phase,unsigned int env,signed int pm,unsigned int wave_tab)661 INLINE signed int OplClass::op_calc1(uint32 phase, unsigned int env, signed int pm, unsigned int wave_tab) {
662 uint32 p;
663 int32 i;
664
665 i = (phase & ~FREQ_MASK) + pm;
666
667 /*logerror("i=%08x (i>>16)&511=%8i phase=%i [pm=%08x] ",i, (i>>16)&511, phase>>FREQ_SH, pm);*/
668
669 p = (env << 4) + sin_tab[ wave_tab + ((i >> FREQ_SH) & SIN_MASK)];
670
671 /*logerror("(p&255=%i p>>8=%i) out= %i\n", p&255,p>>8, tl_tab[p&255]>>(p>>8) );*/
672
673 if (p >= TL_TAB_LEN)
674 return 0;
675 return tl_tab[p];
676 }
677
678
679 #define volume_calc(OP) ((OP)->TLL + ((uint32)(OP)->volume) + (LFO_AM & (OP)->AMmask))
680
681 /* calculate output */
OPL_CALC_CH(OPL_CH * CH)682 INLINE void OplClass::OPL_CALC_CH(OPL_CH *CH) {
683 OPL_SLOT *SLOT;
684 unsigned int env;
685 signed int out;
686
687 phase_modulation = 0;
688
689 /* SLOT 1 */
690 SLOT = &CH->SLOT[SLOT1];
691 env = volume_calc(SLOT);
692 out = SLOT->op1_out[0] + SLOT->op1_out[1];
693 SLOT->op1_out[0] = SLOT->op1_out[1];
694 *SLOT->connect1 += SLOT->op1_out[0];
695 SLOT->op1_out[1] = 0;
696 if (env < ENV_QUIET) {
697 if (!SLOT->FB)
698 out = 0;
699 SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out << SLOT->FB), SLOT->wavetable);
700 }
701
702 /* SLOT 2 */
703 SLOT++;
704 env = volume_calc(SLOT);
705 if (env < ENV_QUIET)
706 output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable);
707 }
708
709 /*
710 operators used in the rhythm sounds generation process:
711
712 Envelope Generator:
713
714 channel operator register number Bass High Snare Tom Top
715 / slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal
716 6 / 0 12 50 70 90 f0 +
717 6 / 1 15 53 73 93 f3 +
718 7 / 0 13 51 71 91 f1 +
719 7 / 1 16 54 74 94 f4 +
720 8 / 0 14 52 72 92 f2 +
721 8 / 1 17 55 75 95 f5 +
722
723 Phase Generator:
724
725 channel operator register number Bass High Snare Tom Top
726 / slot number MULTIPLE Drum Hat Drum Tom Cymbal
727 6 / 0 12 30 +
728 6 / 1 15 33 +
729 7 / 0 13 31 + + +
730 7 / 1 16 34 ----- n o t u s e d -----
731 8 / 0 14 32 +
732 8 / 1 17 35 + +
733
734 channel operator register number Bass High Snare Tom Top
735 number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal
736 6 12,15 B6 A6 +
737
738 7 13,16 B7 A7 + + +
739
740 8 14,17 B8 A8 + + +
741
742 */
743
744 /* calculate rhythm */
745
OPL_CALC_RH(OPL_CH * CH,unsigned int noise)746 INLINE void OplClass::OPL_CALC_RH(OPL_CH *CH, unsigned int noise) {
747 OPL_SLOT *SLOT;
748 signed int out;
749 unsigned int env;
750
751
752 /* Bass Drum (verified on real YM3812):
753 - depends on the channel 6 'connect' register:
754 when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out)
755 when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored
756 - output sample always is multiplied by 2
757 */
758
759 phase_modulation = 0;
760 /* SLOT 1 */
761 SLOT = &CH[6].SLOT[SLOT1];
762 env = volume_calc(SLOT);
763
764 out = SLOT->op1_out[0] + SLOT->op1_out[1];
765 SLOT->op1_out[0] = SLOT->op1_out[1];
766
767 if (!SLOT->CON)
768 phase_modulation = SLOT->op1_out[0];
769 //else ignore output of operator 1
770
771 SLOT->op1_out[1] = 0;
772 if (env < ENV_QUIET) {
773 if (!SLOT->FB)
774 out = 0;
775 SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out << SLOT->FB), SLOT->wavetable);
776 }
777
778 /* SLOT 2 */
779 SLOT++;
780 env = volume_calc(SLOT);
781 if (env < ENV_QUIET)
782 output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable) * 2;
783
784
785 /* Phase generation is based on: */
786 // HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases)
787 // SD (16) channel 7->slot 1
788 // TOM (14) channel 8->slot 1
789 // TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases)
790
791 /* Envelope generation based on: */
792 // HH channel 7->slot1
793 // SD channel 7->slot2
794 // TOM channel 8->slot1
795 // TOP channel 8->slot2
796
797
798 /* The following formulas can be well optimized.
799 I leave them in direct form for now (in case I've missed something).
800 */
801
802 /* High Hat (verified on real YM3812) */
803 env = volume_calc(SLOT7_1);
804 if (env < ENV_QUIET) {
805
806 /* high hat phase generation:
807 phase = d0 or 234 (based on frequency only)
808 phase = 34 or 2d0 (based on noise)
809 */
810
811 /* base frequency derived from operator 1 in channel 7 */
812 unsigned char bit7 = ((SLOT7_1->Cnt >> FREQ_SH) >> 7) & 1;
813 unsigned char bit3 = ((SLOT7_1->Cnt >> FREQ_SH) >> 3) & 1;
814 unsigned char bit2 = ((SLOT7_1->Cnt >> FREQ_SH) >> 2) & 1;
815
816 unsigned char res1 = (bit2 ^ bit7) | bit3;
817
818 /* when res1 = 0 phase = 0x000 | 0xd0; */
819 /* when res1 = 1 phase = 0x200 | (0xd0>>2); */
820 uint32 phase = res1 ? (0x200 | (0xd0 >> 2)) : 0xd0;
821
822 /* enable gate based on frequency of operator 2 in channel 8 */
823 unsigned char bit5e = ((SLOT8_2->Cnt >> FREQ_SH) >> 5) & 1;
824 unsigned char bit3e = ((SLOT8_2->Cnt >> FREQ_SH) >> 3) & 1;
825
826 unsigned char res2 = (bit3e ^ bit5e);
827
828 /* when res2 = 0 pass the phase from calculation above (res1); */
829 /* when res2 = 1 phase = 0x200 | (0xd0>>2); */
830 if (res2)
831 phase = (0x200 | (0xd0 >> 2));
832
833
834 /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */
835 /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */
836 if (phase & 0x200) {
837 if (noise)
838 phase = 0x200 | 0xd0;
839 } else
840 /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */
841 /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */
842 {
843 if (noise)
844 phase = 0xd0 >> 2;
845 }
846
847 output[0] += op_calc(phase << FREQ_SH, env, 0, SLOT7_1->wavetable) * 2;
848 }
849
850 /* Snare Drum (verified on real YM3812) */
851 env = volume_calc(SLOT7_2);
852 if (env < ENV_QUIET) {
853 /* base frequency derived from operator 1 in channel 7 */
854 unsigned char bit8 = ((SLOT7_1->Cnt >> FREQ_SH) >> 8) & 1;
855
856 /* when bit8 = 0 phase = 0x100; */
857 /* when bit8 = 1 phase = 0x200; */
858 uint32 phase = bit8 ? 0x200 : 0x100;
859
860 /* Noise bit XOR'es phase by 0x100 */
861 /* when noisebit = 0 pass the phase from calculation above */
862 /* when noisebit = 1 phase ^= 0x100; */
863 /* in other words: phase ^= (noisebit<<8); */
864 if (noise)
865 phase ^= 0x100;
866
867 output[0] += op_calc(phase << FREQ_SH, env, 0, SLOT7_1->wavetable) * 2;
868 }
869
870 /* Tom Tom (verified on real YM3812) */
871 env = volume_calc(SLOT8_1);
872 if (env < ENV_QUIET)
873 output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2;
874
875 /* Top Cymbal (verified on real YM3812) */
876 env = volume_calc(SLOT8_2);
877 if (env < ENV_QUIET) {
878 /* base frequency derived from operator 1 in channel 7 */
879 unsigned char bit7 = ((SLOT7_1->Cnt >> FREQ_SH) >> 7) & 1;
880 unsigned char bit3 = ((SLOT7_1->Cnt >> FREQ_SH) >> 3) & 1;
881 unsigned char bit2 = ((SLOT7_1->Cnt >> FREQ_SH) >> 2) & 1;
882
883 unsigned char res1 = (bit2 ^ bit7) | bit3;
884
885 /* when res1 = 0 phase = 0x000 | 0x100; */
886 /* when res1 = 1 phase = 0x200 | 0x100; */
887 uint32 phase = res1 ? 0x300 : 0x100;
888
889 /* enable gate based on frequency of operator 2 in channel 8 */
890 unsigned char bit5e = ((SLOT8_2->Cnt >> FREQ_SH) >> 5) & 1;
891 unsigned char bit3e = ((SLOT8_2->Cnt >> FREQ_SH) >> 3) & 1;
892
893 unsigned char res2 = (bit3e ^ bit5e);
894 /* when res2 = 0 pass the phase from calculation above (res1); */
895 /* when res2 = 1 phase = 0x200 | 0x100; */
896 if (res2)
897 phase = 0x300;
898
899 output[0] += op_calc(phase << FREQ_SH, env, 0, SLOT8_2->wavetable) * 2;
900 }
901
902 }
903
904
905 /* generic table initialize */
init_tables(void)906 int OplClass::init_tables(void) {
907 signed int i, x;
908 signed int n;
909 double o, m;
910
911
912 for (x = 0; x < TL_RES_LEN; x++) {
913 m = (1 << 16) / pow(2, (x + 1) * (ENV_STEP / 4.0) / 8.0);
914 m = floor(m);
915
916 /* we never reach (1<<16) here due to the (x+1) */
917 /* result fits within 16 bits at maximum */
918
919 n = (int)m; /* 16 bits here */
920 n >>= 4; /* 12 bits here */
921 if (n & 1) /* round to nearest */
922 n = (n >> 1) + 1;
923 else
924 n = n >> 1;
925 /* 11 bits here (rounded) */
926 n <<= 1; /* 12 bits here (as in real chip) */
927 tl_tab[ x * 2 + 0 ] = n;
928 tl_tab[ x * 2 + 1 ] = -tl_tab[ x * 2 + 0 ];
929
930 for (i = 1; i < 12; i++) {
931 tl_tab[ x * 2 + 0 + i * 2 * TL_RES_LEN ] = tl_tab[ x * 2 + 0 ] >> i;
932 tl_tab[ x * 2 + 1 + i * 2 * TL_RES_LEN ] = -tl_tab[ x * 2 + 0 + i * 2 * TL_RES_LEN ];
933 }
934 }
935 /*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/
936
937
938 for (i = 0; i < SIN_LEN; i++) {
939 /* non-standard sinus */
940 m = sin(((i * 2) + 1) * PI / SIN_LEN); /* checked against the real chip */
941
942 /* we never reach zero here due to ((i*2)+1) */
943
944 if (m > 0.0)
945 o = 8 * log(1.0 / m) / log(2); /* convert to 'decibels' */
946 else
947 o = 8 * log(-1.0 / m) / log(2); /* convert to 'decibels' */
948
949 o = o / (ENV_STEP / 4);
950
951 n = (int)(2.0 * o);
952 if (n & 1) /* round to nearest */
953 n = (n >> 1) + 1;
954 else
955 n = n >> 1;
956
957 sin_tab[ i ] = n * 2 + (m >= 0.0 ? 0 : 1);
958
959 /*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/
960 }
961
962 for (i = 0; i < SIN_LEN; i++) {
963 /* waveform 1: __ __ */
964 /* / \____/ \____*/
965 /* output only first half of the sinus waveform (positive one) */
966
967 if (i & (1 << (SIN_BITS - 1)))
968 sin_tab[1 * SIN_LEN + i] = TL_TAB_LEN;
969 else
970 sin_tab[1 * SIN_LEN + i] = sin_tab[i];
971
972 /* waveform 2: __ __ __ __ */
973 /* / \/ \/ \/ \*/
974 /* abs(sin) */
975
976 sin_tab[2 * SIN_LEN + i] = sin_tab[i & (SIN_MASK >> 1) ];
977
978 /* waveform 3: _ _ _ _ */
979 /* / |_/ |_/ |_/ |_*/
980 /* abs(output only first quarter of the sinus waveform) */
981
982 if (i & (1 << (SIN_BITS - 2)))
983 sin_tab[3 * SIN_LEN + i] = TL_TAB_LEN;
984 else
985 sin_tab[3 * SIN_LEN + i] = sin_tab[i & (SIN_MASK >> 2)];
986
987 /*logerror("FMOPL.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] );
988 logerror("FMOPL.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] );
989 logerror("FMOPL.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] );*/
990 }
991 /*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/
992
993 return 1;
994 }
995
OPLCloseTable(void)996 static void OPLCloseTable(void) {
997 #ifdef SAVE_SAMPLE
998 fclose(sample[0]);
999 #endif
1000 }
1001
1002
1003
OPL_initalize(FM_OPL * OPL)1004 static void OPL_initalize(FM_OPL *OPL) {
1005 int i;
1006
1007 /* frequency base */
1008 OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate : 0;
1009
1010
1011 /* Timer base time */
1012 OPL->TimerBase = 1.0 / ((double)OPL->clock / 72.0);
1013
1014 /* make fnumber -> increment counter table */
1015 for (i = 0 ; i < 1024 ; i++) {
1016 /* opn phase increment counter = 20bit */
1017 OPL->fn_tab[i] = (uint32)((double)i * 64 * OPL->freqbase * (1 << (FREQ_SH - 10))); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */
1018 }
1019
1020
1021 /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */
1022 /* One entry from LFO_AM_TABLE lasts for 64 samples */
1023 OPL->lfo_am_inc = (1.0 / 64.0) * (1 << LFO_SH) * OPL->freqbase;
1024
1025 /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */
1026 OPL->lfo_pm_inc = (1.0 / 1024.0) * (1 << LFO_SH) * OPL->freqbase;
1027
1028 /*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/
1029
1030 /* Noise generator: a step takes 1 sample */
1031 OPL->noise_f = (1.0 / 1.0) * (1 << FREQ_SH) * OPL->freqbase;
1032
1033 OPL->eg_timer_add = (1 << EG_SH) * OPL->freqbase;
1034 OPL->eg_timer_overflow = (1) * (1 << EG_SH);
1035 /*logerror("OPLinit eg_timer_add=%8x eg_timer_overflow=%8x\n", OPL->eg_timer_add, OPL->eg_timer_overflow);*/
1036
1037 }
1038
FM_KEYON(OPL_SLOT * SLOT,uint32 key_set)1039 INLINE void FM_KEYON(OPL_SLOT *SLOT, uint32 key_set) {
1040 if (!SLOT->key) {
1041 /* restart Phase Generator */
1042 SLOT->Cnt = 0;
1043 /* phase -> Attack */
1044 SLOT->state = EG_ATT;
1045 }
1046 SLOT->key |= key_set;
1047 }
1048
FM_KEYOFF(OPL_SLOT * SLOT,uint32 key_clr)1049 INLINE void FM_KEYOFF(OPL_SLOT *SLOT, uint32 key_clr) {
1050 if (SLOT->key) {
1051 SLOT->key &= key_clr;
1052
1053 if (!SLOT->key) {
1054 /* phase -> Release */
1055 if (SLOT->state > EG_REL)
1056 SLOT->state = EG_REL;
1057 }
1058 }
1059 }
1060
1061 /* update phase increment counter of operator (also update the EG rates if necessary) */
CALC_FCSLOT(OPL_CH * CH,OPL_SLOT * SLOT)1062 INLINE void CALC_FCSLOT(OPL_CH *CH, OPL_SLOT *SLOT) {
1063 int ksr;
1064
1065 /* (frequency) phase increment counter */
1066 SLOT->Incr = CH->fc * SLOT->mul;
1067 ksr = CH->kcode >> SLOT->KSR;
1068
1069 if (SLOT->ksr != ksr) {
1070 SLOT->ksr = ksr;
1071
1072 /* calculate envelope generator rates */
1073 if ((SLOT->ar + SLOT->ksr) < 16 + 62) {
1074 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1075 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
1076 } else {
1077 SLOT->eg_sh_ar = 0;
1078 SLOT->eg_sel_ar = 13 * RATE_STEPS;
1079 }
1080 SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ];
1081 SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
1082 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ];
1083 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
1084 }
1085 }
1086
1087 /* set multi,am,vib,EG-TYP,KSR,mul */
set_mul(FM_OPL * OPL,int slot,int v)1088 INLINE void set_mul(FM_OPL *OPL, int slot, int v) {
1089 OPL_CH *CH = &OPL->P_CH[slot / 2];
1090 OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
1091
1092 SLOT->mul = mul_tab[v & 0x0f];
1093 SLOT->KSR = (v & 0x10) ? 0 : 2;
1094 SLOT->eg_type = (v & 0x20);
1095 SLOT->vib = (v & 0x40);
1096 SLOT->AMmask = (v & 0x80) ? ~0 : 0;
1097 CALC_FCSLOT(CH, SLOT);
1098 }
1099
1100 /* set ksl & tl */
set_ksl_tl(FM_OPL * OPL,int slot,int v)1101 INLINE void set_ksl_tl(FM_OPL *OPL, int slot, int v) {
1102 OPL_CH *CH = &OPL->P_CH[slot / 2];
1103 OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
1104 int ksl = v >> 6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */
1105
1106 SLOT->ksl = ksl ? 3 - ksl : 31;
1107 SLOT->TL = (v & 0x3f) << (ENV_BITS - 1 - 7); /* 7 bits TL (bit 6 = always 0) */
1108
1109 SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
1110 }
1111
1112 /* set attack rate & decay rate */
set_ar_dr(FM_OPL * OPL,int slot,int v)1113 INLINE void set_ar_dr(FM_OPL *OPL, int slot, int v) {
1114 OPL_CH *CH = &OPL->P_CH[slot / 2];
1115 OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
1116
1117 SLOT->ar = (v >> 4) ? 16 + ((v >> 4) << 2) : 0;
1118
1119 if ((SLOT->ar + SLOT->ksr) < 16 + 62) {
1120 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1121 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
1122 } else {
1123 SLOT->eg_sh_ar = 0;
1124 SLOT->eg_sel_ar = 13 * RATE_STEPS;
1125 }
1126
1127 SLOT->dr = (v & 0x0f) ? 16 + ((v & 0x0f) << 2) : 0;
1128 SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ];
1129 SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
1130 }
1131
1132 /* set sustain level & release rate */
set_sl_rr(FM_OPL * OPL,int slot,int v)1133 INLINE void set_sl_rr(FM_OPL *OPL, int slot, int v) {
1134 OPL_CH *CH = &OPL->P_CH[slot / 2];
1135 OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
1136
1137 SLOT->sl = sl_tab[ v >> 4 ];
1138
1139 SLOT->rr = (v & 0x0f) ? 16 + ((v & 0x0f) << 2) : 0;
1140 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ];
1141 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
1142 }
1143
1144
1145 /* write a value v to register r on OPL chip */
OPLWriteReg(FM_OPL * OPL,int r,int v)1146 void OplClass::OPLWriteReg(FM_OPL *OPL, int r, int v) {
1147 OPL_CH *CH;
1148 int slot;
1149 int block_fnum;
1150
1151
1152 /* adjust bus to 8 bits */
1153 r &= 0xff;
1154 v &= 0xff;
1155
1156
1157 switch (r & 0xe0) {
1158 case 0x00: /* 00-1f:control */
1159 switch (r & 0x1f) {
1160 case 0x01: /* waveform select enable */
1161 if (OPL->type & OPL_TYPE_WAVESEL) {
1162 OPL->wavesel = v & 0x20;
1163 /* do not change the waveform previously selected */
1164 }
1165 break;
1166 case 0x02: /* Timer 1 */
1167 OPL->T[0] = (256 - v) * 4;
1168 break;
1169 case 0x03: /* Timer 2 */
1170 OPL->T[1] = (256 - v) * 16;
1171 break;
1172 case 0x04: /* IRQ clear / mask and Timer enable */
1173 if (v & 0x80) {
1174 /* IRQ flag clear */
1175 OPL_STATUS_RESET(OPL, 0x7f);
1176 } else {
1177 /* set IRQ mask ,timer enable*/
1178 uint8 st1 = v & 1;
1179 uint8 st2 = (v >> 1) & 1;
1180 /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
1181 OPL_STATUS_RESET(OPL, v & 0x78);
1182 OPL_STATUSMASK_SET(OPL, ((~v) & 0x78) | 0x01);
1183 /* timer 2 */
1184 if (OPL->st[1] != st2) {
1185 double interval = st2 ? (double)OPL->T[1] * OPL->TimerBase : 0.0;
1186 OPL->st[1] = st2;
1187 if (OPL->TimerHandler)(OPL->TimerHandler)(OPL->TimerParam + 1, interval);
1188 }
1189 /* timer 1 */
1190 if (OPL->st[0] != st1) {
1191 double interval = st1 ? (double)OPL->T[0] * OPL->TimerBase : 0.0;
1192 OPL->st[0] = st1;
1193 if (OPL->TimerHandler)(OPL->TimerHandler)(OPL->TimerParam + 0, interval);
1194 }
1195 }
1196 break;
1197 case 0x08: /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
1198 OPL->mode = v;
1199 break;
1200
1201
1202 }
1203 break;
1204 case 0x20: /* am ON, vib ON, ksr, eg_type, mul */
1205 slot = slot_array[r & 0x1f];
1206 if (slot < 0) return;
1207 set_mul(OPL, slot, v);
1208 break;
1209 case 0x40:
1210 slot = slot_array[r & 0x1f];
1211 if (slot < 0) return;
1212 set_ksl_tl(OPL, slot, v);
1213 break;
1214 case 0x60:
1215 slot = slot_array[r & 0x1f];
1216 if (slot < 0) return;
1217 set_ar_dr(OPL, slot, v);
1218 break;
1219 case 0x80:
1220 slot = slot_array[r & 0x1f];
1221 if (slot < 0) return;
1222 set_sl_rr(OPL, slot, v);
1223 break;
1224 case 0xa0:
1225 if (r == 0xbd) { /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */
1226 OPL->lfo_am_depth = v & 0x80;
1227 OPL->lfo_pm_depth_range = (v & 0x40) ? 8 : 0;
1228
1229 OPL->rhythm = v & 0x3f;
1230
1231 if (OPL->rhythm & 0x20) {
1232 /* BD key on/off */
1233 if (v & 0x10) {
1234 FM_KEYON(&OPL->P_CH[6].SLOT[SLOT1], 2U);
1235 FM_KEYON(&OPL->P_CH[6].SLOT[SLOT2], 2U);
1236 } else {
1237 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1], ~2U);
1238 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2], ~2U);
1239 }
1240 /* HH key on/off */
1241 if (v & 0x01) FM_KEYON(&OPL->P_CH[7].SLOT[SLOT1], 2U);
1242 else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1], ~2U);
1243 /* SD key on/off */
1244 if (v & 0x08) FM_KEYON(&OPL->P_CH[7].SLOT[SLOT2], 2U);
1245 else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2], ~2U);
1246 /* TOM key on/off */
1247 if (v & 0x04) FM_KEYON(&OPL->P_CH[8].SLOT[SLOT1], 2U);
1248 else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1], ~2U);
1249 /* TOP-CY key on/off */
1250 if (v & 0x02U) FM_KEYON(&OPL->P_CH[8].SLOT[SLOT2], 2U);
1251 else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2], ~2U);
1252 } else {
1253 /* BD key off */
1254 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1], ~2U);
1255 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2], ~2U);
1256 /* HH key off */
1257 FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1], ~2U);
1258 /* SD key off */
1259 FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2], ~2U);
1260 /* TOM key off */
1261 FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1], ~2U);
1262 /* TOP-CY off */
1263 FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2], ~2U);
1264 }
1265 return;
1266 }
1267 /* keyon,block,fnum */
1268 if ((r & 0x0f) > 8) return;
1269 CH = &OPL->P_CH[r & 0x0f];
1270 if (!(r & 0x10)) {
1271 /* a0-a8 */
1272 block_fnum = (CH->block_fnum & 0x1f00) | v;
1273 } else {
1274 /* b0-b8 */
1275 block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff);
1276
1277 if (v & 0x20) {
1278 FM_KEYON(&CH->SLOT[SLOT1], 1U);
1279 FM_KEYON(&CH->SLOT[SLOT2], 1U);
1280 } else {
1281 FM_KEYOFF(&CH->SLOT[SLOT1], ~1U);
1282 FM_KEYOFF(&CH->SLOT[SLOT2], ~1U);
1283 }
1284 }
1285 /* update */
1286 if (CH->block_fnum != (uint32)block_fnum) {
1287 uint8 block = block_fnum >> 10;
1288
1289 CH->block_fnum = block_fnum;
1290
1291 CH->ksl_base = ksl_tab[block_fnum >> 6];
1292 CH->fc = OPL->fn_tab[block_fnum & 0x03ff] >> (7 - block);
1293
1294 /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */
1295 CH->kcode = (CH->block_fnum & 0x1c00) >> 9;
1296
1297 /* the info below is actually opposite to what is stated in the Manuals (verifed on real YM3812) */
1298 /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */
1299 /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */
1300 if (OPL->mode & 0x40)
1301 CH->kcode |= (CH->block_fnum & 0x100) >> 8; /* notesel == 1 */
1302 else
1303 CH->kcode |= (CH->block_fnum & 0x200) >> 9; /* notesel == 0 */
1304
1305 /* refresh Total Level in both SLOTs of this channel */
1306 CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base >> CH->SLOT[SLOT1].ksl);
1307 CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base >> CH->SLOT[SLOT2].ksl);
1308
1309 /* refresh frequency counter in both SLOTs of this channel */
1310 CALC_FCSLOT(CH, &CH->SLOT[SLOT1]);
1311 CALC_FCSLOT(CH, &CH->SLOT[SLOT2]);
1312 }
1313 break;
1314 case 0xc0:
1315 /* FB,C */
1316 if ((r & 0x0f) > 8) return;
1317 CH = &OPL->P_CH[r & 0x0f];
1318 CH->SLOT[SLOT1].FB = (v >> 1) & 7 ? ((v >> 1) & 7) + 7 : 0;
1319 CH->SLOT[SLOT1].CON = v & 1;
1320 CH->SLOT[SLOT1].connect1 = CH->SLOT[SLOT1].CON ? &output[0] : &phase_modulation;
1321 break;
1322 case 0xe0: /* waveform select */
1323 /* simply ignore write to the waveform select register if selecting not enabled in test register */
1324 if (OPL->wavesel) {
1325 slot = slot_array[r & 0x1f];
1326 if (slot < 0) return;
1327 CH = &OPL->P_CH[slot / 2];
1328
1329 CH->SLOT[slot & 1].wavetable = (v & 0x03) * SIN_LEN;
1330 }
1331 break;
1332 }
1333 }
1334
1335 /* lock/unlock for common table */
OPL_LockTable(void)1336 int OplClass::OPL_LockTable(void) {
1337 num_lock++;
1338 if (num_lock > 1) return 0;
1339
1340 /* first time */
1341
1342 cur_chip = NULL;
1343 /* allocate total level table (128kb space) */
1344 if (!init_tables()) {
1345 num_lock--;
1346 return -1;
1347 }
1348
1349 return 0;
1350 }
1351
OPL_UnLockTable(void)1352 void OplClass::OPL_UnLockTable(void) {
1353 if (num_lock) num_lock--;
1354 if (num_lock) return;
1355
1356 /* last time */
1357
1358 cur_chip = NULL;
1359 OPLCloseTable();
1360
1361 }
1362
OPLResetChip(FM_OPL * OPL)1363 void OplClass::OPLResetChip(FM_OPL *OPL) {
1364 int c, s;
1365 int i;
1366
1367 OPL->eg_timer = 0;
1368 OPL->eg_cnt = 0;
1369
1370 OPL->noise_rng = 1; /* noise shift register */
1371 OPL->mode = 0; /* normal mode */
1372 OPL_STATUS_RESET(OPL, 0x7f);
1373
1374 /* reset with register write */
1375 OPLWriteReg(OPL, 0x01, 0); /* wavesel disable */
1376 OPLWriteReg(OPL, 0x02, 0); /* Timer1 */
1377 OPLWriteReg(OPL, 0x03, 0); /* Timer2 */
1378 OPLWriteReg(OPL, 0x04, 0); /* IRQ mask clear */
1379 for (i = 0xff ; i >= 0x20 ; i--) OPLWriteReg(OPL, i, 0);
1380
1381 /* reset operator parameters */
1382 for (c = 0 ; c < 9 ; c++) {
1383 OPL_CH *CH = &OPL->P_CH[c];
1384 for (s = 0 ; s < 2 ; s++) {
1385 /* wave table */
1386 CH->SLOT[s].wavetable = 0;
1387 CH->SLOT[s].state = EG_OFF;
1388 CH->SLOT[s].volume = MAX_ATT_INDEX;
1389 }
1390 }
1391
1392 }
1393
1394 /* Create one of virtual YM3812 */
1395 /* 'clock' is chip clock in Hz */
1396 /* 'rate' is sampling rate */
OPLCreate(int type,int clock,int rate)1397 FM_OPL *OplClass::OPLCreate(int type, int clock, int rate) {
1398 char *ptr;
1399 FM_OPL *OPL;
1400 int state_size;
1401
1402 if (OPL_LockTable() == -1) return NULL;
1403
1404 /* calculate OPL state size */
1405 state_size = sizeof(FM_OPL);
1406
1407 /* allocate memory block */
1408 ptr = (char *)malloc(state_size);
1409
1410 if (ptr == NULL)
1411 return NULL;
1412
1413 /* clear */
1414 memset(ptr, 0, state_size);
1415
1416 OPL = (FM_OPL *)ptr;
1417
1418 ptr += sizeof(FM_OPL);
1419
1420 OPL->type = type;
1421 OPL->clock = clock;
1422 OPL->rate = rate;
1423
1424 /* init global tables */
1425 OPL_initalize(OPL);
1426
1427 /* reset chip */
1428 OPLResetChip(OPL);
1429 return OPL;
1430 }
1431
1432 /* Destroy one of virtual YM3812 */
OPLDestroy(FM_OPL * OPL)1433 void OplClass::OPLDestroy(FM_OPL *OPL) {
1434 OPL_UnLockTable();
1435 free(OPL);
1436 }
1437
1438 /* Option handlers */
1439
OPLSetTimerHandler(FM_OPL * OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)1440 static void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler, int channelOffset) {
1441 OPL->TimerHandler = TimerHandler;
1442 OPL->TimerParam = channelOffset;
1443 }
OPLSetIRQHandler(FM_OPL * OPL,OPL_IRQHANDLER IRQHandler,int param)1444 static void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param) {
1445 OPL->IRQHandler = IRQHandler;
1446 OPL->IRQParam = param;
1447 }
OPLSetUpdateHandler(FM_OPL * OPL,OPL_UPDATEHANDLER UpdateHandler,int param)1448 static void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler, int param) {
1449 OPL->UpdateHandler = UpdateHandler;
1450 OPL->UpdateParam = param;
1451 }
1452
1453 /* YM3812 I/O interface */
OPLWrite(FM_OPL * OPL,int a,int v)1454 int OplClass::OPLWrite(FM_OPL *OPL, int a, int v) {
1455 if (!(a & 1)) {
1456 /* address port */
1457 OPL->address = v & 0xff;
1458 } else {
1459 /* data port */
1460 if (OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam, 0);
1461 OPLWriteReg(OPL, OPL->address, v);
1462 }
1463 return OPL->status >> 7;
1464 }
1465
OPLRead(FM_OPL * OPL,int a)1466 static unsigned char OPLRead(FM_OPL *OPL, int a) {
1467 if (!(a & 1)) {
1468 /* status port */
1469 return OPL->status & (OPL->statusmask | 0x80);
1470 }
1471
1472 return 0xff;
1473 }
1474
1475 /* CSM Key Controll */
CSMKeyControll(OPL_CH * CH)1476 INLINE void CSMKeyControll(OPL_CH *CH) {
1477 FM_KEYON(&CH->SLOT[SLOT1], 4U);
1478 FM_KEYON(&CH->SLOT[SLOT2], 4U);
1479
1480 /* The key off should happen exactly one sample later - not implemented correctly yet */
1481
1482 FM_KEYOFF(&CH->SLOT[SLOT1], ~4U);
1483 FM_KEYOFF(&CH->SLOT[SLOT2], ~4U);
1484 }
1485
1486
OPLTimerOver(FM_OPL * OPL,int c)1487 static int OPLTimerOver(FM_OPL *OPL, int c) {
1488 if (c) {
1489 /* Timer B */
1490 OPL_STATUS_SET(OPL, 0x20);
1491 } else {
1492 /* Timer A */
1493 OPL_STATUS_SET(OPL, 0x40);
1494 /* CSM mode key,TL controll */
1495 if (OPL->mode & 0x80) {
1496 /* CSM mode total level latch and auto key on */
1497 int ch;
1498 if (OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam, 0);
1499 for (ch = 0; ch < 9; ch++)
1500 CSMKeyControll(&OPL->P_CH[ch]);
1501 }
1502 }
1503 /* reload timer */
1504 if (OPL->TimerHandler)(OPL->TimerHandler)(OPL->TimerParam + c, (double)OPL->T[c]*OPL->TimerBase);
1505 return OPL->status >> 7;
1506 }
1507
1508 #if (BUILD_YM3812)
1509
1510
1511
YM3812Init(int num,int clock,int rate)1512 int OplClass::YM3812Init(int num, int clock, int rate) {
1513 int i;
1514
1515 if (YM3812NumChips)
1516 return -1; /* duplicate init. */
1517
1518 YM3812NumChips = num;
1519
1520 for (i = 0; i < YM3812NumChips; i++) {
1521 /* emulator create */
1522 OPL_YM3812[i] = OPLCreate(OPL_TYPE_YM3812, clock, rate);
1523 if (OPL_YM3812[i] == NULL) {
1524 /* it's really bad - we run out of memeory */
1525 YM3812NumChips = 0;
1526 return -1;
1527 }
1528 }
1529
1530 return 0;
1531 }
1532
YM3812Shutdown(void)1533 void OplClass::YM3812Shutdown(void) {
1534 int i;
1535
1536 for (i = 0; i < YM3812NumChips; i++) {
1537 /* emulator shutdown */
1538 OPLDestroy(OPL_YM3812[i]);
1539 OPL_YM3812[i] = NULL;
1540 }
1541 YM3812NumChips = 0;
1542 }
YM3812ResetChip(int which)1543 void OplClass::YM3812ResetChip(int which) {
1544 OPLResetChip(OPL_YM3812[which]);
1545 }
1546
YM3812Write(int which,int a,int v)1547 int OplClass::YM3812Write(int which, int a, int v) {
1548 return OPLWrite(OPL_YM3812[which], a, v);
1549 }
1550
YM3812Read(int which,int a)1551 unsigned char OplClass::YM3812Read(int which, int a) {
1552 /* YM3812 always returns bit2 and bit1 in HIGH state */
1553 return OPLRead(OPL_YM3812[which], a) | 0x06 ;
1554 }
YM3812TimerOver(int which,int c)1555 int OplClass::YM3812TimerOver(int which, int c) {
1556 return OPLTimerOver(OPL_YM3812[which], c);
1557 }
1558
YM3812SetTimerHandler(int which,OPL_TIMERHANDLER TimerHandler,int channelOffset)1559 void OplClass::YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) {
1560 OPLSetTimerHandler(OPL_YM3812[which], TimerHandler, channelOffset);
1561 }
YM3812SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param)1562 void OplClass::YM3812SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param) {
1563 OPLSetIRQHandler(OPL_YM3812[which], IRQHandler, param);
1564 }
YM3812SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param)1565 void OplClass::YM3812SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param) {
1566 OPLSetUpdateHandler(OPL_YM3812[which], UpdateHandler, param);
1567 }
1568
1569
1570 /*
1571 ** Generate samples for one of the YM3812's
1572 **
1573 ** 'which' is the virtual YM3812 number
1574 ** '*buffer' is the output buffer pointer
1575 ** 'length' is the number of samples that should be generated
1576 */
YM3812UpdateOne(int which,int16 * buffer,int length)1577 void OplClass::YM3812UpdateOne(int which, int16 *buffer, int length) {
1578 FM_OPL *OPL = OPL_YM3812[which];
1579 uint8 rhythm = OPL->rhythm & 0x20;
1580 OPLSAMPLE *buf = buffer;
1581 int i;
1582
1583 if ((void *)OPL != cur_chip) {
1584 cur_chip = (void *)OPL;
1585 /* rhythm slots */
1586 SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1];
1587 SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2];
1588 SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1];
1589 SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2];
1590 }
1591 for (i = 0; i < length ; i++) {
1592 int lt;
1593
1594 output[0] = 0;
1595
1596 advance_lfo(OPL);
1597
1598 /* FM part */
1599 OPL_CALC_CH(&OPL->P_CH[0]);
1600 OPL_CALC_CH(&OPL->P_CH[1]);
1601 OPL_CALC_CH(&OPL->P_CH[2]);
1602 OPL_CALC_CH(&OPL->P_CH[3]);
1603 OPL_CALC_CH(&OPL->P_CH[4]);
1604 OPL_CALC_CH(&OPL->P_CH[5]);
1605
1606 if (!rhythm) {
1607 OPL_CALC_CH(&OPL->P_CH[6]);
1608 OPL_CALC_CH(&OPL->P_CH[7]);
1609 OPL_CALC_CH(&OPL->P_CH[8]);
1610 } else { /* Rhythm part */
1611 OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng >> 0) & 1);
1612 }
1613
1614 lt = output[0];
1615
1616 lt >>= FINAL_SH;
1617
1618 /* limit check */
1619 lt = limit(lt , MAXOUT, MINOUT);
1620
1621 #ifdef SAVE_SAMPLE
1622 SAVE_ALL_CHANNELS
1623 #endif
1624
1625 /* store to sound buffer */
1626 buf[i] = lt;
1627
1628 advancex(OPL);
1629 }
1630
1631 }
1632 #endif /* BUILD_YM3812 */
1633
1634 } // End of namespace Nuvie
1635 } // End of namespace Ultima
1636