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