openMSX
YMF278.cc
Go to the documentation of this file.
1 // Based on ymf278b.c written by R. Belmont and O. Galibert
2 
3 // Improved by Valley Bell, 2018
4 // Thanks to niekniek and l_oliveira for providing recordings from OPL4 hardware.
5 // Thanks to superctr and wouterv for discussing changes.
6 //
7 // Improvements:
8 // - added TL interpolation, recordings show that internal TL levels are 0x00..0xff
9 // - fixed ADSR speeds, attack rate 15 is now instant
10 // - correct clamping of intermediate Rate Correction values
11 // - emulation of "loop glitch" (going out-of-bounds by playing a sample faster than it the loop is long)
12 // - made calculation of sample position cleaner and closer to how the HW works
13 // - increased output resolution from TL (0.375dB) to envelope (0.09375dB)
14 // - fixed volume table -6dB steps are done using bit shifts, steps in between are multiplicators
15 // - made octave -8 freeze the sample
16 // - verified that TL and envelope levels are applied separately, both go silent at -60dB
17 // - implemented pseudo-reverb and damping according to manual
18 // - made pseudo-reverb ignore Rate Correction (real hardware ignores it)
19 // - reimplemented LFO, speed exactly matches the formulas that were probably used when creating the manual
20 // - fixed LFO (tremolo) amplitude modulation
21 // - made LFO vibrato and tremolo accurate to hardware
22 //
23 // Known issues:
24 // - Octave -8 was only tested with fnum 0. Other fnum values might behave differently.
25 
26 // This class doesn't model a full YMF278b chip. Instead it only models the
27 // wave part. The FM part in modeled in YMF262 (it's almost 100% compatible,
28 // the small differences are handled in YMF262). The status register and
29 // interaction with the FM registers (e.g. the NEW2 bit) is currently handled
30 // in the MSXMoonSound class.
31 
32 #include "YMF278.hh"
33 #include "DeviceConfig.hh"
34 #include "MSXMotherBoard.hh"
35 #include "MSXException.hh"
36 #include "enumerate.hh"
37 #include "one_of.hh"
38 #include "outer.hh"
39 #include "ranges.hh"
40 #include "serialize.hh"
41 #include "xrange.hh"
42 #include <algorithm>
43 
44 namespace openmsx {
45 
46 // envelope output entries
47 // fixed to match recordings from actual OPL4 -Valley Bell
48 constexpr int MAX_ATT_INDEX = 0x280; // makes attack phase right and also goes well with "envelope stops at -60dB"
49 constexpr int MIN_ATT_INDEX = 0;
50 constexpr int TL_SHIFT = 2; // envelope values are 4x as fine as TL levels
51 
52 constexpr unsigned LFO_SHIFT = 18; // LFO period of up to 0x40000 sample
53 constexpr unsigned LFO_PERIOD = 1 << LFO_SHIFT;
54 
55 // Envelope Generator phases
56 constexpr int EG_ATT = 4;
57 constexpr int EG_DEC = 3;
58 constexpr int EG_SUS = 2;
59 constexpr int EG_REL = 1;
60 constexpr int EG_OFF = 0;
61 // these 2 are only used in old savestates (and are converted to EG_REL on load)
62 constexpr int EG_REV = 5; // pseudo reverb
63 constexpr int EG_DMP = 6; // damp
64 
65 // Pan values, units are -3dB, i.e. 8.
66 constexpr uint8_t pan_left[16] = {
67  0, 8, 16, 24, 32, 40, 48, 255, 255, 0, 0, 0, 0, 0, 0, 0
68 };
69 constexpr uint8_t pan_right[16] = {
70  0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 48, 40, 32, 24, 16, 8
71 };
72 
73 // decay level table (3dB per step)
74 // 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)
75 static constexpr int16_t SC(int dB) { return int16_t(dB / 3 * 0x20); }
76 constexpr int16_t dl_tab[16] = {
77  SC( 0), SC( 3), SC( 6), SC( 9), SC(12), SC(15), SC(18), SC(21),
78  SC(24), SC(27), SC(30), SC(33), SC(36), SC(39), SC(42), SC(93)
79 };
80 
81 constexpr byte RATE_STEPS = 8;
82 constexpr byte eg_inc[15 * RATE_STEPS] = {
83 //cycle:0 1 2 3 4 5 6 7
84  0, 1, 0, 1, 0, 1, 0, 1, // 0 rates 00..12 0 (increment by 0 or 1)
85  0, 1, 0, 1, 1, 1, 0, 1, // 1 rates 00..12 1
86  0, 1, 1, 1, 0, 1, 1, 1, // 2 rates 00..12 2
87  0, 1, 1, 1, 1, 1, 1, 1, // 3 rates 00..12 3
88 
89  1, 1, 1, 1, 1, 1, 1, 1, // 4 rate 13 0 (increment by 1)
90  1, 1, 1, 2, 1, 1, 1, 2, // 5 rate 13 1
91  1, 2, 1, 2, 1, 2, 1, 2, // 6 rate 13 2
92  1, 2, 2, 2, 1, 2, 2, 2, // 7 rate 13 3
93 
94  2, 2, 2, 2, 2, 2, 2, 2, // 8 rate 14 0 (increment by 2)
95  2, 2, 2, 4, 2, 2, 2, 4, // 9 rate 14 1
96  2, 4, 2, 4, 2, 4, 2, 4, // 10 rate 14 2
97  2, 4, 4, 4, 2, 4, 4, 4, // 11 rate 14 3
98 
99  4, 4, 4, 4, 4, 4, 4, 4, // 12 rates 15 0, 15 1, 15 2, 15 3 for decay
100  8, 8, 8, 8, 8, 8, 8, 8, // 13 rates 15 0, 15 1, 15 2, 15 3 for attack (zero time)
101  0, 0, 0, 0, 0, 0, 0, 0, // 14 infinity rates for attack and decay(s)
102 };
103 
104 [[nodiscard]] static constexpr byte O(int a) { return a * RATE_STEPS; }
105 constexpr byte eg_rate_select[64] = {
106  O(14),O(14),O(14),O(14), // inf rate
107  O( 0),O( 1),O( 2),O( 3),
108  O( 0),O( 1),O( 2),O( 3),
109  O( 0),O( 1),O( 2),O( 3),
110  O( 0),O( 1),O( 2),O( 3),
111  O( 0),O( 1),O( 2),O( 3),
112  O( 0),O( 1),O( 2),O( 3),
113  O( 0),O( 1),O( 2),O( 3),
114  O( 0),O( 1),O( 2),O( 3),
115  O( 0),O( 1),O( 2),O( 3),
116  O( 0),O( 1),O( 2),O( 3),
117  O( 0),O( 1),O( 2),O( 3),
118  O( 0),O( 1),O( 2),O( 3),
119  O( 4),O( 5),O( 6),O( 7),
120  O( 8),O( 9),O(10),O(11),
121  O(12),O(12),O(12),O(12),
122 };
123 
124 // rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
125 // shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
126 // mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0
127 constexpr byte eg_rate_shift[64] = {
128  12, 12, 12, 12,
129  11, 11, 11, 11,
130  10, 10, 10, 10,
131  9, 9, 9, 9,
132  8, 8, 8, 8,
133  7, 7, 7, 7,
134  6, 6, 6, 6,
135  5, 5, 5, 5,
136  4, 4, 4, 4,
137  3, 3, 3, 3,
138  2, 2, 2, 2,
139  1, 1, 1, 1,
140  0, 0, 0, 0,
141  0, 0, 0, 0,
142  0, 0, 0, 0,
143  0, 0, 0, 0,
144 };
145 
146 
147 // number of steps the LFO counter advances per sample
148 // LFO frequency (Hz) -> LFO counter steps per sample
149 [[nodiscard]] static constexpr int L(double a) { return int((LFO_PERIOD * a) / 44100.0 + 0.5); }
150 constexpr int lfo_period[8] = {
151  L(0.168), // step: 1, period: 262144 samples
152  L(2.019), // step: 12, period: 21845 samples
153  L(3.196), // step: 19, period: 13797 samples
154  L(4.206), // step: 25, period: 10486 samples
155  L(5.215), // step: 31, period: 8456 samples
156  L(5.888), // step: 35, period: 7490 samples
157  L(6.224), // step: 37, period: 7085 samples
158  L(7.066), // step: 42, period: 6242 samples
159 };
160 
161 
162 // formula used by Yamaha docs:
163 // vib_depth_cents(x) = (log2(0x400 + x) - 10) * 1200
164 constexpr int16_t vib_depth[8] = {
165  0, // 0.000 cents
166  2, // 3.378 cents
167  3, // 5.065 cents
168  4, // 6.750 cents
169  6, // 10.114 cents
170  12, // 20.170 cents
171  24, // 40.106 cents
172  48, // 79.307 cents
173 };
174 
175 
176 // formula used by Yamaha docs:
177 // am_depth_db(x) = (x-1) / 0x40 * 6.0
178 // They use (x-1), because the depth is multiplied with the AM counter, which has a range of 0..0x7F.
179 // Thus the maximum attenuation with x=0x80 is (0x7F * 0x80) >> 7 = 0x7F.
180 // reversed formula:
181 // am_depth(dB) = round(dB / 6.0 * 0x40) + 1
182 constexpr uint8_t am_depth[8] = {
183  0x00, // 0.000 dB
184  0x14, // 1.781 dB
185  0x20, // 2.906 dB
186  0x28, // 3.656 dB
187  0x30, // 4.406 dB
188  0x40, // 5.906 dB
189  0x50, // 7.406 dB
190  0x80, // 11.910 dB
191 };
192 
193 
194 YMF278::Slot::Slot()
195 {
196  reset();
197 }
198 
199 // Sign extend a 4-bit value to int (32-bit)
200 // require: x in range [0..15]
201 [[nodiscard]] static constexpr int sign_extend_4(int x)
202 {
203  return (x ^ 8) - 8;
204 }
205 
206 // Params: oct in [-8 .. +7]
207 // fn in [ 0 .. 1023]
208 // We want to interpret oct as a signed 4-bit number and calculate
209 // ((fn | 1024) + vib) << (5 + sign_extend_4(oct))
210 // Though in this formula the shift can go over a negative distance (in that
211 // case we should shift in the other direction).
212 [[nodiscard]] static constexpr unsigned calcStep(int8_t oct, uint16_t fn, int16_t vib = 0)
213 {
214  if (oct == -8) return 0;
215  unsigned t = (fn + 1024 + vib) << (8 + oct); // use '+' iso '|' (generates slightly better code)
216  return t >> 3; // was shifted 3 positions too far
217 }
218 
219 void YMF278::Slot::reset()
220 {
221  wave = FN = OCT = TLdest = TL = pan = vib = AM = 0;
222  DL = AR = D1R = D2R = RC = RR = 0;
223  PRVB = keyon = DAMP = false;
224  stepptr = 0;
225  step = calcStep(OCT, FN);
226  bits = startaddr = loopaddr = endaddr = 0;
227  env_vol = MAX_ATT_INDEX;
228 
229  lfo_active = false;
230  lfo_cnt = 0;
231  lfo = 0;
232 
233  state = EG_OFF;
234 
235  // not strictly needed, but avoid UMR on savestate
236  pos = 0;
237 }
238 
239 int YMF278::Slot::compute_rate(int val) const
240 {
241  if (val == 0) {
242  return 0;
243  } else if (val == 15) {
244  return 63;
245  }
246  int res = val * 4;
247  if (RC != 15) {
248  // clamping verified with HW tests -Valley Bell
249  res += 2 * std::clamp(OCT + RC, 0, 15);
250  res += (FN & 0x200) ? 1 : 0;
251  }
252  return std::clamp(res, 0, 63);
253 }
254 
255 int YMF278::Slot::compute_decay_rate(int val) const
256 {
257  if (DAMP) {
258  // damping
259  // The manual lists these values for time and attenuation: (44100 samples/second)
260  // -12dB at 5.8ms, sample 256
261  // -48dB at 8.0ms, sample 352
262  // -72dB at 9.4ms, sample 416
263  // -96dB at 10.9ms, sample 480
264  // This results in these durations and rate values for the respective phases:
265  // 0dB .. -12dB: 256 samples (5.80ms) -> 128 samples per -6dB = rate 48
266  // -12dB .. -48dB: 96 samples (2.18ms) -> 16 samples per -6dB = rate 63
267  // -48dB .. -72dB: 64 samples (1.45ms) -> 16 samples per -6dB = rate 63
268  // -72dB .. -96dB: 64 samples (1.45ms) -> 16 samples per -6dB = rate 63
269  // Damping was verified to ignore rate correction.
270  if (env_vol < dl_tab[4]) {
271  return 48; // 0dB .. -12dB
272  } else {
273  return 63; // -12dB .. -96dB
274  }
275  }
276  if (PRVB) {
277  // pseudo reverb
278  // activated when reaching -18dB, overrides D1R/D2R/RR with reverb rate 5
279  //
280  // The manual is actually a bit unclear and just says "RATE=5",
281  // referring to the D1R/D2R/RR register value. However, later
282  // pages use "RATE" to refer to the "internal" rate, which is
283  // (register * 4) + rate correction. HW recordings prove that
284  // Rate Correction is ignored, so pseudo reverb just sets the
285  // "internal" rate to a value of 4*5 = 20.
286  if (env_vol >= dl_tab[6]) {
287  return 20;
288  }
289  }
290  return compute_rate(val);
291 }
292 
293 int16_t YMF278::Slot::compute_vib() const
294 {
295  // verified via hardware recording:
296  // With LFO speed 0 (period 262144 samples), each vibrato step takes
297  // 4096 samples.
298  // -> 64 steps total
299  // Also, with vibrato depth 7 (80 cents) and an F-Num of 0x400, the
300  // final F-Nums are: 0x400 .. 0x43C, 0x43C .. 0x400, 0x400 .. 0x3C4,
301  // 0x3C4 .. 0x400
302  int16_t lfo_fm = lfo_cnt / (LFO_PERIOD / 0x40);
303  // results in +0x00..+0x0F, +0x0F..+0x00, -0x00..-0x0F, -0x0F..-0x00
304  if (lfo_fm & 0x10) lfo_fm ^= 0x1F;
305  if (lfo_fm & 0x20) lfo_fm = -(lfo_fm & 0x0F);
306 
307  return (lfo_fm * vib_depth[vib]) / 12;
308 }
309 
310 uint16_t YMF278::Slot::compute_am() const
311 {
312  // verified via hardware recording:
313  // With LFO speed 0 (period 262144 samples), each tremolo step takes
314  // 1024 samples.
315  // -> 256 steps total
316  uint16_t lfo_am = lfo_cnt / (LFO_PERIOD / 0x100);
317  // results in 0x00..0x7F, 0x7F..0x00
318  if (lfo_am >= 0x80) lfo_am ^= 0xFF;
319 
320  return (lfo_am * am_depth[AM]) >> 7;
321 }
322 
323 
324 void YMF278::advance()
325 {
326  eg_cnt++;
327 
328  // modulo counters for volume interpolation
329  int tl_int_cnt = eg_cnt % 9; // 0 .. 8
330  int tl_int_step = (eg_cnt / 9) % 3; // 0 .. 2
331 
332  for (auto& op : slots) {
333  // volume interpolation
334  if (tl_int_cnt == 0) {
335  if (tl_int_step == 0) {
336  // decrease volume by one step every 27 samples
337  if (op.TL < op.TLdest) ++op.TL;
338  } else {
339  // increase volume by one step every 13.5 samples
340  if (op.TL > op.TLdest) --op.TL;
341  }
342  }
343 
344  if (op.lfo_active) {
345  op.lfo_cnt = (op.lfo_cnt + lfo_period[op.lfo]) & (LFO_PERIOD - 1);
346  }
347 
348  // Envelope Generator
349  switch (op.state) {
350  case EG_ATT: { // attack phase
351  uint8_t rate = op.compute_rate(op.AR);
352  // Verified by HW recording (and matches Nemesis' tests of the YM2612):
353  // AR = 0xF during KeyOn results in instant switch to EG_DEC. (see keyOnHelper)
354  // Setting AR = 0xF while the attack phase is in progress freezes the envelope.
355  if (rate >= 63) {
356  break;
357  }
358  uint8_t shift = eg_rate_shift[rate];
359  if (!(eg_cnt & ((1 << shift) - 1))) {
360  uint8_t select = eg_rate_select[rate];
361  // >>4 makes the attack phase's shape match the actual chip -Valley Bell
362  op.env_vol += (~op.env_vol * eg_inc[select + ((eg_cnt >> shift) & 7)]) >> 4;
363  if (op.env_vol <= MIN_ATT_INDEX) {
364  op.env_vol = MIN_ATT_INDEX;
365  // TODO does the real HW skip EG_DEC completely,
366  // or is it active for 1 sample?
367  op.state = op.DL ? EG_DEC : EG_SUS;
368  }
369  }
370  break;
371  }
372  case EG_DEC: { // decay phase
373  uint8_t rate = op.compute_decay_rate(op.D1R);
374  uint8_t shift = eg_rate_shift[rate];
375  if (!(eg_cnt & ((1 << shift) - 1))) {
376  uint8_t select = eg_rate_select[rate];
377  op.env_vol += eg_inc[select + ((eg_cnt >> shift) & 7)];
378  if (op.env_vol >= op.DL) {
379  op.state = (op.env_vol < MAX_ATT_INDEX) ? EG_SUS : EG_OFF;
380  }
381  }
382  break;
383  }
384  case EG_SUS: { // sustain phase
385  uint8_t rate = op.compute_decay_rate(op.D2R);
386  uint8_t shift = eg_rate_shift[rate];
387  if (!(eg_cnt & ((1 << shift) - 1))) {
388  uint8_t select = eg_rate_select[rate];
389  op.env_vol += eg_inc[select + ((eg_cnt >> shift) & 7)];
390  if (op.env_vol >= MAX_ATT_INDEX) {
391  op.env_vol = MAX_ATT_INDEX;
392  op.state = EG_OFF;
393  }
394  }
395  break;
396  }
397  case EG_REL: { // release phase
398  uint8_t rate = op.compute_decay_rate(op.RR);
399  uint8_t shift = eg_rate_shift[rate];
400  if (!(eg_cnt & ((1 << shift) - 1))) {
401  uint8_t select = eg_rate_select[rate];
402  op.env_vol += eg_inc[select + ((eg_cnt >> shift) & 7)];
403  if (op.env_vol >= MAX_ATT_INDEX) {
404  op.env_vol = MAX_ATT_INDEX;
405  op.state = EG_OFF;
406  }
407  }
408  break;
409  }
410  case EG_OFF:
411  // nothing
412  break;
413 
414  default:
415  UNREACHABLE;
416  }
417  }
418 }
419 
420 int16_t YMF278::getSample(Slot& slot, uint16_t pos) const
421 {
422  // TODO How does this behave when R#2 bit 0 = 1?
423  // As-if read returns 0xff? (Like for CPU memory reads.) Or is
424  // sound generation blocked at some higher level?
425  switch (slot.bits) {
426  case 0: {
427  // 8 bit
428  return readMem(slot.startaddr + pos) << 8;
429  }
430  case 1: {
431  // 12 bit
432  unsigned addr = slot.startaddr + ((pos / 2) * 3);
433  if (pos & 1) {
434  return (readMem(addr + 2) << 8) |
435  (readMem(addr + 1) & 0xF0);
436  } else {
437  return (readMem(addr + 0) << 8) |
438  ((readMem(addr + 1) << 4) & 0xF0);
439  }
440  }
441  case 2: {
442  // 16 bit
443  unsigned addr = slot.startaddr + (pos * 2);
444  return (readMem(addr + 0) << 8) |
445  (readMem(addr + 1));
446  }
447  default:
448  // TODO unspecified
449  return 0;
450  }
451 }
452 
453 uint16_t YMF278::nextPos(Slot& slot, uint16_t pos, uint16_t increment)
454 {
455  // If there is a 4-sample loop and you advance 12 samples per step,
456  // it may exceed the end offset.
457  // This is abused by the "Lizard Star" song to generate noise at 0:52. -Valley Bell
458  pos += increment;
459  if ((uint32_t(pos) + slot.endaddr) >= 0x10000) // check position >= (negated) end address
460  pos += slot.endaddr + slot.loopaddr; // This is how the actual chip does it.
461  return pos;
462 }
463 
464 bool YMF278::anyActive()
465 {
466  return ranges::any_of(slots, [](auto& op) { return op.state != EG_OFF; });
467 }
468 
469 // In: 'envVol', 0=max volume, others -> -3/32 = -0.09375 dB/step
470 // Out: 'x' attenuated by the corresponding factor.
471 // Note: microbenchmarks have shown that re-doing this calculation is about the
472 // same speed as using a 4kB lookup table.
473 static constexpr int vol_factor(int x, unsigned envVol)
474 {
475  if (envVol >= MAX_ATT_INDEX) return 0; // hardware clips to silence below -60dB
476  int vol_mul = 0x80 - (envVol & 0x3F); // 0x40 values per 6dB
477  int vol_shift = 7 + (envVol >> 6);
478  return (x * ((0x8000 * vol_mul) >> vol_shift)) >> 15;
479 }
480 
481 void YMF278::setMixLevel(uint8_t x, EmuTime::param time)
482 {
483  static constexpr float level[8] = {
484  (1.00f / 1), // 0dB
485  (0.75f / 1), // -3dB (approx)
486  (1.00f / 2), // -6dB
487  (0.75f / 2), // -9dB (approx)
488  (1.00f / 4), // -12dB
489  (0.75f / 4), // -15dB (approx)
490  (1.00f / 8), // -18dB
491  (0.00f ), // -inf dB
492  };
493  setSoftwareVolume(level[x & 7], level[(x >> 3) & 7], time);
494 }
495 
496 void YMF278::generateChannels(float** bufs, unsigned num)
497 {
498  if (!anyActive()) {
499  // TODO update internal state, even if muted
500  // TODO also mute individual channels
501  std::fill_n(bufs, 24, nullptr);
502  return;
503  }
504 
505  for (auto j : xrange(num)) {
506  for (auto i : xrange(24)) {
507  auto& sl = slots[i];
508  if (sl.state == EG_OFF) {
509  //bufs[i][2 * j + 0] += 0;
510  //bufs[i][2 * j + 1] += 0;
511  continue;
512  }
513 
514  int16_t sample = (getSample(sl, sl.pos) * (0x10000 - sl.stepptr) +
515  getSample(sl, nextPos(sl, sl.pos, 1)) * sl.stepptr) >> 16;
516  // TL levels are 00..FF internally (TL register value 7F is mapped to TL level FF)
517  // Envelope levels have 4x the resolution (000..3FF)
518  // Volume levels are approximate logarithmic. -6dB result in half volume. Steps in between use linear interpolation.
519  // A volume of -60dB or lower results in silence. (value 0x280..0x3FF).
520  // Recordings from actual hardware indicate that TL level and envelope level are applied separarely.
521  // Each of them is clipped to silence below -60dB, but TL+envelope might result in a lower volume. -Valley Bell
522  uint16_t envVol = std::min(sl.env_vol + ((sl.lfo_active && sl.AM) ? sl.compute_am() : 0),
523  MAX_ATT_INDEX);
524  int smplOut = vol_factor(vol_factor(sample, envVol), sl.TL << TL_SHIFT);
525 
526  // Panning is also done separately. (low-volume TL + low-volume panning goes below -60dB)
527  // I'll be taking wild guess and assume that -3dB is approximated with 75%. (same as with TL and envelope levels)
528  // The same applies to the PCM mix level.
529  int32_t volLeft = pan_left [sl.pan]; // note: register 0xF9 is handled externally
530  int32_t volRight = pan_right[sl.pan];
531  // 0 -> 0x20, 8 -> 0x18, 16 -> 0x10, 24 -> 0x0C, etc. (not using vol_factor here saves array boundary checks)
532  volLeft = (0x20 - (volLeft & 0x0f)) >> (volLeft >> 4);
533  volRight = (0x20 - (volRight & 0x0f)) >> (volRight >> 4);
534 
535  bufs[i][2 * j + 0] += (smplOut * volLeft ) >> 5;
536  bufs[i][2 * j + 1] += (smplOut * volRight) >> 5;
537 
538  unsigned step = (sl.lfo_active && sl.vib)
539  ? calcStep(sl.OCT, sl.FN, sl.compute_vib())
540  : sl.step;
541  sl.stepptr += step;
542 
543  if (sl.stepptr >= 0x10000) {
544  sl.pos = nextPos(sl, sl.pos, sl.stepptr >> 16);
545  sl.stepptr &= 0xffff;
546  }
547  }
548  advance();
549  }
550 }
551 
552 void YMF278::keyOnHelper(YMF278::Slot& slot)
553 {
554  // Unlike FM, the envelope level is reset. (And it makes sense, because you restart the sample.)
555  slot.env_vol = MAX_ATT_INDEX;
556  if (slot.compute_rate(slot.AR) < 63) {
557  slot.state = EG_ATT;
558  } else {
559  // Nuke.YKT verified that the FM part does it exactly this way,
560  // and the OPL4 manual says it's instant as well.
561  slot.env_vol = MIN_ATT_INDEX;
562  // see comment in 'case EG_ATT' in YMF278::advance()
563  slot.state = slot.DL ? EG_DEC : EG_SUS;
564  }
565  slot.stepptr = 0;
566  slot.pos = 0;
567 }
568 
569 void YMF278::writeReg(byte reg, byte data, EmuTime::param time)
570 {
571  updateStream(time); // TODO optimize only for regs that directly influence sound
572  writeRegDirect(reg, data, time);
573 }
574 
575 void YMF278::writeRegDirect(byte reg, byte data, EmuTime::param time)
576 {
577  // Handle slot registers specifically
578  if (reg >= 0x08 && reg <= 0xF7) {
579  int sNum = (reg - 8) % 24;
580  auto& slot = slots[sNum];
581  switch ((reg - 8) / 24) {
582  case 0: {
583  slot.wave = (slot.wave & 0x100) | data;
584  int waveTblHdr = (regs[2] >> 2) & 0x7;
585  int base = (slot.wave < 384 || !waveTblHdr) ?
586  (slot.wave * 12) :
587  (waveTblHdr * 0x80000 + ((slot.wave - 384) * 12));
588  byte buf[12];
589  for (auto i : xrange(12)) {
590  // TODO What if R#2 bit 0 = 1?
591  // See also getSample()
592  buf[i] = readMem(base + i);
593  }
594  slot.bits = (buf[0] & 0xC0) >> 6;
595  slot.startaddr = buf[2] | (buf[1] << 8) | ((buf[0] & 0x3F) << 16);
596  slot.loopaddr = buf[4] | (buf[3] << 8);
597  slot.endaddr = buf[6] | (buf[5] << 8);
598  for (auto i : xrange(7, 12)) {
599  // Verified on real YMF278:
600  // After tone loading, if you read these
601  // registers, their value actually has changed.
602  writeRegDirect(8 + sNum + (i - 2) * 24, buf[i], time);
603  }
604  if (slot.keyon) {
605  keyOnHelper(slot);
606  } else {
607  slot.stepptr = 0;
608  slot.pos = 0;
609  }
610  break;
611  }
612  case 1: {
613  slot.wave = (slot.wave & 0xFF) | ((data & 0x1) << 8);
614  slot.FN = (slot.FN & 0x380) | (data >> 1);
615  slot.step = calcStep(slot.OCT, slot.FN);
616  break;
617  }
618  case 2: {
619  slot.FN = (slot.FN & 0x07F) | ((data & 0x07) << 7);
620  slot.PRVB = (data & 0x08) != 0;
621  slot.OCT = sign_extend_4((data & 0xF0) >> 4);
622  slot.step = calcStep(slot.OCT, slot.FN);
623  break;
624  }
625  case 3: {
626  uint8_t t = data >> 1;
627  slot.TLdest = (t != 0x7f) ? t : 0xff; // verified on HW via volume interpolation
628  if (data & 1) {
629  // directly change volume
630  slot.TL = slot.TLdest;
631  } else {
632  // interpolate volume
633  }
634  break;
635  }
636  case 4:
637  if (data & 0x10) {
638  // output to DO1 pin:
639  // this pin is not used in moonsound
640  // we emulate this by muting the sound
641  slot.pan = 8; // both left/right -inf dB
642  } else {
643  slot.pan = data & 0x0F;
644  }
645 
646  if (data & 0x20) {
647  // LFO reset
648  slot.lfo_active = false;
649  slot.lfo_cnt = 0;
650  } else {
651  // LFO activate
652  slot.lfo_active = true;
653  }
654 
655  slot.DAMP = (data & 0x40) != 0;
656 
657  if (data & 0x80) {
658  if (!slot.keyon) {
659  slot.keyon = true;
660  keyOnHelper(slot);
661  }
662  } else {
663  if (slot.keyon) {
664  slot.keyon = false;
665  slot.state = EG_REL;
666  }
667  }
668  break;
669  case 5:
670  slot.lfo = (data >> 3) & 0x7;
671  slot.vib = data & 0x7;
672  break;
673  case 6:
674  slot.AR = data >> 4;
675  slot.D1R = data & 0xF;
676  break;
677  case 7:
678  slot.DL = dl_tab[data >> 4];
679  slot.D2R = data & 0xF;
680  break;
681  case 8:
682  slot.RC = data >> 4;
683  slot.RR = data & 0xF;
684  break;
685  case 9:
686  slot.AM = data & 0x7;
687  break;
688  }
689  } else {
690  // All non-slot registers
691  switch (reg) {
692  case 0x00: // TEST
693  case 0x01:
694  break;
695 
696  case 0x02:
697  // wave-table-header / memory-type / memory-access-mode
698  // Simply store in regs[2]
699  break;
700 
701  case 0x03:
702  // Verified on real YMF278:
703  // * Don't update the 'memAdr' variable on writes to
704  // reg 3 and 4. Only store the value in the 'regs'
705  // array for later use.
706  // * The upper 2 bits are not used to address the
707  // external memories (so from a HW pov they don't
708  // matter). But if you read back this register, the
709  // upper 2 bits always read as '0' (even if you wrote
710  // '1'). So we mask the bits here already.
711  data &= 0x3F;
712  break;
713 
714  case 0x04:
715  // See reg 3.
716  break;
717 
718  case 0x05:
719  // Verified on real YMF278: (see above)
720  // Only writes to reg 5 change the (full) 'memAdr'.
721  memAdr = (regs[3] << 16) | (regs[4] << 8) | data;
722  break;
723 
724  case 0x06: // memory data
725  if (regs[2] & 1) {
726  writeMem(memAdr, data);
727  ++memAdr; // no need to mask (again) here
728  } else {
729  // Verified on real YMF278:
730  // - writes are ignored
731  // - memAdr is NOT increased
732  }
733  break;
734 
735  case 0xf8: // These are implemented in MSXMoonSound.cc
736  case 0xf9:
737  break;
738  }
739  }
740 
741  regs[reg] = data;
742 }
743 
744 byte YMF278::readReg(byte reg)
745 {
746  // no need to call updateStream(time)
747  byte result = peekReg(reg);
748  if (reg == 6) {
749  // Memory Data Register
750  if (regs[2] & 1) {
751  // Verified on real YMF278:
752  // memAdr is only increased when 'regs[2] & 1'
753  ++memAdr; // no need to mask (again) here
754  }
755  }
756  return result;
757 }
758 
759 byte YMF278::peekReg(byte reg) const
760 {
761  switch (reg) {
762  case 2: // 3 upper bits are device ID
763  return (regs[2] & 0x1F) | 0x20;
764 
765  case 6: // Memory Data Register
766  if (regs[2] & 1) {
767  return readMem(memAdr);
768  } else {
769  // Verified on real YMF278
770  return 0xff;
771  }
772 
773  default:
774  return regs[reg];
775  }
776 }
777 
778 constexpr unsigned INPUT_RATE = 44100;
779 
780 YMF278::YMF278(const std::string& name_, int ramSize_,
781  const DeviceConfig& config)
782  : ResampledSoundDevice(config.getMotherBoard(), name_, "MoonSound wave-part",
783  24, INPUT_RATE, true)
784  , motherBoard(config.getMotherBoard())
785  , debugRegisters(motherBoard, getName())
786  , debugMemory (motherBoard, getName())
787  , rom(getName() + " ROM", "rom", config)
788  , ram(config, getName() + " RAM", "YMF278 sample RAM",
789  ramSize_ * 1024) // size in kB
790 {
791  if (rom.getSize() != 0x200000) { // 2MB
792  throw MSXException(
793  "Wrong ROM for MoonSound (YMF278). The ROM (usually "
794  "called yrw801.rom) should have a size of exactly 2MB.");
795  }
796  if ((ramSize_ != 0) && // - -
797  (ramSize_ != 128) && // 128kB -
798  (ramSize_ != 256) && // 128kB 128kB
799  (ramSize_ != 512) && // 512kB -
800  (ramSize_ != 640) && // 512kB 128kB
801  (ramSize_ != 1024) && // 512kB 512kB
802  (ramSize_ != 2048)) { // 512kB 512kB 512kB 512kB
803  throw MSXException(
804  "Wrong sampleram size for MoonSound (YMF278). "
805  "Got ", ramSize_, ", but must be one of "
806  "0, 128, 256, 512, 640, 1024 or 2048.");
807  }
808 
809  memAdr = 0; // avoid UMR
810  ranges::fill(regs, 0);
811 
812  registerSound(config);
813  reset(motherBoard.getCurrentTime()); // must come after registerSound() because of call to setSoftwareVolume() via setMixLevel()
814 }
815 
817 {
818  unregisterSound();
819 }
820 
822 {
823  ram.clear(0);
824 }
825 
826 void YMF278::reset(EmuTime::param time)
827 {
828  updateStream(time);
829 
830  eg_cnt = 0;
831 
832  for (auto& op : slots) {
833  op.reset();
834  }
835  regs[2] = 0; // avoid UMR
836  for (int i = 0xf7; i >= 0; --i) { // reverse order to avoid UMR
837  writeRegDirect(i, 0, time);
838  }
839  memAdr = 0;
840  setMixLevel(0, time);
841 }
842 
843 // This routine translates an address from the (upper) MoonSound address space
844 // to an address inside the (linearized) SRAM address space.
845 //
846 // The following info is based on measurements on a real MoonSound (v2.0)
847 // PCB. This PCB can have several possible SRAM configurations:
848 // 128kB:
849 // 1 SRAM chip of 128kB, chip enable (/CE) of this SRAM chip is connected to
850 // the 1Y0 output of a 74LS139 (2-to-4 decoder). The enable input of the
851 // 74LS139 is connected to YMF278 pin /MCS6 and the 74LS139 1B:1A inputs are
852 // connected to YMF278 pins MA18:MA17. So the SRAM is selected when /MC6 is
853 // active and MA18:MA17 == 0:0.
854 // 256kB:
855 // 2 SRAM chips of 128kB. First one connected as above. Second one has /CE
856 // connected to 74LS139 pin 1Y1. So SRAM2 is selected when /MSC6 is active
857 // and MA18:MA17 == 0:1.
858 // 512kB:
859 // 1 SRAM chip of 512kB, /CE connected to /MCS6
860 // 640kB:
861 // 1 SRAM chip of 512kB, /CE connected to /MCS6
862 // 1 SRAM chip of 128kB, /CE connected to /MCS7.
863 // (This means SRAM2 is potentially mirrored over a 512kB region)
864 // 1024kB:
865 // 1 SRAM chip of 512kB, /CE connected to /MCS6
866 // 1 SRAM chip of 512kB, /CE connected to /MCS7
867 // 2048kB:
868 // 1 SRAM chip of 512kB, /CE connected to /MCS6
869 // 1 SRAM chip of 512kB, /CE connected to /MCS7
870 // 1 SRAM chip of 512kB, /CE connected to /MCS8
871 // 1 SRAM chip of 512kB, /CE connected to /MCS9
872 // This configuration is not so easy to create on the v2.0 PCB. So it's
873 // very rare.
874 //
875 // So the /MCS6 and /MCS7 (and /MCS8 and /MCS9 in case of 2048kB) signals are
876 // used to select the different SRAM chips. The meaning of these signals
877 // depends on the 'memory access mode'. This mode can be changed at run-time
878 // via bit 1 in register 2. The following table indicates for which regions
879 // these signals are active (normally MoonSound should be used with mode=0):
880 // mode=0 mode=1
881 // /MCS6 0x200000-0x27FFFF 0x380000-0x39FFFF
882 // /MCS7 0x280000-0x2FFFFF 0x3A0000-0x3BFFFF
883 // /MCS8 0x300000-0x37FFFF 0x3C0000-0x3DFFFF
884 // /MCS9 0x380000-0x3FFFFF 0x3E0000-0x3FFFFF
885 //
886 // (For completeness) MoonSound also has 2MB ROM (YRW801), /CE of this ROM is
887 // connected to YMF278 /MCS0. In both mode=0 and mode=1 this signal is active
888 // for the region 0x000000-0x1FFFFF. (But this routine does not handle ROM).
889 unsigned YMF278::getRamAddress(unsigned addr) const
890 {
891  addr -= 0x200000; // RAM starts at 0x200000
892  if (regs[2] & 2) [[unlikely]] {
893  // Normally MoonSound is used in 'memory access mode = 0'. But
894  // in the rare case that mode=1 we adjust the address.
895  if ((0x180000 <= addr) && (addr <= 0x1FFFFF)) {
896  addr -= 0x180000;
897  switch (addr & 0x060000) {
898  case 0x000000: // [0x380000-0x39FFFF]
899  // 1st 128kB of SRAM1
900  break;
901  case 0x020000: // [0x3A0000-0x3BFFFF]
902  if (ram.getSize() == 256 * 1024) {
903  // 2nd 128kB SRAM chip
904  } else {
905  // 2nd block of 128kB in SRAM2
906  // In case of 512+128, we use mirroring
907  addr += 0x080000;
908  }
909  break;
910  case 0x040000: // [0x3C0000-0x3DFFFF]
911  // 3rd 128kB block in SRAM3
912  addr += 0x100000;
913  break;
914  case 0x060000: // [0x3EFFFF-0x3FFFFF]
915  // 4th 128kB block in SRAM4
916  addr += 0x180000;
917  break;
918  }
919  } else {
920  addr = unsigned(-1); // unmapped
921  }
922  }
923  if (ram.getSize() == 640 * 1024) {
924  // Verified on real MoonSound cartridge (v2.0): In case of
925  // 640kB (1x512kB + 1x128kB), the 128kB SRAM chip is 4 times
926  // visible. None of the other SRAM configurations show similar
927  // mirroring (because the others are powers of two).
928  if (addr > 0x080000) {
929  addr &= ~0x060000;
930  }
931  }
932  return addr;
933 }
934 
935 byte YMF278::readMem(unsigned address) const
936 {
937  // Verified on real YMF278: address space wraps at 4MB.
938  address &= 0x3FFFFF;
939  if (address < 0x200000) {
940  // ROM connected to /MCS0
941  return rom[address];
942  } else {
943  unsigned ramAddr = getRamAddress(address);
944  if (ramAddr < ram.getSize()) {
945  return ram[ramAddr];
946  } else {
947  // unmapped region
948  return 255; // TODO check
949  }
950  }
951 }
952 
953 void YMF278::writeMem(unsigned address, byte value)
954 {
955  address &= 0x3FFFFF;
956  if (address < 0x200000) {
957  // can't write to ROM
958  } else {
959  unsigned ramAddr = getRamAddress(address);
960  if (ramAddr < ram.getSize()) {
961  ram.write(ramAddr, value);
962  } else {
963  // can't write to unmapped memory
964  }
965  }
966 }
967 
968 // version 1: initial version, some variables were saved as char
969 // version 2: serialization framework was fixed to save/load chars as numbers
970 // but for backwards compatibility we still load old savestates as
971 // characters
972 // version 3: 'step' is no longer stored (it is recalculated)
973 // version 4:
974 // - removed members: 'lfo', 'LD', 'active'
975 // - new members 'TLdest', 'keyon', 'DAMP' restored from registers instead of serialized
976 // - store 'OCT' sign-extended
977 // - store 'endaddr' as 2s complement
978 // - removed EG_DMP and EG_REV enum values from 'state'
979 // version 5:
980 // - re-added 'lfo' member. This is not stored in the savestate, instead it's
981 // restored from register values in YMF278::serialize()
982 // - removed members 'lfo_step' and ' 'lfo_max'
983 // - 'lfo_cnt' has changed meaning (but we don't try to translate old to new meaning)
984 // version 6:
985 // - removed members: 'sample1', 'sample2'
986 template<typename Archive>
987 void YMF278::Slot::serialize(Archive& ar, unsigned version)
988 {
989  // TODO restore more state from registers
990  ar.serialize("startaddr", startaddr,
991  "loopaddr", loopaddr,
992  "stepptr", stepptr,
993  "pos", pos,
994  "env_vol", env_vol,
995  "lfo_cnt", lfo_cnt,
996  "DL", DL,
997  "wave", wave,
998  "FN", FN);
999  if (ar.versionAtLeast(version, 4)) {
1000  ar.serialize("endaddr", endaddr,
1001  "OCT", OCT);
1002  } else {
1003  unsigned e = 0; ar.serialize("endaddr", e); endaddr = (e ^ 0xffff) + 1;
1004 
1005  char O = 0;
1006  if (ar.versionAtLeast(version, 2)) {
1007  ar.serialize("OCT", O);
1008  } else {
1009  ar.serializeChar("OCT", O);
1010  }
1011  OCT = sign_extend_4(O);
1012  }
1013 
1014  if (ar.versionAtLeast(version, 2)) {
1015  ar.serialize("PRVB", PRVB,
1016  "TL", TL,
1017  "pan", pan,
1018  "vib", vib,
1019  "AM", AM,
1020  "AR", AR,
1021  "D1R", D1R,
1022  "D2R", D2R,
1023  "RC", RC,
1024  "RR", RR);
1025  } else {
1026  // for backwards compatibility with old savestates
1027  char PRVB_ = 0; ar.serializeChar("PRVB", PRVB_); PRVB = PRVB_;
1028  char TL_ = 0; ar.serializeChar("TL", TL_ ); TL = TL_;
1029  char pan_ = 0; ar.serializeChar("pan", pan_); pan = pan_;
1030  char vib_ = 0; ar.serializeChar("vib", vib_); vib = vib_;
1031  char AM_ = 0; ar.serializeChar("AM", AM_ ); AM = AM_;
1032  char AR_ = 0; ar.serializeChar("AR", AR_ ); AR = AR_;
1033  char D1R_ = 0; ar.serializeChar("D1R", D1R_); D1R = D1R_;
1034  char D2R_ = 0; ar.serializeChar("D2R", D2R_); D2R = D2R_;
1035  char RC_ = 0; ar.serializeChar("RC", RC_ ); RC = RC_;
1036  char RR_ = 0; ar.serializeChar("RR", RR_ ); RR = RR_;
1037  }
1038  ar.serialize("bits", bits,
1039  "lfo_active", lfo_active);
1040 
1041  ar.serialize("state", state);
1042  if (ar.versionBelow(version, 4)) {
1043  assert(Archive::IS_LOADER);
1044  if (state == one_of(EG_REV, EG_DMP)) {
1045  state = EG_REL;
1046  }
1047  }
1048 
1049  // Recalculate redundant state
1050  if constexpr (Archive::IS_LOADER) {
1051  step = calcStep(OCT, FN);
1052  }
1053 
1054  // This old comment is NOT completely true:
1055  // Older version also had "env_vol_step" and "env_vol_lim" but those
1056  // members were nowhere used, so removed those in the current
1057  // version (it's ok to remove members from the savestate without
1058  // updating the version number).
1059  // When you remove member variables without increasing the version
1060  // number, new openMSX executables can still read old savestates. And
1061  // if you try to load a new savestate in an old openMSX version you do
1062  // get a (cryptic) error message. But if the version number is
1063  // increased the error message is much clearer.
1064 }
1065 
1066 // version 1: initial version
1067 // version 2: loadTime and busyTime moved to MSXMoonSound class
1068 // version 3: memAdr cannot be restored from register values
1069 // version 4: implement ram via Ram class
1070 template<typename Archive>
1071 void YMF278::serialize(Archive& ar, unsigned version)
1072 {
1073  ar.serialize("slots", slots,
1074  "eg_cnt", eg_cnt);
1075  if (ar.versionAtLeast(version, 4)) {
1076  ar.serialize("ram", ram);
1077  } else {
1078  ar.serialize_blob("ram", ram.getWriteBackdoor(), ram.getSize());
1079  }
1080  ar.serialize_blob("registers", regs, sizeof(regs));
1081  if (ar.versionAtLeast(version, 3)) { // must come after 'regs'
1082  ar.serialize("memadr", memAdr);
1083  } else {
1084  assert(Archive::IS_LOADER);
1085  // Old formats didn't store 'memAdr' so we also can't magically
1086  // restore the correct value. The best we can do is restore the
1087  // last set address.
1088  regs[3] &= 0x3F; // mask upper two bits
1089  memAdr = (regs[3] << 16) | (regs[4] << 8) | regs[5];
1090  }
1091 
1092  // TODO restore more state from registers
1093  if constexpr (Archive::IS_LOADER) {
1094  for (auto [i, sl] : enumerate(slots)) {
1095  auto t = regs[0x50 + i] >> 1;
1096  sl.TLdest = (t != 0x7f) ? t : 0xff;
1097 
1098  sl.keyon = (regs[0x68 + i] & 0x80) != 0;
1099  sl.DAMP = (regs[0x68 + i] & 0x40) != 0;
1100  sl.lfo = (regs[0x80 + i] >> 3) & 7;
1101  }
1102  }
1103 }
1105 
1106 
1107 // class DebugRegisters
1108 
1109 YMF278::DebugRegisters::DebugRegisters(MSXMotherBoard& motherBoard_,
1110  const std::string& name_)
1111  : SimpleDebuggable(motherBoard_, name_ + " regs",
1112  "OPL4 registers", 0x100)
1113 {
1114 }
1115 
1116 byte YMF278::DebugRegisters::read(unsigned address)
1117 {
1118  auto& ymf278 = OUTER(YMF278, debugRegisters);
1119  return ymf278.peekReg(address);
1120 }
1121 
1122 void YMF278::DebugRegisters::write(unsigned address, byte value, EmuTime::param time)
1123 {
1124  auto& ymf278 = OUTER(YMF278, debugRegisters);
1125  ymf278.writeReg(address, value, time);
1126 }
1127 
1128 
1129 // class DebugMemory
1130 
1131 YMF278::DebugMemory::DebugMemory(MSXMotherBoard& motherBoard_,
1132  const std::string& name_)
1133  : SimpleDebuggable(motherBoard_, name_ + " mem",
1134  "OPL4 memory (includes both ROM and RAM)", 0x400000) // 4MB
1135 {
1136 }
1137 
1138 byte YMF278::DebugMemory::read(unsigned address)
1139 {
1140  auto& ymf278 = OUTER(YMF278, debugMemory);
1141  return ymf278.readMem(address);
1142 }
1143 
1144 void YMF278::DebugMemory::write(unsigned address, byte value)
1145 {
1146  auto& ymf278 = OUTER(YMF278, debugMemory);
1147  ymf278.writeMem(address, value);
1148 }
1149 
1150 } // namespace openmsx
TclObject t
Definition: one_of.hh:7
EmuTime::param getCurrentTime()
Convenience method: This is the same as getScheduler().getCurrentTime().
unsigned getSize() const
Definition: Rom.hh:34
void updateStream(EmuTime::param time)
Definition: SoundDevice.cc:138
void setSoftwareVolume(float volume, EmuTime::param time)
Change the 'software volume' of this sound device.
Definition: SoundDevice.cc:143
void unregisterSound()
Unregisters this sound device with the Mixer.
Definition: SoundDevice.cc:133
void registerSound(const DeviceConfig &config)
Registers this sound device with the Mixer.
Definition: SoundDevice.cc:88
void clear(byte c=0xff)
Definition: TrackedRam.hh:43
void write(unsigned addr, byte value)
Definition: TrackedRam.hh:38
byte * getWriteBackdoor()
Definition: TrackedRam.hh:52
unsigned getSize() const
Definition: TrackedRam.hh:20
byte readMem(unsigned address) const
Definition: YMF278.cc:935
void writeReg(byte reg, byte data, EmuTime::param time)
Definition: YMF278.cc:569
void setMixLevel(uint8_t x, EmuTime::param time)
Definition: YMF278.cc:481
YMF278(const std::string &name, int ramSize, const DeviceConfig &config)
Definition: YMF278.cc:780
void writeMem(unsigned address, byte value)
Definition: YMF278.cc:953
void reset(EmuTime::param time)
Definition: YMF278.cc:826
byte readReg(byte reg)
Definition: YMF278.cc:744
void clearRam()
Definition: YMF278.cc:821
byte peekReg(byte reg) const
Definition: YMF278.cc:759
void serialize(Archive &ar, unsigned version)
Definition: YMF278.cc:1071
constexpr auto step
Definition: eeprom.cc:9
constexpr auto enumerate(Iterable &&iterable)
Heavily inspired by Nathan Reed's blog post: Python-Like enumerate() In C++17 http://reedbeta....
Definition: enumerate.hh:28
constexpr double e
Definition: Math.hh:18
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:258
constexpr vecN< N, T > clamp(const vecN< N, T > &x, const vecN< N, T > &minVal, const vecN< N, T > &maxVal)
Definition: gl_vec.hh:285
std::string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:727
This file implemented 3 utility functions:
Definition: Autofire.cc:9
constexpr byte eg_rate_shift[32+64+32]
Definition: YM2151.cc:196
constexpr int EG_DMP
Definition: YMF278.cc:63
constexpr int16_t dl_tab[16]
Definition: YMF278.cc:76
constexpr uint8_t pan_right[16]
Definition: YMF278.cc:69
constexpr unsigned EG_SUS
Definition: YM2151.cc:39
constexpr int16_t vib_depth[8]
Definition: YMF278.cc:164
constexpr int TL_SHIFT
Definition: YMF278.cc:50
constexpr unsigned RATE_STEPS
Definition: YM2151.cc:119
constexpr byte eg_inc[19 *RATE_STEPS]
Definition: YM2151.cc:120
constexpr unsigned LFO_SHIFT
Definition: YMF278.cc:52
constexpr uint8_t pan_left[16]
Definition: YMF278.cc:66
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:127
void serialize(Archive &ar, T &t, unsigned version)
constexpr unsigned EG_REL
Definition: YM2151.cc:40
constexpr byte eg_rate_select[32+64+32]
Definition: YM2151.cc:152
constexpr int MIN_ATT_INDEX
Definition: YM2151.cc:35
constexpr unsigned LFO_PERIOD
Definition: YMF278.cc:53
constexpr int MAX_ATT_INDEX
Definition: YM2151.cc:34
constexpr int EG_REV
Definition: YMF278.cc:62
constexpr unsigned EG_DEC
Definition: YM2151.cc:38
constexpr uint8_t am_depth[8]
Definition: YMF278.cc:182
constexpr int lfo_period[8]
Definition: YMF278.cc:150
constexpr unsigned EG_OFF
Definition: YM2151.cc:41
constexpr unsigned EG_ATT
Definition: YM2151.cc:37
bool any_of(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:169
constexpr void fill(ForwardRange &&range, const T &value)
Definition: ranges.hh:256
#define OUTER(type, member)
Definition: outer.hh:41
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1009
#define UNREACHABLE
Definition: unreachable.hh:38
constexpr auto xrange(T e)
Definition: xrange.hh:133