Skip to content

Commit 673d86c

Browse files
committed
v20151101
1 parent 382a53c commit 673d86c

20 files changed

+215
-169
lines changed

Changelog.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
Tale's JSFX Pack
22

3+
v20151101 (1 November 2015)
4+
5+
+ wavetable_synth: Added cycloid wavetable.
6+
+ wavetable_synth: Adjusted modified square wavetable pulse width.
7+
+ Added icon to Windows installer.
8+
+ Fixed compatibility warning after closing installer on Windows 10.
9+
+ four: Added naive Fourier series summation.
10+
+ Minor library documentation improvements.
11+
312
v20151025 (25 October 2015)
413

514
+ poly: Optimised half-wave rectified sine, triangular pulse, trapezoid.
@@ -99,7 +108,7 @@ v20150322 (22 March 2015)
99108
+ rc_filter: Added a multimode RC filter effect.
100109
+ malloc: Added dynamic memory management library (malloc.jsfx-inc).
101110
+ wavetable_synth: Added velocity control, phase lock.
102-
+ wavetable_synth: Added Combo Organ, Full Organ wavetables.
111+
+ wavetable_synth: Added combo organ, full organ wavetables.
103112
+ colored_noise/mono_synth/wavetable_synth: Nitpicked gain calculation.
104113
+ rbj: Removed Direct Form I/II instance variables.
105114
+ zdf: Nitpicked gain over Q in documentation.

Data/Tale/wavetables/Cycloid.flac

1.81 KB
Binary file not shown.
-191 Bytes
Binary file not shown.

Data/Tale/wavetables/Source/wavetable_generator.cpp

Lines changed: 71 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4,147 +4,151 @@
44

55
#include "wavetable_generator.h"
66

7-
double circ(double t, int k, int n, double)
7+
double circ(double t, int k, double)
88
{
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;
1010
}
1111

12-
double combo(double t, int k, int n, double num)
12+
double arc(double t, int k, double)
1313
{
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)
1624
{
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;
1928
}
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;
2131
}
2232

23-
double full(double t, int k, int n, double)
33+
double full(double t, int k, double)
2434
{
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;
2736
}
2837

29-
double half(double t, int k, int n, double)
38+
double half(double t, int k, double pw = 0.5)
3039
{
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;
3341
}
3442

35-
double ham(double t, int k, int n, double num)
43+
double ham(double t, int k, double n = 3)
3644
{
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)
3949
{
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;
4353
}
44-
double a = 0;
45-
switch (inum)
54+
55+
double a;
56+
switch (int_n)
4657
{
4758
case 1: a = 1; break;
4859
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;
5061
case 4: a = 0.309382307569317671624986587631; break;
5162
case 5: a = 0.268382163704272314053156378577; break;
5263
case 6: a = 0.236287471015808936414259733283; break;
5364
case 7: a = 0.208586523765622755544058009036; break;
5465
case 8: a = 0.18534593451986317025337314135; break;
55-
default: case 9: a = 0.172410339992880773385408588183; break;
66+
case 9: a = 0.172410339992880773385408588183; break;
5667
}
57-
return a * sin(2*M_PI * k * t) * sigma(k, n);
68+
69+
return a * sin(2*M_PI * k * (t + 0.5));
5870
}
5971

60-
double lpsqr(double t, int k, int n, double fc)
72+
double lpsqr(double t, int k, double fc)
6173
{
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;
6675
}
6776

68-
double rect(double t, int k, int n, double pw)
77+
double rect(double t, int k, double pw)
6978
{
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;
7280
}
7381

74-
double saw(double t, int k, int n, double)
82+
double saw(double t, int k, double)
7583
{
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;
7785
}
7886

79-
double sine(double t, int k, int n, double)
87+
double sine(double t, int k, double)
8088
{
81-
return k == 1 ? sin(2*M_PI * k * t) : 0;
89+
return k == 1 ? -sin(2*M_PI * k * t) : 0;
8290
}
8391

84-
double sqr(double t, int k, int n, double)
92+
double sqr(double t, int k, double)
8593
{
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;
8795
}
8896

89-
double sqr2(double t, int k, int n, double pw)
97+
double sqr2(double t, int k, double pw)
9098
{
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;
92100
}
93101

94-
double stairs(double t, int k, int n, double pw)
102+
double stairs(double t, int k, double)
95103
{
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;
100105
}
101106

102-
double trap(double t, int k, int n, double pw)
107+
double trap(double t, int k, double pw = 0.5)
103108
{
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;
106110
}
107111

108-
double tri(double t, int k, int n, double)
112+
double tri(double t, int k, double)
109113
{
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;
112115
}
113116

114-
double tri2(double t, int k, int n, double pw)
117+
double tri2(double t, int k, double pw)
115118
{
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;
118120
}
119121

120-
double trip(double t, int k, int n, double pw)
122+
double trip(double t, int k, double pw = 0.5)
121123
{
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));
126129
}
127130

128131
int main()
129132
{
130133
bool ok = true;
131134

132135
ok &= gen_wavetbl("Circle.wav", circ);
136+
ok &= gen_wavetbl("Cycloid.wav", arc);
133137
ok &= gen_wavetbl("Combo Organ.wav", combo, 3);
134138
ok &= gen_wavetbl("Filtered Square.wav", lpsqr, M_SQRT2);
135139
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);
138142
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);
140144
ok &= gen_wavetbl("Modified Triangle.wav", tri2, 0.3);
141145
ok &= gen_wavetbl("Narrow Pulse.wav", rect, 0.1);
142146
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);
145149
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);
148152
ok &= gen_wavetbl("Triangle.wav", tri);
149153
ok &= gen_wavetbl("Triangular Pulse.wav", trip, 0.5);
150154

Data/Tale/wavetables/Source/wavetable_generator.h

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,32 @@
3030

3131
#include "WDL/wavwrite.h"
3232

33-
static double sigma(int k, int n)
34-
{
35-
double x = M_PI * k / (n + 1);
36-
return sin(x) / x;
37-
}
38-
39-
static bool gen_wavetbl(const char* filename, int bps, double (*fourier_series)(double, int, int, double), double param)
33+
static bool gen_wavetbl(const char* filename, int bps, double (*fourier_series)(double, int, double), double param = 0, double phase = 0, bool sigma = true)
4034
{
4135
static const int num_wavetbls = 8, wavetbl_len = 4 << (num_wavetbls - 1), wavetbl_size = num_wavetbls * wavetbl_len;
4236
double wavetbl[wavetbl_size];
4337

4438
double* tbl = wavetbl;
4539
for (int i = 0; i < num_wavetbls; ++i)
4640
{
47-
int n = 1 << i;
41+
const int m = (1 << i) + 1;
4842

4943
for (int j = 0; j < wavetbl_len; ++j)
5044
{
51-
double t = (double)j / wavetbl_len;
45+
double t = (double)j / wavetbl_len + 0.5 + phase;
46+
t -= (int)t;
5247

53-
double sum = 0;
54-
for (int k = 1; k <= n; ++k)
48+
const double dc = fourier_series(t, 0, param);
49+
double sum = dc;
50+
for (int k = 1; k < m; ++k)
5551
{
56-
sum += fourier_series(t, k, n, param);
52+
double y = fourier_series(t, k, param);
53+
if (sigma)
54+
{
55+
const double x = M_PI * k / m;
56+
y *= sin(x)/x;
57+
}
58+
sum += y;
5759
}
5860

5961
*tbl++ = M_SQRT1_2 * sum;
@@ -67,7 +69,7 @@ static bool gen_wavetbl(const char* filename, int bps, double (*fourier_series)(
6769
return fh.BytesWritten() == wavetbl_size * bps/8;
6870
}
6971

70-
static bool gen_wavetbl(const char* filename, double (*fourier_series)(double, int, int, double), double param = 0)
72+
static bool gen_wavetbl(const char* filename, double (*fourier_series)(double, int, double), double param = 0, double phase = 0, bool sigma = true)
7173
{
72-
return gen_wavetbl(filename, 16, fourier_series, param);
74+
return gen_wavetbl(filename, 16, fourier_series, param, phase, sigma);
7375
}

Effects/Tale/adsr.jsfx-inc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ desc:ADSR envelope
1010
slider3:-12.0<-120.0,24.0,1.0>Sustain (dB)
1111
slider4:500<0,5000,1>Release (ms)
1212

13-
import adsr.jsfx-inc
14-
import midi_queue.jsfx-inc
15-
import poly_blep.jsfx-inc
13+
import Tale/adsr.jsfx-inc
14+
import Tale/midi_queue.jsfx-inc
15+
import Tale/poly_blep.jsfx-inc
1616

1717
@slider
1818

@@ -56,8 +56,8 @@ desc:ADSR envelope
5656
* adsr_sets(gain) -- Sustain
5757
* adsr_setr(time) -- Release
5858
Example: adsr.adsr_seta(0.003);
59-
Sets the ADSR envelope time (specified in seconds) or gain [0.0..1.0]
60-
value, and returns the coefficient or gain value.
59+
Sets the ADSR envelope time (specified in seconds) or the gain
60+
[0.0..1.0] factor, and returns the coefficient or the gain factor.
6161

6262
Processing Functions
6363

@@ -94,7 +94,7 @@ desc:ADSR envelope
9494

9595
* scale
9696
Example: adsr2.adsr_a(adsr1.scale);
97-
The current scale value.
97+
The current scale factor.
9898

9999
*/
100100

Effects/Tale/array.jsfx-inc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ desc:Simple two-dimensional array interface
66

77
desc:Last-note priority mono synth
88

9-
import malloc.jsfx-inc
10-
import array.jsfx-inc
11-
import midi_queue.jsfx-inc
12-
import poly_blep.jsfx-inc
9+
import Tale/malloc.jsfx-inc
10+
import Tale/array.jsfx-inc
11+
import Tale/midi_queue.jsfx-inc
12+
import Tale/poly_blep.jsfx-inc
1313

1414
@init
1515

@@ -86,12 +86,12 @@ desc:Simple two-dimensional array interface
8686
Example: ptr = array.array_add();
8787
Adds a row to the end of the array and returns its local memory index.
8888
Note that the row is added but not initialised (i.e. it does not
89-
contain any data yet).
89+
contain any data yet, nor is it zeroed.).
9090

9191
* array_insert(ptr)
9292
Example: array.array_insert(array.array_get(0));
9393
Inserts a row into the array. Note that the row is inserted but not
94-
initialised (i.e. it does not contain any data yet).
94+
initialised.
9595

9696
* array_remove(ptr)
9797
Example: array.array_remove(array.array_get(0));

0 commit comments

Comments
 (0)