{
   "labels" : [
      "machine",
      "car",
      "engine"
   ],
   "code" : "//Fig 45.3: A \"toy\" engine\r\n//Instead of using a toggle object to simulate the break, the same functionality is implemented by moving the mouse cursor into the right or left half of the screen.\r\n\r\n(\r\n{\r\n        var toy, toggle, noise;\r\n \r\n        toggle = MouseX.kr(0,1).round(1);\r\n \r\n        toy = BPF.ar(WhiteNoise.ar, 9, 15.reciprocal); \r\n        toy = (toggle * toy);\r\n        toy = (toy + (SinOsc.ar(9) * K2A.ar(Select.kr(toggle, [1,0])))) * 600;\r\n        toy = Clip.ar(toy, 0, 1);\r\n        toy = (toy - OnePole.ar(toy, exp(-2pi * (10 * SampleDur.ir))));\r\n        toy = OnePole.ar(toy, exp(-2pi * (30 * SampleDur.ir)));\r\n \r\n        noise = WhiteNoise.ar;\r\n        noise = (noise - OnePole.ar(noise, exp(-2pi * (1000 * SampleDur.ir))));\r\n        noise = BPF.ar(noise, 590, 4.reciprocal);\r\n \r\n        toy = toy * noise; \r\n \r\n        toy = BPF.ar(toy, [470, 780, 1024], [8, 9, 10].reciprocal).sum;\r\n        toy = (toy - OnePole.ar(toy, exp(-2pi * (100 * SampleDur.ir))));\r\n        toy = (toy * 2).dup;\r\n \r\n}.play;\r\n)\r\n\r\n\r\n\r\n//Fig 45.4/45.5: A four cylinder engine with slugging speed\r\n\r\n(\r\n{\r\n        var jitterEngine, noise, bufferA, bufferB, fourstroke, engineSpeed;\r\n \r\n        bufferA = LocalBuf(44100, 1); \r\n        bufferB = LocalBuf(44100, 1); \r\n \r\n        engineSpeed = MouseX.kr(0,1);\r\n \r\n        noise = WhiteNoise.ar;\r\n        noise = OnePole.ar(noise, exp(-2pi * (20 * SampleDur.ir)));\r\n        noise = OnePole.ar(noise, exp(-2pi * (20 * SampleDur.ir)));\r\n        noise = DelTapWr.ar([bufferA, bufferB], [noise * 0.5, noise * 10]);\r\n \r\n        fourstroke = DelTapRd.ar(bufferA, noise[0], [5, 10, 15, 20]/1000); \r\n        fourstroke = \r\n                        LFSaw.ar(OnePole.ar((K2A.ar(engineSpeed) * 40), exp(-2pi * (0.8 * SampleDur.ir))), 1, 0.5, 0.5)\r\n                         + fourstroke\r\n                         - [0.75, 0.5, 0.25, 0];\r\n        fourstroke = (fourstroke * 2pi).cos;\r\n        fourstroke.scope;\r\n \r\n        fourstroke = \r\n                        fourstroke \r\n                        * (DelTapRd.ar(bufferB, noise[1], [5, 10, 15, 20]/1000) + ((1 - engineSpeed) * 15 + 7));\r\n        fourstroke = 1 / ((fourstroke * fourstroke) + 1);\r\n        fourstroke = fourstroke.sum!2 * 0.25;\r\n \r\n}.play;\r\n)\r\n\r\n\r\n\r\n//Fig 45.8: Advanced Engine\r\n//Advanced engine with multiple transmission paths and warping non-linear waveguide. Contains the subpatches from fig 45.5, 45.6 and 45.7. At the end there is also an example how to control some parameters via a MIDI controller.\r\n\r\n(\r\ne = SynthDef(\\engine, {\r\n \r\n        | // arguments range: 0.0 - 1.0         \r\n        mixCylinders   = 0.8,\r\n        mixParabolic   = 0.9,\r\n        engineSpeed    = 0, \r\n        parabolaDelay  = 0.15,\r\n        warpDelay      = 0.4,\r\n        waveguideWarp  = 0.67,\r\n        wguideFeedback = 0.35,\r\n        wguideLength1  = 0.2,\r\n        wguideLength2  = 0.3,\r\n        wguideWidth1   = 0.5,\r\n        wguideWidth2   = 0.7\r\n        |\r\n \r\n        // To be able to send arrays as arguments you have to declare them as variables and\r\n        // use NamedControl.kr. Take also a look at the MIDI example at the bottom how to address them. \r\n        var transDelay = NamedControl.kr(\\transDelay, [0.2, 0.3, 0.45]);\r\n        var overtonePhase = NamedControl.kr(\\overtonePhase, [0.25, 0.35, 0.5]);\r\n        var overtoneFreq = NamedControl.kr(\\overtoneFreq, [0.3, 0.47, 0.38]);\r\n        var overtoneAmp = NamedControl.kr(\\overtoneAmp, [0.1, 0.2, 0.2]);\r\n \r\n        var noise, bufferA, bufferB, bufferTd, fourstroke, phasor, td, parabola, fm1, preFM1, \r\n        fm2, preFM2, overtone, overtoneDrive, e1b, e2a, e2b, e1a, spacewarp, engine;\r\n \r\n        engineSpeed = MouseX.kr(0,1);\r\n \r\n \r\n        bufferA = LocalBuf(44100, 1); \r\n        bufferB = LocalBuf(44100, 1); \r\n        bufferTd = LocalBuf(44100, 1); \r\n \r\n \r\n        noise = WhiteNoise.ar;\r\n        noise = OnePole.ar(noise, exp(-2pi * (20 * SampleDur.ir)));\r\n        noise = OnePole.ar(noise, exp(-2pi * (20 * SampleDur.ir)));\r\n        noise = (DelTapWr.ar([bufferA, bufferB], [noise * 0.5, noise * 30]));\r\n \r\n        phasor = LFSaw.ar(\r\n                OnePole.ar(K2A.ar(engineSpeed) * 30, exp(-2pi * (0.8 * SampleDur.ir))), \r\n                1, 0.5, 0.5);\r\n        td = DelTapWr.ar(bufferTd, phasor);\r\n \r\n        fourstroke = DelTapRd.ar(bufferA, noise[0], [5, 10, 15, 20]/1000, 4); \r\n        fourstroke = phasor + fourstroke - [0.75, 0.5, 0.25, 0];\r\n        fourstroke = (fourstroke * 2pi).cos;\r\n        fourstroke = fourstroke * (DelTapRd.ar(bufferB, noise[1], [5, 10, 15, 20]/1000, 4) + ((1 - engineSpeed) * 15 + 7));\r\n        fourstroke = 1 / ((fourstroke * fourstroke) + 1);\r\n        fourstroke = fourstroke.sum * mixCylinders;\r\n        fourstroke = fourstroke - OnePole.ar(fourstroke, exp(-2pi * (4 * SampleDur.ir)));\r\n \r\n \r\n        parabola = DelTapRd.ar(bufferTd, td, (parabolaDelay * 100)/1000, 1) - 0.5;\r\n        parabola = parabola * parabola * (-4) + 1 * 3 * mixParabolic;\r\n \r\n \r\n        preFM1 = DelTapRd.ar(bufferTd, td, (warpDelay * 100)/1000, 1);\r\n        preFM1 = (preFM1 * 2pi).cos;\r\n        preFM2 = K2A.ar(engineSpeed * waveguideWarp);\r\n        preFM2 = OnePole.ar(preFM2, exp(-2pi * (0.2 * SampleDur.ir)));\r\n        fm1 = (1 - preFM1) * preFM2 + 0.5;\r\n        fm2 = (preFM2 * preFM1) + 0.5;\r\n \r\n \r\n        overtoneDrive  = overtoneDrive!3;\r\n        overtone = overtone!3;\r\n \r\n        3.do{|i|\r\n \r\n                overtoneDrive[i] = DelTapRd.ar(bufferTd, td, (transDelay[i]*100)/1000) * (0.5**(i+1)*32);\r\n                overtoneDrive[i] = Wrap.ar(overtoneDrive[i]);\r\n \r\n                overtone[i] = overtoneDrive[i].max(overtonePhase[i]) - overtonePhase[i];\r\n                overtone[i] = overtone[i] * (1 - overtonePhase[i]).reciprocal;\r\n                overtone[i] = overtone[i] * ((overtoneFreq[i] * 12) * overtonePhase[i]);\r\n                overtone[i] = Wrap.ar(overtone[i]) - 0.5;\r\n                overtone[i] = (overtone[i] * overtone[i]) * (-4) + 1 * 0.5;\r\n                overtone[i] = (overtone[i] * (1 - overtoneDrive[i])) * (overtoneAmp[i] * 12);\r\n        };\r\n \r\n \r\n        # e1b, e2b, e2a, e1a = DelayC.ar(\r\n                in: InFeedback.ar(bus:(10..13)), \r\n                maxdelaytime: 1,\r\n                delaytime: ((([wguideLength1,wguideWidth1,wguideLength2,wguideWidth2] * 40) \r\n                        * [fm1,fm1,fm2,fm1])/1000)\r\n        );\r\n \r\n        OffsetOut.ar(11, e1b + overtone[1]);\r\n \r\n        e2b = e2b + overtone[2];\r\n        OffsetOut.ar(13, e2b);  \r\n \r\n        e2a = e2a + overtone[0];\r\n        OffsetOut.ar(10, e2a);\r\n \r\n        OffsetOut.ar(12, e1a * wguideFeedback + (parabola - OnePole.ar(parabola, exp(-2pi * (30 * SampleDur.ir)))));\r\n \r\n        spacewarp = e1b + e2b + e2a + e1a;\r\n        spacewarp = spacewarp - OnePole.ar(spacewarp, exp(-2pi * (200 * SampleDur.ir)));\r\n        spacewarp = spacewarp - OnePole.ar(spacewarp, exp(-2pi * (200 * SampleDur.ir)));\r\n \r\n        engine = (spacewarp + fourstroke)!2 * 0.5;\r\n \r\n        Out.ar(0, engine);\r\n \r\n}).play;\r\n)\r\n\r\n\r\n//For testing so many different parameters at once, a device with multiple controllers is your best friend.\r\n\r\nMIDIIn.connectAll;\r\n(\r\n        var transFreq = Array.newClear(3);      \r\n \r\n        MIDIFunc.cc({ |val, num|\r\n                switch( num, \r\n                1,      {e.set(\\wguideFeedback, (val/128).range(0,1).postln)},\r\n                2,      {e.set(\\mixParabolic, (val/128).range(0,1).postln)},\r\n                3,      {e.setn(\\overtoneFreq, transFreq.put(0, (val/128).range(0,1)).postln)},\r\n                4,      {e.setn(\\overtoneFreq, transFreq.put(1, (val/128).range(0,1)).postln)},\r\n                5,      {e.setn(\\overtoneFreq, transFreq.put(2, (val/128).range(0,1)).postln)},\r\n                6,      {e.set(\\parabolicDelay, (val/128).range(0,1).postln)},\r\n                7,      {e.set(\\warpDelay, (val/128).range(0,1).postln)},\r\n                8,      {e.set(\\waveguideWarp, (val/128).range(0,1).postln)},\r\n                )       \r\n        });\r\n \r\n)\r\n\r\n\r\n\r\n// code also available here:\r\n// http://en.wikibooks.org/wiki/Designing_Sound_in_SuperCollider/Cars",
   "id" : "1-4RH",
   "is_private" : null,
   "author" : "DSastre",
   "name" : "Cars",
   "description" : "A \"toy\" engine, a four cylinder engine with slugging speed and an advanced engine  example. Based on pure data code from the book \"Designing Sound\" by Andy Farnell. (Chapter 45)",
   "ancestor_list" : []
}
