* 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.
| ... | ... |
@@ -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) |