1/*
2    PolyBLEP implementation in Faust
3    Copyright(C) 2010 Sampo Savolainen <v2@iki.fi>
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18*/
19import ("math.lib");
20import ("music.lib");
21
22at_frame = plus_one ~ _
23with {
24	plus_one = _+(1);
25};
26
27zero_to_one(n) = at_frame / n;
28
29fast_polyblep(z) = polyblep_lookup
30with {
31	table_size = int(16384);
32
33	polynomial(t) = select2( t > 0,
34				((t*t)/2 + t + 0.5),
35				(t - (t*t)/2 - 0.5));
36
37	polynomial_from_idx(i) = float(i)*2.0/float(table_size)-1.0 : polynomial;
38
39	polyblep_table = rdtable(table_size, polynomial_from_idx, int(+(1) ~ _ : -(1)));
40
41	polyblep_lookup = (z+1)/2.0*float(table_size) <: (polyblep_table(floor:int) + polyblep_table(ceil:int))/2;
42};
43
44polyblep_square_master(f, bias) = (phase ~ _) <: polyblep_square_slave, _
45with {
46	freq = f * bias;
47
48	q = float(freq)/float(SR);
49	phase = +(q) : fmod(_, 1.0);
50};
51polyblep_cpp = ffunction(float polyblep_table_lookup(float), "polyblep.cpp","");
52
53polyblep_square_slave(phase) = naive_square(phase) : (polyb_it ~ _) : (!, _)
54with {
55
56	q = fmod(phase - phase' + 1, 1.0);
57
58	polyblep_real(t) = select2( t > 0,
59				   ((t*t)/2 + t + 0.5),
60				   (t - (t*t)/2 - 0.5));
61
62	//polyblep(t) = polyblep_cpp( t / q);
63	polyblep(t) = polyblep_real( t / q);
64	//polyblep(t) = fast_polyblep( t / q);
65
66	naive_square(ph) = ph, select2( ph < 0.5, -1.0, 1.0);
67
68	// 0 no polyblep
69	// 1 add polyblep at ph
70	// 2 add reverse phase polyblep at ph - 0.5
71	selector(ph) = select2( (ph - ph') <= 0,
72		       select2( fmod(ph+0.5,1.0) < q, 0, 2), 1);
73
74	// Detects square wave discontinuities by checking whether phase has went past 0 or 0.5
75	// delays signal by one.
76	polyb_it(prev, ph, x) =
77		selector(ph) <:
78			square_blep_x   (_, x,    ph,  q) ,
79			square_blep_prev(_, prev, ph', q);
80/*
81			square_blep_x   (_, x,    ph,  q) ,
82			square_blep_prev(_, prev, ph', q);
83*/
84
85	square_blep_x    = ffunction (float square_blep_x   (int, float, float, float), "polyblep.cpp", "");
86	square_blep_prev = ffunction (float square_blep_prev(int, float, float, float), "polyblep.cpp", "");
87/*
88		select3(_,
89			x,
90			x + polyblep(ph) * 2,
91			x - polyblep(ph - 0.5) * 2),
92		select3(_,
93			prev,
94			prev + polyblep(ph' - 1.0) * 2,
95			prev - polyblep(ph' - 0.5) * 2);
96*/
97};
98
99
100//process = zero_to_one(2048) * 2 - 1 : fast_polyblep;
101
102//process = fast_polyblep( 2.4 / 1923.4);
103/*
104phase_divisor(ph) = slow_accumulator(ph) / 2.0
105with {
106        slow_accumulator(x) = (prevphase(x) ~ _) + x;
107
108        prevphase(x, whichphase) = select2( (x - x@1) < 0, whichphase, 1-whichphase);
109};
110
111process = polyblep_square_master(3440.1, 1.0) : _, (phase_divisor : polyblep_square_slave);
112*/
113
114
115
116tet12(note) = 440*8 * 2.0^((note + 1) / 12.0);
117
118import ("divider.dsp");
119import ("biquad.dsp");
120import ("wave_transformer.dsp");
121
122entropy = noise : biquad_lp(3.0) : *(log(1.005)) : +(1);
123//entropy = noise
124//	: biquad_lp(hslider("entropy lp", 0.1, 0.1, 100.0, 0.1))
125//	: *(log(hslider("entropy", 0.0, 0.0, 1.0, 0.01)+1))
126//	: +(1);
127
128ac_noise = (+(50/float(SR)) ~ _) : fmod(_, 1.0) <: select2(_ < 0.5, 0, _) : *(2*PI) : sin : *(hslider("ac noise", 0.0, 0.0, 1.0, 0.01));
129
130
131sine(freq) = (+(freq/float(SR)) ~ _) : fmod(_, 1.0) : *(2*PI) : sin;
132tri(freq) = 0.25 + (+(freq/float(SR)) ~ _) : fmod(_, 1.0) <: select2(_ < 0.5, 1-(_-0.5)*2*2, _*2*2-1);
133
134
135
136
137sin_tri = hslider("sin/tri",0.0,0.0,1.0,0.01);
138
139ac_bias_amount    = 0.0005;
140//ac_bias_amount    = hslider("ac bias", 0.0, 0.0, 1.0, 0.001) / 10; // 0.003
141pure_noise_amount = 0.0015;
142//pure_noise_amount = hslider("pure noise",0.0, 0.0, 1.0, 0.001);
143
144//ac = sine(100) * (1-sin_tri) + tri(100) *sin_tri : *(log(1+ac_bias_amount));
145ac = sine(50) : abs : *(log(1+ac_bias_amount));
146
147
148//process = polyblep_square_master(tet12(2), 1.0);
149//process = polyblep_square_master(tet12(2), 1.0) : divider
150/*
151process = polyblep_square_master(tet12(2), entropy + ac) : divider
152	: par(i, 8, +(ac_noise)) // : wave_transformer_I1;
153	: par(i, 8, +(noise * pure_noise_amount))
154	: par(i, 8, *(0.2));
155//	: par(i, 8, *(button("on_off")));
156*/
157
158
159import ("percussion.dsp");
160import ("rc_filter.dsp");
161
162
163testphase = (+(350/float(SR)) ~ fmod(_,1.0));
164
165
166//process = testphase : -(0.5) : *(2) <: percussion_envelope, _;
167
168
169//div7_hp_resistance = (1/56000) + (1/ (180000 + (1/((1/15000)+(1/100000))))) : 1/_;
170
171
172//process = noise : (passive_lp(15000, 0.047));
173
174
175process = _, _;
176
177
178