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
467 if (op.state > EG_REL) {
474void YM2151::envelopeKONKOFF(std::span<YM2151Operator, 4> op,
int v)
const
479 keyOff(op[0],
unsigned(~1));
484 keyOff(op[1],
unsigned(~1));
489 keyOff(op[2],
unsigned(~1));
494 keyOff(op[3],
unsigned(~1));
498void YM2151::setConnect(std::span<YM2151Operator, 4> o,
int cha,
int v)
500 YM2151Operator& om1 = o[0];
501 YM2151Operator& om2 = o[1];
502 YM2151Operator& oc1 = o[2];
512 om1.mem_connect = &m2;
521 om1.mem_connect = &m2;
530 om1.mem_connect = &m2;
539 om1.mem_connect = &c2;
547 oc1.connect = &chanOut[cha];
549 om1.mem_connect = &mem;
556 om1.connect =
nullptr;
557 oc1.connect = &chanOut[cha];
558 om2.connect = &chanOut[cha];
559 om1.mem_connect = &m2;
568 oc1.connect = &chanOut[cha];
569 om2.connect = &chanOut[cha];
570 om1.mem_connect = &mem;
579 om1.connect = &chanOut[cha];
580 oc1.connect = &chanOut[cha];
581 om2.connect = &chanOut[cha];
582 om1.mem_connect = &mem;
587void YM2151::refreshEG(std::span<YM2151Operator, 4> op)
589 unsigned kc = op[0].kc;
592 unsigned v = kc >> op[0].ks;
593 if ((op[0].ar + v) < 32 + 62) {
594 op[0].eg_sh_ar = eg_rate_shift [op[0].ar + v];
595 op[0].eg_sel_ar = eg_rate_select[op[0].ar + v];
598 op[0].eg_sel_ar = 17 * RATE_STEPS;
600 op[0].eg_sh_d1r = eg_rate_shift [op[0].d1r + v];
601 op[0].eg_sel_d1r = eg_rate_select[op[0].d1r + v];
602 op[0].eg_sh_d2r = eg_rate_shift [op[0].d2r + v];
603 op[0].eg_sel_d2r = eg_rate_select[op[0].d2r + v];
604 op[0].eg_sh_rr = eg_rate_shift [op[0].rr + v];
605 op[0].eg_sel_rr = eg_rate_select[op[0].rr + v];
608 if ((op[1].ar + v) < 32 + 62) {
609 op[1].eg_sh_ar = eg_rate_shift [op[1].ar + v];
610 op[1].eg_sel_ar = eg_rate_select[op[1].ar + v];
613 op[1].eg_sel_ar = 17 * RATE_STEPS;
615 op[1].eg_sh_d1r = eg_rate_shift [op[1].d1r + v];
616 op[1].eg_sel_d1r = eg_rate_select[op[1].d1r + v];
617 op[1].eg_sh_d2r = eg_rate_shift [op[1].d2r + v];
618 op[1].eg_sel_d2r = eg_rate_select[op[1].d2r + v];
619 op[1].eg_sh_rr = eg_rate_shift [op[1].rr + v];
620 op[1].eg_sel_rr = eg_rate_select[op[1].rr + v];
623 if ((op[2].ar + v) < 32 + 62) {
624 op[2].eg_sh_ar = eg_rate_shift [op[2].ar + v];
625 op[2].eg_sel_ar = eg_rate_select[op[2].ar + v];
628 op[2].eg_sel_ar = 17 * RATE_STEPS;
630 op[2].eg_sh_d1r = eg_rate_shift [op[2].d1r + v];
631 op[2].eg_sel_d1r = eg_rate_select[op[2].d1r + v];
632 op[2].eg_sh_d2r = eg_rate_shift [op[2].d2r + v];
633 op[2].eg_sel_d2r = eg_rate_select[op[2].d2r + v];
634 op[2].eg_sh_rr = eg_rate_shift [op[2].rr + v];
635 op[2].eg_sel_rr = eg_rate_select[op[2].rr + v];
638 if ((op[3].ar + v) < 32 + 62) {
639 op[3].eg_sh_ar = eg_rate_shift [op[3].ar + v];
640 op[3].eg_sel_ar = eg_rate_select[op[3].ar + v];
643 op[3].eg_sel_ar = 17 * RATE_STEPS;
645 op[3].eg_sh_d1r = eg_rate_shift [op[3].d1r + v];
646 op[3].eg_sel_d1r = eg_rate_select[op[3].d1r + v];
647 op[3].eg_sh_d2r = eg_rate_shift [op[3].d2r + v];
648 op[3].eg_sel_d2r = eg_rate_select[op[3].d2r + v];
649 op[3].eg_sh_rr = eg_rate_shift [op[3].rr + v];
650 op[3].eg_sel_rr = eg_rate_select[op[3].rr + v];
657 YM2151Operator& op = oper[(r & 0x07) * 4 + ((r & 0x18) >> 3)];
669 if (v & 2) lfo_phase = 0;
674 envelopeKONKOFF(subspan<4>(oper, 4 * (v & 7)), v);
679 noise_f = noise_tab[v & 0x1f];
685 timer_A_val |= v << 2;
686 timer1->setValue(timer_A_val);
690 timer_A_val &= 0x03fc;
691 timer_A_val |= v & 3;
692 timer1->setValue(timer_A_val);
707 timer1->setStart((v & 4) != 0, time);
708 timer2->setStart((v & 8) != 0, time);
712 lfo_overflow = (1 << ((15 - (v >> 4)) + 3));
713 lfo_counter_add = 0x10 + (v & 0x0f);
718 pmd = narrow<int8_t>(v & 0x7f);
736 auto o = subspan<4>(oper, 4 * (r & 7));
739 o[0].fb_shift = ((v >> 3) & 7) ? ((v >> 3) & 7) + 6 : 0;
740 pan[(r & 7) * 2 + 0] = (v & 0x40) ? ~0 : 0;
741 pan[(r & 7) * 2 + 1] = (v & 0x80) ? ~0 : 0;
742 setConnect(o, r & 7, v & 7);
748 unsigned kc_channel = (v - (v>>2))*64;
750 kc_channel |= (o[0].kc_i & 63);
753 o[0].kc_i = kc_channel;
755 o[1].kc_i = kc_channel;
757 o[2].kc_i = kc_channel;
759 o[3].kc_i = kc_channel;
762 o[0].dt1 = dt1_freq[o[0].dt1_i + kc];
763 o[0].freq = ((freq[kc_channel + o[0].dt2] + o[0].dt1) * o[0].mul) >> 1;
765 o[1].dt1 = dt1_freq[o[1].dt1_i + kc];
766 o[1].freq = ((freq[kc_channel + o[1].dt2] + o[1].dt1) * o[1].mul) >> 1;
768 o[2].dt1 = dt1_freq[o[2].dt1_i + kc];
769 o[2].freq = ((freq[kc_channel + o[2].dt2] + o[2].dt1) * o[2].mul) >> 1;
771 o[3].dt1 = dt1_freq[o[3].dt1_i + kc];
772 o[3].freq = ((freq[kc_channel + o[3].dt2] + o[3].dt1) * o[3].mul) >> 1;
780 if (v != (o[0].kc_i & 63)) {
781 unsigned kc_channel = v;
782 kc_channel |= (o[0].kc_i & ~63);
784 o[0].kc_i = kc_channel;
785 o[1].kc_i = kc_channel;
786 o[2].kc_i = kc_channel;
787 o[3].kc_i = kc_channel;
789 o[0].freq = ((freq[kc_channel + o[0].dt2] + o[0].dt1) * o[0].mul) >> 1;
790 o[1].freq = ((freq[kc_channel + o[1].dt2] + o[1].dt1) * o[1].mul) >> 1;
791 o[2].freq = ((freq[kc_channel + o[2].dt2] + o[2].dt1) * o[2].mul) >> 1;
792 o[3].freq = ((freq[kc_channel + o[3].dt2] + o[3].dt1) * o[3].mul) >> 1;
797 o[0].pms = narrow<int8_t>((v >> 4) & 7);
804 unsigned olddt1_i = op.dt1_i;
805 unsigned oldMul = op.mul;
807 op.dt1_i = (v & 0x70) << 1;
808 op.mul = (v & 0x0f) ? (v & 0x0f) << 1 : 1;
810 if (olddt1_i != op.dt1_i) {
811 op.dt1 = dt1_freq[op.dt1_i + (op.kc>>2)];
813 if ((olddt1_i != op.dt1_i) || (oldMul != op.mul)) {
814 op.freq = ((freq[op.kc_i + op.dt2] + op.dt1) * op.mul) >> 1;
819 op.tl = (v & 0x7f) << (ENV_BITS - 7);
823 unsigned oldKs = op.ks;
824 unsigned oldAr = op.ar;
825 op.ks = 5 - (v >> 6);
826 op.ar = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
828 if ((op.ar != oldAr) || (op.ks != oldKs)) {
829 if ((op.ar + (op.kc >> op.ks)) < 32 + 62) {
830 op.eg_sh_ar = eg_rate_shift [op.ar + (op.kc>>op.ks)];
831 op.eg_sel_ar = eg_rate_select[op.ar + (op.kc>>op.ks)];
834 op.eg_sel_ar = 17 * RATE_STEPS;
837 if (op.ks != oldKs) {
838 op.eg_sh_d1r = eg_rate_shift [op.d1r + (op.kc >> op.ks)];
839 op.eg_sel_d1r = eg_rate_select[op.d1r + (op.kc >> op.ks)];
840 op.eg_sh_d2r = eg_rate_shift [op.d2r + (op.kc >> op.ks)];
841 op.eg_sel_d2r = eg_rate_select[op.d2r + (op.kc >> op.ks)];
842 op.eg_sh_rr = eg_rate_shift [op.rr + (op.kc >> op.ks)];
843 op.eg_sel_rr = eg_rate_select[op.rr + (op.kc >> op.ks)];
848 op.AMmask = (v & 0x80) ? ~0 : 0;
849 op.d1r = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
850 op.eg_sh_d1r = eg_rate_shift [op.d1r + (op.kc >> op.ks)];
851 op.eg_sel_d1r = eg_rate_select[op.d1r + (op.kc >> op.ks)];
855 unsigned olddt2 = op.dt2;
856 op.dt2 = dt2_tab[v >> 6];
857 if (op.dt2 != olddt2) {
858 op.freq = ((freq[op.kc_i + op.dt2] + op.dt1) * op.mul) >> 1;
860 op.d2r = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
861 op.eg_sh_d2r = eg_rate_shift [op.d2r + (op.kc >> op.ks)];
862 op.eg_sel_d2r = eg_rate_select[op.d2r + (op.kc >> op.ks)];
866 op.d1l = d1l_tab[v >> 4];
867 op.rr = 34 + ((v & 0x0f) << 2);
868 op.eg_sh_rr = eg_rate_shift [op.rr + (op.kc >> op.ks)];
869 op.eg_sel_rr = eg_rate_select[op.rr + (op.kc >> op.ks)];
874static constexpr auto INPUT_RATE = unsigned(
cstd::round(3579545 / 64.0));
879 , irq(config.getMotherBoard(), getName() +
".IRQ")
880 , timer1(
EmuTimer::createOPM_1(config.getScheduler(), *this))
881 , timer2(variant_ ==
Variant::YM2164 ?
EmuTimer::createOPP_2(config.getScheduler(), *this)
882 :
EmuTimer::createOPM_2(config.getScheduler(), *this))
889 std::cout <<
"tl_tab:";
890 for (
const auto& e : tl_tab) std::cout <<
' ' << e;
893 std::cout <<
"sin_tab:";
894 for (
const auto& e : sin_tab) std::cout <<
' ' << e;
897 std::cout <<
"d1l_tab:";
898 for (
const auto& e : d1l_tab) std::cout <<
' ' << e;
901 std::cout <<
"freq:";
902 for (
const auto& e : freq) std::cout <<
' ' << e;
905 std::cout <<
"dt1_freq:";
906 for (
const auto& e : dt1_freq) std::cout <<
' ' << e;
909 std::cout <<
"noise_tab:";
910 for (
const auto& e : noise_tab) std::cout <<
' ' << e;
924bool YM2151::checkMuteHelper()
926 return ranges::all_of(oper, [](
auto& op) {
return op.state == EG_OFF; });
932 for (
auto& op : oper) {
933 memset(&op,
'\0',
sizeof(op));
934 op.volume = MAX_ATT_INDEX;
953 timer1->setStart(
false, time);
954 timer2->setStart(
false, time);
959 noise_f = noise_tab[0];
966 for (
auto i :
xrange(0x20, 0x100)) {
967 writeReg(narrow<uint8_t>(i), 0, time);
973int YM2151::opCalc(
const YM2151Operator& op,
unsigned env,
int pm)
const
975 unsigned p = (env << 3) + sin_tab[(
int((op.phase & ~FREQ_MASK) + (pm << 15)) >> FREQ_SH) & SIN_MASK];
976 if (p >= TL_TAB_LEN) {
982int YM2151::opCalc1(
const YM2151Operator& op,
unsigned env,
int pm)
const
984 int i = (narrow_cast<int>(op.phase) & ~FREQ_MASK) + pm;
985 unsigned p = (env << 3) + sin_tab[(i >> FREQ_SH) & SIN_MASK];
986 if (p >= TL_TAB_LEN) {
992unsigned YM2151::volumeCalc(
const YM2151Operator& op,
unsigned AM)
const
994 return op.tl + unsigned(op.volume) + (AM & op.AMmask);
997void YM2151::chanCalc(
unsigned chan)
999 m2 = c1 = c2 = mem = 0;
1000 auto op = subspan<4>(oper, 4 * chan);
1001 *op[0].mem_connect = op[0].mem_value;
1005 AM = lfa << (op[0].ams-1);
1007 unsigned env = volumeCalc(op[0], AM);
1009 int out = op[0].fb_out_prev + op[0].fb_out_curr;
1010 op[0].fb_out_prev = op[0].fb_out_curr;
1012 if (!op[0].connect) {
1014 mem = c1 = c2 = op[0].fb_out_prev;
1016 *op[0].connect = op[0].fb_out_prev;
1018 op[0].fb_out_curr = 0;
1019 if (env < ENV_QUIET) {
1020 if (!op[0].fb_shift) {
1023 op[0].fb_out_curr = opCalc1(op[0], env, (out << op[0].fb_shift));
1027 env = volumeCalc(op[1], AM);
1028 if (env < ENV_QUIET) {
1029 *op[1].connect += opCalc(op[1], env, m2);
1031 env = volumeCalc(op[2], AM);
1032 if (env < ENV_QUIET) {
1033 *op[2].connect += opCalc(op[2], env, c1);
1035 env = volumeCalc(op[3], AM);
1036 if (env < ENV_QUIET) {
1037 chanOut[chan] += opCalc(op[3], env, c2);
1040 op[0].mem_value = mem;
1043void YM2151::chan7Calc()
1045 m2 = c1 = c2 = mem = 0;
1046 auto op = subspan<4>(oper, 4 * 7);
1048 *op[0].mem_connect = op[0].mem_value;
1052 AM = lfa << (op[0].ams - 1);
1054 unsigned env = volumeCalc(op[0], AM);
1056 int out = op[0].fb_out_prev + op[0].fb_out_curr;
1057 op[0].fb_out_prev = op[0].fb_out_curr;
1059 if (!op[0].connect) {
1061 mem = c1 = c2 = op[0].fb_out_prev;
1064 *op[0].connect = op[0].fb_out_prev;
1066 op[0].fb_out_curr = 0;
1067 if (env < ENV_QUIET) {
1068 if (!op[0].fb_shift) {
1071 op[0].fb_out_curr = opCalc1(op[0], env, (out << op[0].fb_shift));
1075 env = volumeCalc(op[1], AM);
1076 if (env < ENV_QUIET) {
1077 *op[1].connect += opCalc(op[1], env, m2);
1079 env = volumeCalc(op[2], AM);
1080 if (env < ENV_QUIET) {
1081 *op[2].connect += opCalc(op[2], env, c1);
1083 env = volumeCalc(op[3], AM);
1087 noiseOut = (narrow<int>(env) ^ 0x3ff) * 2;
1089 chanOut[7] += (noise_rng & 0x10000) ? noiseOut : -noiseOut;
1091 if (env < ENV_QUIET) {
1092 chanOut[7] += opCalc(op[3], env, c2);
1096 op[0].mem_value = mem;
1303void YM2151::advanceEG()
1305 if (eg_timer++ != 3) {
1313 for (
auto& op : oper) {
1316 if (!(eg_cnt & ((1 << op.eg_sh_ar) - 1))) {
1317 op.volume += (~op.volume *
1318 (eg_inc[op.eg_sel_ar + ((eg_cnt >> op.eg_sh_ar) & 7)])
1320 if (op.volume <= MIN_ATT_INDEX) {
1321 op.volume = MIN_ATT_INDEX;
1328 if (!(eg_cnt & ((1 << op.eg_sh_d1r) - 1))) {
1329 op.volume += eg_inc[op.eg_sel_d1r + ((eg_cnt >> op.eg_sh_d1r) & 7)];
1330 if (
unsigned(op.volume) >= op.d1l) {
1337 if (!(eg_cnt & ((1 << op.eg_sh_d2r) - 1))) {
1338 op.volume += eg_inc[op.eg_sel_d2r + ((eg_cnt >> op.eg_sh_d2r) & 7)];
1339 if (op.volume >= MAX_ATT_INDEX) {
1340 op.volume = MAX_ATT_INDEX;
1347 if (!(eg_cnt & ((1 << op.eg_sh_rr) - 1))) {
1348 op.volume += eg_inc[op.eg_sel_rr + ((eg_cnt >> op.eg_sh_rr) & 7)];
1349 if (op.volume >= MAX_ATT_INDEX) {
1350 op.volume = MAX_ATT_INDEX;
1359void YM2151::advance()
1365 if (lfo_timer++ >= lfo_overflow) {
1367 lfo_counter += lfo_counter_add;
1368 lfo_phase += (lfo_counter >> 4);
1374 unsigned i = lfo_phase;
1377 auto [a, p] = [&]() -> std::pair<int, int> {
1385 ((i < 128) ? i : (i - 255))
1392 ((i < 128) ? 255 : 0),
1393 ((i < 128) ? 128 : -128)
1401 ((i < 128) ? (255 - (i * 2)) : ((i * 2) - 256)),
1405 }
else if (i < 128) {
1407 }
else if (i < 192) {
1423 lfo_noise_waveform[i],
1424 (lfo_noise_waveform[i] - 128)
1428 lfa = a * amd / 128;
1429 lfp = p * pmd / 128;
1443 unsigned j = ((noise_rng ^ (noise_rng >> 3)) & 1) ^ 1;
1444 noise_rng = (j << 16) | (noise_rng >> 1);
1448 for (
auto c :
xrange(8)) {
1449 auto op = subspan<4>(oper, 4 * c);
1453 if (op[0].pms < 6) {
1454 mod_ind >>= (6 - op[0].pms);
1456 mod_ind <<= (op[0].pms - 5);
1459 unsigned kc_channel = op[0].kc_i + mod_ind;
1460 op[0].phase += ((freq[kc_channel + op[0].dt2] + op[0].dt1) * op[0].mul) >> 1;
1461 op[1].phase += ((freq[kc_channel + op[1].dt2] + op[1].dt1) * op[1].mul) >> 1;
1462 op[2].phase += ((freq[kc_channel + op[2].dt2] + op[2].dt1) * op[2].mul) >> 1;
1463 op[3].phase += ((freq[kc_channel + op[3].dt2] + op[3].dt1) * op[3].mul) >> 1;
1465 op[0].phase += op[0].freq;
1466 op[1].phase += op[1].freq;
1467 op[2].phase += op[2].freq;
1468 op[3].phase += op[3].freq;
1471 op[0].phase += op[0].freq;
1472 op[1].phase += op[1].freq;
1473 op[2].phase += op[2].freq;
1474 op[3].phase += op[3].freq;
1488 for (
auto& op : oper) {
1493 for (
auto& op : oper) {
1494 keyOff(op,
unsigned(~2));
1501void YM2151::generateChannels(std::span<float*> bufs,
unsigned num)
1503 if (checkMuteHelper()) {
1509 for (
auto i :
xrange(num)) {
1512 for (
auto j :
xrange(8 - 1)) {
1519 for (
auto j :
xrange(8)) {
1520 bufs[j][2 * i + 0] += narrow_cast<float>(narrow_cast<int>(chanOut[j] & pan[2 * j + 0]));
1521 bufs[j][2 * i + 1] += narrow_cast<float>(narrow_cast<int>(chanOut[j] & pan[2 * j + 1]));
1527void YM2151::callback(uint8_t flag)
1529 assert(flag ==
one_of(1, 2));
1532 if ((flag == 1) && (irq_enable & 0x80)) {
1542void YM2151::setStatus(uint8_t flags)
1545 auto enable = (irq_enable >> 2) & 3;
1546 if ((status & enable) != 0) {
1551void YM2151::resetStatus(uint8_t flags)
1554 auto enable = (irq_enable >> 2) & 3;
1555 if ((status & enable) == 0) {
1561template<
typename Archive>
1562void YM2151::YM2151Operator::serialize(Archive& a,
unsigned )
1566 a.serialize(
"phase", phase,
1572 "mem_value", mem_value,
1574 "fb_out_curr", fb_out_curr,
1575 "fb_out_prev", fb_out_prev,
1591 "eg_sh_ar", eg_sh_ar,
1592 "eg_sel_ar", eg_sel_ar,
1593 "eg_sh_d1r", eg_sh_d1r,
1594 "eg_sel_d1r", eg_sel_d1r,
1595 "eg_sh_d2r", eg_sh_d2r,
1596 "eg_sel_d2r", eg_sel_d2r,
1597 "eg_sh_rr", eg_sh_rr,
1598 "eg_sel_rr", eg_sel_rr);
1601template<
typename Archive>
1604 a.serialize(
"irq", irq,
1610 "eg_timer", eg_timer,
1611 "lfo_phase", lfo_phase,
1612 "lfo_timer", lfo_timer,
1613 "lfo_overflow", lfo_overflow,
1614 "lfo_counter", lfo_counter,
1615 "lfo_counter_add", lfo_counter_add,
1619 "noise_rng", noise_rng,
1623 "irq_enable", irq_enable,
1630 "timer_A_val", timer_A_val,
1631 "lfo_wsel", lfo_wsel,
1636 a.serialize_blob(
"registers", regs);
1638 if constexpr (Archive::IS_LOADER) {
1640 EmuTime::param time = timer1->getCurrentTime();
1641 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:
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)