Browse code

[NCSF] Interpolation changes:

* Removed Cosine, 4-Point B-Spline, 6-Point B-Spline, and 6-point
Osculating.
* Added 4-Point Legrange and 6-Point Legrange.
* Changed wording of the Sinc interpolation to mention that it is
16-point.

Naram Qashat authored on 2014/09/28 00:07:18
Showing 4 changed files
... ...
@@ -43,7 +43,6 @@ TempSndReg::TempSndReg() : CR(0), SOURCE(nullptr), TIMER(0), REPEAT_POINT(0), LE
43 43
 }
44 44
 
45 45
 bool Channel::initializedLUTs = false;
46
-double Channel::cosine_lut[Channel::COSINE_RESOLUTION];
47 46
 double Channel::sinc_lut[Channel::SINC_SAMPLES + 1];
48 47
 
49 48
 #ifndef M_PI
... ...
@@ -62,8 +61,6 @@ Channel::Channel() : chnId(-1), tempReg(), state(CS_NONE), trackId(-1), prio(0),
62 61
 {
63 62
 	if (!this->initializedLUTs)
64 63
 	{
65
-		for (unsigned i = 0; i < COSINE_RESOLUTION; ++i)
66
-			this->cosine_lut[i] = (1.0 - std::cos((static_cast<double>(i) / COSINE_RESOLUTION) * M_PI)) * 0.5;
67 64
 		double dx = static_cast<double>(SINC_WIDTH) / SINC_SAMPLES, x = 0.0;
68 65
 		for (unsigned i = 0; i <= SINC_SAMPLES; ++i, x += dx)
69 66
 			this->sinc_lut[i] = std::abs(x) < SINC_WIDTH ? sinc(x) * sinc(x / SINC_WIDTH) : 0.0;
... ...
@@ -621,52 +618,33 @@ int32_t Channel::Interpolate()
621 618
 			sum += data[i - static_cast<int>(SINC_WIDTH) + 1] * kernel[i];
622 619
 		return static_cast<int32_t>(sum / kernel_sum);
623 620
 	}
624
-	else if (this->ply->interpolation > INTERPOLATION_COSINE)
621
+	else if (this->ply->interpolation > INTERPOLATION_LINEAR)
625 622
 	{
626 623
 		double c0, c1, c2, c3, c4, c5;
627 624
 
628
-		if (this->ply->interpolation > INTERPOLATION_4POINTBSPLINE)
625
+		if (this->ply->interpolation == INTERPOLATION_6POINTLEGRANGE)
629 626
 		{
630
-			if (this->ply->interpolation == INTERPOLATION_6POINTBSPLINE)
631
-			{
632
-				double ym2py2 = data[-2] + data[2], ym1py1 = data[-1] + data[1];
633
-				double y2mym2 = data[2] - data[-2], y1mym1 = data[1] - data[-1];
634
-				double sixthym1py1 = 1 / 6.0 * ym1py1;
635
-				c0 = 1 / 120.0 * ym2py2 + 13 / 60.0 * ym1py1 + 0.55 * data[0];
636
-				c1 = 1 / 24.0 * y2mym2 + 5 / 12.0 * y1mym1;
637
-				c2 = 1 / 12.0 * ym2py2 + sixthym1py1 - 0.5 * data[0];
638
-				c3 = 1 / 12.0 * y2mym2 - 1 / 6.0 * y1mym1;
639
-				c4 = 1 / 24.0 * ym2py2 - sixthym1py1 + 0.25 * data[0];
640
-				c5 = 1 / 120.0 * (data[3] - data[-2]) + 1 / 24.0 * (data[-1] - data[2]) + 1 / 12.0 * (data[1] - data[0]);
641
-				return static_cast<int32_t>(((((c5 * ratio + c4) * ratio + c3) * ratio + c2) * ratio + c1) * ratio + c0);
642
-			}
643
-			else // INTERPOLATION_6POINTOSCULATING
644
-			{
645
-				ratio -= 0.5;
646
-				double even1 = data[-2] + data[3], odd1 = data[-2] - data[3];
647
-				double even2 = data[-1] + data[2], odd2 = data[-1] - data[2];
648
-				double even3 = data[0] + data[1], odd3 = data[0] - data[1];
649
-				c0 = 0.01171875 * even1 - 0.09765625 * even2 + 0.5859375 * even3;
650
-				c1 = 0.2109375 * odd2 - 281 / 192.0 * odd3 - 13 / 384.0 * odd1;
651
-				c2 = 0.40625 * even2 - 17 / 48.0 * even3 - 5 / 96.0 * even1;
652
-				c3 = 0.1875 * odd1 - 53 / 48.0 * odd2 + 2.375 * odd3;
653
-				c4 = 1 / 48.0 * even1 - 0.0625 * even2 + 1 / 24.0 * even3;
654
-				c5 = 25 / 24.0 * odd2 - 25 / 12.0 * odd3 - 5 / 24.0 * odd1;
655
-				return static_cast<int32_t>(((((c5 * ratio + c4) * ratio + c3) * ratio + c2) * ratio + c1) * ratio + c0);
656
-			}
627
+			ratio -= 0.5;
628
+			double even1 = data[-2] + data[3], odd1 = data[-2] - data[3];
629
+			double even2 = data[-1] + data[2], odd2 = data[-1] - data[2];
630
+			double even3 = data[0] + data[1], odd3 = data[0] - data[1];
631
+			c0 = 0.01171875 * even1 - 0.09765625 * even2 + 0.5859375 * even3;
632
+			c1 = 25 / 384.0 * odd2 - 1.171875 * odd3 - 0.0046875 * odd1;
633
+			c2 = 0.40625 * even2 - 17 / 48.0 * even3 - 5 / 96.0 * even1;
634
+			c3 = 1 / 48.0 * odd1 - 13 / 48.0 * odd2 + 17 / 24.0 * odd3;
635
+			c4 = 1 / 48.0 * even1 - 0.0625 * even2 + 1 / 24.0 * even3;
636
+			c5 = 1 / 24.0 * odd2 - 1 / 12.0 * odd3 - 1 / 120.0 * odd1;
637
+			return static_cast<int32_t>(((((c5 * ratio + c4) * ratio + c3) * ratio + c2) * ratio + c1) * ratio + c0);
657 638
 		}
658
-		else // INTERPOLATION_4POINTBSPLINE
639
+		else // INTERPOLATION_4POINTLEAGRANGE
659 640
 		{
660
-			double ym1py1 = data[-1] + data[1];
661
-			c0 = 1 / 6.0 * ym1py1 + 2 / 3.0 * data[0];
662
-			c1 = 0.5 * (data[1] - data[-1]);
663
-			c2 = 0.5 * ym1py1 - data[0];
664
-			c3 = 0.5 * (data[0] - data[1]) + 1 / 6.0 * (data[2] - data[-1]);
641
+			c0 = data[0];
642
+			c1 = data[1] - 1 / 3.0 * data[-1] - 0.5 * data[0] - 1 / 6.0 * data[2];
643
+			c2 = 0.5 * (data[-1] + data[1]) - data[0];
644
+			c3 = 1 / 6.0 * (data[2] - data[-1]) + 0.5 * (data[0] - data[1]);
665 645
 			return static_cast<int32_t>(((c3 * ratio + c2) * ratio + c1) * ratio + c0);
666 646
 		}
667 647
 	}
668
-	else if (this->ply->interpolation == INTERPOLATION_COSINE)
669
-		return static_cast<int32_t>(data[0] + this->cosine_lut[static_cast<unsigned>(ratio * COSINE_RESOLUTION)] * (data[1] - data[0]));
670 648
 	else // INTERPOLATION_LINEAR
671 649
 		return static_cast<int32_t>(data[0] + ratio * (data[1] - data[0]));
672 650
 }
... ...
@@ -216,11 +216,9 @@ struct Channel
216 216
 	 * of the program.
217 217
 	 */
218 218
 	static bool initializedLUTs;
219
-	static const unsigned COSINE_RESOLUTION = 8192;
220 219
 	static const unsigned SINC_RESOLUTION = 8192;
221 220
 	static const unsigned SINC_WIDTH = 8;
222 221
 	static const unsigned SINC_SAMPLES = SINC_RESOLUTION * SINC_WIDTH;
223
-	static double cosine_lut[COSINE_RESOLUTION];
224 222
 	static double sinc_lut[SINC_SAMPLES + 1];
225 223
 
226 224
 	RingBuffer<SINC_WIDTH * 2> ringBuffer;
... ...
@@ -54,9 +54,7 @@ enum Interpolation
54 54
 {
55 55
 	INTERPOLATION_NONE,
56 56
 	INTERPOLATION_LINEAR,
57
-	INTERPOLATION_COSINE,
58
-	INTERPOLATION_4POINTBSPLINE,
59
-	INTERPOLATION_6POINTOSCULATING,
60
-	INTERPOLATION_6POINTBSPLINE,
57
+	INTERPOLATION_4POINTLEGRANGE,
58
+	INTERPOLATION_6POINTLEGRANGE,
61 59
 	INTERPOLATION_SINC
62 60
 };
... ...
@@ -42,7 +42,7 @@ public:
42 42
 unsigned XSFConfig::initSampleRate = 44100;
43 43
 std::string XSFConfig::commonName = "NCSF Decoder";
44 44
 std::string XSFConfig::versionNumber = "1.8.1";
45
-unsigned XSFConfig_NCSF::initInterpolation = 5;
45
+unsigned XSFConfig_NCSF::initInterpolation = 4;
46 46
 std::string XSFConfig_NCSF::initMutes = "0000000000000000";
47 47
 
48 48
 XSFConfig *XSFConfig::Create()
... ...
@@ -96,11 +96,9 @@ INT_PTR CALLBACK XSFConfig_NCSF::ConfigDialogProc(HWND hwndDlg, UINT uMsg, WPARA
96 96
 			// Interpolation
97 97
 			SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"None"));
98 98
 			SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"Linear"));
99
-			SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"Cosine"));
100
-			SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"4-point, 3rd-order B-spline"));
101
-			SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"6-point, 5th-order Osculating"));
102
-			SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"6-point, 5th-order B-spline"));
103
-			SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"Sinc (Lanczos Window)"));
99
+			SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"4-point, 3rd-order Legrange"));
100
+			SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"6-point, 5th-order Legrange"));
101
+			SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(L"16-point Sinc (Lanczos Window)"));
104 102
 			SendMessageW(GetDlgItem(hwndDlg, idInterpolation), CB_SETCURSEL, this->interpolation, 0);
105 103
 			// Mutes
106 104
 			for (int x = 0, numMutes = this->mutes.size(); x < numMutes; ++x)