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