#pragma once #include "pch.h" #include "SNES/DSP/Dsp.h" class DspInterpolation { private: static constexpr int16_t const gauss[512] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 59, 60, 61, 62, 64, 65, 66, 67, 69, 70, 71, 73, 74, 76, 77, 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 94, 95, 97, 99, 100, 102, 104, 106, 107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 130, 132, 134, 137, 139, 141, 143, 145, 147, 150, 152, 154, 156, 159, 161, 163, 166, 168, 171, 173, 175, 178, 180, 183, 186, 188, 191, 193, 196, 199, 201, 204, 207, 210, 212, 215, 218, 221, 224, 227, 230, 233, 236, 239, 242, 245, 248, 251, 254, 257, 260, 263, 267, 270, 273, 276, 280, 283, 286, 290, 293, 297, 300, 304, 307, 311, 314, 318, 321, 325, 328, 332, 336, 339, 343, 347, 351, 354, 358, 362, 366, 370, 374, 378, 381, 385, 389, 393, 397, 401, 405, 410, 414, 418, 422, 426, 430, 434, 439, 443, 447, 451, 456, 460, 464, 469, 473, 477, 482, 486, 491, 495, 499, 504, 508, 513, 517, 522, 527, 531, 536, 540, 545, 550, 554, 559, 563, 568, 573, 577, 582, 587, 592, 596, 601, 606, 611, 615, 620, 625, 630, 635, 640, 644, 649, 654, 659, 664, 669, 674, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728, 732, 737, 742, 747, 752, 757, 762, 767, 772, 777, 782, 787, 792, 797, 802, 806, 811, 816, 821, 826, 831, 836, 841, 846, 851, 855, 860, 865, 870, 875, 880, 884, 889, 894, 899, 904, 908, 913, 918, 923, 927, 932, 937, 941, 946, 951, 955, 960, 965, 969, 974, 978, 983, 988, 992, 997,1001,1005,1010,1014,1019,1023,1027,1032,1036, 1040,1045,1049,1053,1057,1061,1066,1070,1074,1078,1082,1086,1090,1094,1098,1102, 1106,1109,1113,1117,1121,1125,1128,1132,1136,1139,1143,1146,1150,1153,1157,1160, 1164,1167,1170,1174,1177,1180,1183,1186,1190,1193,1196,1199,1202,1205,1207,1210, 1213,1216,1219,1221,1224,1227,1229,1232,1234,1237,1239,1241,1244,1246,1248,1251, 1253,1255,1257,1259,1261,1263,1265,1267,1269,1270,1272,1274,1275,1277,1279,1280, 1282,1283,1284,1286,1287,1288,1290,1291,1292,1293,1294,1295,1296,1297,1297,1298, 1299,1300,1300,1301,1302,1302,1303,1303,1303,1304,1304,1304,1304,1304,1305,1305, }; public: static int16_t Gauss(int32_t interpolationPos, int16_t* samples, uint8_t bufferPos) { uint8_t pos = (interpolationPos >> 12) + bufferPos; uint8_t offset = (interpolationPos >> 4) & 0xFF; //"The above 3 wrap at 15 bits signed. The last is added to that, and is clamped rather than wrapped. int32_t out = (int16_t)( ((gauss[255 - offset] * (int32_t)samples[pos % 12]) >> 11) + ((gauss[511 - offset] * (int32_t)samples[(pos + 1) % 12]) >> 11) + ((gauss[256 + offset] * (int32_t)samples[(pos + 2) % 12]) >> 11) ) + ((gauss[offset] * (int32_t)samples[(pos + 3) % 12]) >> 11); return Dsp::Clamp16(out) & ~0x01; } static int16_t Cubic(int32_t interpolationPos, int16_t* samples, uint8_t bufferPos) { uint8_t pos = (interpolationPos >> 12) + bufferPos; float v0 = samples[pos % 12] / 32768.0f; float v1 = samples[(pos + 1) % 12] / 32768.0f; float v2 = samples[(pos + 2) % 12] / 32768.0f; float v3 = samples[(pos + 3) % 12] / 32768.0f; float a = (v3 - v2) - (v0 - v1); float b = (v0 - v1) - a; float c = v2 - v0; float d = v1; float ratio = (float)(interpolationPos & 0xFFF) / 0x1000; return Dsp::Clamp16((d + ratio * (c + ratio * (b + ratio * a))) * 32768); } static int16_t Sinc(int32_t interpolationPos, int16_t* samples, uint8_t bufferPos) { uint8_t pos = (interpolationPos >> 12) + bufferPos; uint16_t offset = ((interpolationPos >> 4) & 0xFF) * 8; return Dsp::Clamp16(( (_sincTable[offset + 0] * samples[(pos + 0) % 12]) + (_sincTable[offset + 1] * samples[(pos + 1) % 12]) + (_sincTable[offset + 2] * samples[(pos + 2) % 12]) + (_sincTable[offset + 3] * samples[(pos + 3) % 12]) + (_sincTable[offset + 4] * samples[(pos + 4) % 12]) + (_sincTable[offset + 5] * samples[(pos + 5) % 12]) + (_sincTable[offset + 6] * samples[(pos + 6) % 12]) + (_sincTable[offset + 7] * samples[(pos + 7) % 12]) ) >> 14); } private: /* * Table generated via the following Python script (Original source: https://tomroelandts.com/articles/how-to-create-a-simple-low-pass-filter) ---- from __future__ import division import numpy as np fc = 0.5 # Cutoff frequency as a fraction of the sampling rate (in (0, 0.5)). N = 10 n = np.arange(N) for x in range(0, 256): # Compute sinc filter. h = np.sinc(2 * fc * (n - 4 - (x / 255.0))) # Compute Blackman window. w = 0.42 - 0.5 * np.cos(2 * np.pi * n / (N - 1)) + \ 0.08 * np.cos(4 * np.pi * n / (N - 1)) # Multiply sinc filter by window. h = h * w # Normalize to get unity gain. h = h / np.sum(h) * 16384 print(h.astype(int)) ---- */ static constexpr int16_t const _sincTable[2048] = { 0, 0, 0, 16384, 0, 0, 0, 0, -1, 8, -42, 16370, 64, -21, 5, 0, -2, 17, -84, 16356, 129, -42, 11, -1, -3, 25, -125, 16341, 194, -64, 17, -2, -4, 34, -167, 16326, 260, -85, 23, -3, -5, 42, -207, 16310, 326, -106, 29, -4, -6, 51, -248, 16293, 392, -128, 34, -5, -7, 59, -288, 16276, 459, -150, 40, -6, -8, 68, -327, 16257, 526, -171, 46, -6, -10, 76, -366, 16238, 594, -193, 52, -7, -11, 84, -405, 16219, 662, -214, 58, -8, -12, 92, -443, 16198, 730, -236, 64, -9, -13, 100, -481, 16177, 798, -258, 69, -10, -14, 108, -519, 16156, 867, -279, 75, -11, -15, 116, -556, 16133, 937, -301, 81, -12, -16, 124, -592, 16110, 1006, -323, 87, -12, -17, 132, -629, 16086, 1076, -345, 93, -13, -18, 140, -664, 16062, 1147, -366, 99, -14, -19, 148, -700, 16037, 1218, -388, 104, -15, -20, 155, -735, 16011, 1289, -410, 110, -16, -21, 163, -770, 15984, 1360, -432, 116, -17, -22, 171, -804, 15957, 1432, -453, 122, -17, -23, 178, -838, 15929, 1504, -475, 127, -18, -24, 186, -871, 15901, 1576, -497, 133, -19, -25, 193, -904, 15871, 1649, -519, 139, -20, -26, 200, -936, 15841, 1721, -540, 145, -21, -27, 208, -969, 15811, 1795, -562, 150, -22, -28, 215, -1000, 15780, 1868, -584, 156, -22, -29, 222, -1032, 15748, 1942, -605, 162, -23, -30, 229, -1062, 15715, 2016, -627, 167, -24, -31, 236, -1093, 15682, 2091, -649, 173, -25, -32, 243, -1123, 15648, 2165, -670, 179, -26, -33, 250, -1153, 15614, 2240, -692, 184, -27, -34, 256, -1182, 15579, 2315, -713, 190, -27, -35, 263, -1211, 15543, 2391, -735, 196, -28, -36, 270, -1239, 15507, 2467, -756, 201, -29, -37, 276, -1267, 15470, 2543, -778, 207, -30, -38, 283, -1295, 15432, 2619, -799, 212, -31, -38, 289, -1322, 15394, 2695, -820, 218, -31, -39, 295, -1349, 15355, 2772, -842, 223, -32, -40, 302, -1375, 15316, 2849, -863, 229, -33, -41, 308, -1401, 15276, 2926, -884, 234, -34, -42, 314, -1427, 15235, 3004, -905, 240, -34, -43, 320, -1452, 15194, 3081, -926, 245, -35, -44, 326, -1476, 15152, 3159, -947, 250, -36, -44, 332, -1501, 15109, 3237, -968, 256, -37, -45, 338, -1525, 15066, 3316, -989, 261, -38, -46, 343, -1548, 15022, 3394, -1010, 266, -38, -47, 349, -1571, 14978, 3473, -1030, 272, -39, -48, 355, -1594, 14933, 3552, -1051, 277, -40, -48, 360, -1616, 14888, 3631, -1071, 282, -41, -49, 366, -1638, 14842, 3710, -1092, 287, -41, -50, 371, -1659, 14795, 3789, -1112, 292, -42, -51, 376, -1680, 14748, 3869, -1132, 297, -43, -51, 381, -1701, 14700, 3949, -1153, 302, -43, -52, 386, -1721, 14652, 4029, -1173, 307, -44, -53, 391, -1741, 14603, 4109, -1193, 312, -45, -53, 396, -1761, 14553, 4189, -1212, 317, -46, -54, 401, -1780, 14503, 4270, -1232, 322, -46, -55, 406, -1798, 14453, 4350, -1252, 327, -47, -56, 411, -1817, 14402, 4431, -1271, 332, -48, -56, 415, -1834, 14350, 4512, -1291, 337, -48, -57, 420, -1852, 14298, 4593, -1310, 342, -49, -57, 424, -1869, 14245, 4674, -1329, 346, -50, -58, 429, -1885, 14192, 4755, -1348, 351, -50, -59, 433, -1902, 14138, 4836, -1367, 356, -51, -59, 437, -1918, 14084, 4918, -1386, 360, -52, -60, 441, -1933, 14029, 4999, -1405, 365, -52, -61, 445, -1948, 13973, 5081, -1423, 369, -53, -61, 449, -1963, 13917, 5163, -1442, 374, -54, -62, 453, -1977, 13861, 5244, -1460, 378, -54, -62, 457, -1991, 13804, 5326, -1478, 383, -55, -63, 461, -2004, 13747, 5408, -1496, 387, -55, -63, 464, -2018, 13689, 5490, -1514, 391, -56, -64, 468, -2030, 13631, 5572, -1532, 395, -57, -64, 471, -2043, 13572, 5655, -1549, 400, -57, -65, 475, -2055, 13512, 5737, -1567, 404, -58, -65, 478, -2066, 13453, 5819, -1584, 408, -58, -66, 481, -2077, 13392, 5901, -1601, 412, -59, -66, 485, -2088, 13332, 5984, -1618, 416, -59, -67, 488, -2099, 13270, 6066, -1635, 420, -60, -67, 491, -2109, 13209, 6149, -1651, 424, -60, -68, 493, -2118, 13147, 6231, -1668, 428, -61, -68, 496, -2128, 13084, 6314, -1684, 431, -61, -68, 499, -2137, 13021, 6396, -1700, 435, -62, -69, 502, -2145, 12958, 6479, -1716, 439, -63, -69, 504, -2153, 12894, 6561, -1732, 443, -63, -70, 507, -2161, 12829, 6644, -1747, 446, -63, -70, 509, -2169, 12765, 6726, -1763, 450, -64, -70, 511, -2176, 12699, 6809, -1778, 453, -64, -71, 514, -2183, 12634, 6891, -1793, 456, -65, -71, 516, -2189, 12568, 6973, -1808, 460, -65, -71, 518, -2195, 12501, 7056, -1822, 463, -66, -72, 520, -2201, 12435, 7138, -1836, 466, -66, -72, 522, -2206, 12367, 7221, -1851, 469, -67, -72, 523, -2211, 12300, 7303, -1865, 473, -67, -72, 525, -2216, 12232, 7385, -1878, 476, -67, -73, 527, -2220, 12164, 7467, -1892, 479, -68, -73, 528, -2224, 12095, 7549, -1905, 482, -68, -73, 530, -2227, 12026, 7631, -1918, 484, -69, -73, 531, -2230, 11956, 7713, -1931, 487, -69, -74, 532, -2233, 11886, 7795, -1944, 490, -69, -74, 534, -2236, 11816, 7877, -1956, 493, -70, -74, 535, -2238, 11745, 7959, -1968, 495, -70, -74, 536, -2240, 11675, 8041, -1980, 498, -70, -74, 537, -2241, 11603, 8122, -1992, 500, -71, -75, 538, -2242, 11532, 8204, -2004, 503, -71, -75, 539, -2243, 11460, 8285, -2015, 505, -71, -75, 539, -2244, 11387, 8366, -2026, 507, -72, -75, 540, -2244, 11315, 8447, -2037, 509, -72, -75, 541, -2244, 11242, 8528, -2047, 512, -72, -75, 541, -2243, 11169, 8609, -2058, 514, -72, -75, 541, -2242, 11095, 8690, -2068, 516, -73, -75, 542, -2241, 11021, 8770, -2077, 518, -73, -75, 542, -2240, 10947, 8851, -2087, 520, -73, -75, 542, -2238, 10873, 8931, -2096, 521, -73, -76, 542, -2236, 10798, 9011, -2105, 523, -74, -76, 542, -2233, 10723, 9091, -2114, 525, -74, -76, 542, -2231, 10648, 9171, -2123, 526, -74, -76, 542, -2228, 10572, 9250, -2131, 528, -74, -76, 542, -2224, 10496, 9330, -2139, 529, -74, -76, 542, -2221, 10420, 9409, -2146, 531, -75, -76, 541, -2217, 10344, 9488, -2154, 532, -75, -76, 541, -2213, 10267, 9567, -2161, 533, -75, -76, 540, -2208, 10190, 9646, -2168, 534, -75, -75, 540, -2203, 10113, 9724, -2174, 535, -75, -75, 539, -2198, 10036, 9802, -2181, 536, -75, -75, 538, -2193, 9958, 9880, -2187, 537, -75, -75, 537, -2187, 9880, 9958, -2193, 538, -75, -75, 536, -2181, 9802, 10036, -2198, 539, -75, -75, 535, -2174, 9724, 10113, -2203, 540, -75, -75, 534, -2168, 9646, 10190, -2208, 540, -76, -75, 533, -2161, 9567, 10267, -2213, 541, -76, -75, 532, -2154, 9488, 10344, -2217, 541, -76, -75, 531, -2146, 9409, 10420, -2221, 542, -76, -74, 529, -2139, 9330, 10496, -2224, 542, -76, -74, 528, -2131, 9250, 10572, -2228, 542, -76, -74, 526, -2123, 9171, 10648, -2231, 542, -76, -74, 525, -2114, 9091, 10723, -2233, 542, -76, -74, 523, -2105, 9011, 10798, -2236, 542, -76, -73, 521, -2096, 8931, 10873, -2238, 542, -75, -73, 520, -2087, 8851, 10947, -2240, 542, -75, -73, 518, -2077, 8770, 11021, -2241, 542, -75, -73, 516, -2068, 8690, 11095, -2242, 541, -75, -72, 514, -2058, 8609, 11169, -2243, 541, -75, -72, 512, -2047, 8528, 11242, -2244, 541, -75, -72, 509, -2037, 8447, 11315, -2244, 540, -75, -72, 507, -2026, 8366, 11387, -2244, 539, -75, -71, 505, -2015, 8285, 11460, -2243, 539, -75, -71, 503, -2004, 8204, 11532, -2242, 538, -75, -71, 500, -1992, 8122, 11603, -2241, 537, -74, -70, 498, -1980, 8041, 11675, -2240, 536, -74, -70, 495, -1968, 7959, 11745, -2238, 535, -74, -70, 493, -1956, 7877, 11816, -2236, 534, -74, -69, 490, -1944, 7795, 11886, -2233, 532, -74, -69, 487, -1931, 7713, 11956, -2230, 531, -73, -69, 484, -1918, 7631, 12026, -2227, 530, -73, -68, 482, -1905, 7549, 12095, -2224, 528, -73, -68, 479, -1892, 7467, 12164, -2220, 527, -73, -67, 476, -1878, 7385, 12232, -2216, 525, -72, -67, 473, -1865, 7303, 12300, -2211, 523, -72, -67, 469, -1851, 7221, 12367, -2206, 522, -72, -66, 466, -1836, 7138, 12435, -2201, 520, -72, -66, 463, -1822, 7056, 12501, -2195, 518, -71, -65, 460, -1808, 6973, 12568, -2189, 516, -71, -65, 456, -1793, 6891, 12634, -2183, 514, -71, -64, 453, -1778, 6809, 12699, -2176, 511, -70, -64, 450, -1763, 6726, 12765, -2169, 509, -70, -63, 446, -1747, 6644, 12829, -2161, 507, -70, -63, 443, -1732, 6561, 12894, -2153, 504, -69, -63, 439, -1716, 6479, 12958, -2145, 502, -69, -62, 435, -1700, 6396, 13021, -2137, 499, -68, -61, 431, -1684, 6314, 13084, -2128, 496, -68, -61, 428, -1668, 6231, 13147, -2118, 493, -68, -60, 424, -1651, 6149, 13209, -2109, 491, -67, -60, 420, -1635, 6066, 13270, -2099, 488, -67, -59, 416, -1618, 5984, 13332, -2088, 485, -66, -59, 412, -1601, 5901, 13392, -2077, 481, -66, -58, 408, -1584, 5819, 13453, -2066, 478, -65, -58, 404, -1567, 5737, 13512, -2055, 475, -65, -57, 400, -1549, 5655, 13572, -2043, 471, -64, -57, 395, -1532, 5572, 13631, -2030, 468, -64, -56, 391, -1514, 5490, 13689, -2018, 464, -63, -55, 387, -1496, 5408, 13747, -2004, 461, -63, -55, 383, -1478, 5326, 13804, -1991, 457, -62, -54, 378, -1460, 5244, 13861, -1977, 453, -62, -54, 374, -1442, 5163, 13917, -1963, 449, -61, -53, 369, -1423, 5081, 13973, -1948, 445, -61, -52, 365, -1405, 4999, 14029, -1933, 441, -60, -52, 360, -1386, 4918, 14084, -1918, 437, -59, -51, 356, -1367, 4836, 14138, -1902, 433, -59, -50, 351, -1348, 4755, 14192, -1885, 429, -58, -50, 346, -1329, 4674, 14245, -1869, 424, -57, -49, 342, -1310, 4593, 14298, -1852, 420, -57, -48, 337, -1291, 4512, 14350, -1834, 415, -56, -48, 332, -1271, 4431, 14402, -1817, 411, -56, -47, 327, -1252, 4350, 14453, -1798, 406, -55, -46, 322, -1232, 4270, 14503, -1780, 401, -54, -46, 317, -1212, 4189, 14553, -1761, 396, -53, -45, 312, -1193, 4109, 14603, -1741, 391, -53, -44, 307, -1173, 4029, 14652, -1721, 386, -52, -43, 302, -1153, 3949, 14700, -1701, 381, -51, -43, 297, -1132, 3869, 14748, -1680, 376, -51, -42, 292, -1112, 3789, 14795, -1659, 371, -50, -41, 287, -1092, 3710, 14842, -1638, 366, -49, -41, 282, -1071, 3631, 14888, -1616, 360, -48, -40, 277, -1051, 3552, 14933, -1594, 355, -48, -39, 272, -1030, 3473, 14978, -1571, 349, -47, -38, 266, -1010, 3394, 15022, -1548, 343, -46, -38, 261, -989, 3316, 15066, -1525, 338, -45, -37, 256, -968, 3237, 15109, -1501, 332, -44, -36, 250, -947, 3159, 15152, -1476, 326, -44, -35, 245, -926, 3081, 15194, -1452, 320, -43, -34, 240, -905, 3004, 15235, -1427, 314, -42, -34, 234, -884, 2926, 15276, -1401, 308, -41, -33, 229, -863, 2849, 15316, -1375, 302, -40, -32, 223, -842, 2772, 15355, -1349, 295, -39, -31, 218, -820, 2695, 15394, -1322, 289, -38, -31, 212, -799, 2619, 15432, -1295, 283, -38, -30, 207, -778, 2543, 15470, -1267, 276, -37, -29, 201, -756, 2467, 15507, -1239, 270, -36, -28, 196, -735, 2391, 15543, -1211, 263, -35, -27, 190, -713, 2315, 15579, -1182, 256, -34, -27, 184, -692, 2240, 15614, -1153, 250, -33, -26, 179, -670, 2165, 15648, -1123, 243, -32, -25, 173, -649, 2091, 15682, -1093, 236, -31, -24, 167, -627, 2016, 15715, -1062, 229, -30, -23, 162, -605, 1942, 15748, -1032, 222, -29, -22, 156, -584, 1868, 15780, -1000, 215, -28, -22, 150, -562, 1795, 15811, -969, 208, -27, -21, 145, -540, 1721, 15841, -936, 200, -26, -20, 139, -519, 1649, 15871, -904, 193, -25, -19, 133, -497, 1576, 15901, -871, 186, -24, -18, 127, -475, 1504, 15929, -838, 178, -23, -17, 122, -453, 1432, 15957, -804, 171, -22, -17, 116, -432, 1360, 15984, -770, 163, -21, -16, 110, -410, 1289, 16011, -735, 155, -20, -15, 104, -388, 1218, 16037, -700, 148, -19, -14, 99, -366, 1147, 16062, -664, 140, -18, -13, 93, -345, 1076, 16086, -629, 132, -17, -12, 87, -323, 1006, 16110, -592, 124, -16, -12, 81, -301, 937, 16133, -556, 116, -15, -11, 75, -279, 867, 16156, -519, 108, -14, -10, 69, -258, 798, 16177, -481, 100, -13, -9, 64, -236, 730, 16198, -443, 92, -12, -8, 58, -214, 662, 16219, -405, 84, -11, -7, 52, -193, 594, 16238, -366, 76, -10, -6, 46, -171, 526, 16257, -327, 68, -8, -6, 40, -150, 459, 16276, -288, 59, -7, -5, 34, -128, 392, 16293, -248, 51, -6, -4, 29, -106, 326, 16310, -207, 42, -5, -3, 23, -85, 260, 16326, -167, 34, -4, -2, 17, -64, 194, 16341, -125, 25, -3, -1, 11, -42, 129, 16356, -84, 17, -2, 0, 5, -21, 64, 16370, -42, 8, -1, 0, 0, 0, 0, 16384, 0, 0, 0, }; };