1declare name "Tremolo";
2declare category "Modulation";
3declare gladefile "tremolo_ui.glade";
4
5/*
6** Model of a vactrol tremolo unit by "transmogrify"
7** c.f. http://sourceforge.net/apps/phpbb/guitarix/viewtopic.php?f=7&t=44&p=233&hilit=transmogrifox#p233
8** http://transmogrifox.webs.com/vactrol.m
9*/
10
11import("stdfaust.lib");
12
13/* vactrol model */
14
15/* transcendental functions in fast signal path:
16** cds: 2 exp() (2 alpha containing each 1 exp())
17** vactrol: 1 exp(), 1 pow(), 1 log()
18*/
19
20R1 = 2700;
21Ra = 1e6;
22Rb = 300;
23b = exp(log(Ra)/log(Rb)) - exp(1);
24dTC = 0.06;
25minTC = log(0.005/dTC);
26
27cds = ((_ <: _,_),_ : _+(1-alpha)*_) ~ (_<:*(alpha)) with {
28    iSR = 1/ma.SR;
29    dRC = dTC * exp(*(minTC));
30    alpha = 1 - iSR / (dRC + iSR);
31};
32
33vactrol = pow(_,1.9) : cds : *(b) + exp(1) : exp(log(Ra)/log) : R1/(_ + R1);
34
35/* triangle oscillator (not bandlimited, frequency is approximate) */
36
37trianglewave(freq) = _ ~ (_ <: _ + hyst) : /(periodsamps) with {
38   if(c,t,e) = select2(c,e,t);
39    hyst(x) = if(_ > 0, 2 * (x < periodsamps) - 1, 1 - 2 * (x > 0)) ~ _;
40    periodsamps = int(ma.SR / (2*float(freq)));
41};
42
43/* tremolo unit, using triangle or sine oscillator as lfo */
44
45tremolo(freq, depth) = lfo * depth + 1 - depth : vactrol with {
46    sine(freq) = (os.oscs(freq) + 1) / 2 : max(0); // max(0) because of numerical inaccuracy
47    SINE=checkbox("SINE[enum:triangle|sine|square]");
48    lfo = select3(SINE, trianglewave(freq), sine(freq), os.lf_squarewavepos(freq));
49};
50
51wet = vslider("wet_dry[name:Dry/Wet][tooltip:percentage of processed signal in output signal]",  100, 0, 100, 1) : /(100);
52dry = 1 - wet;
53
54process =  _<:*(dry),(*(wet): *(tremolo(vslider("freq[name:Freq]",5,0.1,50,0.1),vslider("depth[name:Depth]",0.5,0,1,0.01)))):>_;
55