openMSX
YM2413Okazaki.cc
Go to the documentation of this file.
1 /*
2  * Based on:
3  * emu2413.c -- YM2413 emulator written by Mitsutaka Okazaki 2001
4  * heavily rewritten to fit openMSX structure
5  */
6 
7 #include "YM2413Okazaki.hh"
8 #include "Math.hh"
9 #include "cstd.hh"
10 #include "inline.hh"
11 #include "ranges.hh"
12 #include "serialize.hh"
13 #include "unreachable.hh"
14 #include <cstring>
15 #include <cassert>
16 #include <iostream>
17 
18 namespace openmsx {
19 namespace YM2413Okazaki {
20 
21 // Number of bits in 'PhaseModulation' fixed point type.
22 static constexpr int PM_FP_BITS = 8;
23 
24 // Dynamic range (Accuracy of sin table)
25 static constexpr int DB_BITS = 8;
26 static constexpr int DB_MUTE = 1 << DB_BITS;
27 static constexpr int DBTABLEN = 3 * DB_MUTE; // enough to not have to check for overflow
28 
29 static constexpr double DB_STEP = 48.0 / DB_MUTE;
30 static constexpr double EG_STEP = 0.375;
31 static constexpr double TL_STEP = 0.75;
32 
33 // Size of Sintable ( 8 -- 18 can be used, but 9 recommended.)
34 static constexpr int PG_BITS = 9;
35 static constexpr int PG_WIDTH = 1 << PG_BITS;
36 static constexpr int PG_MASK = PG_WIDTH - 1;
37 
38 // Phase increment counter
39 static constexpr int DP_BITS = 18;
40 static constexpr int DP_BASE_BITS = DP_BITS - PG_BITS;
41 
42 // Dynamic range of envelope
43 static constexpr int EG_BITS = 7;
44 
45 // Bits for linear value
46 static constexpr int DB2LIN_AMP_BITS = 8;
47 static constexpr int SLOT_AMP_BITS = DB2LIN_AMP_BITS;
48 
49 // Bits for Amp modulator
50 static constexpr int AM_PG_BITS = 8;
51 static constexpr int AM_PG_WIDTH = 1 << AM_PG_BITS;
52 static constexpr int AM_DP_BITS = 16;
53 static constexpr int AM_DP_WIDTH = 1 << AM_DP_BITS;
54 static constexpr int AM_DP_MASK = AM_DP_WIDTH - 1;
55 
56 // LFO Amplitude Modulation table (verified on real YM3812)
57 // 27 output levels (triangle waveform);
58 // 1 level takes one of: 192, 256 or 448 samples
59 //
60 // Length: 210 elements.
61 // Each of the elements has to be repeated
62 // exactly 64 times (on 64 consecutive samples).
63 // The whole table takes: 64 * 210 = 13440 samples.
64 //
65 // Verified on real YM3812 (OPL2), but I believe it's the same for YM2413
66 // because it closely matches the YM2413 AM parameters:
67 // speed = 3.7Hz
68 // depth = 4.875dB
69 // Also this approch can be easily implemented in HW, the previous one (see SVN
70 // history) could not.
71 static constexpr unsigned LFO_AM_TAB_ELEMENTS = 210;
72 
73 // Extra (derived) constants
74 static const EnvPhaseIndex EG_DP_MAX = EnvPhaseIndex(1 << 7);
75 static const EnvPhaseIndex EG_DP_INF = EnvPhaseIndex(1 << 8); // as long as it's bigger
76 
77 // LFO Phase Modulation table (copied from Burczynski core)
78 static const signed char pmTable[8][8] =
79 {
80  { 0, 0, 0, 0, 0, 0, 0, 0, }, // FNUM = 000xxxxxx
81  { 0, 0, 1, 0, 0, 0,-1, 0, }, // FNUM = 001xxxxxx
82  { 0, 1, 2, 1, 0,-1,-2,-1, }, // FNUM = 010xxxxxx
83  { 0, 1, 3, 1, 0,-1,-3,-1, }, // FNUM = 011xxxxxx
84  { 0, 2, 4, 2, 0,-2,-4,-2, }, // FNUM = 100xxxxxx
85  { 0, 2, 5, 2, 0,-2,-5,-2, }, // FNUM = 101xxxxxx
86  { 0, 3, 6, 3, 0,-3,-6,-3, }, // FNUM = 110xxxxxx
87  { 0, 3, 7, 3, 0,-3,-7,-3, }, // FNUM = 111xxxxxx
88 };
89 
90 // LFO Amplitude Modulation table (verified on real YM3812)
91 static const unsigned char lfo_am_table[LFO_AM_TAB_ELEMENTS] = {
92  0,0,0,0,0,0,0,
93  1,1,1,1,
94  2,2,2,2,
95  3,3,3,3,
96  4,4,4,4,
97  5,5,5,5,
98  6,6,6,6,
99  7,7,7,7,
100  8,8,8,8,
101  9,9,9,9,
102  10,10,10,10,
103  11,11,11,11,
104  12,12,12,12,
105  13,13,13,13,
106  14,14,14,14,
107  15,15,15,15,
108  16,16,16,16,
109  17,17,17,17,
110  18,18,18,18,
111  19,19,19,19,
112  20,20,20,20,
113  21,21,21,21,
114  22,22,22,22,
115  23,23,23,23,
116  24,24,24,24,
117  25,25,25,25,
118  26,26,26,
119  25,25,25,25,
120  24,24,24,24,
121  23,23,23,23,
122  22,22,22,22,
123  21,21,21,21,
124  20,20,20,20,
125  19,19,19,19,
126  18,18,18,18,
127  17,17,17,17,
128  16,16,16,16,
129  15,15,15,15,
130  14,14,14,14,
131  13,13,13,13,
132  12,12,12,12,
133  11,11,11,11,
134  10,10,10,10,
135  9,9,9,9,
136  8,8,8,8,
137  7,7,7,7,
138  6,6,6,6,
139  5,5,5,5,
140  4,4,4,4,
141  3,3,3,3,
142  2,2,2,2,
143  1,1,1,1,
144 };
145 
146 // ML-table
147 static const byte mlTable[16] = {
148  1, 1*2, 2*2, 3*2, 4*2, 5*2, 6*2, 7*2,
149  8*2, 9*2, 10*2, 10*2, 12*2, 12*2, 15*2, 15*2
150 };
151 
152 // dB to linear table (used by Slot)
153 // dB(0 .. DB_MUTE-1) -> linear(0 .. DB2LIN_AMP_WIDTH)
154 // indices in range:
155 // [0, DB_MUTE ) actual values, from max to min
156 // [DB_MUTE, DBTABLEN) filled with min val (to allow some overflow in index)
157 // [DBTABLEN, 2*DBTABLEN) as above but for negative output values
158 struct Db2LinTab {
159  int tab[2 * DBTABLEN];
160 };
161 static constexpr Db2LinTab makeDB2LinTable()
162 {
163  Db2LinTab dB2Lin = {};
164 
165  for (int i = 0; i < DB_MUTE; ++i) {
166  dB2Lin.tab[i] = int(double((1 << DB2LIN_AMP_BITS) - 1) *
167  cstd::pow<5, 3>(10, -double(i) * DB_STEP / 20));
168  }
169  dB2Lin.tab[DB_MUTE - 1] = 0;
170  for (int i = DB_MUTE; i < DBTABLEN; ++i) {
171  dB2Lin.tab[i] = 0;
172  }
173  for (int i = 0; i < DBTABLEN; ++i) {
174  dB2Lin.tab[i + DBTABLEN] = -dB2Lin.tab[i];
175  }
176 
177  return dB2Lin;
178 }
179 static constexpr Db2LinTab dB2Lin = makeDB2LinTable();
180 
181 // Linear to Log curve conversion table (for Attack rate)
183  unsigned tab[1 << EG_BITS];
184 };
185 static constexpr ArAdjustTable makeAdjustTable()
186 {
187  ArAdjustTable arAdjust = {};
188 
189  arAdjust.tab[0] = (1 << EG_BITS) - 1;
190  constexpr double l127 = cstd::log<5, 4>(127.0);
191  for (int i = 1; i < (1 << EG_BITS); ++i) {
192  arAdjust.tab[i] = unsigned(double(1 << EG_BITS) - 1 -
193  ((1 << EG_BITS) - 1) * cstd::log<5, 4>(double(i)) / l127);
194  }
195 
196  return arAdjust;
197 }
198 static constexpr ArAdjustTable arAdjust = makeAdjustTable();
199 
200 // KSL + TL Table values are in range [0, 112]
201 struct TllTable {
202  byte tab[4][16 * 8];
203 };
204 static constexpr TllTable makeTllTable()
205 {
206  TllTable tll = {};
207 
208  // Processed version of Table III-5 from the Application Manual.
209  constexpr unsigned kltable[16] = {
210  0, 24, 32, 37, 40, 43, 45, 47, 48, 50, 51, 52, 53, 54, 55, 56
211  };
212  // Note: KL [0..3] results in {0.0, 1.5, 3.0, 6.0} dB/oct.
213  // This is different from Y8950 and YMF262 which have {0, 3, 1.5, 6}.
214  // (2nd and 3rd elements are swapped). Verified on real YM2413.
215 
216  for (unsigned freq = 0; freq < 16 * 8; ++freq) {
217  unsigned fnum = freq & 15;
218  unsigned block = freq / 16;
219  int tmp = 2 * kltable[fnum] - 16 * (7 - block);
220  for (unsigned KL = 0; KL < 4; ++KL) {
221  unsigned t = (tmp <= 0 || KL == 0) ? 0 : (tmp >> (3 - KL));
222  assert(t <= 112);
223  tll.tab[KL][freq] = t;
224  }
225  }
226 
227  return tll;
228 }
229 static constexpr TllTable tll = makeTllTable();
230 
231 // WaveTable for each envelope amp
232 // values are in range [0, DB_MUTE) (for positive values)
233 // or [0, DB_MUTE) + DBTABLEN (for negative values)
234 struct SinTable {
235  unsigned full[PG_WIDTH];
236  unsigned half[PG_WIDTH];
237 };
238 static constexpr int lin2db(double d)
239 {
240  // lin(+0.0 .. +1.0) to dB(DB_MUTE-1 .. 0)
241  return (d == 0)
242  ? DB_MUTE - 1
243  : std::min(-int(20.0 * cstd::log10<5, 2>(d) / DB_STEP), DB_MUTE - 1); // 0 - 127
244 }
245 static constexpr SinTable makeSinTable()
246 {
247  SinTable sinTable = {};
248 
249  for (int i = 0; i < PG_WIDTH / 4; ++i) {
250  sinTable.full[i] = lin2db(cstd::sin<2>(double(2.0 * M_PI) * i / PG_WIDTH));
251  }
252  for (int i = 0; i < PG_WIDTH / 4; ++i) {
253  sinTable.full[PG_WIDTH / 2 - 1 - i] = sinTable.full[i];
254  }
255  for (int i = 0; i < PG_WIDTH / 2; ++i) {
256  sinTable.full[PG_WIDTH / 2 + i] = DBTABLEN + sinTable.full[i];
257  }
258 
259  for (int i = 0; i < PG_WIDTH / 2; ++i) {
260  sinTable.half[i] = sinTable.full[i];
261  }
262  for (int i = PG_WIDTH / 2; i < PG_WIDTH; ++i) {
263  sinTable.half[i] = sinTable.full[0];
264  }
265 
266  return sinTable;
267 }
268 static constexpr SinTable sinTable = makeSinTable();
269 static constexpr unsigned const * const waveform[2] = {sinTable.full, sinTable.half};
270 
271 // Phase incr table for attack, decay and release
272 // note: original code had indices swapped. It also had
273 // a separate table for attack
274 // 17.15 fixed point
276  int tab[16][16];
277 };
278 static constexpr DphaseDRTable makeDphaseDRTable()
279 {
280  DphaseDRTable dphaseDR = {};
281 
282  for (unsigned Rks = 0; Rks < 16; ++Rks) {
283  dphaseDR.tab[Rks][0] = 0;
284  for (unsigned DR = 1; DR < 16; ++DR) {
285  unsigned RM = std::min(DR + (Rks >> 2), 15u);
286  unsigned RL = Rks & 3;
287  dphaseDR.tab[Rks][DR] =
288  ((RL + 4) << EP_FP_BITS) >> (16 - RM);
289  }
290  }
291 
292  return dphaseDR;
293 }
294 static constexpr DphaseDRTable dphaseDR = makeDphaseDRTable();
295 
296 // Sustain level (17.15 fixed point)
297 struct SlTable {
298  unsigned tab[16];
299 };
300 static constexpr SlTable makeSusLevTable()
301 {
302  SlTable sl = {};
303 
304  for (int i = 0; i < 16; ++i) {
305  double x = (i == 15) ? 48.0 : (3.0 * i);
306  sl.tab[i] = int(x / EG_STEP) << EP_FP_BITS;
307  }
308 
309  return sl;
310 }
311 static constexpr SlTable sl = makeSusLevTable();
312 
313 //
314 // Helper functions
315 //
316 static constexpr int EG2DB(int d)
317 {
318  return d * int(EG_STEP / DB_STEP);
319 }
320 static constexpr unsigned TL2EG(unsigned d)
321 {
322  assert(d < 64); // input is in range [0..63]
323  return d * int(TL_STEP / EG_STEP);
324 }
325 
326 static constexpr unsigned DB_POS(double x)
327 {
328  int result = int(x / DB_STEP);
329  assert(0 <= result);
330  assert(result < DB_MUTE);
331  return result;
332 }
333 static constexpr unsigned DB_NEG(double x)
334 {
335  return DBTABLEN + DB_POS(x);
336 }
337 
338 static constexpr bool BIT(unsigned s, unsigned b)
339 {
340  return (s >> b) & 1;
341 }
342 
343 //
344 // Patch
345 //
347  : AMPM(0), EG(false), AR(0), DR(0), RR(0)
348 {
349  setKR(0);
350  setML(0);
351  setKL(0);
352  setTL(0);
353  setWF(0);
354  setFB(0);
355  setSL(0);
356 }
357 
359 {
360  AMPM = (data[0] >> 6) & 3;
361  EG = (data[0] >> 5) & 1;
362  setKR ((data[0] >> 4) & 1);
363  setML ((data[0] >> 0) & 15);
364  setKL ((data[2] >> 6) & 3);
365  setTL ((data[2] >> 0) & 63);
366  setWF ((data[3] >> 3) & 1);
367  setFB ((data[3] >> 0) & 7);
368  AR = (data[4] >> 4) & 15;
369  DR = (data[4] >> 0) & 15;
370  setSL ((data[6] >> 4) & 15);
371  RR = (data[6] >> 0) & 15;
372 }
373 
375 {
376  AMPM = (data[1] >> 6) & 3;
377  EG = (data[1] >> 5) & 1;
378  setKR ((data[1] >> 4) & 1);
379  setML ((data[1] >> 0) & 15);
380  setKL ((data[3] >> 6) & 3);
381  setTL (0);
382  setWF ((data[3] >> 4) & 1);
383  setFB (0);
384  AR = (data[5] >> 4) & 15;
385  DR = (data[5] >> 0) & 15;
386  setSL ((data[7] >> 4) & 15);
387  RR = (data[7] >> 0) & 15;
388 }
389 
390 void Patch::setKR(byte value)
391 {
392  KR = value ? 8 : 10;
393 }
394 void Patch::setML(byte value)
395 {
396  ML = mlTable[value];
397 }
398 void Patch::setKL(byte value)
399 {
400  KL = tll.tab[value];
401 }
402 void Patch::setTL(byte value)
403 {
404  assert(value < 64);
405  assert(TL2EG(value) < 256);
406  TL = TL2EG(value);
407 }
408 void Patch::setWF(byte value)
409 {
410  WF = waveform[value];
411 }
412 void Patch::setFB(byte value)
413 {
414  FB = value ? 8 - value : 0;
415 }
416 void Patch::setSL(byte value)
417 {
418  SL = sl.tab[value];
419 }
420 
421 
422 //
423 // Slot
424 //
426 {
427  cphase = 0;
428  ranges::fill(dphase, 0);
429  output = 0;
430  feedback = 0;
431  setEnvelopeState(FINISH);
432  dphaseDRTableRks = dphaseDR.tab[0];
433  tll = 0;
434  sustain = false;
435  volume = TL2EG(0);
436  slot_on_flag = 0;
437 }
438 
439 void Slot::updatePG(unsigned freq)
440 {
441  // Pre-calculate all phase-increments. The 8 different values are for
442  // the 8 steps of the PM stuff (for mod and car phase calculation).
443  // When PM isn't used then dphase[0] is used (pmTable[.][0] == 0).
444  // The original Okazaki core calculated the PM stuff in a different
445  // way. This algorithm was copied from the Burczynski core because it
446  // is much more suited for a (cheap) hardware calculation.
447  unsigned fnum = freq & 511;
448  unsigned block = freq / 512;
449  for (int pm = 0; pm < 8; ++pm) {
450  unsigned tmp = ((2 * fnum + pmTable[fnum >> 6][pm]) * patch.ML) << block;
451  dphase[pm] = tmp >> (21 - DP_BITS);
452  }
453 }
454 
455 void Slot::updateTLL(unsigned freq, bool actAsCarrier)
456 {
457  tll = patch.KL[freq >> 5] + (actAsCarrier ? volume : patch.TL);
458 }
459 
460 void Slot::updateRKS(unsigned freq)
461 {
462  unsigned rks = freq >> patch.KR;
463  assert(rks < 16);
464  dphaseDRTableRks = dphaseDR.tab[rks];
465 }
466 
468 {
469  switch (state) {
470  case ATTACK:
471  // Original code had separate table for AR, the values in
472  // this table were 12 times bigger than the values in the
473  // dphaseDRTableRks table, expect for the value for AR=15.
474  // But when AR=15, the value doesn't matter.
475  //
476  // This factor 12 can also be seen in the attack/decay rates
477  // table in the ym2413 application manual (table III-7, page
478  // 13). For other chips like OPL1, OPL3 this ratio seems to be
479  // different.
480  eg_dphase = EnvPhaseIndex::create(
481  dphaseDRTableRks[patch.AR] * 12);
482  break;
483  case DECAY:
484  eg_dphase = EnvPhaseIndex::create(dphaseDRTableRks[patch.DR]);
485  break;
486  case SUSTAIN:
487  eg_dphase = EnvPhaseIndex::create(dphaseDRTableRks[patch.RR]);
488  break;
489  case RELEASE: {
490  unsigned idx = sustain ? 5
491  : (patch.EG ? patch.RR
492  : 7);
493  eg_dphase = EnvPhaseIndex::create(dphaseDRTableRks[idx]);
494  break;
495  }
496  case SETTLE:
497  // Value based on ym2413 application manual:
498  // - p10: (envelope graph)
499  // DP: 10ms
500  // - p13: (table III-7 attack and decay rates)
501  // Rate 12-0 -> 10.22ms
502  // Rate 12-1 -> 8.21ms
503  // Rate 12-2 -> 6.84ms
504  // Rate 12-3 -> 5.87ms
505  // The datasheet doesn't say anything about key-scaling for
506  // this state (in fact it doesn't say much at all about this
507  // state). Experiments showed that the with key-scaling the
508  // output matches closer the real HW. Also all other states use
509  // key-scaling.
510  eg_dphase = EnvPhaseIndex::create(dphaseDRTableRks[12]);
511  break;
512  case SUSHOLD:
513  case FINISH:
514  eg_dphase = EnvPhaseIndex(0);
515  break;
516  }
517 }
518 
519 void Slot::updateAll(unsigned freq, bool actAsCarrier)
520 {
521  updatePG(freq);
522  updateTLL(freq, actAsCarrier);
523  updateRKS(freq);
524  updateEG(); // EG should be updated last
525 }
526 
528 {
529  state = state_;
530  switch (state) {
531  case ATTACK:
532  eg_phase_max = (patch.AR == 15) ? EnvPhaseIndex(0) : EG_DP_MAX;
533  break;
534  case DECAY:
535  eg_phase_max = EnvPhaseIndex::create(patch.SL);
536  break;
537  case SUSHOLD:
538  eg_phase_max = EG_DP_INF;
539  break;
540  case SETTLE:
541  case SUSTAIN:
542  case RELEASE:
543  eg_phase_max = EG_DP_MAX;
544  break;
545  case FINISH:
546  eg_phase = EG_DP_MAX;
547  eg_phase_max = EG_DP_INF;
548  break;
549  }
550  updateEG();
551 }
552 
553 bool Slot::isActive() const
554 {
555  return state != FINISH;
556 }
557 
558 // Slot key on
560 {
561  setEnvelopeState(ATTACK);
562  eg_phase = EnvPhaseIndex(0);
563  cphase = 0;
564 }
565 
566 // Slot key on, without resetting the phase
568 {
569  setEnvelopeState(ATTACK);
570  eg_phase = EnvPhaseIndex(0);
571 }
572 
573 // Slot key off
575 {
576  if (state == FINISH) return; // already in off state
577  if (state == ATTACK) {
578  eg_phase = EnvPhaseIndex(arAdjust.tab[eg_phase.toInt()]);
579  }
580  setEnvelopeState(RELEASE);
581 }
582 
583 
584 // Change a rhythm voice
585 void Slot::setPatch(const Patch& newPatch)
586 {
587  patch = newPatch; // copy data
588  if ((state == SUSHOLD) && (patch.EG == 0)) {
589  setEnvelopeState(SUSTAIN);
590  }
591  setEnvelopeState(state); // recalc eg_phase_max
592 }
593 
594 // Set new volume based on 4-bit register value (0-15).
595 void Slot::setVolume(unsigned value)
596 {
597  // '<< 2' to transform 4 bits to the same range as the 6 bits TL field
598  volume = TL2EG(value << 2);
599 }
600 
601 
602 //
603 // Channel
604 //
605 
607 {
608  car.sibling = &mod; // car needs a pointer to its sibling
609  mod.sibling = nullptr; // mod doesn't need this pointer
610 }
611 
612 void Channel::reset(YM2413& ym2413)
613 {
614  mod.reset();
615  car.reset();
616  setPatch(0, ym2413);
617 }
618 
619 // Change a voice
620 void Channel::setPatch(unsigned num, YM2413& ym2413)
621 {
622  mod.setPatch(ym2413.getPatch(num, false));
623  car.setPatch(ym2413.getPatch(num, true));
624 }
625 
626 // Set sustain parameter
627 void Channel::setSustain(bool sustain, bool modActAsCarrier)
628 {
629  car.sustain = sustain;
630  if (modActAsCarrier) {
631  mod.sustain = sustain;
632  }
633 }
634 
635 // Channel key on
637 {
638  // TODO Should we also test mod.slot_on_flag?
639  // Should we set mod.slot_on_flag?
640  // Can make a difference for channel 7/8 in ryhthm mode.
641  if (!car.slot_on_flag) {
642  car.setEnvelopeState(SETTLE);
643  // this will shortly set both car and mod to ATTACK state
644  }
645  car.slot_on_flag |= 1;
646  mod.slot_on_flag |= 1;
647 }
648 
649 // Channel key off
651 {
652  // Note: no mod.slotOff() in original code!!!
653  if (car.slot_on_flag) {
654  car.slot_on_flag &= ~1;
655  mod.slot_on_flag &= ~1;
656  if (!car.slot_on_flag) {
657  car.slotOff();
658  }
659  }
660 }
661 
662 
663 //
664 // YM2413
665 //
666 
667 static byte inst_data[16 + 3][8] = {
668  { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // user instrument
669  { 0x61,0x61,0x1e,0x17,0xf0,0x7f,0x00,0x17 }, // violin
670  { 0x13,0x41,0x16,0x0e,0xfd,0xf4,0x23,0x23 }, // guitar
671  { 0x03,0x01,0x9a,0x04,0xf3,0xf3,0x13,0xf3 }, // piano
672  { 0x11,0x61,0x0e,0x07,0xfa,0x64,0x70,0x17 }, // flute
673  { 0x22,0x21,0x1e,0x06,0xf0,0x76,0x00,0x28 }, // clarinet
674  { 0x21,0x22,0x16,0x05,0xf0,0x71,0x00,0x18 }, // oboe
675  { 0x21,0x61,0x1d,0x07,0x82,0x80,0x17,0x17 }, // trumpet
676  { 0x23,0x21,0x2d,0x16,0x90,0x90,0x00,0x07 }, // organ
677  { 0x21,0x21,0x1b,0x06,0x64,0x65,0x10,0x17 }, // horn
678  { 0x21,0x21,0x0b,0x1a,0x85,0xa0,0x70,0x07 }, // synthesizer
679  { 0x23,0x01,0x83,0x10,0xff,0xb4,0x10,0xf4 }, // harpsichord
680  { 0x97,0xc1,0x20,0x07,0xff,0xf4,0x22,0x22 }, // vibraphone
681  { 0x61,0x00,0x0c,0x05,0xc2,0xf6,0x40,0x44 }, // synthesizer bass
682  { 0x01,0x01,0x56,0x03,0x94,0xc2,0x03,0x12 }, // acoustic bass
683  { 0x21,0x01,0x89,0x03,0xf1,0xe4,0xf0,0x23 }, // electric guitar
684  { 0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8 },
685  { 0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7 },
686  { 0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55 }
687 };
688 
690 {
691  if (false) {
692  for (auto& e : dB2Lin.tab) std::cout << e << ' ';
693  std::cout << '\n';
694 
695  for (auto& e : arAdjust.tab) std::cout << e << ' ';
696  std::cout << '\n';
697 
698  for (int i = 0; i < 4; ++i) {
699  for (int j = 0; j < 16 * 8; ++j) {
700  std::cout << int(tll.tab[i][j]) << ' ';
701  }
702  std::cout << '\n';
703  }
704  std::cout << '\n';
705 
706  for (auto& e : sinTable.full) std::cout << e << ' ';
707  std::cout << '\n';
708  for (auto& e : sinTable.half) std::cout << e << ' ';
709  std::cout << '\n';
710 
711  for (int i = 0; i < 16; ++i) {
712  for (int j = 0; j < 16; ++j) {
713  std::cout << dphaseDR.tab[i][j] << ' ';
714  }
715  std::cout << '\n';
716  }
717  std::cout << '\n';
718 
719  for (auto& e : sl.tab) std::cout << e << ' ';
720  std::cout << '\n';
721  }
722 
723  memset(reg, 0, sizeof(reg)); // avoid UMR
724 
725  for (unsigned i = 0; i < 16 + 3; ++i) {
726  patches[i][0].initModulator(inst_data[i]);
727  patches[i][1].initCarrier (inst_data[i]);
728  }
729 
730  reset();
731 }
732 
733 // Reset whole of OPLL except patch datas
734 void YM2413::reset()
735 {
736  pm_phase = 0;
737  am_phase = 0;
738  noise_seed = 0xFFFF;
739 
740  for (auto& ch : channels) {
741  ch.reset(*this);
742  }
743  for (unsigned i = 0; i < 0x40; ++i) {
744  writeReg(i, 0);
745  }
746 }
747 
748 // Drum key on
750 {
751  Channel& ch6 = channels[6];
752  if (!ch6.car.slot_on_flag) {
754  // this will shortly set both car and mod to ATTACK state
755  }
756  ch6.car.slot_on_flag |= 2;
757  ch6.mod.slot_on_flag |= 2;
758 }
760 {
761  // TODO do these also use the SETTLE stuff?
762  Channel& ch7 = channels[7];
763  if (!ch7.mod.slot_on_flag) {
764  ch7.mod.slotOn2();
765  }
766  ch7.mod.slot_on_flag |= 2;
767 }
769 {
770  Channel& ch7 = channels[7];
771  if (!ch7.car.slot_on_flag) {
772  ch7.car.slotOn();
773  }
774  ch7.car.slot_on_flag |= 2;
775 }
777 {
778  Channel& ch8 = channels[8];
779  if (!ch8.mod.slot_on_flag) {
780  ch8.mod.slotOn();
781  }
782  ch8.mod.slot_on_flag |= 2;
783 }
785 {
786  Channel& ch8 = channels[8];
787  if (!ch8.car.slot_on_flag) {
788  ch8.car.slotOn2();
789  }
790  ch8.car.slot_on_flag |= 2;
791 }
792 
793 // Drum key off
795 {
796  Channel& ch6 = channels[6];
797  if (ch6.car.slot_on_flag) {
798  ch6.car.slot_on_flag &= ~2;
799  ch6.mod.slot_on_flag &= ~2;
800  if (!ch6.car.slot_on_flag) {
801  ch6.car.slotOff();
802  }
803  }
804 }
806 {
807  Channel& ch7 = channels[7];
808  if (ch7.mod.slot_on_flag) {
809  ch7.mod.slot_on_flag &= ~2;
810  if (!ch7.mod.slot_on_flag) {
811  ch7.mod.slotOff();
812  }
813  }
814 }
816 {
817  Channel& ch7 = channels[7];
818  if (ch7.car.slot_on_flag) {
819  ch7.car.slot_on_flag &= ~2;
820  if (!ch7.car.slot_on_flag) {
821  ch7.car.slotOff();
822  }
823  }
824 }
826 {
827  Channel& ch8 = channels[8];
828  if (ch8.mod.slot_on_flag) {
829  ch8.mod.slot_on_flag &= ~2;
830  if (!ch8.mod.slot_on_flag) {
831  ch8.mod.slotOff();
832  }
833  }
834 }
836 {
837  Channel& ch8 = channels[8];
838  if (ch8.car.slot_on_flag) {
839  ch8.car.slot_on_flag &= ~2;
840  if (!ch8.car.slot_on_flag) {
841  ch8.car.slotOff();
842  }
843  }
844 }
845 
847 {
848  Channel& ch6 = channels[6];
849  Channel& ch7 = channels[7];
850  Channel& ch8 = channels[8];
851 
852  // flags = X | X | mode | BD | SD | TOM | TC | HH
853  byte flags = reg[0x0E];
854  if ((flags ^ old) & 0x20) {
855  if (flags & 0x20) {
856  // OFF -> ON
857  ch6.setPatch(16, *this);
858  ch7.setPatch(17, *this);
859  ch7.mod.setVolume(reg[0x37] >> 4);
860  ch8.setPatch(18, *this);
861  ch8.mod.setVolume(reg[0x38] >> 4);
862  } else {
863  // ON -> OFF
864  ch6.setPatch(reg[0x36] >> 4, *this);
865  keyOff_BD();
866  ch7.setPatch(reg[0x37] >> 4, *this);
867  keyOff_SD();
868  keyOff_HH();
869  ch8.setPatch(reg[0x38] >> 4, *this);
870  keyOff_TOM();
871  keyOff_CYM();
872  }
873  }
874  if (flags & 0x20) {
875  if (flags & 0x10) keyOn_BD(); else keyOff_BD();
876  if (flags & 0x08) keyOn_SD(); else keyOff_SD();
877  if (flags & 0x04) keyOn_TOM(); else keyOff_TOM();
878  if (flags & 0x02) keyOn_CYM(); else keyOff_CYM();
879  if (flags & 0x01) keyOn_HH(); else keyOff_HH();
880  }
881 
882  unsigned freq6 = getFreq(6);
883  ch6.mod.updateAll(freq6, false);
884  ch6.car.updateAll(freq6, true);
885  unsigned freq7 = getFreq(7);
886  ch7.mod.updateAll(freq7, isRhythm());
887  ch7.car.updateAll(freq7, true);
888  unsigned freq8 = getFreq(8);
889  ch8.mod.updateAll(freq8, isRhythm());
890  ch8.car.updateAll(freq8, true);
891 }
892 
894 {
895  for (unsigned i = 0; i < 9; ++i) {
896  int slot_on = (reg[0x20 + i] & 0x10) ? 1 : 0;
897  Channel& ch = channels[i];
898  ch.mod.slot_on_flag = slot_on;
899  ch.car.slot_on_flag = slot_on;
900  }
901  if (isRhythm()) {
902  Channel& ch6 = channels[6];
903  ch6.mod.slot_on_flag |= (reg[0x0e] & 0x10) ? 2 : 0; // BD1
904  ch6.car.slot_on_flag |= (reg[0x0e] & 0x10) ? 2 : 0; // BD2
905  Channel& ch7 = channels[7];
906  ch7.mod.slot_on_flag |= (reg[0x0e] & 0x01) ? 2 : 0; // HH
907  ch7.car.slot_on_flag |= (reg[0x0e] & 0x08) ? 2 : 0; // SD
908  Channel& ch8 = channels[8];
909  ch8.mod.slot_on_flag |= (reg[0x0e] & 0x04) ? 2 : 0; // TOM
910  ch8.car.slot_on_flag |= (reg[0x0e] & 0x02) ? 2 : 0; // CYM
911  }
912 }
913 
914 // Convert Amp(0 to EG_HEIGHT) to Phase(0 to 8PI)
915 static constexpr int wave2_8pi(int e)
916 {
917  int shift = SLOT_AMP_BITS - PG_BITS - 2;
918  if (shift > 0) {
919  return e >> shift;
920  } else {
921  return e << -shift;
922  }
923 }
924 
925 // PG
926 ALWAYS_INLINE unsigned Slot::calc_phase(unsigned lfo_pm)
927 {
928  cphase += dphase[lfo_pm];
929  return cphase >> DP_BASE_BITS;
930 }
931 
932 // EG
933 void Slot::calc_envelope_outline(unsigned& out)
934 {
935  switch (state) {
936  case ATTACK:
937  out = 0;
938  eg_phase = EnvPhaseIndex(0);
939  setEnvelopeState(DECAY);
940  break;
941  case DECAY:
942  eg_phase = eg_phase_max;
943  setEnvelopeState(patch.EG ? SUSHOLD : SUSTAIN);
944  break;
945  case SUSTAIN:
946  case RELEASE:
947  setEnvelopeState(FINISH);
948  break;
949  case SETTLE:
950  // Comment copied from Burczynski code (didn't verify myself):
951  // When CARRIER envelope gets down to zero level, phases in
952  // BOTH operators are reset (at the same time?).
953  slotOn();
954  sibling->slotOn();
955  break;
956  case SUSHOLD:
957  case FINISH:
958  default:
959  UNREACHABLE;
960  break;
961  }
962 }
963 template <bool HAS_AM, bool FIXED_ENV>
964 ALWAYS_INLINE unsigned Slot::calc_envelope(int lfo_am, unsigned fixed_env)
965 {
966  assert(!FIXED_ENV || (state == SUSHOLD) || (state == FINISH));
967 
968  if (FIXED_ENV) {
969  unsigned out = fixed_env;
970  if (HAS_AM) {
971  out += lfo_am; // [0, 512)
972  out |= 3;
973  } else {
974  // out |= 3 is already done in calc_fixed_env()
975  }
976  return out;
977  } else {
978  unsigned out = eg_phase.toInt(); // in range [0, 128)
979  if (state == ATTACK) {
980  out = arAdjust.tab[out]; // [0, 128)
981  }
982  eg_phase += eg_dphase;
983  if (eg_phase >= eg_phase_max) {
984  calc_envelope_outline(out);
985  }
986  out = EG2DB(out + tll); // [0, 480)
987  if (HAS_AM) {
988  out += lfo_am; // [0, 512)
989  }
990  return out | 3;
991  }
992 }
993 template <bool HAS_AM> unsigned Slot::calc_fixed_env() const
994 {
995  assert((state == SUSHOLD) || (state == FINISH));
996  assert(eg_dphase == EnvPhaseIndex(0));
997  unsigned out = eg_phase.toInt(); // in range [0, 128)
998  out = EG2DB(out + tll); // [0, 480)
999  if (!HAS_AM) {
1000  out |= 3;
1001  }
1002  return out;
1003 }
1004 
1005 // CARRIER
1006 template<bool HAS_AM, bool FIXED_ENV>
1007 ALWAYS_INLINE int Slot::calc_slot_car(unsigned lfo_pm, int lfo_am, int fm, unsigned fixed_env)
1008 {
1009  int phase = calc_phase(lfo_pm) + wave2_8pi(fm);
1010  unsigned egout = calc_envelope<HAS_AM, FIXED_ENV>(lfo_am, fixed_env);
1011  int newOutput = dB2Lin.tab[patch.WF[phase & PG_MASK] + egout];
1012  output = (output + newOutput) >> 1;
1013  return output;
1014 }
1015 
1016 // MODULATOR
1017 template<bool HAS_AM, bool HAS_FB, bool FIXED_ENV>
1018 ALWAYS_INLINE int Slot::calc_slot_mod(unsigned lfo_pm, int lfo_am, unsigned fixed_env)
1019 {
1020  assert((patch.FB != 0) == HAS_FB);
1021  unsigned phase = calc_phase(lfo_pm);
1022  unsigned egout = calc_envelope<HAS_AM, FIXED_ENV>(lfo_am, fixed_env);
1023  if (HAS_FB) {
1024  phase += wave2_8pi(feedback) >> patch.FB;
1025  }
1026  int newOutput = dB2Lin.tab[patch.WF[phase & PG_MASK] + egout];
1027  feedback = (output + newOutput) >> 1;
1028  output = newOutput;
1029  return feedback;
1030 }
1031 
1032 // TOM (ch8 mod)
1034 {
1035  unsigned phase = calc_phase(0);
1036  unsigned egout = calc_envelope<false, false>(0, 0);
1037  return dB2Lin.tab[patch.WF[phase & PG_MASK] + egout];
1038 }
1039 
1040 // SNARE (ch7 car)
1042 {
1043  unsigned phase = calc_phase(0);
1044  unsigned egout = calc_envelope<false, false>(0, 0);
1045  return BIT(phase, 7)
1046  ? dB2Lin.tab[(noise ? DB_POS(0.0) : DB_POS(15.0)) + egout]
1047  : dB2Lin.tab[(noise ? DB_NEG(0.0) : DB_NEG(15.0)) + egout];
1048 }
1049 
1050 // TOP-CYM (ch8 car)
1051 ALWAYS_INLINE int Slot::calc_slot_cym(unsigned phase7, unsigned phase8)
1052 {
1053  unsigned egout = calc_envelope<false, false>(0, 0);
1054  unsigned dbout = (((BIT(phase7, PG_BITS - 8) ^
1055  BIT(phase7, PG_BITS - 1)) |
1056  BIT(phase7, PG_BITS - 7)) ^
1057  ( BIT(phase8, PG_BITS - 7) &
1058  !BIT(phase8, PG_BITS - 5)))
1059  ? DB_NEG(3.0)
1060  : DB_POS(3.0);
1061  return dB2Lin.tab[dbout + egout];
1062 }
1063 
1064 // HI-HAT (ch7 mod)
1065 ALWAYS_INLINE int Slot::calc_slot_hat(unsigned phase7, unsigned phase8, bool noise)
1066 {
1067  unsigned egout = calc_envelope<false, false>(0, 0);
1068  unsigned dbout = (((BIT(phase7, PG_BITS - 8) ^
1069  BIT(phase7, PG_BITS - 1)) |
1070  BIT(phase7, PG_BITS - 7)) ^
1071  ( BIT(phase8, PG_BITS - 7) &
1072  !BIT(phase8, PG_BITS - 5)))
1073  ? (noise ? DB_NEG(12.0) : DB_NEG(24.0))
1074  : (noise ? DB_POS(12.0) : DB_POS(24.0));
1075  return dB2Lin.tab[dbout + egout];
1076 }
1077 
1078 float YM2413::getAmplificationFactor() const
1079 {
1080  return 1.0f / (1 << DB2LIN_AMP_BITS);
1081 }
1082 
1083 bool YM2413::isRhythm() const
1084 {
1085  return (reg[0x0E] & 0x20) != 0;
1086 }
1087 
1088 unsigned YM2413::getFreq(unsigned channel) const
1089 {
1090  // combined fnum (=9bit) and block (=3bit)
1091  assert(channel < 9);
1092  return reg[0x10 + channel] | ((reg[0x20 + channel] & 0x0F) << 8);
1093 }
1094 
1095 Patch& YM2413::getPatch(unsigned instrument, bool carrier)
1096 {
1097  return patches[instrument][carrier];
1098 }
1099 
1100 template <unsigned FLAGS>
1101 ALWAYS_INLINE void YM2413::calcChannel(Channel& ch, float* buf, unsigned num)
1102 {
1103  // VC++ requires explicit conversion to bool. Compiler bug??
1104  const bool HAS_CAR_PM = (FLAGS & 1) != 0;
1105  const bool HAS_CAR_AM = (FLAGS & 2) != 0;
1106  const bool HAS_MOD_PM = (FLAGS & 4) != 0;
1107  const bool HAS_MOD_AM = (FLAGS & 8) != 0;
1108  const bool HAS_MOD_FB = (FLAGS & 16) != 0;
1109  const bool HAS_CAR_FIXED_ENV = (FLAGS & 32) != 0;
1110  const bool HAS_MOD_FIXED_ENV = (FLAGS & 64) != 0;
1111 
1112  assert(((ch.car.patch.AMPM & 1) != 0) == HAS_CAR_PM);
1113  assert(((ch.car.patch.AMPM & 2) != 0) == HAS_CAR_AM);
1114  assert(((ch.mod.patch.AMPM & 1) != 0) == HAS_MOD_PM);
1115  assert(((ch.mod.patch.AMPM & 2) != 0) == HAS_MOD_AM);
1116 
1117  unsigned tmp_pm_phase = pm_phase;
1118  unsigned tmp_am_phase = am_phase;
1119  unsigned car_fixed_env = 0; // dummy
1120  unsigned mod_fixed_env = 0; // dummy
1121  if (HAS_CAR_FIXED_ENV) {
1122  car_fixed_env = ch.car.calc_fixed_env<HAS_CAR_AM>();
1123  }
1124  if (HAS_MOD_FIXED_ENV) {
1125  mod_fixed_env = ch.mod.calc_fixed_env<HAS_MOD_AM>();
1126  }
1127 
1128  unsigned sample = 0;
1129  do {
1130  unsigned lfo_pm = 0;
1131  if (HAS_CAR_PM || HAS_MOD_PM) {
1132  // Copied from Burczynski:
1133  // There are only 8 different steps for PM, and each
1134  // step lasts for 1024 samples. This results in a PM
1135  // freq of 6.1Hz (but datasheet says it's 6.4Hz).
1136  ++tmp_pm_phase;
1137  lfo_pm = (tmp_pm_phase >> 10) & 7;
1138  }
1139  int lfo_am = 0; // avoid warning
1140  if (HAS_CAR_AM || HAS_MOD_AM) {
1141  ++tmp_am_phase;
1142  if (tmp_am_phase == (LFO_AM_TAB_ELEMENTS * 64)) {
1143  tmp_am_phase = 0;
1144  }
1145  lfo_am = lfo_am_table[tmp_am_phase / 64];
1146  }
1147  int fm = ch.mod.calc_slot_mod<HAS_MOD_AM, HAS_MOD_FB, HAS_MOD_FIXED_ENV>(
1148  HAS_MOD_PM ? lfo_pm : 0, lfo_am, mod_fixed_env);
1149  buf[sample] += ch.car.calc_slot_car<HAS_CAR_AM, HAS_CAR_FIXED_ENV>(
1150  HAS_CAR_PM ? lfo_pm : 0, lfo_am, fm, car_fixed_env);
1151  ++sample;
1152  } while (sample < num);
1153 }
1154 
1155 void YM2413::generateChannels(float* bufs[9 + 5], unsigned num)
1156 {
1157  assert(num != 0);
1158 
1159  unsigned m = isRhythm() ? 6 : 9;
1160  for (unsigned i = 0; i < m; ++i) {
1161  Channel& ch = channels[i];
1162  if (ch.car.isActive()) {
1163  // Below we choose between 128 specialized versions of
1164  // calcChannel(). This allows to move a lot of
1165  // conditional code out of the inner-loop.
1166  bool carFixedEnv = (ch.car.state == SUSHOLD) ||
1167  (ch.car.state == FINISH);
1168  bool modFixedEnv = (ch.mod.state == SUSHOLD) ||
1169  (ch.mod.state == FINISH);
1170  if (ch.car.state == SETTLE) {
1171  modFixedEnv = false;
1172  }
1173  unsigned flags = ( ch.car.patch.AMPM << 0) |
1174  ( ch.mod.patch.AMPM << 2) |
1175  ((ch.mod.patch.FB != 0) << 4) |
1176  ( carFixedEnv << 5) |
1177  ( modFixedEnv << 6);
1178  switch (flags) {
1179  case 0: calcChannel< 0>(ch, bufs[i], num); break;
1180  case 1: calcChannel< 1>(ch, bufs[i], num); break;
1181  case 2: calcChannel< 2>(ch, bufs[i], num); break;
1182  case 3: calcChannel< 3>(ch, bufs[i], num); break;
1183  case 4: calcChannel< 4>(ch, bufs[i], num); break;
1184  case 5: calcChannel< 5>(ch, bufs[i], num); break;
1185  case 6: calcChannel< 6>(ch, bufs[i], num); break;
1186  case 7: calcChannel< 7>(ch, bufs[i], num); break;
1187  case 8: calcChannel< 8>(ch, bufs[i], num); break;
1188  case 9: calcChannel< 9>(ch, bufs[i], num); break;
1189  case 10: calcChannel< 10>(ch, bufs[i], num); break;
1190  case 11: calcChannel< 11>(ch, bufs[i], num); break;
1191  case 12: calcChannel< 12>(ch, bufs[i], num); break;
1192  case 13: calcChannel< 13>(ch, bufs[i], num); break;
1193  case 14: calcChannel< 14>(ch, bufs[i], num); break;
1194  case 15: calcChannel< 15>(ch, bufs[i], num); break;
1195  case 16: calcChannel< 16>(ch, bufs[i], num); break;
1196  case 17: calcChannel< 17>(ch, bufs[i], num); break;
1197  case 18: calcChannel< 18>(ch, bufs[i], num); break;
1198  case 19: calcChannel< 19>(ch, bufs[i], num); break;
1199  case 20: calcChannel< 20>(ch, bufs[i], num); break;
1200  case 21: calcChannel< 21>(ch, bufs[i], num); break;
1201  case 22: calcChannel< 22>(ch, bufs[i], num); break;
1202  case 23: calcChannel< 23>(ch, bufs[i], num); break;
1203  case 24: calcChannel< 24>(ch, bufs[i], num); break;
1204  case 25: calcChannel< 25>(ch, bufs[i], num); break;
1205  case 26: calcChannel< 26>(ch, bufs[i], num); break;
1206  case 27: calcChannel< 27>(ch, bufs[i], num); break;
1207  case 28: calcChannel< 28>(ch, bufs[i], num); break;
1208  case 29: calcChannel< 29>(ch, bufs[i], num); break;
1209  case 30: calcChannel< 30>(ch, bufs[i], num); break;
1210  case 31: calcChannel< 31>(ch, bufs[i], num); break;
1211  case 32: calcChannel< 32>(ch, bufs[i], num); break;
1212  case 33: calcChannel< 33>(ch, bufs[i], num); break;
1213  case 34: calcChannel< 34>(ch, bufs[i], num); break;
1214  case 35: calcChannel< 35>(ch, bufs[i], num); break;
1215  case 36: calcChannel< 36>(ch, bufs[i], num); break;
1216  case 37: calcChannel< 37>(ch, bufs[i], num); break;
1217  case 38: calcChannel< 38>(ch, bufs[i], num); break;
1218  case 39: calcChannel< 39>(ch, bufs[i], num); break;
1219  case 40: calcChannel< 40>(ch, bufs[i], num); break;
1220  case 41: calcChannel< 41>(ch, bufs[i], num); break;
1221  case 42: calcChannel< 42>(ch, bufs[i], num); break;
1222  case 43: calcChannel< 43>(ch, bufs[i], num); break;
1223  case 44: calcChannel< 44>(ch, bufs[i], num); break;
1224  case 45: calcChannel< 45>(ch, bufs[i], num); break;
1225  case 46: calcChannel< 46>(ch, bufs[i], num); break;
1226  case 47: calcChannel< 47>(ch, bufs[i], num); break;
1227  case 48: calcChannel< 48>(ch, bufs[i], num); break;
1228  case 49: calcChannel< 49>(ch, bufs[i], num); break;
1229  case 50: calcChannel< 50>(ch, bufs[i], num); break;
1230  case 51: calcChannel< 51>(ch, bufs[i], num); break;
1231  case 52: calcChannel< 52>(ch, bufs[i], num); break;
1232  case 53: calcChannel< 53>(ch, bufs[i], num); break;
1233  case 54: calcChannel< 54>(ch, bufs[i], num); break;
1234  case 55: calcChannel< 55>(ch, bufs[i], num); break;
1235  case 56: calcChannel< 56>(ch, bufs[i], num); break;
1236  case 57: calcChannel< 57>(ch, bufs[i], num); break;
1237  case 58: calcChannel< 58>(ch, bufs[i], num); break;
1238  case 59: calcChannel< 59>(ch, bufs[i], num); break;
1239  case 60: calcChannel< 60>(ch, bufs[i], num); break;
1240  case 61: calcChannel< 61>(ch, bufs[i], num); break;
1241  case 62: calcChannel< 62>(ch, bufs[i], num); break;
1242  case 63: calcChannel< 63>(ch, bufs[i], num); break;
1243  case 64: calcChannel< 64>(ch, bufs[i], num); break;
1244  case 65: calcChannel< 65>(ch, bufs[i], num); break;
1245  case 66: calcChannel< 66>(ch, bufs[i], num); break;
1246  case 67: calcChannel< 67>(ch, bufs[i], num); break;
1247  case 68: calcChannel< 68>(ch, bufs[i], num); break;
1248  case 69: calcChannel< 69>(ch, bufs[i], num); break;
1249  case 70: calcChannel< 70>(ch, bufs[i], num); break;
1250  case 71: calcChannel< 71>(ch, bufs[i], num); break;
1251  case 72: calcChannel< 72>(ch, bufs[i], num); break;
1252  case 73: calcChannel< 73>(ch, bufs[i], num); break;
1253  case 74: calcChannel< 74>(ch, bufs[i], num); break;
1254  case 75: calcChannel< 75>(ch, bufs[i], num); break;
1255  case 76: calcChannel< 76>(ch, bufs[i], num); break;
1256  case 77: calcChannel< 77>(ch, bufs[i], num); break;
1257  case 78: calcChannel< 78>(ch, bufs[i], num); break;
1258  case 79: calcChannel< 79>(ch, bufs[i], num); break;
1259  case 80: calcChannel< 80>(ch, bufs[i], num); break;
1260  case 81: calcChannel< 81>(ch, bufs[i], num); break;
1261  case 82: calcChannel< 82>(ch, bufs[i], num); break;
1262  case 83: calcChannel< 83>(ch, bufs[i], num); break;
1263  case 84: calcChannel< 84>(ch, bufs[i], num); break;
1264  case 85: calcChannel< 85>(ch, bufs[i], num); break;
1265  case 86: calcChannel< 86>(ch, bufs[i], num); break;
1266  case 87: calcChannel< 87>(ch, bufs[i], num); break;
1267  case 88: calcChannel< 88>(ch, bufs[i], num); break;
1268  case 89: calcChannel< 89>(ch, bufs[i], num); break;
1269  case 90: calcChannel< 90>(ch, bufs[i], num); break;
1270  case 91: calcChannel< 91>(ch, bufs[i], num); break;
1271  case 92: calcChannel< 92>(ch, bufs[i], num); break;
1272  case 93: calcChannel< 93>(ch, bufs[i], num); break;
1273  case 94: calcChannel< 94>(ch, bufs[i], num); break;
1274  case 95: calcChannel< 95>(ch, bufs[i], num); break;
1275  case 96: calcChannel< 96>(ch, bufs[i], num); break;
1276  case 97: calcChannel< 97>(ch, bufs[i], num); break;
1277  case 98: calcChannel< 98>(ch, bufs[i], num); break;
1278  case 99: calcChannel< 99>(ch, bufs[i], num); break;
1279  case 100: calcChannel<100>(ch, bufs[i], num); break;
1280  case 101: calcChannel<101>(ch, bufs[i], num); break;
1281  case 102: calcChannel<102>(ch, bufs[i], num); break;
1282  case 103: calcChannel<103>(ch, bufs[i], num); break;
1283  case 104: calcChannel<104>(ch, bufs[i], num); break;
1284  case 105: calcChannel<105>(ch, bufs[i], num); break;
1285  case 106: calcChannel<106>(ch, bufs[i], num); break;
1286  case 107: calcChannel<107>(ch, bufs[i], num); break;
1287  case 108: calcChannel<108>(ch, bufs[i], num); break;
1288  case 109: calcChannel<109>(ch, bufs[i], num); break;
1289  case 110: calcChannel<110>(ch, bufs[i], num); break;
1290  case 111: calcChannel<111>(ch, bufs[i], num); break;
1291  case 112: calcChannel<112>(ch, bufs[i], num); break;
1292  case 113: calcChannel<113>(ch, bufs[i], num); break;
1293  case 114: calcChannel<114>(ch, bufs[i], num); break;
1294  case 115: calcChannel<115>(ch, bufs[i], num); break;
1295  case 116: calcChannel<116>(ch, bufs[i], num); break;
1296  case 117: calcChannel<117>(ch, bufs[i], num); break;
1297  case 118: calcChannel<118>(ch, bufs[i], num); break;
1298  case 119: calcChannel<119>(ch, bufs[i], num); break;
1299  case 120: calcChannel<120>(ch, bufs[i], num); break;
1300  case 121: calcChannel<121>(ch, bufs[i], num); break;
1301  case 122: calcChannel<122>(ch, bufs[i], num); break;
1302  case 123: calcChannel<123>(ch, bufs[i], num); break;
1303  case 124: calcChannel<124>(ch, bufs[i], num); break;
1304  case 125: calcChannel<125>(ch, bufs[i], num); break;
1305  case 126: calcChannel<126>(ch, bufs[i], num); break;
1306  case 127: calcChannel<127>(ch, bufs[i], num); break;
1307  default: UNREACHABLE;
1308  }
1309  } else {
1310  bufs[i] = nullptr;
1311  }
1312  }
1313  // update AM, PM unit
1314  pm_phase += num;
1315  am_phase = (am_phase + num) % (LFO_AM_TAB_ELEMENTS * 64);
1316 
1317  if (isRhythm()) {
1318  bufs[6] = nullptr;
1319  bufs[7] = nullptr;
1320  bufs[8] = nullptr;
1321 
1322  Channel& ch6 = channels[6];
1323  Channel& ch7 = channels[7];
1324  Channel& ch8 = channels[8];
1325 
1326  unsigned old_noise = noise_seed;
1327  unsigned old_cphase7 = ch7.mod.cphase;
1328  unsigned old_cphase8 = ch8.car.cphase;
1329 
1330  if (ch6.car.isActive()) {
1331  for (unsigned sample = 0; sample < num; ++sample) {
1332  bufs[ 9][sample] += 2 *
1333  ch6.car.calc_slot_car<false, false>(
1334  0, 0, ch6.mod.calc_slot_mod<
1335  false, false, false>(0, 0, 0), 0);
1336  }
1337  } else {
1338  bufs[9] = nullptr;
1339  }
1340 
1341  if (ch7.car.isActive()) {
1342  for (unsigned sample = 0; sample < num; ++sample) {
1343  noise_seed >>= 1;
1344  bool noise_bit = noise_seed & 1;
1345  if (noise_bit) noise_seed ^= 0x8003020;
1346  bufs[10][sample] +=
1347  -2 * ch7.car.calc_slot_snare(noise_bit);
1348  }
1349  } else {
1350  bufs[10] = nullptr;
1351  }
1352 
1353  if (ch8.car.isActive()) {
1354  for (unsigned sample = 0; sample < num; ++sample) {
1355  unsigned phase7 = ch7.mod.calc_phase(0);
1356  unsigned phase8 = ch8.car.calc_phase(0);
1357  bufs[11][sample] +=
1358  -2 * ch8.car.calc_slot_cym(phase7, phase8);
1359  }
1360  } else {
1361  bufs[11] = nullptr;
1362  }
1363 
1364  if (ch7.mod.isActive()) {
1365  // restore noise, ch7/8 cphase
1366  noise_seed = old_noise;
1367  ch7.mod.cphase = old_cphase7;
1368  ch8.car.cphase = old_cphase8;
1369  for (unsigned sample = 0; sample < num; ++sample) {
1370  noise_seed >>= 1;
1371  bool noise_bit = noise_seed & 1;
1372  if (noise_bit) noise_seed ^= 0x8003020;
1373  unsigned phase7 = ch7.mod.calc_phase(0);
1374  unsigned phase8 = ch8.car.calc_phase(0);
1375  bufs[12][sample] +=
1376  2 * ch7.mod.calc_slot_hat(phase7, phase8, noise_bit);
1377  }
1378  } else {
1379  bufs[12] = nullptr;
1380  }
1381 
1382  if (ch8.mod.isActive()) {
1383  for (unsigned sample = 0; sample < num; ++sample) {
1384  bufs[13][sample] += 2 * ch8.mod.calc_slot_tom();
1385  }
1386  } else {
1387  bufs[13] = nullptr;
1388  }
1389  } else {
1390  bufs[ 9] = nullptr;
1391  bufs[10] = nullptr;
1392  bufs[11] = nullptr;
1393  bufs[12] = nullptr;
1394  bufs[13] = nullptr;
1395  }
1396 }
1397 
1398 void YM2413::writeReg(byte r, byte data)
1399 {
1400  assert(r < 0x40);
1401 
1402  switch (r) {
1403  case 0x00: {
1404  reg[r] = data;
1405  patches[0][0].AMPM = (data >> 6) & 3;
1406  patches[0][0].EG = (data >> 5) & 1;
1407  patches[0][0].setKR ((data >> 4) & 1);
1408  patches[0][0].setML ((data >> 0) & 15);
1409  unsigned m = isRhythm() ? 6 : 9;
1410  for (unsigned i = 0; i < m; ++i) {
1411  if ((reg[0x30 + i] & 0xF0) == 0) {
1412  Channel& ch = channels[i];
1413  ch.setPatch(0, *this); // TODO optimize
1414  unsigned freq = getFreq(i);
1415  ch.mod.updatePG (freq);
1416  ch.mod.updateRKS(freq);
1417  ch.mod.updateEG();
1418  }
1419  }
1420  break;
1421  }
1422  case 0x01: {
1423  reg[r] = data;
1424  patches[0][1].AMPM = (data >> 6) & 3;
1425  patches[0][1].EG = (data >> 5) & 1;
1426  patches[0][1].setKR ((data >> 4) & 1);
1427  patches[0][1].setML ((data >> 0) & 15);
1428  unsigned m = isRhythm() ? 6 : 9;
1429  for (unsigned i = 0; i < m; ++i) {
1430  if ((reg[0x30 + i] & 0xF0) == 0) {
1431  Channel& ch = channels[i];
1432  ch.setPatch(0, *this); // TODO optimize
1433  unsigned freq = getFreq(i);
1434  ch.car.updatePG (freq);
1435  ch.car.updateRKS(freq);
1436  ch.car.updateEG();
1437  }
1438  }
1439  break;
1440  }
1441  case 0x02: {
1442  reg[r] = data;
1443  patches[0][0].setKL((data >> 6) & 3);
1444  patches[0][0].setTL((data >> 0) & 63);
1445  unsigned m = isRhythm() ? 6 : 9;
1446  for (unsigned i = 0; i < m; ++i) {
1447  if ((reg[0x30 + i] & 0xF0) == 0) {
1448  Channel& ch = channels[i];
1449  ch.setPatch(0, *this); // TODO optimize
1450  bool actAsCarrier = (i >= 7) && isRhythm();
1451  assert(!actAsCarrier); (void)actAsCarrier;
1452  ch.mod.updateTLL(getFreq(i), false);
1453  }
1454  }
1455  break;
1456  }
1457  case 0x03: {
1458  reg[r] = data;
1459  patches[0][1].setKL((data >> 6) & 3);
1460  patches[0][1].setWF((data >> 4) & 1);
1461  patches[0][0].setWF((data >> 3) & 1);
1462  patches[0][0].setFB((data >> 0) & 7);
1463  unsigned m = isRhythm() ? 6 : 9;
1464  for (unsigned i = 0; i < m; ++i) {
1465  if ((reg[0x30 + i] & 0xF0) == 0) {
1466  Channel& ch = channels[i];
1467  ch.setPatch(0, *this); // TODO optimize
1468  }
1469  }
1470  break;
1471  }
1472  case 0x04: {
1473  reg[r] = data;
1474  patches[0][0].AR = (data >> 4) & 15;
1475  patches[0][0].DR = (data >> 0) & 15;
1476  unsigned m = isRhythm() ? 6 : 9;
1477  for (unsigned i = 0; i < m; ++i) {
1478  if ((reg[0x30 + i] & 0xF0) == 0) {
1479  Channel& ch = channels[i];
1480  ch.setPatch(0, *this); // TODO optimize
1481  ch.mod.updateEG();
1482  if (ch.mod.state == ATTACK) {
1484  }
1485  }
1486  }
1487  break;
1488  }
1489  case 0x05: {
1490  reg[r] = data;
1491  patches[0][1].AR = (data >> 4) & 15;
1492  patches[0][1].DR = (data >> 0) & 15;
1493  unsigned m = isRhythm() ? 6 : 9;
1494  for (unsigned i = 0; i < m; ++i) {
1495  if ((reg[0x30 + i] & 0xF0) == 0) {
1496  Channel& ch = channels[i];
1497  ch.setPatch(0, *this); // TODO optimize
1498  ch.car.updateEG();
1499  if (ch.car.state == ATTACK) {
1501  }
1502  }
1503  }
1504  break;
1505  }
1506  case 0x06: {
1507  reg[r] = data;
1508  patches[0][0].setSL((data >> 4) & 15);
1509  patches[0][0].RR = (data >> 0) & 15;
1510  unsigned m = isRhythm() ? 6 : 9;
1511  for (unsigned i = 0; i < m; ++i) {
1512  if ((reg[0x30 + i] & 0xF0) == 0) {
1513  Channel& ch = channels[i];
1514  ch.setPatch(0, *this); // TODO optimize
1515  ch.mod.updateEG();
1516  if (ch.mod.state == DECAY) {
1518  }
1519  }
1520  }
1521  break;
1522  }
1523  case 0x07: {
1524  reg[r] = data;
1525  patches[0][1].setSL((data >> 4) & 15);
1526  patches[0][1].RR = (data >> 0) & 15;
1527  unsigned m = isRhythm() ? 6 : 9;
1528  for (unsigned i = 0; i < m; i++) {
1529  if ((reg[0x30 + i] & 0xF0) == 0) {
1530  Channel& ch = channels[i];
1531  ch.setPatch(0, *this); // TODO optimize
1532  ch.car.updateEG();
1533  if (ch.car.state == DECAY) {
1535  }
1536  }
1537  }
1538  break;
1539  }
1540  case 0x0E: {
1541  byte old = reg[r];
1542  reg[r] = data;
1543  setRhythmFlags(old);
1544  break;
1545  }
1546  case 0x19: case 0x1A: case 0x1B: case 0x1C:
1547  case 0x1D: case 0x1E: case 0x1F:
1548  r -= 9; // verified on real YM2413
1549  // fall-through
1550  case 0x10: case 0x11: case 0x12: case 0x13: case 0x14:
1551  case 0x15: case 0x16: case 0x17: case 0x18: {
1552  reg[r] = data;
1553  unsigned cha = r & 0x0F; assert(cha < 9);
1554  Channel& ch = channels[cha];
1555  bool actAsCarrier = (cha >= 7) && isRhythm();
1556  unsigned freq = getFreq(cha);
1557  ch.mod.updateAll(freq, actAsCarrier);
1558  ch.car.updateAll(freq, true);
1559  break;
1560  }
1561  case 0x29: case 0x2A: case 0x2B: case 0x2C:
1562  case 0x2D: case 0x2E: case 0x2F:
1563  r -= 9; // verified on real YM2413
1564  // fall-through
1565  case 0x20: case 0x21: case 0x22: case 0x23: case 0x24:
1566  case 0x25: case 0x26: case 0x27: case 0x28: {
1567  reg[r] = data;
1568  unsigned cha = r & 0x0F; assert(cha < 9);
1569  Channel& ch = channels[cha];
1570  bool modActAsCarrier = (cha >= 7) && isRhythm();
1571  ch.setSustain((data >> 5) & 1, modActAsCarrier);
1572  if (data & 0x10) {
1573  ch.keyOn();
1574  } else {
1575  ch.keyOff();
1576  }
1577  unsigned freq = getFreq(cha);
1578  ch.mod.updateAll(freq, modActAsCarrier);
1579  ch.car.updateAll(freq, true);
1580  break;
1581  }
1582  case 0x39: case 0x3A: case 0x3B: case 0x3C:
1583  case 0x3D: case 0x3E: case 0x3F:
1584  r -= 9; // verified on real YM2413
1585  // fall-through
1586  case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
1587  case 0x35: case 0x36: case 0x37: case 0x38: {
1588  reg[r] = data;
1589  unsigned cha = r & 0x0F; assert(cha < 9);
1590  Channel& ch = channels[cha];
1591  if (isRhythm() && (cha >= 6)) {
1592  if (cha > 6) {
1593  // channel 7 or 8 in ryhthm mode
1594  ch.mod.setVolume(data >> 4);
1595  }
1596  } else {
1597  ch.setPatch(data >> 4, *this);
1598  }
1599  ch.car.setVolume(data & 15);
1600  bool actAsCarrier = (cha >= 7) && isRhythm();
1601  unsigned freq = getFreq(cha);
1602  ch.mod.updateAll(freq, actAsCarrier);
1603  ch.car.updateAll(freq, true);
1604  break;
1605  }
1606  default:
1607  break;
1608  }
1609 }
1610 
1611 byte YM2413::peekReg(byte r) const
1612 {
1613  return reg[r];
1614 }
1615 
1616 } // namespace YM2413Okazaki
1617 
1618 static std::initializer_list<enum_string<YM2413Okazaki::EnvelopeState>> envelopeStateInfo = {
1619  { "ATTACK", YM2413Okazaki::ATTACK },
1620  { "DECAY", YM2413Okazaki::DECAY },
1621  { "SUSHOLD", YM2413Okazaki::SUSHOLD },
1622  { "SUSTAIN", YM2413Okazaki::SUSTAIN },
1623  { "RELEASE", YM2413Okazaki::RELEASE },
1624  { "SETTLE", YM2413Okazaki::SETTLE },
1625  { "FINISH", YM2413Okazaki::FINISH }
1626 };
1627 SERIALIZE_ENUM(YM2413Okazaki::EnvelopeState, envelopeStateInfo);
1628 
1629 namespace YM2413Okazaki {
1630 
1631 // version 1: initial version
1632 // version 2: don't serialize "type / actAsCarrier" anymore, it's now
1633 // a calculated value
1634 // version 3: don't serialize slot_on_flag anymore
1635 // version 4: don't serialize volume anymore
1636 template<typename Archive>
1637 void Slot::serialize(Archive& ar, unsigned /*version*/)
1638 {
1639  ar.serialize("feedback", feedback);
1640  ar.serialize("output", output);
1641  ar.serialize("cphase", cphase);
1642  ar.serialize("state", state);
1643  ar.serialize("eg_phase", eg_phase);
1644  ar.serialize("sustain", sustain);
1645 
1646  // These are restored by calls to
1647  // updateAll(): eg_dphase, dphaseDRTableRks, tll, dphase
1648  // setEnvelopeState(): eg_phase_max
1649  // setPatch(): patch
1650  // setVolume(): volume
1651  // update_key_status(): slot_on_flag
1652 }
1653 
1654 // version 1: initial version
1655 // version 2: removed patch_number, freq
1656 template<typename Archive>
1657 void Channel::serialize(Archive& ar, unsigned /*version*/)
1658 {
1659  ar.serialize("mod", mod);
1660  ar.serialize("car", car);
1661 }
1662 
1663 
1664 // version 1: initial version
1665 // version 2: 'registers' are moved here (no longer serialized in base class)
1666 // version 3: no longer serialize 'user_patch_mod' and 'user_patch_car'
1667 template<typename Archive>
1668 void YM2413::serialize(Archive& ar, unsigned version)
1669 {
1670  if (ar.versionBelow(version, 2)) ar.beginTag("YM2413Core");
1671  ar.serialize("registers", reg);
1672  if (ar.versionBelow(version, 2)) ar.endTag("YM2413Core");
1673 
1674  // no need to serialize patches[]
1675  // patches[0] is restored from registers, the others are read-only
1676  ar.serialize("channels", channels);
1677  ar.serialize("pm_phase", pm_phase);
1678  ar.serialize("am_phase", am_phase);
1679  ar.serialize("noise_seed", noise_seed);
1680 
1681  if (ar.isLoader()) {
1682  patches[0][0].initModulator(&reg[0]);
1683  patches[0][1].initCarrier (&reg[0]);
1684  for (int i = 0; i < 9; ++i) {
1685  Channel& ch = channels[i];
1686  // restore patch
1687  unsigned p = ((i >= 6) && isRhythm())
1688  ? (16 + (i - 6))
1689  : (reg[0x30 + i] >> 4);
1690  ch.setPatch(p, *this); // before updateAll()
1691  // restore volume
1692  ch.car.setVolume(reg[0x30 + i] & 15);
1693  if (isRhythm() && (i >= 7)) { // ch 7/8 ryhthm
1694  ch.mod.setVolume(reg[0x30 + i] >> 4);
1695  }
1696  // sync various variables
1697  bool actAsCarrier = (i >= 7) && isRhythm();
1698  unsigned freq = getFreq(i);
1699  ch.mod.updateAll(freq, actAsCarrier);
1700  ch.car.updateAll(freq, true);
1701  ch.mod.setEnvelopeState(ch.mod.state);
1702  ch.car.setEnvelopeState(ch.car.state);
1703  }
1704  update_key_status();
1705  }
1706 }
1707 
1708 } // namespace YM2413Okazaki
1709 
1710 using YM2413Okazaki::YM2413;
1713 
1714 } // namespace openmsx
SERIALIZE_ENUM(CassettePlayer::State, stateInfo)
unsigned calc_envelope(int lfo_am, unsigned fixed_env)
void setWF(byte value)
Set waveform [0..1].
void setKR(byte value)
Sets the Key Scale of Rate (0 or 1).
void setSL(byte value)
Sets sustain level [0..15].
REGISTER_POLYMORPHIC_INITIALIZER(Pluggable, CassettePlayer, "CassettePlayer")
void setTL(byte value)
Set volume (total level) [0..63].
#define ALWAYS_INLINE
Definition: inline.hh:16
vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:269
void calcChannel(Channel &ch, float *buf, unsigned num)
void setEnvelopeState(EnvelopeState state)
#define M_PI
Definition: Math.hh:26
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
Abstract interface for the YM2413 core.
Definition: YM2413Core.hh:26
int calc_slot_mod(unsigned lfo_pm, int lfo_am, unsigned fixed_env)
void serialize(Archive &ar, unsigned version)
void calc_envelope_outline(unsigned &out)
void setSustain(bool sustain, bool modActAsCarrier)
void fill(ForwardRange &&range, const T &value)
Definition: ranges.hh:179
void serialize(Archive &ar, unsigned version)
void updateRKS(unsigned freq)
void initModulator(const byte *data)
int calc_slot_hat(unsigned phase7, unsigned phase8, bool noise)
constexpr auto data(C &c) -> decltype(c.data())
Definition: span.hh:69
void serialize(Archive &ar, unsigned version)
void setML(byte value)
Sets the frequency multiplier factor [0..15].
void initCarrier(const byte *data)
void updateTLL(unsigned freq, bool actAsCarrier)
void setKL(byte value)
Sets Key scale level [0..3].
void setPatch(unsigned num, YM2413 &ym2413)
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
void setVolume(unsigned value)
void updateAll(unsigned freq, bool actAsCarrier)
int calc_slot_cym(unsigned phase7, unsigned phase8)
Patch()
Creates an uninitialized Patch object; call initXXX() before use.
Patch & getPatch(unsigned instrument, bool carrier)
unsigned calc_fixed_env() const
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:840
YM2413
Definition: YM2413.cc:88
void setFB(byte value)
Sets the amount of feedback [0..7].
unsigned calc_phase(unsigned lfo_pm)
void setPatch(const Patch &patch)
FixedPoint< EP_FP_BITS > EnvPhaseIndex
void updatePG(unsigned freq)
unsigned getFreq(unsigned channel) const
int calc_slot_car(unsigned lfo_pm, int lfo_am, int fm, unsigned fixed_env)
TclObject t
static constexpr FixedPoint create(int value)
Create new fixed point object from given representation.
Definition: FixedPoint.hh:43
#define UNREACHABLE
Definition: unreachable.hh:38