diff --git a/Frameworks/HivelyPlayer/HivelyPlayer/blip_buf.c b/Frameworks/HivelyPlayer/HivelyPlayer/blip_buf.c index 70f1afb0a..ffa9582f5 100644 --- a/Frameworks/HivelyPlayer/HivelyPlayer/blip_buf.c +++ b/Frameworks/HivelyPlayer/HivelyPlayer/blip_buf.c @@ -238,42 +238,41 @@ int hvl_blip_read_samples( hvl_blip_t* m, int out [], int count, int gain ) restrict */ -/* Sinc_Generator( 0.9, 0.55, 4.5 ) */ -static short const bl_step [phase_count + 1] [half_width] = +static int const bl_step [phase_count + 1] [half_width] = { -{ 43, -115, 350, -488, 1136, -914, 5861,21022}, -{ 44, -118, 348, -473, 1076, -799, 5274,21001}, -{ 45, -121, 344, -454, 1011, -677, 4706,20936}, -{ 46, -122, 336, -431, 942, -549, 4156,20829}, -{ 47, -123, 327, -404, 868, -418, 3629,20679}, -{ 47, -122, 316, -375, 792, -285, 3124,20488}, -{ 47, -120, 303, -344, 714, -151, 2644,20256}, -{ 46, -117, 289, -310, 634, -17, 2188,19985}, -{ 46, -114, 273, -275, 553, 117, 1758,19675}, -{ 44, -108, 255, -237, 471, 247, 1356,19327}, -{ 43, -103, 237, -199, 390, 373, 981,18944}, -{ 42, -98, 218, -160, 310, 495, 633,18527}, -{ 40, -91, 198, -121, 231, 611, 314,18078}, -{ 38, -84, 178, -81, 153, 722, 22,17599}, -{ 36, -76, 157, -43, 80, 824, -241,17092}, -{ 34, -68, 135, -3, 8, 919, -476,16558}, -{ 32, -61, 115, 34, -60, 1006, -683,16001}, -{ 29, -52, 94, 70, -123, 1083, -862,15422}, -{ 27, -44, 73, 106, -184, 1152,-1015,14824}, -{ 25, -36, 53, 139, -239, 1211,-1142,14210}, -{ 22, -27, 34, 170, -290, 1261,-1244,13582}, -{ 20, -20, 16, 199, -335, 1301,-1322,12942}, -{ 18, -12, -3, 226, -375, 1331,-1376,12293}, -{ 15, -4, -19, 250, -410, 1351,-1408,11638}, -{ 13, 3, -35, 272, -439, 1361,-1419,10979}, -{ 11, 9, -49, 292, -464, 1362,-1410,10319}, -{ 9, 16, -63, 309, -483, 1354,-1383, 9660}, -{ 7, 22, -75, 322, -496, 1337,-1339, 9005}, -{ 6, 26, -85, 333, -504, 1312,-1280, 8355}, -{ 4, 31, -94, 341, -507, 1278,-1205, 7713}, -{ 3, 35, -102, 347, -506, 1238,-1119, 7082}, -{ 1, 40, -110, 350, -499, 1190,-1021, 6464}, -{ 0, 43, -115, 350, -488, 1136, -914, 5861} +{ 0, 0, 0, 0, 0, 0, 0,32768}, +{ -1, 9, -30, 79, -178, 380, -923,32713}, +{ -2, 17, -58, 153, -346, 739,-1775,32549}, +{ -3, 24, -83, 221, -503, 1073,-2555,32277}, +{ -4, 30, -107, 284, -647, 1382,-3259,31898}, +{ -5, 36, -127, 340, -778, 1662,-3887,31415}, +{ -5, 40, -145, 390, -895, 1913,-4439,30832}, +{ -6, 44, -160, 433, -998, 2133,-4914,30151}, +{ -6, 47, -172, 469,-1085, 2322,-5313,29377}, +{ -6, 49, -181, 499,-1158, 2479,-5636,28515}, +{ -6, 50, -188, 521,-1215, 2604,-5885,27570}, +{ -5, 51, -193, 537,-1257, 2697,-6063,26548}, +{ -5, 51, -195, 547,-1285, 2760,-6172,25455}, +{ -5, 50, -195, 550,-1298, 2792,-6214,24298}, +{ -4, 49, -192, 548,-1298, 2795,-6193,23084}, +{ -4, 47, -188, 540,-1284, 2770,-6112,21820}, +{ -3, 45, -182, 526,-1258, 2719,-5976,20513}, +{ -3, 42, -175, 508,-1221, 2643,-5788,19172}, +{ -2, 39, -166, 486,-1173, 2544,-5554,17805}, +{ -2, 36, -156, 460,-1116, 2425,-5277,16418}, +{ -1, 33, -145, 431,-1050, 2287,-4963,15020}, +{ -1, 30, -133, 399, -977, 2132,-4615,13618}, +{ -1, 26, -120, 365, -898, 1963,-4240,12221}, +{ 0, 23, -107, 329, -813, 1783,-3843,10836}, +{ 0, 20, -94, 292, -725, 1593,-3427, 9470}, +{ 0, 17, -81, 254, -633, 1396,-2998, 8131}, +{ 0, 14, -68, 215, -540, 1194,-2560, 6824}, +{ 0, 11, -56, 177, -446, 989,-2119, 5556}, +{ 0, 8, -43, 139, -353, 784,-1678, 4334}, +{ 0, 6, -31, 102, -260, 581,-1242, 3162}, +{ 0, 3, -20, 66, -170, 381, -814, 2046}, +{ 0, 1, -9, 32, -83, 187, -399, 991}, +{ 0, 0, 0, 0, 0, 0, 0, 0} }; /* Shifting by pre_shift allows calculation using unsigned int rather than @@ -288,8 +287,8 @@ void hvl_blip_add_delta( hvl_blip_t* m, unsigned time, int delta ) int const phase_shift = frac_bits - phase_bits; int phase = fixed >> phase_shift & (phase_count - 1); - short const* in = bl_step [phase]; - short const* rev = bl_step [phase_count - phase]; + int const* in = bl_step [phase]; + int const* rev = bl_step [phase_count - phase]; int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1); int delta2 = (delta * interp) >> delta_bits; diff --git a/Frameworks/HivelyPlayer/HivelyPlayer/sinc_generator.c b/Frameworks/HivelyPlayer/HivelyPlayer/sinc_generator.c new file mode 100644 index 000000000..32aaf0c38 --- /dev/null +++ b/Frameworks/HivelyPlayer/HivelyPlayer/sinc_generator.c @@ -0,0 +1,88 @@ +#include +#include +#define _USE_MATH_DEFINES +#include + +#ifndef M_PI +#define M_PI 3.141592653589793 +#endif + +enum { half_width = 8 }; +enum { phase_bits = 5 }; +enum { phase_count = 1 << phase_bits }; +enum { sinc_samples = phase_count * half_width }; + +static float sinc_lut[sinc_samples + 1]; +static float window_lut[sinc_samples + 1]; +static int bl_step[phase_count + 1] [half_width]; + +static int fEqual(const float b, const float a) +{ + return fabs(a - b) < 1.0e-6; +} + +static float sinc(float x) +{ + return fEqual(x, 0.0) ? 1.0 : sin(x * M_PI) / (x * M_PI); +} + +int main(void) +{ + unsigned i; + int k; + double dx = (float)(half_width) / sinc_samples, x = 0.0; + for (i = 0; i < sinc_samples + 1; ++i, x += dx) + { + float y = x / half_width; +#if 0 + // Blackman + float window = 0.42659 - 0.49656 * cos(M_PI + M_PI * y) + 0.076849 * cos(2.0 * M_PI * y); +#elif 1 + // Nuttal 3 term + float window = 0.40897 + 0.5 * cos(M_PI * y) + 0.09103 * cos(2.0 * M_PI * y); +#elif 0 + // C.R.Helmrich's 2 term window + float window = 0.79445 * cos(0.5 * M_PI * y) + 0.20555 * cos(1.5 * M_PI * y); +#elif 0 + // Lanczos + float window = sinc(y); +#endif + sinc_lut[i] = fabs(x) < half_width ? sinc(x) : 0.0; + window_lut[i] = window; + } + + for (i = 0; i <= phase_count / 2; ++i) + { + float kernel_sum = 0; + float kernel[half_width * 2]; + for (k = half_width; k >= -half_width + 1; --k) + { + int pos = k * phase_count; + int abs_pos = abs(i - pos); + kernel_sum += kernel[k + half_width - 1] = sinc_lut[abs_pos] * window_lut[abs_pos]; + } + kernel_sum = (1.0 / kernel_sum) * 32768.0; + for (k = 0; k < half_width; ++k) + bl_step[i][k] = (int)(kernel[k] * kernel_sum); + for (k = 0; k < half_width; ++k) + bl_step[phase_count - i][half_width - k - 1] = (int)(kernel[half_width + k] * kernel_sum); + } + + printf( "static int const bl_step [phase_count + 1] [half_width] =\n{\n" ); + + for (i = 0; i <= phase_count; ++i) + { + printf("{"); + for (k = 0; k < half_width; ++k) + { + printf("%5d", bl_step[i][k]); + if (k < half_width - 1) printf(","); + } + printf("}"); if (i < phase_count) printf(","); + printf("\n"); + } + + printf( "};\n" ); + + return 0; +}