1
+ import ( " stdfaust.lib" ) ;
2
+
3
+ // Average filter
4
+ filterLength = 500;
5
+ movingAvg( x) = par ( i, filterLength, x@( i)) :> _/ filterLength;
6
+
7
+ // Delay handle delay
8
+ delayAvg = delMs * ( ma. SR/ 1000 ) : movingAvg;
9
+ delSec = delMs / 1000;
10
+
11
+ // Measured tape speed= 8ips = 0.203 m/s
12
+ // headDist = 0.203 * delSec; //[m] Not used
13
+
14
+ // creating an angular frequency
15
+ pulse( freq) = os. lf_saw( freq) * ( ma. PI) ;
16
+
17
+ // phasenoise frequency is related to drift freq: i want smooth changes->freq has to be lower for
18
+ // low freq drift while noise amplitude has to be higher
19
+ delDrift1 = sin ( sinArg) * ampliSec * ma. SR // Capstan: Observed amplitude = 0.15 ms
20
+ with
21
+ {
22
+ phaseNoise = ( no. noise* 5 ) : fi. lowpass6e( 100 ) ; // adding noise to phase
23
+ freq = 26;
24
+ phase = ma. PI * 3 / 2 + phaseNoise;
25
+ sinArg = pulse( freq) + phase;
26
+ ampliSec = 0.00015;
27
+ } ;
28
+ delDrift2 = sin ( sinArg) * ampliSec * ma. SR // Pinch wheel1: Observed amplitude = 0.15 ms
29
+ with
30
+ {
31
+ phaseNoise = ( no. noise* 7 ) : fi. lowpass6e( 35 ) ; // adding noise to phase
32
+ freq = 5;
33
+ phase = 0 + phaseNoise; // not visible in paper
34
+ sinArg = pulse( freq) + phase;
35
+ ampliSec = 0.00010 * delSec;
36
+ } ;
37
+ delDrift3 = sin ( sinArg) * ampliSec * ma. SR // Pinch wheel2: Observed amplitude = 0.75 ms
38
+ with
39
+ {
40
+ phaseNoise = ( no. noise* 20 ) : fi. lowpass6e( 20 ) ; // adding noise to phase
41
+ freq = 2.5;
42
+ phase = ma. PI * 3 / 4 + phaseNoise;
43
+ sinArg = pulse( freq) + phase;
44
+ ampliSec = 0.00075 * delSec;
45
+ } ;
46
+
47
+ // Noise
48
+ delNoise = ( no. noise* noiseAmp * ma. SR) : LPfilter
49
+ with
50
+ {
51
+ // Noise is proportional to head separation.
52
+ noiseAmp = 0.00075 * delSec;
53
+ LPfilter = fi. lowpass3e( 70 ) ;
54
+ } ;
55
+
56
+ // 0.75 is a factor to make the overall variation level similar to the paper
57
+ delayTotal = (( delDrift1 + delDrift2 + delDrift3 + delNoise)* 0.75 ) + delayAvg;
58
+
59
+ // Variable comb filter
60
+ pole = 0.9999;
61
+ filterDel = startFactor + (( endFactor- startFactor) * delSec) : int
62
+ with
63
+ { // 48000 hardcoded SR, for some reason it does not work with ma.SR
64
+ firstNotchFreqStart = 7.5; // [Hz]
65
+ firstNotchFreqEnd = 2;
66
+ startFactor = 48000 /( 2 * firstNotchFreqStart) ;
67
+ endFactor = 48000 /( 2 * firstNotchFreqEnd) ;
68
+ } ;
69
+ ffComb( delay, pole) = _<: _, _@delay* pole :> _/ 2;
70
+
71
+ delayProcessed = delayTotal : ffComb( filterDel, pole) : int ;
72
+
73
+ // Actual Delay + feedback
74
+ delayFunction( n, d, x) = x @ min ( n, max ( 0 , d)) ;
75
+ feedback( x) = ( x : tapeSat + x ~ ( delay * repeats)) : filter
76
+ with
77
+ {
78
+ tapeSat = co. limiter_1176_R4_mono;
79
+ delay = delayFunction( 50000 , delayProcessed, x) ;
80
+ filter = fi. lowpass( 2 , 7000 ) ;
81
+ } ;
82
+
83
+ // Nonlinear distortion
84
+ // amplifier(g) = ef.cubicnl_nodc(g, 0.1); //Not used
85
+
86
+ // User params
87
+ delMs = hslider ( " delay(ms)" , 300 , 1 , 1000 , 1 ) ;
88
+ repeats = vslider ( " feedback[style:knob]" , 0.5 , 0 , 2 , 0.01 ) ;
89
+ // echoLevel = vslider("Echo Volume[style:knob]", 0.5, 0, 1, 0.01); //Not used
90
+
91
+ delay_module( dtime, phase) = rwtable ( MAX_DELAY, 0.0 , indexphasor( dtime, phase) : int , _, indexphasor( dtime, phase+ 1 ) : int ) : window with {
92
+ window = *( sin ( 0.5 * ma. PI* phasor_phase( dtime, phase)/ dtime)) ;
93
+ } ; // init have to be 0.0 floating point
94
+ reversedelay_mono( dtime) = _<: delay_module( dtime, 0 ) , delay_module( dtime, dtime/ 2 ) :> _;
95
+
96
+ /* Process*/
97
+ process = feedback( _) <: _, _;
0 commit comments