1// imported by echo.dsp and echomt.dsp 2 3import("stdfaust.lib"); 4 5echo_group(x) = x; // Let layout2.dsp lay us out 6 knobs_group(x) = ekg(x); 7 switches_group(x) = esg(x); 8 9dmax = 32768; // one and done 10dmaxs = float(dmax)/44100.0; 11 12Nnines = 1.8; // Increase until you get the desired maximum amount of smoothing when fbs==1 13//fastpow2 = ffunction(float fastpow2(float), "fast_pow2.h", ""); 14fbspr(fbs) = 1.0 - pow(2.0, (-3.33219*Nnines*fbs)); // pole radius of feedback smoother 15inputSelect(gi) = _,0 : select2(gi); 16echo_mono(dmax,curdel,tapdel,fb,fbspr,gi) = inputSelect(gi) : (+:si.smooth(fbspr) 17 <: de.fdelay(dmax,curdel), 18 de.fdelay(dmax,tapdel)) 19 ~(*(fb),!) : !,_; 20 21tau2pole(tau) = ba.if(tau>0, exp(-1.0/(tau*ma.SR)), 0.0); 22t60smoother(dEchoT60) = si.smooth(tau2pole(dEchoT60/6.91)); 23 24dEchoT60 = knobs_group(vslider("[1] DelayT60 [midi:ctrl 60] [style:knob]", 0.5, 0, 100, 0.001)); 25dEchoSamplesRaw = knobs_group(vslider("[0] Delay [midi:ctrl 4] [style:knob]", 0.5, 0.001, (dmaxs-0.001), 0.001)) * ma.SR; 26dEchoSamples = dEchoSamplesRaw : t60smoother(dEchoT60); 27warpRaw = knobs_group(vslider("[0] Warp [midi:ctrl 62] [style:knob]", 0, -1.0, 1.0, 0.001)); 28 29scrubAmpRaw = 0; 30 31scrubPhaseRaw = 0; 32fb = knobs_group(vslider("[2] Feedback [midi:ctrl 3] [style:knob]", .3, 0.0, 1.0, 0.0001)); 33amp = knobs_group(vslider("[3] Amp [midi:ctrl 2] [style:knob]", .5, 0, 1, 0.001)) : si.smooth(ba.tau2pole(ampT60/6.91)); 34 35ampT60 = 0.15661; 36fbs = knobs_group(vslider("[5] [midi:ctrl 76] FeedbackSm [style:knob]", 0, 0, 1, 0.00001)); 37gi = switches_group(1-vslider("[7] [midi:ctrl 105] EnableEcho[style:knob]",0,0,1,1)); // "ground input" switches input to zeros 38 39// Warp and Scrubber stuff: 40enableEcho = (scrubAmpRaw > 0.00001); 41triggerScrubOn = (enableEcho - enableEcho') > 0; // enableEcho went 0 to 1 42triggerScrubOff = (enableEcho - enableEcho') < 0; // enableEcho went 1 to 0 43// Ramps up only during scrub "hold" time and is otherwise zero: 44counter = (enableEcho * (triggerScrubOn : + ~ +(1) * enableEcho : -(2))) & (dmax-1); 45// implementation that continues scrubbing where it left off: 46 47scrubPhase = scrubPhaseRaw : t60smoother(dEchoT60*(1-triggerScrubOff)); 48scrubAmp = scrubAmpRaw : t60smoother(dEchoT60*(1-triggerScrubOff)); 49warp = warpRaw : t60smoother(dEchoT60); 50dTapSamplesRaw = dEchoSamplesRaw * (1.0 + warp + scrubPhase * scrubAmp) + float(counter); 51dTapSamples = dTapSamplesRaw : t60smoother(dEchoT60*(1-triggerScrubOff)); 52 53process = _ <: _, amp * echo_mono(dmax,dEchoSamples,dTapSamples,fb,fbspr(fbs),gi) : +; 54// This layout loosely follows the MiniMoog-V 55// Arturia-only features are labeled 56// Original versions also added where different 57 58// Need vrocker and hrocker toggle switches in Faust! 59// Need orange and blue color choices 60// Orange => Connect modulation sources to their destinations 61// Blue => Turn audio sources On and Off 62// - and later - 63// White => Turn performance features On and Off 64// Black => Select between modulation sources 65// Julius Smith for Analog Devices 3/1/2017 66 67vrocker(x) = checkbox("%%x [style:vrocker]"); 68hrocker(x) = checkbox("%%x [style:hrocker]"); 69vrockerblue(x) = checkbox("%x [style:vrocker] [color:blue]"); 70vrockerblue(x) = checkbox("%x [style:vrocker] [color:blue]"); 71 // USAGE: vrockerorange("[0] ModulationEnable"); 72 73hrockerblue(x) = checkbox("%%x [style:hrocker] [color:blue]"); 74vrockerred(x) = checkbox("%%x [style:vrocker] [color:red]"); 75hrockerred(x) = checkbox("%%x [style:hrocker] [color:red]"); 76 77declare designer "Robert A. Moog"; 78 79mmg(x) = hgroup("",x); // Minimoog + Effects 80 synthg(x) = mmg(vgroup("[0] Minimoog",x)); 81 fxg(x) = mmg(hgroup("[1] Effects",x)); 82 mg(x) = synthg(hgroup("[0]",x)); 83 cg(x) = mg(vgroup("[0] Controllers",x)); // Formerly named "Modules" but "Minimoog" group-title is enough 84 vg(x) = cg(hgroup("[0] Master Volume", x)); 85 dg(x) = cg(hgroup("[1] Oscillator Tuning & Switching", x)); 86 // Tune knob = master tune 87 dsg(x) = dg(vgroup("[1] Switches", x)); 88 // Oscillator Modulation HrockerRed => apply Modulation Mix output to osc1&2 pitches 89 // [MOVED here from osc3 group] Osc 3 Control VrockerRed => use osc3 as LFO instead of osc3 90 gmmg(x) = cg(hgroup("[2] Glide and ModMix", x)); 91 // Glide knob [0:10] = portamento speed 92 // Modulation Mix knob [0:10] (between Osc3 and Noise) = mix of noise and osc3 modulating osc1&2 pitch and/or VCF freq 93 og(x) = mg(vgroup("[1] Oscillator Bank", x)); 94 osc1(x) = og(hgroup("[1] Oscillator 1", x)); 95 // UNUSED Control switch (for alignment) - Could put Oscillator Modulation switch there 96 // Range rotary switch: LO (slow pulses or rhythm), 32', 16', 8', 4', 2' 97 // Frequency <something> switch: LED to right 98 // Waveform rotary switch: tri, impulse/bent-triangle, saw, pulseWide, pulseMed, pulseNarrow 99 osc2(x) = og(hgroup("[2] Oscillator 2", x)); 100 // UNUSED (originall) or Osc 2 Control VrockerRed 101 // Range rotary switch: LO, 32', 16', 8', 4', 2' 102 // Detuning knob: -7 to 7 [NO SWITCH] 103 // Waveform rotary switch: tri, impulse(?), saw, pulseWide, pulseMed, pulseNarrow 104 osc3(x) = og(hgroup("[3] Oscillator 3", x)); 105 // Osc 3 Control VrockerRed => use osc3 as LFO instead of osc3 106 // Range rotary switch: LO, 32', 16', 8', 4', 2' 107 // Detuning knob: -7 to 7 [NO SWITCH] 108 // Waveform rotary switch: tri, impulse(?), saw, pulseWide, pulseMed, pulseNarrow 109 mixg(x) = mg(vgroup("[2] Mixer", x)); 110 // Each row 5 slots to maintain alignment and include red rockers joining VCF area: 111 mr1(x) = mixg(hgroup("[0] Osc1", x)); // mixer row 1 = 112 // Osc1 Volume and Osc1 HrockerBlue & _ & _ & Filter Modulation HrockerRed 113 // Filter Modulation => Modulation Mix output to VCF freq 114 mr2(x) = mixg(hgroup("[1] Ext In, KeyCtl", x)); // row 2 = Ext In HrockerBlue and Vol and Overload LED and Keyboard Ctl HrockerRed 1 115 mr3(x) = mixg(hgroup("[2] Osc2", x)); // = Osc2 Volume and Osc2 HrockerBlue and Keyboard Ctl HrockerRed 2 116 // Keyboard Control Modulation 1&2 => 0, 1/3, 2/3, all of Keyboard Control Signal ("gate?") applied to VCF freq 117 mr4(x) = mixg(hgroup("[3] Noise", x)); // = Noise HrockerBlue and Volume and Noise Type VrockerBlue 118 mr4cbg(x) = mr4(vgroup("[1]", x)); // = Noise Off and White/Pink selection 119 // two rockers 120 mr5(x) = mixg(hgroup("[4] Osc3", x)); // Osc3 Volume and Osc3 HrockerBlue 121 modg(x) = mg(vgroup("[3] Modifiers", x)); 122 vcfg(x) = modg(vgroup("[0] Filter", x)); 123 vcf1(x) = vcfg(hgroup("[0] [tooltip:freq, Q, ContourScale]", x)); 124 vcf1cbg(x) = vcf1(vgroup("[0] [tooltip:two checkboxes]", x)); 125 // Filter Modulation switch 126 // VCF Off switch 127 // Corner Frequency knob 128 // Filter Emphasis knob 129 // Amount of Contour knob 130 vcf2(x) = vcfg(hgroup("[1] Filter Contour [tooltip:AttFilt, DecFilt, Sustain Level for Filter Contour]", x)); 131 // Attack Time knob 132 // Decay Time knob 133 // Sustain Level knob 134 ng(x) = modg(hgroup("[1] Loudness Contour", x)); 135 // Attack Time knob 136 // Decay Time knob 137 // Sustain Level knob 138 echog(x) = fxg(hgroup("[4] Echo",x)); 139 ekg(x) = echog(vgroup("[0] Knobs",x)); 140 esg(x) = echog(vgroup("[1] Switches",x)); 141 flg(x) = fxg(hgroup("[5] Flanger",x)); 142 flkg(x) = flg(vgroup("[0] Knobs",x)); 143 flsg(x) = flg(vgroup("[1] Switches",x)); 144 chg(x) = fxg(hgroup("[6] Chorus",x)); 145 ckg(x) = chg(vgroup("[0] Knobs",x)); 146 csg(x) = chg(vgroup("[1] Switches",x)); 147 rg(x) = fxg(hgroup("[7] Reverb",x)); 148 rkg(x) = rg(vgroup("[0] Knobs",x)); 149 rsg(x) = rg(vgroup("[1] Switches",x)); 150 outg(x) = fxg(vgroup("[8] Output", x)); 151 volg(x) = outg(hgroup("[0] Volume Main Output", x)); 152 // Volume knob [0-10] 153 // Unison switch (Arturia) or Output connect/disconnect switch (original) 154 // When set, all voices are stacked and instrument is in mono mode 155 tunerg(x) = outg(hgroup("[1] A-440 Switch", x)); 156 vdtpolyg(x) = outg(hgroup("[2] Voice Detune / Poly", x)); 157 // Voice Detune knob [0-10] (Arturia) or 158 // Polyphonic switch [red LED below] (Arturia) 159 // When set, instrument is in polyphonic mode with one oscillator per key 160 clipg(x) = fxg(vgroup("[9] Soft Clip", x)); 161 // Soft Clipping switch [red LED above] 162 kg(x) = synthg(hgroup("[1] Keyboard Group", x)); // Keyboard was 3 1/2 octaves 163 ws(x) = kg(vgroup("[0] Wheels and Switches", x)); 164 s1g(x) = ws(hgroup("[0] Jacks and Rockers", x)); 165 jg(x) = s1g(vgroup("[0] MiniJacks",x)); 166 gdlg(x) = s1g(vgroup("[1] Glide/Decay/Legato Enables",x)); // Arturia 167 // Glide Hrocker (see original Button version below) 168 // Decay Hrocker (see original Button version below) => Sets Release (R) of ADSR to either 0 or Decay (R) 169 // Legato Hrocker (not in original) 170 s2g(x) = ws(hgroup("[1] [tooltip:Wheels+]", x)); 171 bg(x) = s2g(vgroup("[0] [tooltip:Bend Enable and Range]", x)); 172 wg(x) = s2g(hgroup("[1] [tooltip:Bend and Mod Wheels]", x)); 173 // Using Glide/Decay/Legato enables above following Arturia: 174 // dg(x) = s2g(hgroup("[2] Glide and Decay momentary pushbuttons", x)); 175 // Glide Button injects portamento as set by Glide knob 176 // Decay Button uses decay of Loudness Contour (else 0) 177 keys(x) = kg(hgroup("[1] [tooltip:Keys]", x)); 178 gg(x) = keys(hgroup("[0] [tooltip: Gates]",x)); 179 // leave slot 1 open for sustain (below) 180