|
4 | 4 |
|
5 | 5 | #include "wavetable_generator.h" |
6 | 6 |
|
7 | | -double circ(double t, int k, int n, double) |
| 7 | +double circ(double t, int k, double) |
8 | 8 | { |
9 | | - return k & 1 ? 4 * j1(M_PI * (2*k - 1)) * sin(2*M_PI * k * t) / k * sigma(k, n) : 0; |
| 9 | + return k & 1 ? -4 * j1(M_PI * (2*k - 1)) / k * sin(2*M_PI * k * t) : 0; |
10 | 10 | } |
11 | 11 |
|
12 | | -double combo(double t, int k, int n, double num) |
| 12 | +double arc(double t, int k, double) |
13 | 13 | { |
14 | | - int m = 0, inum = (int)num; |
15 | | - for (int i = 0; i < inum && !m; ++i) |
| 14 | + return k ? 2 * j1(M_PI * k) / k * cos(2*M_PI * k * (t + 0.25)) : 0.5*M_PI - 1; |
| 15 | +} |
| 16 | + |
| 17 | +double combo(double t, int k, double n) |
| 18 | +{ |
| 19 | + if (!k) return 0; |
| 20 | + |
| 21 | + const int int_n = (int)n; |
| 22 | + int i = 0; |
| 23 | + for (int j = 0; j < int_n; ++j) |
16 | 24 | { |
17 | | - int j = 1 << i; |
18 | | - if ((k & (2*j - 1)) == j) m = j; |
| 25 | + i = 1 << j; |
| 26 | + if ((k & (2*i - 1)) == i) break; |
| 27 | + i = 0; |
19 | 28 | } |
20 | | - return m ? 4/(inum*M_PI) * sin(2*M_PI * k * t) / k * m * sigma(k, n) : 0; |
| 29 | + |
| 30 | + return i ? 4/(M_PI * int_n) * i / k * sin(2*M_PI * k * (t + 0.5)) : 0; |
21 | 31 | } |
22 | 32 |
|
23 | | -double full(double t, int k, int n, double) |
| 33 | +double full(double t, int k, double) |
24 | 34 | { |
25 | | - double dc = 4/M_PI - 1; |
26 | | - return dc/n - 8/M_PI * cos(2*M_PI * k * t) / (4 * k*k - 1) * sigma(k, n); |
| 35 | + return k ? 8/M_PI / (1 - 4*k*k) * cos(2*M_PI * k * (t + 0.75)) : 4/M_PI - 1; |
27 | 36 | } |
28 | 37 |
|
29 | | -double half(double t, int k, int n, double) |
| 38 | +double half(double t, int k, double pw = 0.5) |
30 | 39 | { |
31 | | - double dc = 2/M_PI - 1; |
32 | | - return dc/n + (k == 1 ? sin(2*M_PI * t) : k & 1 ? 0 : -4/M_PI * cos(2*M_PI * k * t) / (k*k - 1)) * sigma(k, n); |
| 40 | + return k ? (pw*k == 0.5 ? (k & 1 ? -1 : 1) / k : 2/M_PI * pw * cos(M_PI * (1 - pw) * k) / (0.25 - pw*pw * k*k)) * cos(2*M_PI * k * (t + 0.75)) : 4/M_PI * pw - 1; |
33 | 41 | } |
34 | 42 |
|
35 | | -double ham(double t, int k, int n, double num) |
| 43 | +double ham(double t, int k, double n = 3) |
36 | 44 | { |
37 | | - int inum = (int)num; |
38 | | - switch (inum) |
| 45 | + if (!k) return 0; |
| 46 | + |
| 47 | + const int int_n = (int)n; |
| 48 | + switch (int_n) |
39 | 49 | { |
40 | | - case 1: case 2: case 3: case 4: if (k > inum) return 0; break; |
41 | | - case 5: case 6: case 7: case 8: if (k > 4 && (k & 1 || k > 4 + 2 * (inum - 4))) return 0; break; |
42 | | - default: case 9: if (k > 4 && (k & 1 || k > 12) && k != 16) return 0; break; |
| 50 | + case 1: case 2: default: case 3: case 4: if (k > int_n) return 0; break; |
| 51 | + case 5: case 6: case 7: case 8: if (k > 4 && (k & 1 || k > 4 + 2 * (int(n) - 4))) return 0; break; |
| 52 | + case 9: if (k > 4 && (k & 1 || k > 12) && k != 16) return 0; break; |
43 | 53 | } |
44 | | - double a = 0; |
45 | | - switch (inum) |
| 54 | + |
| 55 | + double a; |
| 56 | + switch (int_n) |
46 | 57 | { |
47 | 58 | case 1: a = 1; break; |
48 | 59 | case 2: a = 0.568134086134179594473891938833; break; |
49 | | - case 3: a = /* 0.400084401888847696060480529923 */ 0.4; break; |
| 60 | + default: case 3: a = /* 0.400084401888847696060480529923 */ 0.4; break; |
50 | 61 | case 4: a = 0.309382307569317671624986587631; break; |
51 | 62 | case 5: a = 0.268382163704272314053156378577; break; |
52 | 63 | case 6: a = 0.236287471015808936414259733283; break; |
53 | 64 | case 7: a = 0.208586523765622755544058009036; break; |
54 | 65 | case 8: a = 0.18534593451986317025337314135; break; |
55 | | - default: case 9: a = 0.172410339992880773385408588183; break; |
| 66 | + case 9: a = 0.172410339992880773385408588183; break; |
56 | 67 | } |
57 | | - return a * sin(2*M_PI * k * t) * sigma(k, n); |
| 68 | + |
| 69 | + return a * sin(2*M_PI * k * (t + 0.5)); |
58 | 70 | } |
59 | 71 |
|
60 | | -double lpsqr(double t, int k, int n, double fc) |
| 72 | +double lpsqr(double t, int k, double fc) |
61 | 73 | { |
62 | | - double x = 1/fc * k; |
63 | | - double gain = 1/sqrt(1 + x*x); |
64 | | - double phase_shift = -atan(x); |
65 | | - return k & 1 ? 4/M_PI * gain * sin(2*M_PI * k * t + phase_shift) / k * sigma(k, n) : 0; |
| 74 | + return k & 1 ? 4/M_PI * (fc / (fc*fc + k*k) * cos(2*M_PI * k * t) - fc*fc / ((fc*fc + k*k) * k) * sin(2*M_PI * k * t)) : 0; |
66 | 75 | } |
67 | 76 |
|
68 | | -double rect(double t, int k, int n, double pw) |
| 77 | +double rect(double t, int k, double pw) |
69 | 78 | { |
70 | | - double dc = 2*pw - 1; |
71 | | - return dc/n + 4/M_PI * sin(M_PI * k * pw) * cos(2*M_PI * k * (t - 0.5*pw)) / k * sigma(k, n); |
| 79 | + return k ? 4/M_PI * sin(M_PI * pw * k) / k * cos(2*M_PI * k * (t + 0.5*(1 - pw))) : 2*pw - 1; |
72 | 80 | } |
73 | 81 |
|
74 | | -double saw(double t, int k, int n, double) |
| 82 | +double saw(double t, int k, double) |
75 | 83 | { |
76 | | - return -2/M_PI * sin(2*M_PI * k * t) / k * sigma(k, n); |
| 84 | + return k ? -2/M_PI / k * sin(2*M_PI * k * t) : 0; |
77 | 85 | } |
78 | 86 |
|
79 | | -double sine(double t, int k, int n, double) |
| 87 | +double sine(double t, int k, double) |
80 | 88 | { |
81 | | - return k == 1 ? sin(2*M_PI * k * t) : 0; |
| 89 | + return k == 1 ? -sin(2*M_PI * k * t) : 0; |
82 | 90 | } |
83 | 91 |
|
84 | | -double sqr(double t, int k, int n, double) |
| 92 | +double sqr(double t, int k, double) |
85 | 93 | { |
86 | | - return k & 1 ? 4/M_PI * sin(2*M_PI * k * t) / k * sigma(k, n) : 0; |
| 94 | + return k & 1 ? -4/M_PI / k * sin(2*M_PI * k * t) : 0; |
87 | 95 | } |
88 | 96 |
|
89 | | -double sqr2(double t, int k, int n, double pw) |
| 97 | +double sqr2(double t, int k, double pw) |
90 | 98 | { |
91 | | - return k & 1 ? 4/M_PI * cos(M_PI * k * (0.5 - pw)) * sin(2*M_PI * k * (t + 0.5*pw + 0.75)) / k * sigma(k, n) : 0; |
| 99 | + return k & 1 ? -4/M_PI * cos(0.5*M_PI * k * (1 - pw)) / k * sin(2*M_PI * k * t) : 0; |
92 | 100 | } |
93 | 101 |
|
94 | | -double stairs(double t, int k, int n, double pw) |
| 102 | +double stairs(double t, int k, double) |
95 | 103 | { |
96 | | - double dc = (4*pw - 1) / 3; |
97 | | - double s = k & 1 ? sin(2*M_PI * k * t) / k * sigma(k, n) : 0; |
98 | | - if (2*k <= n) s += 0.5 * sin(M_PI * k * 2*pw) * cos(2*M_PI * k * (2*t - pw)) / k * sigma(2*k, n); |
99 | | - return dc/n + (double)2/3 * 4/M_PI * s; |
| 104 | + return k & 3 ? 8/(3*M_PI) / k * sin(2*M_PI * k * (t + 0.5)) : 0; |
100 | 105 | } |
101 | 106 |
|
102 | | -double trap(double t, int k, int n, double pw) |
| 107 | +double trap(double t, int k, double pw = 0.5) |
103 | 108 | { |
104 | | - double s = k & 1 ? 0.25/(0.5 - pw) * 8/(M_PI*M_PI) * (sin(2*M_PI * k * (t - 0.5*pw)) + sin(2*M_PI * k * (t + 0.5*pw))) / (k*k) * sigma(k, n) : 0; |
105 | | - return k & 2 ? -s : s; |
| 109 | + return k & 1 ? (pw >= 1 ? -4/M_PI / k : -8/(M_PI*M_PI) * sin(0.5*M_PI * (1 - pw) * k) / ((1 - pw) * k*k)) * sin(2*M_PI * k * t) : 0; |
106 | 110 | } |
107 | 111 |
|
108 | | -double tri(double t, int k, int n, double) |
| 112 | +double tri(double t, int k, double) |
109 | 113 | { |
110 | | - double s = k & 1 ? 8/(M_PI*M_PI) * sin(2*M_PI * k * t) / (k*k) * sigma(k, n) : 0; |
111 | | - return k & 2 ? -s : s; |
| 114 | + return k & 1 ? 8/(M_PI*M_PI) / (k*k) * cos(2*M_PI * k * (t + 0.25)) : 0; |
112 | 115 | } |
113 | 116 |
|
114 | | -double tri2(double t, int k, int n, double pw) |
| 117 | +double tri2(double t, int k, double pw) |
115 | 118 | { |
116 | | - double m = 1/pw; |
117 | | - return -2*m*m / (M_PI*M_PI) * sin(M_PI * (1 - pw) * k) * sin(2*M_PI * k * (t + 0.5)) / ((m - 1) * k*k) * sigma(k, n); |
| 119 | + return k ? (pw <= 0 ? 2/M_PI / k : pw >= 1 ? -2/M_PI / k : -2/(M_PI*M_PI) * sin(M_PI * (1 - pw) * k) / (pw * (1 - pw) * k*k)) * sin(2*M_PI * k * (t + (pw <= 0 ? 0.5 : 0))) : 0; |
118 | 120 | } |
119 | 121 |
|
120 | | -double trip(double t, int k, int n, double pw) |
| 122 | +double trip(double t, int k, double pw = 0.5) |
121 | 123 | { |
122 | | - double dc = pw - 1; |
123 | | - double m = 1/(1 - 0.5*pw); |
124 | | - double x = sin(0.5*M_PI * k * pw); |
125 | | - return dc/n + (1 - 0.5*pw) * 4*m*m / (M_PI*M_PI) * x*x * cos(2*M_PI * k * (t - 0.5*pw)) / ((m - 1) * k*k) * sigma(k, n); |
| 124 | + if (!k) return pw - 1; |
| 125 | + if (pw <= 0) return 0; |
| 126 | + |
| 127 | + const double x = sin(0.5*M_PI * pw * k); |
| 128 | + return 8/(M_PI*M_PI) * x*x / (pw * k*k) * cos(2*M_PI * k * (t + 0.25)); |
126 | 129 | } |
127 | 130 |
|
128 | 131 | int main() |
129 | 132 | { |
130 | 133 | bool ok = true; |
131 | 134 |
|
132 | 135 | ok &= gen_wavetbl("Circle.wav", circ); |
| 136 | + ok &= gen_wavetbl("Cycloid.wav", arc); |
133 | 137 | ok &= gen_wavetbl("Combo Organ.wav", combo, 3); |
134 | 138 | ok &= gen_wavetbl("Filtered Square.wav", lpsqr, M_SQRT2); |
135 | 139 | ok &= gen_wavetbl("Full Organ.wav", ham, 9); |
136 | | - ok &= gen_wavetbl("Full-Wave Rectified Sine.wav", full); |
137 | | - ok &= gen_wavetbl("Half-Wave Rectified Sine.wav", half); |
| 140 | + ok &= gen_wavetbl("Full-Wave Rectified Sine.wav", full, 1, 0.75); |
| 141 | + ok &= gen_wavetbl("Half-Wave Rectified Sine.wav", half, 0.5); |
138 | 142 | ok &= gen_wavetbl("Hammond.wav", ham, 3); |
139 | | - ok &= gen_wavetbl("Modified Square.wav", sqr2, 0.25); |
| 143 | + ok &= gen_wavetbl("Modified Square.wav", sqr2, 0.4, 0.85); |
140 | 144 | ok &= gen_wavetbl("Modified Triangle.wav", tri2, 0.3); |
141 | 145 | ok &= gen_wavetbl("Narrow Pulse.wav", rect, 0.1); |
142 | 146 | ok &= gen_wavetbl("Pulse.wav", rect, 0.3); |
143 | | - ok &= gen_wavetbl("Sawtooth.wav", saw); |
144 | | - ok &= gen_wavetbl("Sine.wav", sine); |
| 147 | + ok &= gen_wavetbl("Sawtooth.wav", saw, 1, 0.5); |
| 148 | + ok &= gen_wavetbl("Sine.wav", sine, 0, 0, false); |
145 | 149 | ok &= gen_wavetbl("Square.wav", sqr); |
146 | | - ok &= gen_wavetbl("Staircase.wav", stairs, 0.25); |
147 | | - ok &= gen_wavetbl("Trapezoid.wav", trap, (double)1/3); |
| 150 | + ok &= gen_wavetbl("Staircase.wav", stairs); |
| 151 | + ok &= gen_wavetbl("Trapezoid.wav", trap, (double)2/3); |
148 | 152 | ok &= gen_wavetbl("Triangle.wav", tri); |
149 | 153 | ok &= gen_wavetbl("Triangular Pulse.wav", trip, 0.5); |
150 | 154 |
|
|
0 commit comments