openMSX
YM2413Burczynski.cc
Go to the documentation of this file.
1 /*
2  *
3  * File: ym2413.c - software implementation of YM2413
4  * FM sound generator type OPLL
5  *
6  * Copyright (C) 2002 Jarek Burczynski
7  *
8  * Version 1.0
9  *
10  *
11  * TODO:
12  * - make sure of the sinus amplitude bits
13  * - make sure of the EG resolution bits (looks like the biggest
14  * modulation index generated by the modulator is 123, 124 = no modulation)
15  * - find proper algorithm for attack phase of EG
16  * - tune up instruments ROM
17  * - support sample replay in test mode (it is NOT as simple as setting bit 0
18  * in register 0x0f and using register 0x10 for sample data).
19  * Which games use this feature ?
20  */
21 
22 #include "YM2413Burczynski.hh"
23 #include "Math.hh"
24 #include "cstd.hh"
25 #include "ranges.hh"
26 #include "serialize.hh"
27 #include "xrange.hh"
28 #include <array>
29 #include <cstring>
30 #include <iostream>
31 
32 namespace openmsx {
33 namespace YM2413Burczynski {
34 
35 // envelope output entries
36 constexpr int ENV_BITS = 10;
37 constexpr double ENV_STEP = 128.0 / (1 << ENV_BITS);
38 
39 constexpr int MAX_ATT_INDEX = (1 << (ENV_BITS - 2)) - 1; // 255
40 constexpr int MIN_ATT_INDEX = 0;
41 
42 // sinwave entries
43 constexpr int SIN_BITS = 10;
44 constexpr int SIN_LEN = 1 << SIN_BITS;
45 constexpr int SIN_MASK = SIN_LEN - 1;
46 
47 constexpr int TL_RES_LEN = 256; // 8 bits addressing (real chip)
48 
49 // key scale level
50 // table is 3dB/octave, DV converts this into 6dB/octave
51 // 0.1875 is bit 0 weight of the envelope counter (volume) expressed
52 // in the 'decibel' scale
53 static constexpr int DV(double x) { return int(x / 0.1875); }
54 constexpr int ksl_tab[8 * 16] =
55 {
56  // OCT 0
57  DV( 0.000),DV( 0.000),DV( 0.000),DV( 0.000),
58  DV( 0.000),DV( 0.000),DV( 0.000),DV( 0.000),
59  DV( 0.000),DV( 0.000),DV( 0.000),DV( 0.000),
60  DV( 0.000),DV( 0.000),DV( 0.000),DV( 0.000),
61  // OCT 1
62  DV( 0.000),DV( 0.000),DV( 0.000),DV( 0.000),
63  DV( 0.000),DV( 0.000),DV( 0.000),DV( 0.000),
64  DV( 0.000),DV( 0.750),DV( 1.125),DV( 1.500),
65  DV( 1.875),DV( 2.250),DV( 2.625),DV( 3.000),
66  // OCT 2
67  DV( 0.000),DV( 0.000),DV( 0.000),DV( 0.000),
68  DV( 0.000),DV( 1.125),DV( 1.875),DV( 2.625),
69  DV( 3.000),DV( 3.750),DV( 4.125),DV( 4.500),
70  DV( 4.875),DV( 5.250),DV( 5.625),DV( 6.000),
71  // OCT 3
72  DV( 0.000),DV( 0.000),DV( 0.000),DV( 1.875),
73  DV( 3.000),DV( 4.125),DV( 4.875),DV( 5.625),
74  DV( 6.000),DV( 6.750),DV( 7.125),DV( 7.500),
75  DV( 7.875),DV( 8.250),DV( 8.625),DV( 9.000),
76  // OCT 4
77  DV( 0.000),DV( 0.000),DV( 3.000),DV( 4.875),
78  DV( 6.000),DV( 7.125),DV( 7.875),DV( 8.625),
79  DV( 9.000),DV( 9.750),DV(10.125),DV(10.500),
80  DV(10.875),DV(11.250),DV(11.625),DV(12.000),
81  // OCT 5
82  DV( 0.000),DV( 3.000),DV( 6.000),DV( 7.875),
83  DV( 9.000),DV(10.125),DV(10.875),DV(11.625),
84  DV(12.000),DV(12.750),DV(13.125),DV(13.500),
85  DV(13.875),DV(14.250),DV(14.625),DV(15.000),
86  // OCT 6
87  DV( 0.000),DV( 6.000),DV( 9.000),DV(10.875),
88  DV(12.000),DV(13.125),DV(13.875),DV(14.625),
89  DV(15.000),DV(15.750),DV(16.125),DV(16.500),
90  DV(16.875),DV(17.250),DV(17.625),DV(18.000),
91  // OCT 7
92  DV( 0.000),DV( 9.000),DV(12.000),DV(13.875),
93  DV(15.000),DV(16.125),DV(16.875),DV(17.625),
94  DV(18.000),DV(18.750),DV(19.125),DV(19.500),
95  DV(19.875),DV(20.250),DV(20.625),DV(21.000)
96 };
97 
98 // sustain level table (3dB per step)
99 // 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,45 (dB)
100 static constexpr int SC(int db) { return int(double(db) / ENV_STEP); }
101 constexpr int sl_tab[16] = {
102  SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
103  SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(15)
104 };
105 
106 constexpr uint8_t eg_inc[15][8] =
107 {
108  // cycle: 0 1 2 3 4 5 6 7
109 
110  /* 0 */ { 0,1, 0,1, 0,1, 0,1, }, // rates 00..12 0 (increment by 0 or 1)
111  /* 1 */ { 0,1, 0,1, 1,1, 0,1, }, // rates 00..12 1
112  /* 2 */ { 0,1, 1,1, 0,1, 1,1, }, // rates 00..12 2
113  /* 3 */ { 0,1, 1,1, 1,1, 1,1, }, // rates 00..12 3
114 
115  /* 4 */ { 1,1, 1,1, 1,1, 1,1, }, // rate 13 0 (increment by 1)
116  /* 5 */ { 1,1, 1,2, 1,1, 1,2, }, // rate 13 1
117  /* 6 */ { 1,2, 1,2, 1,2, 1,2, }, // rate 13 2
118  /* 7 */ { 1,2, 2,2, 1,2, 2,2, }, // rate 13 3
119 
120  /* 8 */ { 2,2, 2,2, 2,2, 2,2, }, // rate 14 0 (increment by 2)
121  /* 9 */ { 2,2, 2,4, 2,2, 2,4, }, // rate 14 1
122  /*10 */ { 2,4, 2,4, 2,4, 2,4, }, // rate 14 2
123  /*11 */ { 2,4, 4,4, 2,4, 4,4, }, // rate 14 3
124 
125  /*12 */ { 4,4, 4,4, 4,4, 4,4, }, // rates 15 0, 15 1, 15 2, 15 3 (incr by 4)
126  /*13 */ { 8,8, 8,8, 8,8, 8,8, }, // rates 15 2, 15 3 for attack
127  /*14 */ { 0,0, 0,0, 0,0, 0,0, }, // infinity rates for attack and decay(s)
128 };
129 
130 // note that there is no value 13 in this table - it's directly in the code
131 constexpr uint8_t eg_rate_select[16 + 64 + 16] =
132 {
133  // Envelope Generator rates (16 + 64 rates + 16 RKS)
134  // 16 infinite time rates
135  14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
136 
137  // rates 00-12
138  0, 1, 2, 3,
139  0, 1, 2, 3,
140  0, 1, 2, 3,
141  0, 1, 2, 3,
142  0, 1, 2, 3,
143  0, 1, 2, 3,
144  0, 1, 2, 3,
145  0, 1, 2, 3,
146  0, 1, 2, 3,
147  0, 1, 2, 3,
148  0, 1, 2, 3,
149  0, 1, 2, 3,
150  0, 1, 2, 3,
151 
152  // rate 13
153  4, 5, 6, 7,
154 
155  // rate 14
156  8, 9,10,11,
157 
158  // rate 15
159  12,12,12,12,
160 
161  // 16 dummy rates (same as 15 3)
162  12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
163 };
164 
165 // rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
166 // shift 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0
167 // mask 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0
168 
169 constexpr uint8_t eg_rate_shift[16 + 64 + 16] =
170 {
171  // Envelope Generator counter shifts (16 + 64 rates + 16 RKS)
172  // 16 infinite time rates
173  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
174 
175  // rates 00-12
176  13,13,13,13,
177  12,12,12,12,
178  11,11,11,11,
179  10,10,10,10,
180  9, 9, 9, 9,
181  8, 8, 8, 8,
182  7, 7, 7, 7,
183  6, 6, 6, 6,
184  5, 5, 5, 5,
185  4, 4, 4, 4,
186  3, 3, 3, 3,
187  2, 2, 2, 2,
188  1, 1, 1, 1,
189 
190  // rate 13
191  0, 0, 0, 0,
192 
193  // rate 14
194  0, 0, 0, 0,
195 
196  // rate 15
197  0, 0, 0, 0,
198 
199  // 16 dummy rates (same as 15 3)
200  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
201 };
202 
203 // multiple table
204 static constexpr uint8_t ML(double x) { return uint8_t(2 * x); }
205 constexpr uint8_t mul_tab[16] =
206 {
207  ML( 0.50), ML( 1.00), ML( 2.00), ML( 3.00),
208  ML( 4.00), ML( 5.00), ML( 6.00), ML( 7.00),
209  ML( 8.00), ML( 9.00), ML(10.00), ML(10.00),
210  ML(12.00), ML(12.00), ML(15.00), ML(15.00),
211 };
212 
213 // TL_TAB_LEN is calculated as:
214 // 11 - sinus amplitude bits (Y axis)
215 // 2 - sinus sign bit (Y axis)
216 // TL_RES_LEN - sinus resolution (X axis)
217 constexpr int TL_TAB_LEN = 11 * 2 * TL_RES_LEN;
218 constexpr auto tlTab = [] {
219  std::array<int, TL_TAB_LEN> result = {};
220  for (auto x : xrange(TL_RES_LEN)) {
221  double m = (1 << 16) / cstd::exp2<6>((x + 1) * (ENV_STEP / 4.0) / 8.0);
222 
223  // we never reach (1 << 16) here due to the (x + 1)
224  // result fits within 16 bits at maximum
225  int n = int(m); // 16 bits here
226  n >>= 4; // 12 bits here
227  n = (n >> 1) + (n & 1); // round to nearest
228  // 11 bits here (rounded)
229  for (auto i : xrange(11)) {
230  result[x * 2 + 0 + i * 2 * TL_RES_LEN] = n >> i;
231  result[x * 2 + 1 + i * 2 * TL_RES_LEN] = -(n >> i);
232  }
233  }
234  return result;
235 }();
236 
237 // sin waveform table in 'decibel' scale
238 // two waveforms on OPLL type chips
239 constexpr auto sinTab = [] {
240  std::array<unsigned, SIN_LEN * 2> result = {};
241  for (auto i : xrange(SIN_LEN / 4)) {
242  // checked on real hardware, see also
243  // http://docs.google.com/Doc?id=dd8kqn9f_13cqjkf4gp
244  double m = cstd::sin<2>(((i * 2) + 1) * M_PI / SIN_LEN);
245  int n = int(cstd::round(cstd::log2<8, 3>(m) * -256.0));
246  result[i] = 2 * n;
247  }
248  for (auto i : xrange(SIN_LEN / 4)) {
249  result[SIN_LEN / 4 + i] = result[SIN_LEN / 4 - 1 - i];
250  }
251  for (auto i : xrange(SIN_LEN / 2)) {
252  result[SIN_LEN / 2 + i] = result[i] | 1;
253  }
254  for (auto i : xrange(SIN_LEN / 2)) {
255  result[i + SIN_LEN] = result[i];
256  }
257  for (auto i : xrange(SIN_LEN / 2)) {
258  result[i + SIN_LEN + SIN_LEN / 2] = TL_TAB_LEN;
259  }
260  return result;
261 }();
262 
263 // LFO Amplitude Modulation table (verified on real YM3812)
264 // 27 output levels (triangle waveform);
265 // 1 level takes one of: 192, 256 or 448 samples
266 //
267 // Length: 210 elements.
268 //
269 // Each of the elements has to be repeated
270 // exactly 64 times (on 64 consecutive samples).
271 // The whole table takes: 64 * 210 = 13440 samples.
272 //
273 // We use data>>1, until we find what it really is on real chip...
274 
275 constexpr int LFO_AM_TAB_ELEMENTS = 210;
276 constexpr uint8_t lfo_am_table[LFO_AM_TAB_ELEMENTS] =
277 {
278  0,0,0,0,0,0,0,
279  1,1,1,1,
280  2,2,2,2,
281  3,3,3,3,
282  4,4,4,4,
283  5,5,5,5,
284  6,6,6,6,
285  7,7,7,7,
286  8,8,8,8,
287  9,9,9,9,
288  10,10,10,10,
289  11,11,11,11,
290  12,12,12,12,
291  13,13,13,13,
292  14,14,14,14,
293  15,15,15,15,
294  16,16,16,16,
295  17,17,17,17,
296  18,18,18,18,
297  19,19,19,19,
298  20,20,20,20,
299  21,21,21,21,
300  22,22,22,22,
301  23,23,23,23,
302  24,24,24,24,
303  25,25,25,25,
304  26,26,26,
305  25,25,25,25,
306  24,24,24,24,
307  23,23,23,23,
308  22,22,22,22,
309  21,21,21,21,
310  20,20,20,20,
311  19,19,19,19,
312  18,18,18,18,
313  17,17,17,17,
314  16,16,16,16,
315  15,15,15,15,
316  14,14,14,14,
317  13,13,13,13,
318  12,12,12,12,
319  11,11,11,11,
320  10,10,10,10,
321  9,9,9,9,
322  8,8,8,8,
323  7,7,7,7,
324  6,6,6,6,
325  5,5,5,5,
326  4,4,4,4,
327  3,3,3,3,
328  2,2,2,2,
329  1,1,1,1
330 };
331 
332 // LFO Phase Modulation table (verified on real YM2413)
333 constexpr signed char lfo_pm_table[8][8] =
334 {
335  // FNUM2/FNUM = 0 00xxxxxx (0x0000)
336  { 0, 0, 0, 0, 0, 0, 0, 0, },
337 
338  // FNUM2/FNUM = 0 01xxxxxx (0x0040)
339  { 1, 0, 0, 0,-1, 0, 0, 0, },
340 
341  // FNUM2/FNUM = 0 10xxxxxx (0x0080)
342  { 2, 1, 0,-1,-2,-1, 0, 1, },
343 
344  // FNUM2/FNUM = 0 11xxxxxx (0x00C0)
345  { 3, 1, 0,-1,-3,-1, 0, 1, },
346 
347  // FNUM2/FNUM = 1 00xxxxxx (0x0100)
348  { 4, 2, 0,-2,-4,-2, 0, 2, },
349 
350  // FNUM2/FNUM = 1 01xxxxxx (0x0140)
351  { 5, 2, 0,-2,-5,-2, 0, 2, },
352 
353  // FNUM2/FNUM = 1 10xxxxxx (0x0180)
354  { 6, 3, 0,-3,-6,-3, 0, 3, },
355 
356  // FNUM2/FNUM = 1 11xxxxxx (0x01C0)
357  { 7, 3, 0,-3,-7,-3, 0, 3, },
358 };
359 
360 // This is not 100% perfect yet but very close
361 //
362 // - multi parameters are 100% correct (instruments and drums)
363 // - LFO PM and AM enable are 100% correct
364 // - waveform DC and DM select are 100% correct
365 constexpr uint8_t table[16 + 3][8] = {
366  // MULT MULT modTL DcDmFb AR/DR AR/DR SL/RR SL/RR
367  // 0 1 2 3 4 5 6 7
368  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // user instrument
369  { 0x61, 0x61, 0x1e, 0x17, 0xf0, 0x7f, 0x00, 0x17 }, // violin
370  { 0x13, 0x41, 0x16, 0x0e, 0xfd, 0xf4, 0x23, 0x23 }, // guitar
371  { 0x03, 0x01, 0x9a, 0x04, 0xf3, 0xf3, 0x13, 0xf3 }, // piano
372  { 0x11, 0x61, 0x0e, 0x07, 0xfa, 0x64, 0x70, 0x17 }, // flute
373  { 0x22, 0x21, 0x1e, 0x06, 0xf0, 0x76, 0x00, 0x28 }, // clarinet
374  { 0x21, 0x22, 0x16, 0x05, 0xf0, 0x71, 0x00, 0x18 }, // oboe
375  { 0x21, 0x61, 0x1d, 0x07, 0x82, 0x80, 0x17, 0x17 }, // trumpet
376  { 0x23, 0x21, 0x2d, 0x16, 0x90, 0x90, 0x00, 0x07 }, // organ
377  { 0x21, 0x21, 0x1b, 0x06, 0x64, 0x65, 0x10, 0x17 }, // horn
378  { 0x21, 0x21, 0x0b, 0x1a, 0x85, 0xa0, 0x70, 0x07 }, // synthesizer
379  { 0x23, 0x01, 0x83, 0x10, 0xff, 0xb4, 0x10, 0xf4 }, // harpsichord
380  { 0x97, 0xc1, 0x20, 0x07, 0xff, 0xf4, 0x22, 0x22 }, // vibraphone
381  { 0x61, 0x00, 0x0c, 0x05, 0xc2, 0xf6, 0x40, 0x44 }, // synthesizer bass
382  { 0x01, 0x01, 0x56, 0x03, 0x94, 0xc2, 0x03, 0x12 }, // acoustic bass
383  { 0x21, 0x01, 0x89, 0x03, 0xf1, 0xe4, 0xf0, 0x23 }, // electric guitar
384  // drum instruments definitions
385  // MULTI MULTI modTL xxx AR/DR AR/DR SL/RR SL/RR
386  // 0 1 2 3 4 5 6 7
387  //{ 0x07, 0x21, 0x14, 0x00, 0xee, 0xf8, 0xff, 0xf8 },
388  //{ 0x01, 0x31, 0x00, 0x00, 0xf8, 0xf7, 0xf8, 0xf7 },
389  //{ 0x25, 0x11, 0x00, 0x00, 0xf8, 0xfa, 0xf8, 0x55 }
390  { 0x01, 0x01, 0x16, 0x00, 0xfd, 0xf8, 0x2f, 0x6d },// BD(multi verified, modTL verified, mod env - verified(close), carr. env verified)
391  { 0x01, 0x01, 0x00, 0x00, 0xd8, 0xd8, 0xf9, 0xf8 },// HH(multi verified), SD(multi not used)
392  { 0x05, 0x01, 0x00, 0x00, 0xf8, 0xba, 0x49, 0x55 },// TOM(multi,env verified), TOP CYM(multi verified, env verified)
393 };
394 
395 static constexpr FreqIndex fnumToIncrement(int block_fnum)
396 {
397  // OPLL (YM2413) phase increment counter = 18bit
398  // Chip works with 10.10 fixed point, while we use 16.16.
399  const int block = (block_fnum & 0x1C00) >> 10;
400  return FreqIndex(block_fnum & 0x03FF) >> (11 - block);
401 }
402 
403 inline int Slot::calc_envelope(Channel& channel, unsigned eg_cnt, bool carrier)
404 {
405  switch (state) {
406  case EG_DUMP:
407  // Dump phase is performed by both operators in each channel.
408  // When CARRIER envelope gets down to zero level, phases in BOTH
409  // operators are reset (at the same time?).
410  // TODO: That sounds logical, but it does not match the implementation.
411  if (!(eg_cnt & eg_mask_dp)) {
412  egOut += eg_sel_dp[(eg_cnt >> eg_sh_dp) & 7];
413  if (egOut >= MAX_ATT_INDEX) {
414  egOut = MAX_ATT_INDEX;
415  setEnvelopeState(EG_ATTACK);
416  phase = FreqIndex(0); // restart Phase Generator
417  }
418  }
419  break;
420 
421  case EG_ATTACK:
422  if (!(eg_cnt & eg_mask_ar)) {
423  egOut +=
424  (~egOut * eg_sel_ar[(eg_cnt >> eg_sh_ar) & 7]) >> 2;
425  if (egOut <= MIN_ATT_INDEX) {
426  egOut = MIN_ATT_INDEX;
427  setEnvelopeState(EG_DECAY);
428  }
429  }
430  break;
431 
432  case EG_DECAY:
433  if (!(eg_cnt & eg_mask_dr)) {
434  egOut += eg_sel_dr[(eg_cnt >> eg_sh_dr) & 7];
435  if (egOut >= sl) {
436  setEnvelopeState(EG_SUSTAIN);
437  }
438  }
439  break;
440 
441  case EG_SUSTAIN:
442  // this is important behaviour:
443  // one can change percussive/non-percussive modes on the fly and
444  // the chip will remain in sustain phase
445  // - verified on real YM3812
446  if (eg_sustain) {
447  // non-percussive mode (sustained tone)
448  // do nothing
449  } else {
450  // percussive mode
451  // during sustain phase chip adds Release Rate (in
452  // percussive mode)
453  if (!(eg_cnt & eg_mask_rr)) {
454  egOut += eg_sel_rr[(eg_cnt >> eg_sh_rr) & 7];
455  if (egOut >= MAX_ATT_INDEX) {
456  egOut = MAX_ATT_INDEX;
457  }
458  }
459  // else do nothing in sustain phase
460  }
461  break;
462 
463  case EG_RELEASE:
464  // Exclude modulators in melody channels from performing anything in
465  // this mode.
466  if (carrier) {
467  const bool sustain = !eg_sustain || channel.isSustained();
468  const unsigned mask = sustain ? eg_mask_rs : eg_mask_rr;
469  if (!(eg_cnt & mask)) {
470  const uint8_t shift = sustain ? eg_sh_rs : eg_sh_rr;
471  const uint8_t* sel = sustain ? eg_sel_rs : eg_sel_rr;
472  egOut += sel[(eg_cnt >> shift) & 7];
473  if (egOut >= MAX_ATT_INDEX) {
474  egOut = MAX_ATT_INDEX;
475  setEnvelopeState(EG_OFF);
476  }
477  }
478  }
479  break;
480 
481  case EG_OFF:
482  break;
483  }
484  return egOut;
485 }
486 
487 inline int Slot::calc_phase(Channel& channel, unsigned lfo_pm)
488 {
489  if (vib) {
490  const int lfo_fn_table_index_offset = lfo_pm_table
491  [(channel.getBlockFNum() & 0x01FF) >> 6][lfo_pm];
492  phase += fnumToIncrement(
493  channel.getBlockFNum() * 2 + lfo_fn_table_index_offset
494  ) * mul;
495  } else {
496  // LFO phase modulation disabled for this operator
497  phase += freq;
498  }
499  return phase.toInt();
500 }
501 
502 inline void Slot::updateTotalLevel(Channel& channel)
503 {
504  TLL = TL + (channel.getKeyScaleLevelBase() >> ksl);
505 }
506 
507 inline void Slot::updateAttackRate(int kcodeScaled)
508 {
509  if ((ar + kcodeScaled) < (16 + 62)) {
510  eg_sh_ar = eg_rate_shift[ar + kcodeScaled];
511  eg_sel_ar = eg_inc[eg_rate_select[ar + kcodeScaled]];
512  } else {
513  eg_sh_ar = 0;
514  eg_sel_ar = eg_inc[13];
515  }
516  eg_mask_ar = (1 << eg_sh_ar) - 1;
517 }
518 
519 inline void Slot::updateDecayRate(int kcodeScaled)
520 {
521  eg_sh_dr = eg_rate_shift[dr + kcodeScaled];
522  eg_sel_dr = eg_inc[eg_rate_select[dr + kcodeScaled]];
523  eg_mask_dr = (1 << eg_sh_dr) - 1;
524 }
525 
526 inline void Slot::updateReleaseRate(int kcodeScaled)
527 {
528  eg_sh_rr = eg_rate_shift[rr + kcodeScaled];
529  eg_sel_rr = eg_inc[eg_rate_select[rr + kcodeScaled]];
530  eg_mask_rr = (1 << eg_sh_rr) - 1;
531 }
532 
533 inline int Slot::calcOutput(Channel& channel, unsigned eg_cnt, bool carrier,
534  unsigned lfo_am, int phase2)
535 {
536  int egOut2 = calc_envelope(channel, eg_cnt, carrier);
537  int env = (TLL + egOut2 + (lfo_am & AMmask)) << 5;
538  int p = env + wavetable[phase2 & SIN_MASK];
539  return p < TL_TAB_LEN ? tlTab[p] : 0;
540 }
541 
542 inline int Slot::calc_slot_mod(Channel& channel, unsigned eg_cnt, bool carrier,
543  unsigned lfo_pm, unsigned lfo_am)
544 {
545  // Compute phase.
546  int phase2 = calc_phase(channel, lfo_pm);
547  if (fb_shift) {
548  phase2 += (op1_out[0] + op1_out[1]) >> fb_shift;
549  }
550  // Shift output in 2-place buffer.
551  op1_out[0] = op1_out[1];
552  // Calculate operator output.
553  op1_out[1] = calcOutput(channel, eg_cnt, carrier, lfo_am, phase2);
554  return op1_out[0] << 1;
555 }
556 
557 inline int Channel::calcOutput(unsigned eg_cnt, unsigned lfo_pm, unsigned lfo_am, int fm)
558 {
559  int phase = car.calc_phase(*this, lfo_pm) + fm;
560  return car.calcOutput(*this, eg_cnt, true, lfo_am, phase);
561 }
562 
563 
564 // Operators used in the rhythm sounds generation process:
565 //
566 // Envelope Generator:
567 //
568 // channel operator register number Bass High Snare Tom Top
569 // / slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal
570 // 6 / 0 12 50 70 90 f0 +
571 // 6 / 1 15 53 73 93 f3 +
572 // 7 / 0 13 51 71 91 f1 +
573 // 7 / 1 16 54 74 94 f4 +
574 // 8 / 0 14 52 72 92 f2 +
575 // 8 / 1 17 55 75 95 f5 +
576 //
577 // Phase Generator:
578 //
579 // channel operator register number Bass High Snare Tom Top
580 // / slot number MULTIPLE Drum Hat Drum Tom Cymbal
581 // 6 / 0 12 30 +
582 // 6 / 1 15 33 +
583 // 7 / 0 13 31 + + +
584 // 7 / 1 16 34 ----- n o t u s e d -----
585 // 8 / 0 14 32 +
586 // 8 / 1 17 35 + +
587 //
588 // channel operator register number Bass High Snare Tom Top
589 // number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal
590 // 6 12,15 B6 A6 +
591 // 7 13,16 B7 A7 + + +
592 // 8 14,17 B8 A8 + + +
593 
594 // Phase generation is based on:
595 // HH (13) channel 7->slot 1 combined with channel 8->slot 2
596 // (same combination as TOP CYMBAL but different output phases)
597 // SD (16) channel 7->slot 1
598 // TOM (14) channel 8->slot 1
599 // TOP (17) channel 7->slot 1 combined with channel 8->slot 2
600 // (same combination as HIGH HAT but different output phases)
601 
602 static constexpr int genPhaseHighHat(int phaseM7, int phaseC8, int noise_rng)
603 {
604  // hi == phase >= 0x200
605  // enable gate based on frequency of operator 2 in channel 8
606  bool hi = [&] {
607  if (phaseC8 & 0x28) {
608  return true;
609  } else {
610  // base frequency derived from operator 1 in channel 7
611  // VC++ requires explicit conversion to bool. Compiler bug??
612  const bool bit7 = (phaseM7 & 0x80) != 0;
613  const bool bit3 = (phaseM7 & 0x08) != 0;
614  const bool bit2 = (phaseM7 & 0x04) != 0;
615  return bool((bit2 ^ bit7) | bit3);
616  }
617  }();
618  if (noise_rng & 1) {
619  return hi ? (0x200 | 0xD0) : (0xD0 >> 2);
620  } else {
621  return hi ? (0x200 | (0xD0 >> 2)) : 0xD0;
622  }
623 }
624 
625 static constexpr int genPhaseSnare(int phaseM7, int noise_rng)
626 {
627  // base frequency derived from operator 1 in channel 7
628  // noise bit XOR'es phase by 0x100
629  return ((phaseM7 & 0x100) + 0x100)
630  ^ ((noise_rng & 1) << 8);
631 }
632 
633 static constexpr int genPhaseCymbal(int phaseM7, int phaseC8)
634 {
635  // enable gate based on frequency of operator 2 in channel 8
636  if (phaseC8 & 0x28) {
637  return 0x300;
638  } else {
639  // base frequency derived from operator 1 in channel 7
640  // VC++ requires explicit conversion to bool. Compiler bug??
641  const bool bit7 = (phaseM7 & 0x80) != 0;
642  const bool bit3 = (phaseM7 & 0x08) != 0;
643  const bool bit2 = (phaseM7 & 0x04) != 0;
644  return ((bit2 != bit7) || bit3) ? 0x300 : 0x100;
645  }
646 }
647 
648 
650  : phase(0), freq(0)
651 {
652  ar = dr = rr = KSR = ksl = mul = 0;
653  fb_shift = op1_out[0] = op1_out[1] = 0;
654  TL = TLL = egOut = sl = 0;
655  eg_sh_dp = eg_sh_ar = eg_sh_dr = eg_sh_rr = eg_sh_rs = 0;
656  eg_sel_dp = eg_sel_ar = eg_sel_dr = eg_sel_rr = eg_sel_rs = eg_inc[0];
657  eg_mask_dp = eg_mask_ar = eg_mask_dr = eg_mask_rr = eg_mask_rs = 0;
658  eg_sustain = false;
659  setEnvelopeState(EG_OFF);
660  key = AMmask = vib = 0;
661  wavetable = &sinTab[0 * SIN_LEN];
662 }
663 
665 {
666  if (!key) {
667  // do NOT restart Phase Generator (verified on real YM2413)
668  setEnvelopeState(EG_DUMP);
669  }
670  key |= part;
671 }
672 
674 {
675  if (key) {
676  key &= ~part;
677  if (!key) {
678  if (isActive()) {
679  setEnvelopeState(EG_RELEASE);
680  }
681  }
682  }
683 }
684 
685 void Slot::setKeyOnOff(KeyPart part, bool enabled)
686 {
687  if (enabled) {
688  setKeyOn(part);
689  } else {
690  setKeyOff(part);
691  }
692 }
693 
694 bool Slot::isActive() const
695 {
696  return state != EG_OFF;
697 }
698 
699 void Slot::setEnvelopeState(EnvelopeState state_)
700 {
701  state = state_;
702 }
703 
704 void Slot::setFrequencyMultiplier(uint8_t value)
705 {
706  mul = mul_tab[value];
707 }
708 
709 void Slot::setKeyScaleRate(bool value)
710 {
711  KSR = value ? 0 : 2;
712 }
713 
715 {
716  eg_sustain = value;
717 }
718 
719 void Slot::setVibrato(bool value)
720 {
721  vib = value;
722 }
723 
725 {
726  AMmask = value ? ~0 : 0;
727 }
728 
729 void Slot::setTotalLevel(Channel& channel, uint8_t value)
730 {
731  TL = value << (ENV_BITS - 2 - 7); // 7 bits TL (bit 6 = always 0)
732  updateTotalLevel(channel);
733 }
734 
735 void Slot::setKeyScaleLevel(Channel& channel, uint8_t value)
736 {
737  ksl = value ? (3 - value) : 31;
738  updateTotalLevel(channel);
739 }
740 
741 void Slot::setWaveform(uint8_t value)
742 {
743  wavetable = &sinTab[value * SIN_LEN];
744 }
745 
746 void Slot::setFeedbackShift(uint8_t value)
747 {
748  fb_shift = value ? 8 - value : 0;
749 }
750 
751 void Slot::setAttackRate(const Channel& channel, uint8_t value)
752 {
753  int kcodeScaled = channel.getKeyCode() >> KSR;
754  ar = value ? 16 + (value << 2) : 0;
755  updateAttackRate(kcodeScaled);
756 }
757 
758 void Slot::setDecayRate(const Channel& channel, uint8_t value)
759 {
760  int kcodeScaled = channel.getKeyCode() >> KSR;
761  dr = value ? 16 + (value << 2) : 0;
762  updateDecayRate(kcodeScaled);
763 }
764 
765 void Slot::setReleaseRate(const Channel& channel, uint8_t value)
766 {
767  int kcodeScaled = channel.getKeyCode() >> KSR;
768  rr = value ? 16 + (value << 2) : 0;
769  updateReleaseRate(kcodeScaled);
770 }
771 
772 void Slot::setSustainLevel(uint8_t value)
773 {
774  sl = sl_tab[value];
775 }
776 
778 {
779  updateTotalLevel(channel);
780  updateGenerators(channel);
781 }
782 
784 {
785  wavetable = &sinTab[0 * SIN_LEN];
786  setEnvelopeState(EG_OFF);
787  egOut = MAX_ATT_INDEX;
788 }
789 
791 {
792  // (frequency) phase increment counter
793  freq = channel.getFrequencyIncrement() * mul;
794 
795  // calculate envelope generator rates
796  const int kcodeScaled = channel.getKeyCode() >> KSR;
797  updateAttackRate(kcodeScaled);
798  updateDecayRate(kcodeScaled);
799  updateReleaseRate(kcodeScaled);
800 
801  const int rs = channel.isSustained() ? 16 + (5 << 2) : 16 + (7 << 2);
802  eg_sh_rs = eg_rate_shift[rs + kcodeScaled];
803  eg_sel_rs = eg_inc[eg_rate_select[rs + kcodeScaled]];
804 
805  const int dp = 16 + (13 << 2);
806  eg_sh_dp = eg_rate_shift[dp + kcodeScaled];
807  eg_sel_dp = eg_inc[eg_rate_select[dp + kcodeScaled]];
808 
809  eg_mask_rs = (1 << eg_sh_rs) - 1;
810  eg_mask_dp = (1 << eg_sh_dp) - 1;
811 }
812 
814  : fc(0)
815 {
816  block_fnum = ksl_base = 0;
817  sus = false;
818 }
819 
820 void Channel::setFrequency(int block_fnum_)
821 {
822  if (block_fnum == block_fnum_) return;
823  block_fnum = block_fnum_;
824 
825  ksl_base = ksl_tab[block_fnum >> 5];
826  fc = fnumToIncrement(block_fnum * 2);
827 
828  // Refresh Total Level and frequency counter in both SLOTs of this channel.
829  mod.updateFrequency(*this);
830  car.updateFrequency(*this);
831 }
832 
833 void Channel::setFrequencyLow(uint8_t value)
834 {
835  setFrequency((block_fnum & 0x0F00) | value);
836 }
837 
838 void Channel::setFrequencyHigh(uint8_t value)
839 {
840  setFrequency((value << 8) | (block_fnum & 0x00FF));
841 }
842 
844 {
845  return block_fnum;
846 }
847 
849 {
850  return fc;
851 }
852 
854 {
855  return ksl_base;
856 }
857 
858 uint8_t Channel::getKeyCode() const
859 {
860  // BLK 2,1,0 bits -> bits 3,2,1 of kcode, FNUM MSB -> kcode LSB
861  return (block_fnum & 0x0F00) >> 8;
862 }
863 
865 {
866  return sus;
867 }
868 
869 void Channel::setSustain(bool sustained)
870 {
871  sus = sustained;
872 }
873 
874 void Channel::updateInstrumentPart(int part, uint8_t value)
875 {
876  switch (part) {
877  case 0:
878  mod.setFrequencyMultiplier(value & 0x0F);
879  mod.setKeyScaleRate((value & 0x10) != 0);
880  mod.setEnvelopeSustained((value & 0x20) != 0);
881  mod.setVibrato((value & 0x40) != 0);
882  mod.setAmplitudeModulation((value & 0x80) != 0);
883  mod.updateGenerators(*this);
884  break;
885  case 1:
886  car.setFrequencyMultiplier(value & 0x0F);
887  car.setKeyScaleRate((value & 0x10) != 0);
888  car.setEnvelopeSustained((value & 0x20) != 0);
889  car.setVibrato((value & 0x40) != 0);
890  car.setAmplitudeModulation((value & 0x80) != 0);
891  car.updateGenerators(*this);
892  break;
893  case 2:
894  mod.setKeyScaleLevel(*this, value >> 6);
895  mod.setTotalLevel(*this, value & 0x3F);
896  break;
897  case 3:
898  mod.setWaveform((value & 0x08) >> 3);
899  mod.setFeedbackShift(value & 0x07);
900  car.setKeyScaleLevel(*this, value >> 6);
901  car.setWaveform((value & 0x10) >> 4);
902  break;
903  case 4:
904  mod.setAttackRate(*this, value >> 4);
905  mod.setDecayRate(*this, value & 0x0F);
906  break;
907  case 5:
908  car.setAttackRate(*this, value >> 4);
909  car.setDecayRate(*this, value & 0x0F);
910  break;
911  case 6:
912  mod.setSustainLevel(value >> 4);
913  mod.setReleaseRate(*this, value & 0x0F);
914  break;
915  case 7:
916  car.setSustainLevel(value >> 4);
917  car.setReleaseRate(*this, value & 0x0F);
918  break;
919  }
920 }
921 
922 void Channel::updateInstrument(const uint8_t* inst)
923 {
924  for (auto part : xrange(8)) {
925  updateInstrumentPart(part, inst[part]);
926  }
927 }
928 
930  : lfo_am_cnt(0), lfo_pm_cnt(0)
931 {
932  if (false) {
933  for (const auto& e : tlTab) std::cout << e << '\n';
934  std::cout << '\n';
935  for (const auto& e : sinTab) std::cout << e << '\n';
936  }
937 
938  memset(reg, 0, sizeof(reg)); // avoid UMR
939  eg_cnt = 0;
940  noise_rng = 0;
941 
942  reset();
943 }
944 
945 void YM2413::updateCustomInstrument(int part, uint8_t value)
946 {
947  // Update instrument definition.
948  inst_tab[0][part] = value;
949 
950  // Update every channel that has instrument 0 selected.
951  for (auto ch : xrange(isRhythm() ? 6 : 9)) {
952  Channel& channel = channels[ch];
953  if ((reg[0x30 + ch] & 0xF0) == 0) {
954  channel.updateInstrumentPart(part, value);
955  }
956  }
957 }
958 
959 void YM2413::setRhythmFlags(uint8_t old)
960 {
961  Channel& ch6 = channels[6];
962  Channel& ch7 = channels[7];
963  Channel& ch8 = channels[8];
964 
965  // flags = X | X | mode | BD | SD | TOM | TC | HH
966  uint8_t flags = reg[0x0E];
967  if ((flags ^ old) & 0x20) {
968  if (flags & 0x20) { // OFF -> ON
969  // Bass drum.
970  ch6.updateInstrument(inst_tab[16]);
971  // High hat and snare drum.
972  ch7.updateInstrument(inst_tab[17]);
973  ch7.mod.setTotalLevel(ch7, (reg[0x37] >> 4) << 2); // High hat
974  // Tom-tom and top cymbal.
975  ch8.updateInstrument(inst_tab[18]);
976  ch8.mod.setTotalLevel(ch8, (reg[0x38] >> 4) << 2); // Tom-tom
977  } else { // ON -> OFF
978  ch6.updateInstrument(inst_tab[reg[0x36] >> 4]);
979  ch7.updateInstrument(inst_tab[reg[0x37] >> 4]);
980  ch8.updateInstrument(inst_tab[reg[0x38] >> 4]);
981  // BD key off
982  ch6.mod.setKeyOff(Slot::KEY_RHYTHM);
983  ch6.car.setKeyOff(Slot::KEY_RHYTHM);
984  // HH key off
985  ch7.mod.setKeyOff(Slot::KEY_RHYTHM);
986  // SD key off
987  ch7.car.setKeyOff(Slot::KEY_RHYTHM);
988  // TOM key off
989  ch8.mod.setKeyOff(Slot::KEY_RHYTHM);
990  // TOP-CY off
991  ch8.car.setKeyOff(Slot::KEY_RHYTHM);
992  }
993  }
994  if (flags & 0x20) {
995  // BD key on/off
996  ch6.mod.setKeyOnOff(Slot::KEY_RHYTHM, (flags & 0x10) != 0);
997  ch6.car.setKeyOnOff(Slot::KEY_RHYTHM, (flags & 0x10) != 0);
998  // HH key on/off
999  ch7.mod.setKeyOnOff(Slot::KEY_RHYTHM, (flags & 0x01) != 0);
1000  // SD key on/off
1001  ch7.car.setKeyOnOff(Slot::KEY_RHYTHM, (flags & 0x08) != 0);
1002  // TOM key on/off
1003  ch8.mod.setKeyOnOff(Slot::KEY_RHYTHM, (flags & 0x04) != 0);
1004  // TOP-CY key on/off
1005  ch8.car.setKeyOnOff(Slot::KEY_RHYTHM, (flags & 0x02) != 0);
1006  }
1007 }
1008 
1010 {
1011  eg_cnt = 0;
1012  noise_rng = 1; // noise shift register
1013  idleSamples = 0;
1014 
1015  // setup instruments table
1016  for (auto instrument : xrange(19)) {
1017  ranges::copy(table[instrument], inst_tab[instrument]);
1018  }
1019 
1020  // reset with register write
1021  writeReg(0x0F, 0); // test reg
1022  for (int i = 0x3F; i >= 0x10; --i) {
1023  writeReg(i, 0);
1024  }
1025  registerLatch = 0;
1026 
1027  resetOperators();
1028 }
1029 
1030 void YM2413::resetOperators()
1031 {
1032  for (auto& ch : channels) {
1033  ch.mod.resetOperators();
1034  ch.car.resetOperators();
1035  }
1036 }
1037 
1038 bool YM2413::isRhythm() const
1039 {
1040  return (reg[0x0E] & 0x20) != 0;
1041 }
1042 
1043 Channel& YM2413::getChannelForReg(uint8_t r)
1044 {
1045  uint8_t chan = (r & 0x0F) % 9; // verified on real YM2413
1046  return channels[chan];
1047 }
1048 
1050 {
1051  return 1.0f / 2048.0f;
1052 }
1053 
1054 void YM2413::generateChannels(float* bufs[9 + 5], unsigned num)
1055 {
1056  // TODO make channelActiveBits a member and
1057  // keep it up-to-date all the time
1058 
1059  // bits 0-8 -> ch[0-8].car
1060  // bits 9-17 -> ch[0-8].mod (only ch7 and ch8 used)
1061  unsigned channelActiveBits = 0;
1062 
1063  for (auto ch : xrange(isRhythm() ? 6 : 9)) {
1064  if (channels[ch].car.isActive()) {
1065  channelActiveBits |= 1 << ch;
1066  } else {
1067  bufs[ch] = nullptr;
1068  }
1069  }
1070  if (isRhythm()) {
1071  std::fill_n(bufs + 6, 3, nullptr);
1072  for (auto ch : xrange(6, 9)) {
1073  if (channels[ch].car.isActive()) {
1074  channelActiveBits |= 1 << ch;
1075  } else {
1076  bufs[ch + 3] = nullptr;
1077  }
1078  }
1079  if (channels[7].mod.isActive()) {
1080  channelActiveBits |= 1 << (7 + 9);
1081  } else {
1082  bufs[12] = nullptr;
1083  }
1084  if (channels[8].mod.isActive()) {
1085  channelActiveBits |= 1 << (8 + 9);
1086  } else {
1087  bufs[13] = nullptr;
1088  }
1089  } else {
1090  std::fill_n(bufs + 9, 5, nullptr);
1091  }
1092 
1093  if (channelActiveBits) {
1094  idleSamples = 0;
1095  } else {
1096  if (idleSamples > (CLOCK_FREQ / (72 * 5))) {
1097  // Optimization:
1098  // idle for over 1/5s = 200ms
1099  // we don't care that noise / AM / PM isn't exactly
1100  // in sync with the real HW when music resumes
1101  // Alternative:
1102  // implement an efficient advance(n) method
1103  return;
1104  }
1105  idleSamples += num;
1106  }
1107 
1108  for (auto i : xrange(num)) {
1109  // Amplitude modulation: 27 output levels (triangle waveform)
1110  // 1 level takes one of: 192, 256 or 448 samples
1111  // One entry from LFO_AM_TABLE lasts for 64 samples
1112  lfo_am_cnt.addQuantum();
1113  if (lfo_am_cnt == LFOAMIndex(LFO_AM_TAB_ELEMENTS)) {
1114  // lfo_am_table is 210 elements long
1115  lfo_am_cnt = LFOAMIndex(0);
1116  }
1117  unsigned lfo_am = lfo_am_table[lfo_am_cnt.toInt()] >> 1;
1118  unsigned lfo_pm = lfo_pm_cnt.toInt() & 7;
1119 
1120  for (auto ch : xrange(isRhythm() ? 6 : 9)) {
1121  Channel& channel = channels[ch];
1122  int fm = channel.mod.calc_slot_mod(channel, eg_cnt, false, lfo_pm, lfo_am);
1123  if ((channelActiveBits >> ch) & 1) {
1124  bufs[ch][i] += channel.calcOutput(eg_cnt, lfo_pm, lfo_am, fm);
1125  }
1126  }
1127  if (isRhythm()) {
1128  // Bass Drum (verified on real YM3812):
1129  // - depends on the channel 6 'connect' register:
1130  // when connect = 0 it works the same as in normal (non-rhythm) mode
1131  // (op1->op2->out)
1132  // when connect = 1 _only_ operator 2 is present on output (op2->out),
1133  // operator 1 is ignored
1134  // - output sample always is multiplied by 2
1135  Channel& channel6 = channels[6];
1136  int fm = channel6.mod.calc_slot_mod(channels[6], eg_cnt, true, lfo_pm, lfo_am);
1137  if (channelActiveBits & (1 << 6)) {
1138  bufs[ 9][i] += 2 * channel6.calcOutput(eg_cnt, lfo_pm, lfo_am, fm);
1139  }
1140 
1141  // TODO: Skip phase generation if output will 0 anyway.
1142  // Possible by passing phase generator as a template parameter to
1143  // calcOutput.
1144 
1145  /*C7*/ (void)channels[7].car.calc_phase(channels[7], lfo_pm);
1146  int phaseM7 = channels[7].mod.calc_phase(channels[7], lfo_pm);
1147  int phaseC8 = channels[8].car.calc_phase(channels[8], lfo_pm);
1148  int phaseM8 = channels[8].mod.calc_phase(channels[8], lfo_pm);
1149 
1150  // Snare Drum (verified on real YM3812)
1151  if (channelActiveBits & (1 << 7)) {
1152  Slot& SLOT7_2 = channels[7].car;
1153  bufs[10][i] += 2 * SLOT7_2.calcOutput(channels[7], eg_cnt, true, lfo_am, genPhaseSnare(phaseM7, noise_rng));
1154  }
1155 
1156  // Top Cymbal (verified on real YM2413)
1157  if (channelActiveBits & (1 << 8)) {
1158  Slot& SLOT8_2 = channels[8].car;
1159  bufs[11][i] += 2 * SLOT8_2.calcOutput(channels[8], eg_cnt, true, lfo_am, genPhaseCymbal(phaseM7, phaseC8));
1160  }
1161 
1162  // High Hat (verified on real YM3812)
1163  if (channelActiveBits & (1 << (7 + 9))) {
1164  Slot& SLOT7_1 = channels[7].mod;
1165  bufs[12][i] += 2 * SLOT7_1.calcOutput(channels[7], eg_cnt, true, lfo_am, genPhaseHighHat(phaseM7, phaseC8, noise_rng));
1166  }
1167 
1168  // Tom Tom (verified on real YM3812)
1169  if (channelActiveBits & (1 << (8 + 9))) {
1170  Slot& SLOT8_1 = channels[8].mod;
1171  bufs[13][i] += 2 * SLOT8_1.calcOutput(channels[8], eg_cnt, true, lfo_am, phaseM8);
1172  }
1173  }
1174 
1175  // Vibrato: 8 output levels (triangle waveform)
1176  // 1 level takes 1024 samples
1177  lfo_pm_cnt.addQuantum();
1178 
1179  ++eg_cnt;
1180 
1181  // The Noise Generator of the YM3812 is 23-bit shift register.
1182  // Period is equal to 2^23-2 samples.
1183  // Register works at sampling frequency of the chip, so output
1184  // can change on every sample.
1185  //
1186  // Output of the register and input to the bit 22 is:
1187  // bit0 XOR bit14 XOR bit15 XOR bit22
1188  //
1189  // Simply use bit 22 as the noise output.
1190 
1191  // int j = ((noise_rng >> 0) ^ (noise_rng >> 14) ^
1192  // (noise_rng >> 15) ^ (noise_rng >> 22)) & 1;
1193  // noise_rng = (j << 22) | (noise_rng >> 1);
1194  //
1195  // Instead of doing all the logic operations above, we
1196  // use a trick here (and use bit 0 as the noise output).
1197  // The difference is only that the noise bit changes one
1198  // step ahead. This doesn't matter since we don't know
1199  // what is real state of the noise_rng after the reset.
1200  if (noise_rng & 1) {
1201  noise_rng ^= 0x800302;
1202  }
1203  noise_rng >>= 1;
1204  }
1205 }
1206 
1207 void YM2413::writePort(bool port, uint8_t value, int /*offset*/)
1208 {
1209  if (port == 0) {
1210  registerLatch = value;
1211  } else {
1212  writeReg(registerLatch & 0x3f, value);
1213  }
1214 }
1215 
1216 void YM2413::pokeReg(uint8_t r, uint8_t v)
1217 {
1218  writeReg(r, v);
1219 }
1220 
1221 void YM2413::writeReg(uint8_t r, uint8_t v)
1222 {
1223  uint8_t old = reg[r];
1224  reg[r] = v;
1225 
1226  switch (r & 0xF0) {
1227  case 0x00: { // 00-0F: control
1228  switch (r & 0x0F) {
1229  case 0x00: // AM/VIB/EGTYP/KSR/MULTI (modulator)
1230  case 0x01: // AM/VIB/EGTYP/KSR/MULTI (carrier)
1231  case 0x02: // Key Scale Level, Total Level (modulator)
1232  case 0x03: // Key Scale Level, carrier waveform, modulator waveform,
1233  // Feedback
1234  case 0x04: // Attack, Decay (modulator)
1235  case 0x05: // Attack, Decay (carrier)
1236  case 0x06: // Sustain, Release (modulator)
1237  case 0x07: // Sustain, Release (carrier)
1238  updateCustomInstrument(r, v);
1239  break;
1240  case 0x0E:
1241  setRhythmFlags(old);
1242  break;
1243  }
1244  break;
1245  }
1246  case 0x10: {
1247  // 10-18: FNUM 0-7
1248  Channel& ch = getChannelForReg(r);
1249  ch.setFrequencyLow(v);
1250  break;
1251  }
1252  case 0x20: {
1253  // 20-28: susOn, keyOn, block, FNUM 8
1254  Channel& ch = getChannelForReg(r);
1255  ch.mod.setKeyOnOff(Slot::KEY_MAIN, (v & 0x10) != 0);
1256  ch.car.setKeyOnOff(Slot::KEY_MAIN, (v & 0x10) != 0);
1257  ch.setSustain((v & 0x20) != 0);
1258  // Note: When changing the frequency, a new value for RS is
1259  // computed using the sustain value, so make sure the new
1260  // sustain value is committed first.
1261  ch.setFrequencyHigh(v & 0x0F);
1262  break;
1263  }
1264  case 0x30: { // inst 4 MSBs, VOL 4 LSBs
1265  Channel& ch = getChannelForReg(r);
1266  ch.car.setTotalLevel(ch, (v & 0x0F) << 2);
1267 
1268  // Check wether we are in rhythm mode and handle instrument/volume
1269  // register accordingly.
1270 
1271  uint8_t chan = (r & 0x0F) % 9; // verified on real YM2413
1272  if (isRhythm() && (chan >= 6)) {
1273  if (chan > 6) {
1274  // channel 7 or 8 in rythm mode
1275  // modulator envelope is HH(chan=7) or TOM(chan=8).
1276  ch.mod.setTotalLevel(ch, (v >> 4) << 2);
1277  }
1278  } else {
1279  if ((old & 0xF0) != (v & 0xF0)) {
1280  ch.updateInstrument(inst_tab[v >> 4]);
1281  }
1282  }
1283  break;
1284  }
1285  default:
1286  break;
1287  }
1288 }
1289 
1290 uint8_t YM2413::peekReg(uint8_t r) const
1291 {
1292  return reg[r];
1293 }
1294 
1295 } // namespace YM2413Burczynski
1296 
1297 static constexpr std::initializer_list<enum_string<YM2413Burczynski::Slot::EnvelopeState>> envelopeStateInfo = {
1298  { "DUMP", YM2413Burczynski::Slot::EG_DUMP },
1299  { "ATTACK", YM2413Burczynski::Slot::EG_ATTACK },
1300  { "DECAY", YM2413Burczynski::Slot::EG_DECAY },
1301  { "SUSTAIN", YM2413Burczynski::Slot::EG_SUSTAIN },
1302  { "RELEASE", YM2413Burczynski::Slot::EG_RELEASE },
1304 };
1306 
1307 namespace YM2413Burczynski {
1308 
1309 // version 1: initial version
1310 // version 2: - removed kcodeScaled
1311 // - calculated more members from other state
1312 // (TLL, freq, eg_sel_*, eg_sh_*)
1313 template<typename Archive>
1314 void Slot::serialize(Archive& a, unsigned /*version*/)
1315 {
1316  // TODO some of the serialized members here could be calculated from
1317  // other members
1318  int waveform = (wavetable == &sinTab[0]) ? 0 : 1;
1319  a.serialize("waveform", waveform);
1320  if (a.isLoader()) {
1322  }
1323 
1324  a.serialize("phase", phase,
1325  "TL", TL,
1326  "volume", egOut,
1327  "sl", sl,
1328  "state", state,
1329  "op1_out", op1_out,
1330  "eg_sustain", eg_sustain,
1331  "fb_shift", fb_shift,
1332  "key", key,
1333  "ar", ar,
1334  "dr", dr,
1335  "rr", rr,
1336  "KSR", KSR,
1337  "ksl", ksl,
1338  "mul", mul,
1339  "AMmask", AMmask,
1340  "vib", vib);
1341 
1342  // These are calculated by updateTotalLevel()
1343  // TLL
1344  // These are calculated by updateGenerators()
1345  // freq, eg_sh_ar, eg_sel_ar, eg_sh_dr, eg_sel_dr, eg_sh_rr, eg_sel_rr
1346  // eg_sh_rs, eg_sel_rs, eg_sh_dp, eg_sel_dp
1347 }
1348 
1349 // version 1: original version
1350 // version 2: removed kcode
1351 // version 3: removed instvol_r
1352 template<typename Archive>
1353 void Channel::serialize(Archive& a, unsigned /*version*/)
1354 {
1355  // mod/car were originally an array, keep serializing as such for bwc
1356  Slot slots[2] = { mod, car };
1357  a.serialize("slots", slots);
1358  if (a.isLoader()) {
1359  mod = slots[0];
1360  car = slots[1];
1361  }
1362 
1363  a.serialize("block_fnum", block_fnum,
1364  "fc", fc,
1365  "ksl_base", ksl_base,
1366  "sus", sus);
1367 
1368  if (a.isLoader()) {
1369  mod.updateFrequency(*this);
1370  car.updateFrequency(*this);
1371  }
1372 }
1373 
1374 // version 1: initial version
1375 // version 2: 'registers' are moved here (no longer serialized in base class)
1376 // version 3: removed 'rhythm' variable
1377 // version 4: added 'registerLatch'
1378 template<typename Archive>
1379 void YM2413::serialize(Archive& a, unsigned version)
1380 {
1381  if (a.versionBelow(version, 2)) a.beginTag("YM2413Core");
1382  a.serialize("registers", reg);
1383  if (a.versionBelow(version, 2)) a.endTag("YM2413Core");
1384 
1385  // only serialize user instrument
1386  a.serialize_blob("user_instrument", inst_tab[0], 8);
1387  a.serialize("channels", channels,
1388  "eg_cnt", eg_cnt,
1389  "noise_rng", noise_rng,
1390  "lfo_am_cnt", lfo_am_cnt,
1391  "lfo_pm_cnt", lfo_pm_cnt);
1392  if (a.versionAtLeast(version, 4)) {
1393  a.serialize("registerLatch", registerLatch);
1394  } else {
1395  // could be restored from MSXMusicBase, worth the effort?
1396  }
1397  // don't serialize idleSamples, it's only an optimization
1398 }
1399 
1400 } // namespace YM2413Burczynski
1401 
1405 
1406 } // namespace openmsx
#define M_PI
Definition: Math.hh:27
constexpr int toInt() const
Returns the integer part (rounded down) of this fixed point number.
Definition: FixedPoint.hh:76
constexpr void addQuantum()
Increase this value with the smallest possible amount.
Definition: FixedPoint.hh:217
void updateInstrumentPart(int part, uint8_t value)
Sets some synthesis parameters as specified by the instrument.
void setFrequencyLow(uint8_t value)
Changes the lower 8 bits of the frequency for this channel.
void serialize(Archive &ar, unsigned version)
void setFrequency(int block_fnum)
Sets the frequency for this channel.
void updateInstrument(const uint8_t *inst)
Sets all synthesis parameters as specified by the instrument.
void setFrequencyHigh(uint8_t value)
Changes the higher 4 bits of the frequency for this channel.
int calcOutput(unsigned eg_cnt, unsigned lfo_pm, unsigned lfo_am, int fm)
Calculate the value of the current sample produced by this channel.
void setSustainLevel(uint8_t value)
Sets the sustain level [0..15].
EnvelopeState
Envelope Generator phases Note: These are ordered: phase constants are compared in the code.
void updateFrequency(Channel &channel)
Called by Channel when block_fnum changes.
void setEnvelopeSustained(bool value)
Sets the envelope type of the current instrument.
void setKeyOnOff(KeyPart part, bool enabled)
void setAttackRate(const Channel &channel, uint8_t value)
Sets the attack rate [0..15].
int calcOutput(Channel &channel, unsigned eg_cnt, bool carrier, unsigned lfo_am, int phase)
void setTotalLevel(Channel &channel, uint8_t value)
Sets the total level: [0..63].
void setFrequencyMultiplier(uint8_t value)
Sets the frequency multiplier [0..15].
void setReleaseRate(const Channel &channel, uint8_t value)
Sets the release rate [0..15].
void setWaveform(uint8_t value)
Sets the waveform: 0 = sinus, 1 = half sinus, half silence.
int calc_envelope(Channel &channel, unsigned eg_cnt, bool carrier)
void serialize(Archive &ar, unsigned version)
void setVibrato(bool value)
Enables (true) or disables (false) vibrato.
int calc_phase(Channel &channel, unsigned lfo_pm)
void setAmplitudeModulation(bool value)
Enables (true) or disables (false) amplitude modulation.
void setDecayRate(const Channel &channel, uint8_t value)
Sets the decay rate [0..15].
void setKeyScaleLevel(Channel &channel, uint8_t value)
Sets the key scale level: 0->0 / 1->1.5 / 2->3.0 / 3->6.0 dB/OCT.
void setFeedbackShift(uint8_t value)
Sets the amount of feedback [0..7].
bool isActive() const
Does this slot currently produce an output signal?
int calc_slot_mod(Channel &channel, unsigned eg_cnt, bool carrier, unsigned lfo_pm, unsigned lfo_am)
void setKeyScaleRate(bool value)
Sets the key scale rate: true->0, false->2.
void updateGenerators(Channel &channel)
Update phase increment counter of operator.
void writePort(bool port, uint8_t value, int offset) override
Write to the YM2413 register/data port.
void serialize(Archive &ar, unsigned version)
void reset() override
Reset this YM2413 core.
void pokeReg(uint8_t reg, uint8_t value) override
Write to a YM2413 register (for debug).
float getAmplificationFactor() const override
Returns normalization factor.
void generateChannels(float *bufs[9+5], unsigned num) override
uint8_t peekReg(uint8_t reg) const override
Read from a YM2413 register (for debug).
Abstract interface for the YM2413 core.
Definition: YM2413Core.hh:27
static constexpr int CLOCK_FREQ
Input clock frequency.
Definition: YM2413Core.hh:40
constexpr double round(double x)
Definition: cstd.hh:355
constexpr uint8_t eg_rate_select[16+64+16]
constexpr uint8_t lfo_am_table[LFO_AM_TAB_ELEMENTS]
FixedPoint< 16 > FreqIndex
16.16 fixed point type for frequency calculations.
constexpr uint8_t table[16+3][8]
constexpr signed char lfo_pm_table[8][8]
constexpr uint8_t mul_tab[16]
constexpr int ksl_tab[8 *16]
constexpr uint8_t eg_inc[15][8]
constexpr uint8_t eg_rate_shift[16+64+16]
constexpr unsigned const *const waveform[2]
This file implemented 3 utility functions:
Definition: Autofire.cc:5
SERIALIZE_ENUM(CassettePlayer::State, stateInfo)
REGISTER_POLYMORPHIC_INITIALIZER(Pluggable, CassettePlayer, "CassettePlayer")
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:124
constexpr nibble mask[4][13]
Definition: RP5C01.cc:34
auto copy(InputRange &&range, OutputIter out)
Definition: ranges.hh:149
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:983
constexpr auto xrange(T e)
Definition: xrange.hh:155