Skip to content

Commit

Permalink
SNES: Added sinc audio interpolation option
Browse files Browse the repository at this point in the history
  • Loading branch information
SourMesen committed Dec 27, 2024
1 parent 636e645 commit 21f1f62
Show file tree
Hide file tree
Showing 5 changed files with 310 additions and 1 deletion.
307 changes: 306 additions & 1 deletion Core/SNES/DSP/DspInterpolation.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,309 @@ class DspInterpolation

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 = np.arange(10)
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,
};
};
1 change: 1 addition & 0 deletions Core/SNES/DSP/DspVoice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ void DspVoice::Step3c()
switch(_cfg->InterpolationType) {
case DspInterpolationType::Gauss: output = DspInterpolation::Gauss(_interpolationPos, _sampleBuffer, _bufferPos); break;
case DspInterpolationType::Cubic: output = DspInterpolation::Cubic(_interpolationPos, _sampleBuffer, _bufferPos); break;
case DspInterpolationType::Sinc: output = DspInterpolation::Sinc(_interpolationPos, _sampleBuffer, _bufferPos); break;
case DspInterpolationType::None: output = _sampleBuffer[((_interpolationPos >> 12) + _bufferPos) % 12]; break;
}

Expand Down
1 change: 1 addition & 0 deletions Core/Shared/SettingTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ enum class DspInterpolationType
{
Gauss,
Cubic,
Sinc,
None
};

Expand Down
1 change: 1 addition & 0 deletions UI/Config/SnesConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ public enum DspInterpolationType
{
Gauss,
Cubic,
Sinc,
None
}
}
1 change: 1 addition & 0 deletions UI/Localization/resources.en.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2078,6 +2078,7 @@ E
<Enum ID="DspInterpolationType">
<Value ID="Gauss">Gauss (default, accurate)</Value>
<Value ID="Cubic">Cubic</Value>
<Value ID="Sinc">Sinc</Value>
<Value ID="None">None</Value>
</Enum>
<Enum ID="SnesSuperScopeButtons">
Expand Down

0 comments on commit 21f1f62

Please sign in to comment.