27static constexpr int FREQ_SH = 16;
29static constexpr int FREQ_MASK = (1 << FREQ_SH) - 1;
31static constexpr int ENV_BITS = 10;
32static constexpr int ENV_LEN = 1 << ENV_BITS;
33static constexpr double ENV_STEP = 128.0 / ENV_LEN;
35static constexpr int MAX_ATT_INDEX = ENV_LEN - 1;
36static constexpr int MIN_ATT_INDEX = 0;
38static constexpr unsigned EG_ATT = 4;
39static constexpr unsigned EG_DEC = 3;
40static constexpr unsigned EG_SUS = 2;
41static constexpr unsigned EG_REL = 1;
42static constexpr unsigned EG_OFF = 0;
44static constexpr int SIN_BITS = 10;
45static constexpr int SIN_LEN = 1 << SIN_BITS;
46static constexpr int SIN_MASK = SIN_LEN - 1;
48static constexpr int TL_RES_LEN = 256;
54static constexpr unsigned TL_TAB_LEN = 13 * 2 * TL_RES_LEN;
55static constexpr auto tl_tab = [] {
56 std::array<int, TL_TAB_LEN> result = {};
57 for (
auto x :
xrange(TL_RES_LEN)) {
58 double m = (1 << 16) / cstd::exp2<6>((x + 1) * (ENV_STEP / 4.0) / 8.0);
72 result[x * 2 + 0] = n;
73 result[x * 2 + 1] = -result[x * 2 + 0];
75 for (
auto i :
xrange(1, 13)) {
76 result[x * 2 + 0 + i * 2 * TL_RES_LEN] = result[x * 2 + 0] >> i;
77 result[x * 2 + 1 + i * 2 * TL_RES_LEN] = -result[x * 2 + 0 + i * 2 * TL_RES_LEN];
83static constexpr unsigned ENV_QUIET = TL_TAB_LEN >> 3;
86static constexpr auto sin_tab = [] {
87 std::array<unsigned, SIN_LEN> result = {};
88 for (
auto i :
xrange(SIN_LEN)) {
90 double m = cstd::sin<2>((i * 2 + 1) *
Math::pi / SIN_LEN);
93 double o = -8.0 * cstd::log2<8, 3>(
cstd::abs(m));
94 o = o / (ENV_STEP / 4);
102 result[i] = n * 2 + (m >= 0.0 ? 0 : 1);
109static constexpr auto d1l_tab = [] {
110 std::array<unsigned, 16> result = {};
112 for (
int i = 0; i < 16; ++i) {
114 result[i] = unsigned((i != 15 ? i : i + 16) * (4.0 / ENV_STEP));
120static constexpr unsigned RATE_STEPS = 8;
121static constexpr std::array<uint8_t, 19 * RATE_STEPS> eg_inc = {
146 16,16,16,16,16,16,16,16,
151static constexpr uint8_t O(
int a) {
return narrow<uint8_t>(a * RATE_STEPS); }
153static constexpr std::array<uint8_t, 32 + 64 + 32> eg_rate_select {
156O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
157O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
158O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
159O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
162O( 0),O( 1),O( 2),O( 3),
163O( 0),O( 1),O( 2),O( 3),
164O( 0),O( 1),O( 2),O( 3),
165O( 0),O( 1),O( 2),O( 3),
166O( 0),O( 1),O( 2),O( 3),
167O( 0),O( 1),O( 2),O( 3),
168O( 0),O( 1),O( 2),O( 3),
169O( 0),O( 1),O( 2),O( 3),
170O( 0),O( 1),O( 2),O( 3),
171O( 0),O( 1),O( 2),O( 3),
172O( 0),O( 1),O( 2),O( 3),
173O( 0),O( 1),O( 2),O( 3),
176O( 4),O( 5),O( 6),O( 7),
179O( 8),O( 9),O(10),O(11),
182O(12),O(13),O(14),O(15),
185O(16),O(16),O(16),O(16),
188O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
189O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
190O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
191O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16)
197static constexpr std::array<uint8_t, 32 + 64 + 32> eg_rate_shift = {
200 0, 0, 0, 0, 0, 0, 0, 0,
201 0, 0, 0, 0, 0, 0, 0, 0,
202 0, 0, 0, 0, 0, 0, 0, 0,
203 0, 0, 0, 0, 0, 0, 0, 0,
232 0, 0, 0, 0, 0, 0, 0, 0,
233 0, 0, 0, 0, 0, 0, 0, 0,
234 0, 0, 0, 0, 0, 0, 0, 0,
235 0, 0, 0, 0, 0, 0, 0, 0
247static constexpr std::array<unsigned, 4> dt2_tab = {0, 384, 500, 608};
252static constexpr std::array<uint8_t, 4 * 32> dt1_tab = {
254 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
259 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
262 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
263 5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
266 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
267 8, 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
270static constexpr std::array<uint16_t, 768> phaseInc_rom = {
2711299,1300,1301,1302,1303,1304,1305,1306,1308,1309,1310,1311,1313,1314,1315,1316,
2721318,1319,1320,1321,1322,1323,1324,1325,1327,1328,1329,1330,1332,1333,1334,1335,
2731337,1338,1339,1340,1341,1342,1343,1344,1346,1347,1348,1349,1351,1352,1353,1354,
2741356,1357,1358,1359,1361,1362,1363,1364,1366,1367,1368,1369,1371,1372,1373,1374,
2751376,1377,1378,1379,1381,1382,1383,1384,1386,1387,1388,1389,1391,1392,1393,1394,
2761396,1397,1398,1399,1401,1402,1403,1404,1406,1407,1408,1409,1411,1412,1413,1414,
2771416,1417,1418,1419,1421,1422,1423,1424,1426,1427,1429,1430,1431,1432,1434,1435,
2781437,1438,1439,1440,1442,1443,1444,1445,1447,1448,1449,1450,1452,1453,1454,1455,
2791458,1459,1460,1461,1463,1464,1465,1466,1468,1469,1471,1472,1473,1474,1476,1477,
2801479,1480,1481,1482,1484,1485,1486,1487,1489,1490,1492,1493,1494,1495,1497,1498,
2811501,1502,1503,1504,1506,1507,1509,1510,1512,1513,1514,1515,1517,1518,1520,1521,
2821523,1524,1525,1526,1528,1529,1531,1532,1534,1535,1536,1537,1539,1540,1542,1543,
2831545,1546,1547,1548,1550,1551,1553,1554,1556,1557,1558,1559,1561,1562,1564,1565,
2841567,1568,1569,1570,1572,1573,1575,1576,1578,1579,1580,1581,1583,1584,1586,1587,
2851590,1591,1592,1593,1595,1596,1598,1599,1601,1602,1604,1605,1607,1608,1609,1610,
2861613,1614,1615,1616,1618,1619,1621,1622,1624,1625,1627,1628,1630,1631,1632,1633,
2871637,1638,1639,1640,1642,1643,1645,1646,1648,1649,1651,1652,1654,1655,1656,1657,
2881660,1661,1663,1664,1666,1667,1669,1670,1672,1673,1675,1676,1678,1679,1681,1682,
2891685,1686,1688,1689,1691,1692,1694,1695,1697,1698,1700,1701,1703,1704,1706,1707,
2901709,1710,1712,1713,1715,1716,1718,1719,1721,1722,1724,1725,1727,1728,1730,1731,
2911734,1735,1737,1738,1740,1741,1743,1744,1746,1748,1749,1751,1752,1754,1755,1757,
2921759,1760,1762,1763,1765,1766,1768,1769,1771,1773,1774,1776,1777,1779,1780,1782,
2931785,1786,1788,1789,1791,1793,1794,1796,1798,1799,1801,1802,1804,1806,1807,1809,
2941811,1812,1814,1815,1817,1819,1820,1822,1824,1825,1827,1828,1830,1832,1833,1835,
2951837,1838,1840,1841,1843,1845,1846,1848,1850,1851,1853,1854,1856,1858,1859,1861,
2961864,1865,1867,1868,1870,1872,1873,1875,1877,1879,1880,1882,1884,1885,1887,1888,
2971891,1892,1894,1895,1897,1899,1900,1902,1904,1906,1907,1909,1911,1912,1914,1915,
2981918,1919,1921,1923,1925,1926,1928,1930,1932,1933,1935,1937,1939,1940,1942,1944,
2991946,1947,1949,1951,1953,1954,1956,1958,1960,1961,1963,1965,1967,1968,1970,1972,
3001975,1976,1978,1980,1982,1983,1985,1987,1989,1990,1992,1994,1996,1997,1999,2001,
3012003,2004,2006,2008,2010,2011,2013,2015,2017,2019,2021,2022,2024,2026,2028,2029,
3022032,2033,2035,2037,2039,2041,2043,2044,2047,2048,2050,2052,2054,2056,2058,2059,
3032062,2063,2065,2067,2069,2071,2073,2074,2077,2078,2080,2082,2084,2086,2088,2089,
3042092,2093,2095,2097,2099,2101,2103,2104,2107,2108,2110,2112,2114,2116,2118,2119,
3052122,2123,2125,2127,2129,2131,2133,2134,2137,2139,2141,2142,2145,2146,2148,2150,
3062153,2154,2156,2158,2160,2162,2164,2165,2168,2170,2172,2173,2176,2177,2179,2181,
3072185,2186,2188,2190,2192,2194,2196,2197,2200,2202,2204,2205,2208,2209,2211,2213,
3082216,2218,2220,2222,2223,2226,2227,2230,2232,2234,2236,2238,2239,2242,2243,2246,
3092249,2251,2253,2255,2256,2259,2260,2263,2265,2267,2269,2271,2272,2275,2276,2279,
3102281,2283,2285,2287,2288,2291,2292,2295,2297,2299,2301,2303,2304,2307,2308,2311,
3112315,2317,2319,2321,2322,2325,2326,2329,2331,2333,2335,2337,2338,2341,2342,2345,
3122348,2350,2352,2354,2355,2358,2359,2362,2364,2366,2368,2370,2371,2374,2375,2378,
3132382,2384,2386,2388,2389,2392,2393,2396,2398,2400,2402,2404,2407,2410,2411,2414,
3142417,2419,2421,2423,2424,2427,2428,2431,2433,2435,2437,2439,2442,2445,2446,2449,
3152452,2454,2456,2458,2459,2462,2463,2466,2468,2470,2472,2474,2477,2480,2481,2484,
3162488,2490,2492,2494,2495,2498,2499,2502,2504,2506,2508,2510,2513,2516,2517,2520,
3172524,2526,2528,2530,2531,2534,2535,2538,2540,2542,2544,2546,2549,2552,2553,2556,
3182561,2563,2565,2567,2568,2571,2572,2575,2577,2579,2581,2583,2586,2589,2590,2593
336static constexpr auto freq = [] {
337 std::array<unsigned, 11 * 768> result = {};
345 double mult = 1 << (FREQ_SH - 10);
347 for (
auto i :
xrange(768)) {
348 double phaseInc = phaseInc_rom[i];
352 result[768 + 2 * 768 + i] = int(phaseInc * mult) & 0xffffffc0;
354 for (
auto j :
xrange(2)) {
356 result[768 + j * 768 + i] = (result[768 + 2 * 768 + i] >> (2 - j)) & 0xffffffc0;
359 for (
auto j :
xrange(3, 8)) {
360 result[768 + j * 768 + i] = result[768 + 2 * 768 + i] << (j - 2);
365 for (
auto i :
xrange(768)) {
366 result[0 * 768 + i] = result[1 * 768 + 0];
370 for (
auto j :
xrange(8, 10)) {
371 for (
auto i :
xrange(768)) {
372 result[768 + j * 768 + i] = result[768 + 8 * 768 - 1];
380static constexpr auto dt1_freq = [] {
381 std::array<int, 8 * 32> result = {};
382 double mult = 1 << FREQ_SH;
383 for (
auto j :
xrange(4)) {
384 for (
auto i :
xrange(32)) {
386 double phaseInc = double(dt1_tab[j * 32 + i]) / (1 << 20) * SIN_LEN;
389 result[(j + 0) * 32 + i] =
int(phaseInc * mult);
390 result[(j + 4) * 32 + i] = -result[(j + 0) * 32 + i];
398static constexpr auto noise_tab = [] {
399 std::array<int, 32> result = {};
401 for (
int i = 0; i < 32; ++i) {
402 result[i] = 32 - (i != 31 ? i : 30);
421static constexpr std::array<uint8_t, 256> lfo_noise_waveform = {
4220xFF,0xEE,0xD3,0x80,0x58,0xDA,0x7F,0x94,0x9E,0xE3,0xFA,0x00,0x4D,0xFA,0xFF,0x6A,
4230x7A,0xDE,0x49,0xF6,0x00,0x33,0xBB,0x63,0x91,0x60,0x51,0xFF,0x00,0xD8,0x7F,0xDE,
4240xDC,0x73,0x21,0x85,0xB2,0x9C,0x5D,0x24,0xCD,0x91,0x9E,0x76,0x7F,0x20,0xFB,0xF3,
4250x00,0xA6,0x3E,0x42,0x27,0x69,0xAE,0x33,0x45,0x44,0x11,0x41,0x72,0x73,0xDF,0xA2,
4270x32,0xBD,0x7E,0xA8,0x13,0xEB,0xD3,0x15,0xDD,0xFB,0xC9,0x9D,0x61,0x2F,0xBE,0x9D,
4280x23,0x65,0x51,0x6A,0x84,0xF9,0xC9,0xD7,0x23,0xBF,0x65,0x19,0xDC,0x03,0xF3,0x24,
4290x33,0xB6,0x1E,0x57,0x5C,0xAC,0x25,0x89,0x4D,0xC5,0x9C,0x99,0x15,0x07,0xCF,0xBA,
4300xC5,0x9B,0x15,0x4D,0x8D,0x2A,0x1E,0x1F,0xEA,0x2B,0x2F,0x64,0xA9,0x50,0x3D,0xAB,
4320x50,0x77,0xE9,0xC0,0xAC,0x6D,0x3F,0xCA,0xCF,0x71,0x7D,0x80,0xA6,0xFD,0xFF,0xB5,
4330xBD,0x6F,0x24,0x7B,0x00,0x99,0x5D,0xB1,0x48,0xB0,0x28,0x7F,0x80,0xEC,0xBF,0x6F,
4340x6E,0x39,0x90,0x42,0xD9,0x4E,0x2E,0x12,0x66,0xC8,0xCF,0x3B,0x3F,0x10,0x7D,0x79,
4350x00,0xD3,0x1F,0x21,0x93,0x34,0xD7,0x19,0x22,0xA2,0x08,0x20,0xB9,0xB9,0xEF,0x51,
4370x99,0xDE,0xBF,0xD4,0x09,0x75,0xE9,0x8A,0xEE,0xFD,0xE4,0x4E,0x30,0x17,0xDF,0xCE,
4380x11,0xB2,0x28,0x35,0xC2,0x7C,0x64,0xEB,0x91,0x5F,0x32,0x0C,0x6E,0x00,0xF9,0x92,
4390x19,0xDB,0x8F,0xAB,0xAE,0xD6,0x12,0xC4,0x26,0x62,0xCE,0xCC,0x0A,0x03,0xE7,0xDD,
4400xE2,0x4D,0x8A,0xA6,0x46,0x95,0x0F,0x8F,0xF5,0x15,0x97,0x32,0xD4,0x28,0x1E,0x55
443void YM2151::keyOn(YM2151Operator& op,
unsigned keySet) {
447 op.volume += (~op.volume *
448 (eg_inc[op.eg_sel_ar + ((eg_cnt >> op.eg_sh_ar)&7)])
450 if (op.volume <= MIN_ATT_INDEX) {
451 op.volume = MIN_ATT_INDEX;
458void YM2151::keyOff(YM2151Operator& op,
unsigned keyClear) {
462 if (op.state > EG_REL) {
469void YM2151::envelopeKONKOFF(std::span<YM2151Operator, 4> op,
int v)
474 keyOff(op[0],
unsigned(~1));
479 keyOff(op[1],
unsigned(~1));
484 keyOff(op[2],
unsigned(~1));
489 keyOff(op[3],
unsigned(~1));
493void YM2151::setConnect(std::span<YM2151Operator, 4> o,
int cha,
int v)
495 YM2151Operator& om1 = o[0];
496 YM2151Operator& om2 = o[1];
497 YM2151Operator& oc1 = o[2];
507 om1.mem_connect = &m2;
516 om1.mem_connect = &m2;
525 om1.mem_connect = &m2;
534 om1.mem_connect = &c2;
542 oc1.connect = &chanOut[cha];
544 om1.mem_connect = &mem;
551 om1.connect =
nullptr;
552 oc1.connect = &chanOut[cha];
553 om2.connect = &chanOut[cha];
554 om1.mem_connect = &m2;
563 oc1.connect = &chanOut[cha];
564 om2.connect = &chanOut[cha];
565 om1.mem_connect = &mem;
574 om1.connect = &chanOut[cha];
575 oc1.connect = &chanOut[cha];
576 om2.connect = &chanOut[cha];
577 om1.mem_connect = &mem;
582void YM2151::refreshEG(std::span<YM2151Operator, 4> op)
584 unsigned kc = op[0].kc;
587 unsigned v = kc >> op[0].ks;
588 if ((op[0].ar + v) < 32 + 62) {
589 op[0].eg_sh_ar = eg_rate_shift [op[0].ar + v];
590 op[0].eg_sel_ar = eg_rate_select[op[0].ar + v];
593 op[0].eg_sel_ar = 17 * RATE_STEPS;
595 op[0].eg_sh_d1r = eg_rate_shift [op[0].d1r + v];
596 op[0].eg_sel_d1r = eg_rate_select[op[0].d1r + v];
597 op[0].eg_sh_d2r = eg_rate_shift [op[0].d2r + v];
598 op[0].eg_sel_d2r = eg_rate_select[op[0].d2r + v];
599 op[0].eg_sh_rr = eg_rate_shift [op[0].rr + v];
600 op[0].eg_sel_rr = eg_rate_select[op[0].rr + v];
603 if ((op[1].ar + v) < 32 + 62) {
604 op[1].eg_sh_ar = eg_rate_shift [op[1].ar + v];
605 op[1].eg_sel_ar = eg_rate_select[op[1].ar + v];
608 op[1].eg_sel_ar = 17 * RATE_STEPS;
610 op[1].eg_sh_d1r = eg_rate_shift [op[1].d1r + v];
611 op[1].eg_sel_d1r = eg_rate_select[op[1].d1r + v];
612 op[1].eg_sh_d2r = eg_rate_shift [op[1].d2r + v];
613 op[1].eg_sel_d2r = eg_rate_select[op[1].d2r + v];
614 op[1].eg_sh_rr = eg_rate_shift [op[1].rr + v];
615 op[1].eg_sel_rr = eg_rate_select[op[1].rr + v];
618 if ((op[2].ar + v) < 32 + 62) {
619 op[2].eg_sh_ar = eg_rate_shift [op[2].ar + v];
620 op[2].eg_sel_ar = eg_rate_select[op[2].ar + v];
623 op[2].eg_sel_ar = 17 * RATE_STEPS;
625 op[2].eg_sh_d1r = eg_rate_shift [op[2].d1r + v];
626 op[2].eg_sel_d1r = eg_rate_select[op[2].d1r + v];
627 op[2].eg_sh_d2r = eg_rate_shift [op[2].d2r + v];
628 op[2].eg_sel_d2r = eg_rate_select[op[2].d2r + v];
629 op[2].eg_sh_rr = eg_rate_shift [op[2].rr + v];
630 op[2].eg_sel_rr = eg_rate_select[op[2].rr + v];
633 if ((op[3].ar + v) < 32 + 62) {
634 op[3].eg_sh_ar = eg_rate_shift [op[3].ar + v];
635 op[3].eg_sel_ar = eg_rate_select[op[3].ar + v];
638 op[3].eg_sel_ar = 17 * RATE_STEPS;
640 op[3].eg_sh_d1r = eg_rate_shift [op[3].d1r + v];
641 op[3].eg_sel_d1r = eg_rate_select[op[3].d1r + v];
642 op[3].eg_sh_d2r = eg_rate_shift [op[3].d2r + v];
643 op[3].eg_sel_d2r = eg_rate_select[op[3].d2r + v];
644 op[3].eg_sh_rr = eg_rate_shift [op[3].rr + v];
645 op[3].eg_sel_rr = eg_rate_select[op[3].rr + v];
652 YM2151Operator& op = oper[(r & 0x07) * 4 + ((r & 0x18) >> 3)];
664 if (v & 2) lfo_phase = 0;
669 envelopeKONKOFF(subspan<4>(oper, 4 * (v & 7)), v);
674 noise_f = noise_tab[v & 0x1f];
680 timer_A_val |= v << 2;
681 timer1->setValue(timer_A_val);
685 timer_A_val &= 0x03fc;
686 timer_A_val |= v & 3;
687 timer1->setValue(timer_A_val);
702 timer1->setStart((v & 4) != 0, time);
703 timer2->setStart((v & 8) != 0, time);
707 lfo_overflow = (1 << ((15 - (v >> 4)) + 3));
708 lfo_counter_add = 0x10 + (v & 0x0f);
713 pmd = narrow<int8_t>(v & 0x7f);
731 auto o = subspan<4>(oper, 4 * (r & 7));
734 o[0].fb_shift = ((v >> 3) & 7) ? ((v >> 3) & 7) + 6 : 0;
735 pan[(r & 7) * 2 + 0] = (v & 0x40) ? ~0 : 0;
736 pan[(r & 7) * 2 + 1] = (v & 0x80) ? ~0 : 0;
737 setConnect(o, r & 7, v & 7);
743 unsigned kc_channel = (v - (v>>2))*64;
745 kc_channel |= (o[0].kc_i & 63);
748 o[0].kc_i = kc_channel;
750 o[1].kc_i = kc_channel;
752 o[2].kc_i = kc_channel;
754 o[3].kc_i = kc_channel;
757 o[0].dt1 = dt1_freq[o[0].dt1_i + kc];
758 o[0].freq = ((freq[kc_channel + o[0].dt2] + o[0].dt1) * o[0].mul) >> 1;
760 o[1].dt1 = dt1_freq[o[1].dt1_i + kc];
761 o[1].freq = ((freq[kc_channel + o[1].dt2] + o[1].dt1) * o[1].mul) >> 1;
763 o[2].dt1 = dt1_freq[o[2].dt1_i + kc];
764 o[2].freq = ((freq[kc_channel + o[2].dt2] + o[2].dt1) * o[2].mul) >> 1;
766 o[3].dt1 = dt1_freq[o[3].dt1_i + kc];
767 o[3].freq = ((freq[kc_channel + o[3].dt2] + o[3].dt1) * o[3].mul) >> 1;
775 if (v != (o[0].kc_i & 63)) {
776 unsigned kc_channel = v;
777 kc_channel |= (o[0].kc_i & ~63);
779 o[0].kc_i = kc_channel;
780 o[1].kc_i = kc_channel;
781 o[2].kc_i = kc_channel;
782 o[3].kc_i = kc_channel;
784 o[0].freq = ((freq[kc_channel + o[0].dt2] + o[0].dt1) * o[0].mul) >> 1;
785 o[1].freq = ((freq[kc_channel + o[1].dt2] + o[1].dt1) * o[1].mul) >> 1;
786 o[2].freq = ((freq[kc_channel + o[2].dt2] + o[2].dt1) * o[2].mul) >> 1;
787 o[3].freq = ((freq[kc_channel + o[3].dt2] + o[3].dt1) * o[3].mul) >> 1;
792 o[0].pms = narrow<int8_t>((v >> 4) & 7);
799 unsigned olddt1_i = op.dt1_i;
800 unsigned oldMul = op.mul;
802 op.dt1_i = (v & 0x70) << 1;
803 op.mul = (v & 0x0f) ? (v & 0x0f) << 1 : 1;
805 if (olddt1_i != op.dt1_i) {
806 op.dt1 = dt1_freq[op.dt1_i + (op.kc>>2)];
808 if ((olddt1_i != op.dt1_i) || (oldMul != op.mul)) {
809 op.freq = ((freq[op.kc_i + op.dt2] + op.dt1) * op.mul) >> 1;
814 op.tl = (v & 0x7f) << (ENV_BITS - 7);
818 unsigned oldKs = op.ks;
819 unsigned oldAr = op.ar;
820 op.ks = 5 - (v >> 6);
821 op.ar = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
823 if ((op.ar != oldAr) || (op.ks != oldKs)) {
824 if ((op.ar + (op.kc >> op.ks)) < 32 + 62) {
825 op.eg_sh_ar = eg_rate_shift [op.ar + (op.kc>>op.ks)];
826 op.eg_sel_ar = eg_rate_select[op.ar + (op.kc>>op.ks)];
829 op.eg_sel_ar = 17 * RATE_STEPS;
832 if (op.ks != oldKs) {
833 op.eg_sh_d1r = eg_rate_shift [op.d1r + (op.kc >> op.ks)];
834 op.eg_sel_d1r = eg_rate_select[op.d1r + (op.kc >> op.ks)];
835 op.eg_sh_d2r = eg_rate_shift [op.d2r + (op.kc >> op.ks)];
836 op.eg_sel_d2r = eg_rate_select[op.d2r + (op.kc >> op.ks)];
837 op.eg_sh_rr = eg_rate_shift [op.rr + (op.kc >> op.ks)];
838 op.eg_sel_rr = eg_rate_select[op.rr + (op.kc >> op.ks)];
843 op.AMmask = (v & 0x80) ? ~0 : 0;
844 op.d1r = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
845 op.eg_sh_d1r = eg_rate_shift [op.d1r + (op.kc >> op.ks)];
846 op.eg_sel_d1r = eg_rate_select[op.d1r + (op.kc >> op.ks)];
850 unsigned olddt2 = op.dt2;
851 op.dt2 = dt2_tab[v >> 6];
852 if (op.dt2 != olddt2) {
853 op.freq = ((freq[op.kc_i + op.dt2] + op.dt1) * op.mul) >> 1;
855 op.d2r = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
856 op.eg_sh_d2r = eg_rate_shift [op.d2r + (op.kc >> op.ks)];
857 op.eg_sel_d2r = eg_rate_select[op.d2r + (op.kc >> op.ks)];
861 op.d1l = d1l_tab[v >> 4];
862 op.rr = 34 + ((v & 0x0f) << 2);
863 op.eg_sh_rr = eg_rate_shift [op.rr + (op.kc >> op.ks)];
864 op.eg_sel_rr = eg_rate_select[op.rr + (op.kc >> op.ks)];
869static constexpr auto INPUT_RATE = unsigned(
cstd::round(3579545 / 64.0));
874 , irq(config.getMotherBoard(),
getName() +
".IRQ")
875 , timer1(
EmuTimer::createOPM_1(config.getScheduler(), *this))
876 , timer2(variant_ ==
Variant::YM2164 ?
EmuTimer::createOPP_2(config.getScheduler(), *this)
877 :
EmuTimer::createOPM_2(config.getScheduler(), *this))
884 std::cout <<
"tl_tab:";
885 for (
const auto&
e : tl_tab) std::cout <<
' ' <<
e;
888 std::cout <<
"sin_tab:";
889 for (
const auto&
e : sin_tab) std::cout <<
' ' <<
e;
892 std::cout <<
"d1l_tab:";
893 for (
const auto&
e : d1l_tab) std::cout <<
' ' <<
e;
896 std::cout <<
"freq:";
897 for (
const auto&
e : freq) std::cout <<
' ' <<
e;
900 std::cout <<
"dt1_freq:";
901 for (
const auto&
e : dt1_freq) std::cout <<
' ' <<
e;
904 std::cout <<
"noise_tab:";
905 for (
const auto&
e : noise_tab) std::cout <<
' ' <<
e;
919bool YM2151::checkMuteHelper()
921 return ranges::all_of(oper, [](
auto& op) {
return op.state == EG_OFF; });
927 for (
auto& op : oper) {
928 memset(&op,
'\0',
sizeof(op));
929 op.volume = MAX_ATT_INDEX;
948 timer1->setStart(
false, time);
949 timer2->setStart(
false, time);
954 noise_f = noise_tab[0];
961 for (
auto i :
xrange(0x20, 0x100)) {
962 writeReg(narrow<uint8_t>(i), 0, time);
968int YM2151::opCalc(YM2151Operator& op,
unsigned env,
int pm)
970 unsigned p = (env << 3) + sin_tab[(
int((op.phase & ~FREQ_MASK) + (pm << 15)) >> FREQ_SH) & SIN_MASK];
971 if (p >= TL_TAB_LEN) {
977int YM2151::opCalc1(YM2151Operator& op,
unsigned env,
int pm)
979 int i = (narrow_cast<int>(op.phase) & ~FREQ_MASK) + pm;
980 unsigned p = (env << 3) + sin_tab[(i >> FREQ_SH) & SIN_MASK];
981 if (p >= TL_TAB_LEN) {
987unsigned YM2151::volumeCalc(YM2151Operator& op,
unsigned AM)
989 return op.tl + unsigned(op.volume) + (AM & op.AMmask);
992void YM2151::chanCalc(
unsigned chan)
994 m2 = c1 = c2 = mem = 0;
995 auto op = subspan<4>(oper, 4 * chan);
996 *op[0].mem_connect = op[0].mem_value;
1000 AM = lfa << (op[0].ams-1);
1002 unsigned env = volumeCalc(op[0], AM);
1004 int out = op[0].fb_out_prev + op[0].fb_out_curr;
1005 op[0].fb_out_prev = op[0].fb_out_curr;
1007 if (!op[0].connect) {
1009 mem = c1 = c2 = op[0].fb_out_prev;
1011 *op[0].connect = op[0].fb_out_prev;
1013 op[0].fb_out_curr = 0;
1014 if (env < ENV_QUIET) {
1015 if (!op[0].fb_shift) {
1018 op[0].fb_out_curr = opCalc1(op[0], env, (out << op[0].fb_shift));
1022 env = volumeCalc(op[1], AM);
1023 if (env < ENV_QUIET) {
1024 *op[1].connect += opCalc(op[1], env, m2);
1026 env = volumeCalc(op[2], AM);
1027 if (env < ENV_QUIET) {
1028 *op[2].connect += opCalc(op[2], env, c1);
1030 env = volumeCalc(op[3], AM);
1031 if (env < ENV_QUIET) {
1032 chanOut[chan] += opCalc(op[3], env, c2);
1035 op[0].mem_value = mem;
1038void YM2151::chan7Calc()
1040 m2 = c1 = c2 = mem = 0;
1041 auto op = subspan<4>(oper, 4 * 7);
1043 *op[0].mem_connect = op[0].mem_value;
1047 AM = lfa << (op[0].ams - 1);
1049 unsigned env = volumeCalc(op[0], AM);
1051 int out = op[0].fb_out_prev + op[0].fb_out_curr;
1052 op[0].fb_out_prev = op[0].fb_out_curr;
1054 if (!op[0].connect) {
1056 mem = c1 = c2 = op[0].fb_out_prev;
1059 *op[0].connect = op[0].fb_out_prev;
1061 op[0].fb_out_curr = 0;
1062 if (env < ENV_QUIET) {
1063 if (!op[0].fb_shift) {
1066 op[0].fb_out_curr = opCalc1(op[0], env, (out << op[0].fb_shift));
1070 env = volumeCalc(op[1], AM);
1071 if (env < ENV_QUIET) {
1072 *op[1].connect += opCalc(op[1], env, m2);
1074 env = volumeCalc(op[2], AM);
1075 if (env < ENV_QUIET) {
1076 *op[2].connect += opCalc(op[2], env, c1);
1078 env = volumeCalc(op[3], AM);
1082 noiseOut = (narrow<int>(env) ^ 0x3ff) * 2;
1084 chanOut[7] += (noise_rng & 0x10000) ? noiseOut : -noiseOut;
1086 if (env < ENV_QUIET) {
1087 chanOut[7] += opCalc(op[3], env, c2);
1091 op[0].mem_value = mem;
1298void YM2151::advanceEG()
1300 if (eg_timer++ != 3) {
1308 for (
auto& op : oper) {
1311 if (!(eg_cnt & ((1 << op.eg_sh_ar) - 1))) {
1312 op.volume += (~op.volume *
1313 (eg_inc[op.eg_sel_ar + ((eg_cnt >> op.eg_sh_ar) & 7)])
1315 if (op.volume <= MIN_ATT_INDEX) {
1316 op.volume = MIN_ATT_INDEX;
1323 if (!(eg_cnt & ((1 << op.eg_sh_d1r) - 1))) {
1324 op.volume += eg_inc[op.eg_sel_d1r + ((eg_cnt >> op.eg_sh_d1r) & 7)];
1325 if (
unsigned(op.volume) >= op.d1l) {
1332 if (!(eg_cnt & ((1 << op.eg_sh_d2r) - 1))) {
1333 op.volume += eg_inc[op.eg_sel_d2r + ((eg_cnt >> op.eg_sh_d2r) & 7)];
1334 if (op.volume >= MAX_ATT_INDEX) {
1335 op.volume = MAX_ATT_INDEX;
1342 if (!(eg_cnt & ((1 << op.eg_sh_rr) - 1))) {
1343 op.volume += eg_inc[op.eg_sel_rr + ((eg_cnt >> op.eg_sh_rr) & 7)];
1344 if (op.volume >= MAX_ATT_INDEX) {
1345 op.volume = MAX_ATT_INDEX;
1354void YM2151::advance()
1360 if (lfo_timer++ >= lfo_overflow) {
1362 lfo_counter += lfo_counter_add;
1363 lfo_phase += (lfo_counter >> 4);
1369 unsigned i = lfo_phase;
1372 auto [a, p] = [&]() -> std::pair<int, int> {
1380 ((i < 128) ? i : (i - 255))
1387 ((i < 128) ? 255 : 0),
1388 ((i < 128) ? 128 : -128)
1396 ((i < 128) ? (255 - (i * 2)) : ((i * 2) - 256)),
1400 }
else if (i < 128) {
1402 }
else if (i < 192) {
1418 lfo_noise_waveform[i],
1419 (lfo_noise_waveform[i] - 128)
1423 lfa = a * amd / 128;
1424 lfp = p * pmd / 128;
1438 unsigned j = ((noise_rng ^ (noise_rng >> 3)) & 1) ^ 1;
1439 noise_rng = (j << 16) | (noise_rng >> 1);
1443 for (
auto c :
xrange(8)) {
1444 auto op = subspan<4>(oper, 4 * c);
1448 if (op[0].pms < 6) {
1449 mod_ind >>= (6 - op[0].pms);
1451 mod_ind <<= (op[0].pms - 5);
1454 unsigned kc_channel = op[0].kc_i + mod_ind;
1455 op[0].phase += ((freq[kc_channel + op[0].dt2] + op[0].dt1) * op[0].mul) >> 1;
1456 op[1].phase += ((freq[kc_channel + op[1].dt2] + op[1].dt1) * op[1].mul) >> 1;
1457 op[2].phase += ((freq[kc_channel + op[2].dt2] + op[2].dt1) * op[2].mul) >> 1;
1458 op[3].phase += ((freq[kc_channel + op[3].dt2] + op[3].dt1) * op[3].mul) >> 1;
1460 op[0].phase += op[0].freq;
1461 op[1].phase += op[1].freq;
1462 op[2].phase += op[2].freq;
1463 op[3].phase += op[3].freq;
1466 op[0].phase += op[0].freq;
1467 op[1].phase += op[1].freq;
1468 op[2].phase += op[2].freq;
1469 op[3].phase += op[3].freq;
1483 for (
auto& op : oper) {
1488 for (
auto& op : oper) {
1489 keyOff(op,
unsigned(~2));
1496void YM2151::generateChannels(std::span<float*> bufs,
unsigned num)
1498 if (checkMuteHelper()) {
1504 for (
auto i :
xrange(num)) {
1507 for (
auto j :
xrange(8 - 1)) {
1514 for (
auto j :
xrange(8)) {
1515 bufs[j][2 * i + 0] += narrow_cast<float>(narrow_cast<int>(chanOut[j] & pan[2 * j + 0]));
1516 bufs[j][2 * i + 1] += narrow_cast<float>(narrow_cast<int>(chanOut[j] & pan[2 * j + 1]));
1522void YM2151::callback(uint8_t flag)
1524 assert(flag ==
one_of(1, 2));
1527 if ((flag == 1) && (irq_enable & 0x80)) {
1537void YM2151::setStatus(uint8_t flags)
1540 auto enable = (irq_enable >> 2) & 3;
1541 if ((status & enable) != 0) {
1546void YM2151::resetStatus(uint8_t flags)
1549 auto enable = (irq_enable >> 2) & 3;
1550 if ((status & enable) == 0) {
1556template<
typename Archive>
1561 a.serialize(
"phase", phase,
1567 "mem_value", mem_value,
1569 "fb_out_curr", fb_out_curr,
1570 "fb_out_prev", fb_out_prev,
1586 "eg_sh_ar", eg_sh_ar,
1587 "eg_sel_ar", eg_sel_ar,
1588 "eg_sh_d1r", eg_sh_d1r,
1589 "eg_sel_d1r", eg_sel_d1r,
1590 "eg_sh_d2r", eg_sh_d2r,
1591 "eg_sel_d2r", eg_sel_d2r,
1592 "eg_sh_rr", eg_sh_rr,
1593 "eg_sel_rr", eg_sel_rr);
1596template<
typename Archive>
1599 a.serialize(
"irq", irq,
1605 "eg_timer", eg_timer,
1606 "lfo_phase", lfo_phase,
1607 "lfo_timer", lfo_timer,
1608 "lfo_overflow", lfo_overflow,
1609 "lfo_counter", lfo_counter,
1610 "lfo_counter_add", lfo_counter_add,
1614 "noise_rng", noise_rng,
1618 "irq_enable", irq_enable,
1625 "timer_A_val", timer_A_val,
1626 "lfo_wsel", lfo_wsel,
1631 a.serialize_blob(
"registers", regs);
1633 if constexpr (Archive::IS_LOADER) {
1635 EmuTime::param time = timer1->getCurrentTime();
1636 for (
auto r :
xrange(uint8_t(0x20), uint8_t(0x28))) {
void set()
Set the interrupt request on the bus.
void reset()
Reset the interrupt request on the bus.
void updateStream(EmuTime::param time)
void unregisterSound()
Unregisters this sound device with the Mixer.
void registerSound(const DeviceConfig &config)
Registers this sound device with the Mixer.
uint8_t readStatus() const
void reset(EmuTime::param time)
void serialize(Archive &ar, unsigned version)
YM2151(const std::string &name, static_string_view desc, const DeviceConfig &config, EmuTime::param time, Variant variant)
void writeReg(uint8_t r, uint8_t v, EmuTime::param time)
constexpr double round(double x)
std::string getName(KeyCode keyCode)
Translate key code to key name.
This file implemented 3 utility functions:
void serialize(Archive &ar, T &t, unsigned version)
bool all_of(InputRange &&range, UnaryPredicate pred)
constexpr void fill(ForwardRange &&range, const T &value)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
constexpr auto xrange(T e)