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