30static constexpr int FREQ_SH = 16;
32static constexpr int FREQ_MASK = (1 << FREQ_SH) - 1;
34static constexpr int ENV_BITS = 10;
35static constexpr int ENV_LEN = 1 << ENV_BITS;
36static constexpr double ENV_STEP = 128.0 / ENV_LEN;
38static constexpr int MAX_ATT_INDEX = ENV_LEN - 1;
39static constexpr int MIN_ATT_INDEX = 0;
41static constexpr unsigned EG_ATT = 4;
42static constexpr unsigned EG_DEC = 3;
43static constexpr unsigned EG_SUS = 2;
44static constexpr unsigned EG_REL = 1;
45static constexpr unsigned EG_OFF = 0;
47static constexpr int SIN_BITS = 10;
48static constexpr int SIN_LEN = 1 << SIN_BITS;
49static constexpr int SIN_MASK = SIN_LEN - 1;
51static constexpr int TL_RES_LEN = 256;
57static constexpr unsigned TL_TAB_LEN = 13 * 2 * TL_RES_LEN;
58static constexpr auto tl_tab = [] {
59 std::array<int, TL_TAB_LEN> result = {};
60 for (
auto x :
xrange(TL_RES_LEN)) {
61 double m = (1 << 16) / cstd::exp2<6>((x + 1) * (ENV_STEP / 4.0) / 8.0);
75 result[x * 2 + 0] = n;
76 result[x * 2 + 1] = -result[x * 2 + 0];
78 for (
auto i :
xrange(1, 13)) {
79 result[x * 2 + 0 + i * 2 * TL_RES_LEN] = result[x * 2 + 0] >> i;
80 result[x * 2 + 1 + i * 2 * TL_RES_LEN] = -result[x * 2 + 0 + i * 2 * TL_RES_LEN];
86static constexpr unsigned ENV_QUIET = TL_TAB_LEN >> 3;
89static constexpr auto sin_tab = [] {
90 std::array<unsigned, SIN_LEN> result = {};
91 for (
auto i :
xrange(SIN_LEN)) {
93 double m = cstd::sin<2>((i * 2 + 1) *
Math::pi / SIN_LEN);
96 double o = -8.0 * cstd::log2<8, 3>(
cstd::abs(m));
97 o = o / (ENV_STEP / 4);
99 auto n = int(2.0 * o);
105 result[i] = n * 2 + (m >= 0.0 ? 0 : 1);
112static constexpr auto d1l_tab = [] {
113 std::array<unsigned, 16> result = {};
115 for (
int i = 0; i < 16; ++i) {
117 result[i] = unsigned((i != 15 ? i : i + 16) * (4.0 / ENV_STEP));
123static constexpr unsigned RATE_STEPS = 8;
124static constexpr std::array<uint8_t, 19 * RATE_STEPS> eg_inc = {
149 16,16,16,16,16,16,16,16,
154static constexpr uint8_t O(
int a) {
return narrow<uint8_t>(a * RATE_STEPS); }
156static constexpr std::array<uint8_t, 32 + 64 + 32> eg_rate_select {
159O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
160O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
161O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
162O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
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),
174O( 0),O( 1),O( 2),O( 3),
175O( 0),O( 1),O( 2),O( 3),
176O( 0),O( 1),O( 2),O( 3),
179O( 4),O( 5),O( 6),O( 7),
182O( 8),O( 9),O(10),O(11),
185O(12),O(13),O(14),O(15),
188O(16),O(16),O(16),O(16),
191O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
192O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
193O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
194O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16)
200static constexpr std::array<uint8_t, 32 + 64 + 32> eg_rate_shift = {
203 0, 0, 0, 0, 0, 0, 0, 0,
204 0, 0, 0, 0, 0, 0, 0, 0,
205 0, 0, 0, 0, 0, 0, 0, 0,
206 0, 0, 0, 0, 0, 0, 0, 0,
235 0, 0, 0, 0, 0, 0, 0, 0,
236 0, 0, 0, 0, 0, 0, 0, 0,
237 0, 0, 0, 0, 0, 0, 0, 0,
238 0, 0, 0, 0, 0, 0, 0, 0
250static constexpr std::array<unsigned, 4> dt2_tab = {0, 384, 500, 608};
255static constexpr std::array<uint8_t, 4 * 32> dt1_tab = {
257 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
262 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
265 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
266 5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
269 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
270 8, 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
273static constexpr std::array<uint16_t, 768> phaseInc_rom = {
2741299,1300,1301,1302,1303,1304,1305,1306,1308,1309,1310,1311,1313,1314,1315,1316,
2751318,1319,1320,1321,1322,1323,1324,1325,1327,1328,1329,1330,1332,1333,1334,1335,
2761337,1338,1339,1340,1341,1342,1343,1344,1346,1347,1348,1349,1351,1352,1353,1354,
2771356,1357,1358,1359,1361,1362,1363,1364,1366,1367,1368,1369,1371,1372,1373,1374,
2781376,1377,1378,1379,1381,1382,1383,1384,1386,1387,1388,1389,1391,1392,1393,1394,
2791396,1397,1398,1399,1401,1402,1403,1404,1406,1407,1408,1409,1411,1412,1413,1414,
2801416,1417,1418,1419,1421,1422,1423,1424,1426,1427,1429,1430,1431,1432,1434,1435,
2811437,1438,1439,1440,1442,1443,1444,1445,1447,1448,1449,1450,1452,1453,1454,1455,
2821458,1459,1460,1461,1463,1464,1465,1466,1468,1469,1471,1472,1473,1474,1476,1477,
2831479,1480,1481,1482,1484,1485,1486,1487,1489,1490,1492,1493,1494,1495,1497,1498,
2841501,1502,1503,1504,1506,1507,1509,1510,1512,1513,1514,1515,1517,1518,1520,1521,
2851523,1524,1525,1526,1528,1529,1531,1532,1534,1535,1536,1537,1539,1540,1542,1543,
2861545,1546,1547,1548,1550,1551,1553,1554,1556,1557,1558,1559,1561,1562,1564,1565,
2871567,1568,1569,1570,1572,1573,1575,1576,1578,1579,1580,1581,1583,1584,1586,1587,
2881590,1591,1592,1593,1595,1596,1598,1599,1601,1602,1604,1605,1607,1608,1609,1610,
2891613,1614,1615,1616,1618,1619,1621,1622,1624,1625,1627,1628,1630,1631,1632,1633,
2901637,1638,1639,1640,1642,1643,1645,1646,1648,1649,1651,1652,1654,1655,1656,1657,
2911660,1661,1663,1664,1666,1667,1669,1670,1672,1673,1675,1676,1678,1679,1681,1682,
2921685,1686,1688,1689,1691,1692,1694,1695,1697,1698,1700,1701,1703,1704,1706,1707,
2931709,1710,1712,1713,1715,1716,1718,1719,1721,1722,1724,1725,1727,1728,1730,1731,
2941734,1735,1737,1738,1740,1741,1743,1744,1746,1748,1749,1751,1752,1754,1755,1757,
2951759,1760,1762,1763,1765,1766,1768,1769,1771,1773,1774,1776,1777,1779,1780,1782,
2961785,1786,1788,1789,1791,1793,1794,1796,1798,1799,1801,1802,1804,1806,1807,1809,
2971811,1812,1814,1815,1817,1819,1820,1822,1824,1825,1827,1828,1830,1832,1833,1835,
2981837,1838,1840,1841,1843,1845,1846,1848,1850,1851,1853,1854,1856,1858,1859,1861,
2991864,1865,1867,1868,1870,1872,1873,1875,1877,1879,1880,1882,1884,1885,1887,1888,
3001891,1892,1894,1895,1897,1899,1900,1902,1904,1906,1907,1909,1911,1912,1914,1915,
3011918,1919,1921,1923,1925,1926,1928,1930,1932,1933,1935,1937,1939,1940,1942,1944,
3021946,1947,1949,1951,1953,1954,1956,1958,1960,1961,1963,1965,1967,1968,1970,1972,
3031975,1976,1978,1980,1982,1983,1985,1987,1989,1990,1992,1994,1996,1997,1999,2001,
3042003,2004,2006,2008,2010,2011,2013,2015,2017,2019,2021,2022,2024,2026,2028,2029,
3052032,2033,2035,2037,2039,2041,2043,2044,2047,2048,2050,2052,2054,2056,2058,2059,
3062062,2063,2065,2067,2069,2071,2073,2074,2077,2078,2080,2082,2084,2086,2088,2089,
3072092,2093,2095,2097,2099,2101,2103,2104,2107,2108,2110,2112,2114,2116,2118,2119,
3082122,2123,2125,2127,2129,2131,2133,2134,2137,2139,2141,2142,2145,2146,2148,2150,
3092153,2154,2156,2158,2160,2162,2164,2165,2168,2170,2172,2173,2176,2177,2179,2181,
3102185,2186,2188,2190,2192,2194,2196,2197,2200,2202,2204,2205,2208,2209,2211,2213,
3112216,2218,2220,2222,2223,2226,2227,2230,2232,2234,2236,2238,2239,2242,2243,2246,
3122249,2251,2253,2255,2256,2259,2260,2263,2265,2267,2269,2271,2272,2275,2276,2279,
3132281,2283,2285,2287,2288,2291,2292,2295,2297,2299,2301,2303,2304,2307,2308,2311,
3142315,2317,2319,2321,2322,2325,2326,2329,2331,2333,2335,2337,2338,2341,2342,2345,
3152348,2350,2352,2354,2355,2358,2359,2362,2364,2366,2368,2370,2371,2374,2375,2378,
3162382,2384,2386,2388,2389,2392,2393,2396,2398,2400,2402,2404,2407,2410,2411,2414,
3172417,2419,2421,2423,2424,2427,2428,2431,2433,2435,2437,2439,2442,2445,2446,2449,
3182452,2454,2456,2458,2459,2462,2463,2466,2468,2470,2472,2474,2477,2480,2481,2484,
3192488,2490,2492,2494,2495,2498,2499,2502,2504,2506,2508,2510,2513,2516,2517,2520,
3202524,2526,2528,2530,2531,2534,2535,2538,2540,2542,2544,2546,2549,2552,2553,2556,
3212561,2563,2565,2567,2568,2571,2572,2575,2577,2579,2581,2583,2586,2589,2590,2593
339static constexpr auto freq = [] {
340 std::array<unsigned, 11 * 768> result = {};
348 double mult = 1 << (FREQ_SH - 10);
350 for (
auto i :
xrange(768)) {
351 double phaseInc = phaseInc_rom[i];
355 result[768 + 2 * 768 + i] = int(phaseInc * mult) & 0xffffffc0;
357 for (
auto j :
xrange(2)) {
359 result[768 + j * 768 + i] = (result[768 + 2 * 768 + i] >> (2 - j)) & 0xffffffc0;
362 for (
auto j :
xrange(3, 8)) {
363 result[768 + j * 768 + i] = result[768 + 2 * 768 + i] << (j - 2);
368 for (
auto i :
xrange(768)) {
369 result[0 * 768 + i] = result[1 * 768 + 0];
373 for (
auto j :
xrange(8, 10)) {
374 for (
auto i :
xrange(768)) {
375 result[768 + j * 768 + i] = result[768 + 8 * 768 - 1];
383static constexpr auto dt1_freq = [] {
384 std::array<int, 8 * 32> result = {};
385 double mult = 1 << FREQ_SH;
386 for (
auto j :
xrange(4)) {
387 for (
auto i :
xrange(32)) {
389 double phaseInc = double(dt1_tab[j * 32 + i]) / (1 << 20) * SIN_LEN;
392 result[(j + 0) * 32 + i] =
int(phaseInc * mult);
393 result[(j + 4) * 32 + i] = -result[(j + 0) * 32 + i];
401static constexpr auto noise_tab = [] {
402 std::array<int, 32> result = {};
404 for (
int i = 0; i < 32; ++i) {
405 result[i] = 32 - (i != 31 ? i : 30);
424static constexpr std::array<uint8_t, 256> lfo_noise_waveform = {
4250xFF,0xEE,0xD3,0x80,0x58,0xDA,0x7F,0x94,0x9E,0xE3,0xFA,0x00,0x4D,0xFA,0xFF,0x6A,
4260x7A,0xDE,0x49,0xF6,0x00,0x33,0xBB,0x63,0x91,0x60,0x51,0xFF,0x00,0xD8,0x7F,0xDE,
4270xDC,0x73,0x21,0x85,0xB2,0x9C,0x5D,0x24,0xCD,0x91,0x9E,0x76,0x7F,0x20,0xFB,0xF3,
4280x00,0xA6,0x3E,0x42,0x27,0x69,0xAE,0x33,0x45,0x44,0x11,0x41,0x72,0x73,0xDF,0xA2,
4300x32,0xBD,0x7E,0xA8,0x13,0xEB,0xD3,0x15,0xDD,0xFB,0xC9,0x9D,0x61,0x2F,0xBE,0x9D,
4310x23,0x65,0x51,0x6A,0x84,0xF9,0xC9,0xD7,0x23,0xBF,0x65,0x19,0xDC,0x03,0xF3,0x24,
4320x33,0xB6,0x1E,0x57,0x5C,0xAC,0x25,0x89,0x4D,0xC5,0x9C,0x99,0x15,0x07,0xCF,0xBA,
4330xC5,0x9B,0x15,0x4D,0x8D,0x2A,0x1E,0x1F,0xEA,0x2B,0x2F,0x64,0xA9,0x50,0x3D,0xAB,
4350x50,0x77,0xE9,0xC0,0xAC,0x6D,0x3F,0xCA,0xCF,0x71,0x7D,0x80,0xA6,0xFD,0xFF,0xB5,
4360xBD,0x6F,0x24,0x7B,0x00,0x99,0x5D,0xB1,0x48,0xB0,0x28,0x7F,0x80,0xEC,0xBF,0x6F,
4370x6E,0x39,0x90,0x42,0xD9,0x4E,0x2E,0x12,0x66,0xC8,0xCF,0x3B,0x3F,0x10,0x7D,0x79,
4380x00,0xD3,0x1F,0x21,0x93,0x34,0xD7,0x19,0x22,0xA2,0x08,0x20,0xB9,0xB9,0xEF,0x51,
4400x99,0xDE,0xBF,0xD4,0x09,0x75,0xE9,0x8A,0xEE,0xFD,0xE4,0x4E,0x30,0x17,0xDF,0xCE,
4410x11,0xB2,0x28,0x35,0xC2,0x7C,0x64,0xEB,0x91,0x5F,0x32,0x0C,0x6E,0x00,0xF9,0x92,
4420x19,0xDB,0x8F,0xAB,0xAE,0xD6,0x12,0xC4,0x26,0x62,0xCE,0xCC,0x0A,0x03,0xE7,0xDD,
4430xE2,0x4D,0x8A,0xA6,0x46,0x95,0x0F,0x8F,0xF5,0x15,0x97,0x32,0xD4,0x28,0x1E,0x55
446void YM2151::keyOn(YM2151Operator& op,
unsigned keySet)
const
451 op.volume += (~op.volume *
452 (eg_inc[op.eg_sel_ar + ((eg_cnt >> op.eg_sh_ar)&7)])
454 if (op.volume <= MIN_ATT_INDEX) {
455 op.volume = MIN_ATT_INDEX;
462void YM2151::keyOff(YM2151Operator& op,
unsigned keyClear)
const
466 if (!op.key && (op.state > EG_REL)) {
472void YM2151::envelopeKONKOFF(std::span<YM2151Operator, 4> op,
int v)
const
477 keyOff(op[0],
unsigned(~1));
482 keyOff(op[1],
unsigned(~1));
487 keyOff(op[2],
unsigned(~1));
492 keyOff(op[3],
unsigned(~1));
496void YM2151::setConnect(std::span<YM2151Operator, 4> o,
int cha,
int v)
498 YM2151Operator& om1 = o[0];
499 YM2151Operator& om2 = o[1];
500 YM2151Operator& oc1 = o[2];
510 om1.mem_connect = &m2;
519 om1.mem_connect = &m2;
528 om1.mem_connect = &m2;
537 om1.mem_connect = &c2;
545 oc1.connect = &chanOut[cha];
547 om1.mem_connect = &mem;
554 om1.connect =
nullptr;
555 oc1.connect = &chanOut[cha];
556 om2.connect = &chanOut[cha];
557 om1.mem_connect = &m2;
566 oc1.connect = &chanOut[cha];
567 om2.connect = &chanOut[cha];
568 om1.mem_connect = &mem;
577 om1.connect = &chanOut[cha];
578 oc1.connect = &chanOut[cha];
579 om2.connect = &chanOut[cha];
580 om1.mem_connect = &mem;
585void YM2151::refreshEG(std::span<YM2151Operator, 4> op)
587 unsigned kc = op[0].kc;
590 unsigned v = kc >> op[0].ks;
591 if ((op[0].ar + v) < 32 + 62) {
592 op[0].eg_sh_ar = eg_rate_shift [op[0].ar + v];
593 op[0].eg_sel_ar = eg_rate_select[op[0].ar + v];
596 op[0].eg_sel_ar = 17 * RATE_STEPS;
598 op[0].eg_sh_d1r = eg_rate_shift [op[0].d1r + v];
599 op[0].eg_sel_d1r = eg_rate_select[op[0].d1r + v];
600 op[0].eg_sh_d2r = eg_rate_shift [op[0].d2r + v];
601 op[0].eg_sel_d2r = eg_rate_select[op[0].d2r + v];
602 op[0].eg_sh_rr = eg_rate_shift [op[0].rr + v];
603 op[0].eg_sel_rr = eg_rate_select[op[0].rr + v];
606 if ((op[1].ar + v) < 32 + 62) {
607 op[1].eg_sh_ar = eg_rate_shift [op[1].ar + v];
608 op[1].eg_sel_ar = eg_rate_select[op[1].ar + v];
611 op[1].eg_sel_ar = 17 * RATE_STEPS;
613 op[1].eg_sh_d1r = eg_rate_shift [op[1].d1r + v];
614 op[1].eg_sel_d1r = eg_rate_select[op[1].d1r + v];
615 op[1].eg_sh_d2r = eg_rate_shift [op[1].d2r + v];
616 op[1].eg_sel_d2r = eg_rate_select[op[1].d2r + v];
617 op[1].eg_sh_rr = eg_rate_shift [op[1].rr + v];
618 op[1].eg_sel_rr = eg_rate_select[op[1].rr + v];
621 if ((op[2].ar + v) < 32 + 62) {
622 op[2].eg_sh_ar = eg_rate_shift [op[2].ar + v];
623 op[2].eg_sel_ar = eg_rate_select[op[2].ar + v];
626 op[2].eg_sel_ar = 17 * RATE_STEPS;
628 op[2].eg_sh_d1r = eg_rate_shift [op[2].d1r + v];
629 op[2].eg_sel_d1r = eg_rate_select[op[2].d1r + v];
630 op[2].eg_sh_d2r = eg_rate_shift [op[2].d2r + v];
631 op[2].eg_sel_d2r = eg_rate_select[op[2].d2r + v];
632 op[2].eg_sh_rr = eg_rate_shift [op[2].rr + v];
633 op[2].eg_sel_rr = eg_rate_select[op[2].rr + v];
636 if ((op[3].ar + v) < 32 + 62) {
637 op[3].eg_sh_ar = eg_rate_shift [op[3].ar + v];
638 op[3].eg_sel_ar = eg_rate_select[op[3].ar + v];
641 op[3].eg_sel_ar = 17 * RATE_STEPS;
643 op[3].eg_sh_d1r = eg_rate_shift [op[3].d1r + v];
644 op[3].eg_sel_d1r = eg_rate_select[op[3].d1r + v];
645 op[3].eg_sh_d2r = eg_rate_shift [op[3].d2r + v];
646 op[3].eg_sel_d2r = eg_rate_select[op[3].d2r + v];
647 op[3].eg_sh_rr = eg_rate_shift [op[3].rr + v];
648 op[3].eg_sel_rr = eg_rate_select[op[3].rr + v];
655 YM2151Operator& op = oper[(r & 0x07) * 4 + ((r & 0x18) >> 3)];
667 if (v & 2) lfo_phase = 0;
672 envelopeKONKOFF(subspan<4>(oper, 4 * (v & 7)), v);
677 noise_f = noise_tab[v & 0x1f];
683 timer_A_val |= v << 2;
684 timer1->setValue(timer_A_val);
688 timer_A_val &= 0x03fc;
689 timer_A_val |= v & 3;
690 timer1->setValue(timer_A_val);
705 timer1->setStart((v & 4) != 0, time);
706 timer2->setStart((v & 8) != 0, time);
710 lfo_overflow = (1 << ((15 - (v >> 4)) + 3));
711 lfo_counter_add = 0x10 + (v & 0x0f);
716 pmd = narrow<int8_t>(v & 0x7f);
734 auto o = subspan<4>(oper, 4 * (r & 7));
737 o[0].fb_shift = ((v >> 3) & 7) ? ((v >> 3) & 7) + 6 : 0;
738 pan[(r & 7) * 2 + 0] = (v & 0x40) ? ~0 : 0;
739 pan[(r & 7) * 2 + 1] = (v & 0x80) ? ~0 : 0;
740 setConnect(o, r & 7, v & 7);
746 unsigned kc_channel = (v - (v>>2))*64;
748 kc_channel |= (o[0].kc_i & 63);
751 o[0].kc_i = kc_channel;
753 o[1].kc_i = kc_channel;
755 o[2].kc_i = kc_channel;
757 o[3].kc_i = kc_channel;
760 o[0].dt1 = dt1_freq[o[0].dt1_i + kc];
761 o[0].freq = ((freq[kc_channel + o[0].dt2] + o[0].dt1) * o[0].mul) >> 1;
763 o[1].dt1 = dt1_freq[o[1].dt1_i + kc];
764 o[1].freq = ((freq[kc_channel + o[1].dt2] + o[1].dt1) * o[1].mul) >> 1;
766 o[2].dt1 = dt1_freq[o[2].dt1_i + kc];
767 o[2].freq = ((freq[kc_channel + o[2].dt2] + o[2].dt1) * o[2].mul) >> 1;
769 o[3].dt1 = dt1_freq[o[3].dt1_i + kc];
770 o[3].freq = ((freq[kc_channel + o[3].dt2] + o[3].dt1) * o[3].mul) >> 1;
778 if (v != (o[0].kc_i & 63)) {
779 unsigned kc_channel = v;
780 kc_channel |= (o[0].kc_i & ~63);
782 o[0].kc_i = kc_channel;
783 o[1].kc_i = kc_channel;
784 o[2].kc_i = kc_channel;
785 o[3].kc_i = kc_channel;
787 o[0].freq = ((freq[kc_channel + o[0].dt2] + o[0].dt1) * o[0].mul) >> 1;
788 o[1].freq = ((freq[kc_channel + o[1].dt2] + o[1].dt1) * o[1].mul) >> 1;
789 o[2].freq = ((freq[kc_channel + o[2].dt2] + o[2].dt1) * o[2].mul) >> 1;
790 o[3].freq = ((freq[kc_channel + o[3].dt2] + o[3].dt1) * o[3].mul) >> 1;
795 o[0].pms = narrow<int8_t>((v >> 4) & 7);
802 unsigned olddt1_i = op.dt1_i;
803 unsigned oldMul = op.mul;
805 op.dt1_i = (v & 0x70) << 1;
806 op.mul = (v & 0x0f) ? (v & 0x0f) << 1 : 1;
808 if (olddt1_i != op.dt1_i) {
809 op.dt1 = dt1_freq[op.dt1_i + (op.kc>>2)];
811 if ((olddt1_i != op.dt1_i) || (oldMul != op.mul)) {
812 op.freq = ((freq[op.kc_i + op.dt2] + op.dt1) * op.mul) >> 1;
817 op.tl = (v & 0x7f) << (ENV_BITS - 7);
821 unsigned oldKs = op.ks;
822 unsigned oldAr = op.ar;
823 op.ks = 5 - (v >> 6);
824 op.ar = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
826 if ((op.ar != oldAr) || (op.ks != oldKs)) {
827 if ((op.ar + (op.kc >> op.ks)) < 32 + 62) {
828 op.eg_sh_ar = eg_rate_shift [op.ar + (op.kc>>op.ks)];
829 op.eg_sel_ar = eg_rate_select[op.ar + (op.kc>>op.ks)];
832 op.eg_sel_ar = 17 * RATE_STEPS;
835 if (op.ks != oldKs) {
836 op.eg_sh_d1r = eg_rate_shift [op.d1r + (op.kc >> op.ks)];
837 op.eg_sel_d1r = eg_rate_select[op.d1r + (op.kc >> op.ks)];
838 op.eg_sh_d2r = eg_rate_shift [op.d2r + (op.kc >> op.ks)];
839 op.eg_sel_d2r = eg_rate_select[op.d2r + (op.kc >> op.ks)];
840 op.eg_sh_rr = eg_rate_shift [op.rr + (op.kc >> op.ks)];
841 op.eg_sel_rr = eg_rate_select[op.rr + (op.kc >> op.ks)];
846 op.AMmask = (v & 0x80) ? ~0 : 0;
847 op.d1r = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
848 op.eg_sh_d1r = eg_rate_shift [op.d1r + (op.kc >> op.ks)];
849 op.eg_sel_d1r = eg_rate_select[op.d1r + (op.kc >> op.ks)];
853 unsigned olddt2 = op.dt2;
854 op.dt2 = dt2_tab[v >> 6];
855 if (op.dt2 != olddt2) {
856 op.freq = ((freq[op.kc_i + op.dt2] + op.dt1) * op.mul) >> 1;
858 op.d2r = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
859 op.eg_sh_d2r = eg_rate_shift [op.d2r + (op.kc >> op.ks)];
860 op.eg_sel_d2r = eg_rate_select[op.d2r + (op.kc >> op.ks)];
864 op.d1l = d1l_tab[v >> 4];
865 op.rr = 34 + ((v & 0x0f) << 2);
866 op.eg_sh_rr = eg_rate_shift [op.rr + (op.kc >> op.ks)];
867 op.eg_sel_rr = eg_rate_select[op.rr + (op.kc >> op.ks)];
872static constexpr auto INPUT_RATE = unsigned(
cstd::round(3579545 / 64.0));
877 , irq(config.getMotherBoard(), getName() +
".IRQ")
878 , timer1(
EmuTimer::createOPM_1(config.getScheduler(), *this))
879 , timer2(variant_ ==
Variant::YM2164 ?
EmuTimer::createOPP_2(config.getScheduler(), *this)
880 :
EmuTimer::createOPM_2(config.getScheduler(), *this))
887 std::cout <<
"tl_tab:";
888 for (
const auto& e : tl_tab) std::cout <<
' ' << e;
891 std::cout <<
"sin_tab:";
892 for (
const auto& e : sin_tab) std::cout <<
' ' << e;
895 std::cout <<
"d1l_tab:";
896 for (
const auto& e : d1l_tab) std::cout <<
' ' << e;
899 std::cout <<
"freq:";
900 for (
const auto& e : freq) std::cout <<
' ' << e;
903 std::cout <<
"dt1_freq:";
904 for (
const auto& e : dt1_freq) std::cout <<
' ' << e;
907 std::cout <<
"noise_tab:";
908 for (
const auto& e : noise_tab) std::cout <<
' ' << e;
922bool YM2151::checkMuteHelper()
924 return ranges::all_of(oper, [](
auto& op) {
return op.state == EG_OFF; });
930 for (
auto& op : oper) {
931 memset(&op,
'\0',
sizeof(op));
932 op.volume = MAX_ATT_INDEX;
951 timer1->setStart(
false, time);
952 timer2->setStart(
false, time);
957 noise_f = noise_tab[0];
964 for (
auto i :
xrange(0x20, 0x100)) {
965 writeReg(narrow<uint8_t>(i), 0, time);
971int YM2151::opCalc(
const YM2151Operator& op,
unsigned env,
int pm)
const
973 unsigned p = (env << 3) + sin_tab[(
int((op.phase & ~FREQ_MASK) + (pm << 15)) >> FREQ_SH) & SIN_MASK];
974 if (p >= TL_TAB_LEN) {
980int YM2151::opCalc1(
const YM2151Operator& op,
unsigned env,
int pm)
const
982 int i = (narrow_cast<int>(op.phase) & ~FREQ_MASK) + pm;
983 unsigned p = (env << 3) + sin_tab[(i >> FREQ_SH) & SIN_MASK];
984 if (p >= TL_TAB_LEN) {
990unsigned YM2151::volumeCalc(
const YM2151Operator& op,
unsigned AM)
const
992 return op.tl + unsigned(op.volume) + (AM & op.AMmask);
995void YM2151::chanCalc(
unsigned chan)
997 m2 = c1 = c2 = mem = 0;
998 auto op = subspan<4>(oper, 4 * chan);
999 *op[0].mem_connect = op[0].mem_value;
1003 AM = lfa << (op[0].ams-1);
1005 unsigned env = volumeCalc(op[0], AM);
1007 int out = op[0].fb_out_prev + op[0].fb_out_curr;
1008 op[0].fb_out_prev = op[0].fb_out_curr;
1010 if (!op[0].connect) {
1012 mem = c1 = c2 = op[0].fb_out_prev;
1014 *op[0].connect = op[0].fb_out_prev;
1016 op[0].fb_out_curr = 0;
1017 if (env < ENV_QUIET) {
1018 if (!op[0].fb_shift) {
1021 op[0].fb_out_curr = opCalc1(op[0], env, (out << op[0].fb_shift));
1025 env = volumeCalc(op[1], AM);
1026 if (env < ENV_QUIET) {
1027 *op[1].connect += opCalc(op[1], env, m2);
1029 env = volumeCalc(op[2], AM);
1030 if (env < ENV_QUIET) {
1031 *op[2].connect += opCalc(op[2], env, c1);
1033 env = volumeCalc(op[3], AM);
1034 if (env < ENV_QUIET) {
1035 chanOut[chan] += opCalc(op[3], env, c2);
1038 op[0].mem_value = mem;
1041void YM2151::chan7Calc()
1043 m2 = c1 = c2 = mem = 0;
1044 auto op = subspan<4>(oper, 4 * 7);
1046 *op[0].mem_connect = op[0].mem_value;
1050 AM = lfa << (op[0].ams - 1);
1052 unsigned env = volumeCalc(op[0], AM);
1054 int out = op[0].fb_out_prev + op[0].fb_out_curr;
1055 op[0].fb_out_prev = op[0].fb_out_curr;
1057 if (!op[0].connect) {
1059 mem = c1 = c2 = op[0].fb_out_prev;
1062 *op[0].connect = op[0].fb_out_prev;
1064 op[0].fb_out_curr = 0;
1065 if (env < ENV_QUIET) {
1066 if (!op[0].fb_shift) {
1069 op[0].fb_out_curr = opCalc1(op[0], env, (out << op[0].fb_shift));
1073 env = volumeCalc(op[1], AM);
1074 if (env < ENV_QUIET) {
1075 *op[1].connect += opCalc(op[1], env, m2);
1077 env = volumeCalc(op[2], AM);
1078 if (env < ENV_QUIET) {
1079 *op[2].connect += opCalc(op[2], env, c1);
1081 env = volumeCalc(op[3], AM);
1085 noiseOut = (narrow<int>(env) ^ 0x3ff) * 2;
1087 chanOut[7] += (noise_rng & 0x10000) ? noiseOut : -noiseOut;
1089 if (env < ENV_QUIET) {
1090 chanOut[7] += opCalc(op[3], env, c2);
1094 op[0].mem_value = mem;
1301void YM2151::advanceEG()
1303 if (eg_timer++ != 3) {
1311 for (
auto& op : oper) {
1314 if (!(eg_cnt & ((1 << op.eg_sh_ar) - 1))) {
1315 op.volume += (~op.volume *
1316 (eg_inc[op.eg_sel_ar + ((eg_cnt >> op.eg_sh_ar) & 7)])
1318 if (op.volume <= MIN_ATT_INDEX) {
1319 op.volume = MIN_ATT_INDEX;
1326 if (!(eg_cnt & ((1 << op.eg_sh_d1r) - 1))) {
1327 op.volume += eg_inc[op.eg_sel_d1r + ((eg_cnt >> op.eg_sh_d1r) & 7)];
1328 if (
unsigned(op.volume) >= op.d1l) {
1335 if (!(eg_cnt & ((1 << op.eg_sh_d2r) - 1))) {
1336 op.volume += eg_inc[op.eg_sel_d2r + ((eg_cnt >> op.eg_sh_d2r) & 7)];
1337 if (op.volume >= MAX_ATT_INDEX) {
1338 op.volume = MAX_ATT_INDEX;
1345 if (!(eg_cnt & ((1 << op.eg_sh_rr) - 1))) {
1346 op.volume += eg_inc[op.eg_sel_rr + ((eg_cnt >> op.eg_sh_rr) & 7)];
1347 if (op.volume >= MAX_ATT_INDEX) {
1348 op.volume = MAX_ATT_INDEX;
1357void YM2151::advance()
1363 if (lfo_timer++ >= lfo_overflow) {
1365 lfo_counter += lfo_counter_add;
1366 lfo_phase += (lfo_counter >> 4);
1372 unsigned i = lfo_phase;
1375 auto [a, p] = [&]() -> std::pair<int, int> {
1383 ((i < 128) ? i : (i - 255))
1390 ((i < 128) ? 255 : 0),
1391 ((i < 128) ? 128 : -128)
1399 ((i < 128) ? (255 - (i * 2)) : ((i * 2) - 256)),
1403 }
else if (i < 128) {
1405 }
else if (i < 192) {
1421 lfo_noise_waveform[i],
1422 (lfo_noise_waveform[i] - 128)
1426 lfa = a * amd / 128;
1427 lfp = p * pmd / 128;
1441 unsigned j = ((noise_rng ^ (noise_rng >> 3)) & 1) ^ 1;
1442 noise_rng = (j << 16) | (noise_rng >> 1);
1446 for (
auto c :
xrange(8)) {
1447 auto op = subspan<4>(oper, 4 * c);
1451 if (op[0].pms < 6) {
1452 mod_ind >>= (6 - op[0].pms);
1454 mod_ind <<= (op[0].pms - 5);
1457 unsigned kc_channel = op[0].kc_i + mod_ind;
1458 op[0].phase += ((freq[kc_channel + op[0].dt2] + op[0].dt1) * op[0].mul) >> 1;
1459 op[1].phase += ((freq[kc_channel + op[1].dt2] + op[1].dt1) * op[1].mul) >> 1;
1460 op[2].phase += ((freq[kc_channel + op[2].dt2] + op[2].dt1) * op[2].mul) >> 1;
1461 op[3].phase += ((freq[kc_channel + op[3].dt2] + op[3].dt1) * op[3].mul) >> 1;
1463 op[0].phase += op[0].freq;
1464 op[1].phase += op[1].freq;
1465 op[2].phase += op[2].freq;
1466 op[3].phase += op[3].freq;
1469 op[0].phase += op[0].freq;
1470 op[1].phase += op[1].freq;
1471 op[2].phase += op[2].freq;
1472 op[3].phase += op[3].freq;
1486 for (
auto& op : oper) {
1491 for (
auto& op : oper) {
1492 keyOff(op,
unsigned(~2));
1499void YM2151::generateChannels(std::span<float*> bufs,
unsigned num)
1501 if (checkMuteHelper()) {
1507 for (
auto i :
xrange(num)) {
1510 for (
auto j :
xrange(8 - 1)) {
1517 for (
auto j :
xrange(8)) {
1518 bufs[j][2 * i + 0] += narrow_cast<float>(narrow_cast<int>(chanOut[j] & pan[2 * j + 0]));
1519 bufs[j][2 * i + 1] += narrow_cast<float>(narrow_cast<int>(chanOut[j] & pan[2 * j + 1]));
1525void YM2151::callback(uint8_t flag)
1527 assert(flag ==
one_of(1, 2));
1530 if ((flag == 1) && (irq_enable & 0x80)) {
1540void YM2151::setStatus(uint8_t flags)
1543 auto enable = (irq_enable >> 2) & 3;
1544 if ((status & enable) != 0) {
1549void YM2151::resetStatus(uint8_t flags)
1552 auto enable = (irq_enable >> 2) & 3;
1553 if ((status & enable) == 0) {
1559template<
typename Archive>
1560void YM2151::YM2151Operator::serialize(Archive& a,
unsigned )
1564 a.serialize(
"phase", phase,
1570 "mem_value", mem_value,
1572 "fb_out_curr", fb_out_curr,
1573 "fb_out_prev", fb_out_prev,
1589 "eg_sh_ar", eg_sh_ar,
1590 "eg_sel_ar", eg_sel_ar,
1591 "eg_sh_d1r", eg_sh_d1r,
1592 "eg_sel_d1r", eg_sel_d1r,
1593 "eg_sh_d2r", eg_sh_d2r,
1594 "eg_sel_d2r", eg_sel_d2r,
1595 "eg_sh_rr", eg_sh_rr,
1596 "eg_sel_rr", eg_sel_rr);
1599template<
typename Archive>
1602 a.serialize(
"irq", irq,
1608 "eg_timer", eg_timer,
1609 "lfo_phase", lfo_phase,
1610 "lfo_timer", lfo_timer,
1611 "lfo_overflow", lfo_overflow,
1612 "lfo_counter", lfo_counter,
1613 "lfo_counter_add", lfo_counter_add,
1617 "noise_rng", noise_rng,
1621 "irq_enable", irq_enable,
1628 "timer_A_val", timer_A_val,
1629 "lfo_wsel", lfo_wsel,
1634 a.serialize_blob(
"registers", regs);
1636 if constexpr (Archive::IS_LOADER) {
1638 EmuTime::param time = timer1->getCurrentTime();
1639 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)
void writeReg(uint8_t r, uint8_t v, EmuTime::param time)
constexpr double round(double x)
This file implemented 3 utility functions:
constexpr 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)