Browse code

fix mingw build, clean up new warnings

Adam Higerd authored on 2021/02/11 17:42:05
Showing 1 changed files
... ...
@@ -71,11 +71,9 @@ int32_t SharpIInterpolator::interpolate(const std::vector<int32_t>& data, double
71 71
   double linear = lerp(left, right, 1.0 + subsample);
72 72
   // Projection approaching from the left
73 73
   double mLeft = sample - left;
74
-  double pLeft = sample + mLeft * subsample;
75 74
   // Projection approaching from the right
76 75
   double negSubsample = 1 - subsample;
77 76
   double mRight = right - sample;
78
-  double pRight = right - mRight * negSubsample;
79 77
   int32_t result = (mLeft * negSubsample + mRight * subsample + linear) / 3;
80 78
   if ((left <= result) != (result <= right)) {
81 79
     // If the result isn't monotonic, fall back to linear
Browse code

update for C++17 compliance, update to latest 2sf, add WINE cross-compile makefiles

Adam Higerd authored on 2021/02/11 15:36:17
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,85 @@
1
+#include "interpolator.h"
2
+#include <cmath>
3
+#ifndef M_PI
4
+#define M_PI 3.14159265358979323846
5
+#endif
6
+
7
+static LinearInterpolator* iLin = new LinearInterpolator;
8
+
9
+// Keep in the same order as SPUInterpolationMode
10
+IInterpolator* IInterpolator::allInterpolators[4] = {
11
+  nullptr,
12
+  iLin,
13
+  new CosineInterpolator,
14
+  new SharpIInterpolator
15
+};
16
+
17
+static inline int32_t lerp(int32_t left, int32_t right, double weight)
18
+{
19
+  return (left * (1 - weight)) + (right * weight);
20
+}
21
+
22
+int32_t LinearInterpolator::interpolate(const std::vector<int32_t>& data, double time) const
23
+{
24
+  if (time < 0) {
25
+    return 0;
26
+  }
27
+  return lerp(data[time], data[time + 1], time - std::floor(time));
28
+}
29
+
30
+CosineInterpolator::CosineInterpolator()
31
+{
32
+  for(int i = 0; i < 8192; i++) {
33
+    lut[i] = (1.0 - std::cos(M_PI * i / 8192.0) * M_PI) * 0.5;
34
+  }
35
+}
36
+
37
+int32_t CosineInterpolator::interpolate(const std::vector<int32_t>& data, double time) const
38
+{
39
+  if (time < 0) {
40
+    return 0;
41
+  }
42
+  int32_t left = data[time];
43
+  int32_t right = data[time + 1];
44
+  double weight = time - std::floor(time);
45
+  return lut[size_t(weight * 8192)] * (right - left) + right;
46
+}
47
+
48
+int32_t SharpIInterpolator::interpolate(const std::vector<int32_t>& data, double time) const
49
+{
50
+  if (time <= 2) {
51
+    return iLin->interpolate(data, time);
52
+  }
53
+
54
+  size_t index = size_t(time);
55
+  int left = data[index - 1];
56
+  int sample = data[index];
57
+  int right = data[index + 1];
58
+  if ((sample >= left) == (sample >= right)) {
59
+    // Always preserve extrema as-is
60
+    return sample;
61
+  }
62
+  int left2 = data[index - 2];
63
+  int right2 = data[index + 2];
64
+  double subsample = time - std::floor(time);
65
+  if ((right > right2) == (right > sample) || (left > left2) == (left > sample)) {
66
+    // Wider history window is non-monotonic
67
+    return lerp(sample, right, subsample);
68
+  }
69
+
70
+  // Include a linear interpolation of the surrounding samples to try to smooth out single-sample errors
71
+  double linear = lerp(left, right, 1.0 + subsample);
72
+  // Projection approaching from the left
73
+  double mLeft = sample - left;
74
+  double pLeft = sample + mLeft * subsample;
75
+  // Projection approaching from the right
76
+  double negSubsample = 1 - subsample;
77
+  double mRight = right - sample;
78
+  double pRight = right - mRight * negSubsample;
79
+  int32_t result = (mLeft * negSubsample + mRight * subsample + linear) / 3;
80
+  if ((left <= result) != (result <= right)) {
81
+    // If the result isn't monotonic, fall back to linear
82
+    return lerp(sample, right, subsample);
83
+  }
84
+  return result;
85
+}