// title: The Tunnel // author: Schemawound // description: // This code contains three sections, the first defines the synthdef. // The second starts up the synth and the GUI for playing with the presets live. // The third is used to render out the completed album version of the song. // // The song can be downloaded as part of the free compilation 'Far, Far Away', released by Waxen Wings. // http://waxenwings.bandcamp.com/album/far-far-away // // I have written a blog post detailing the code and the revisions it went through // http://schemawound.tumblr.com/post/21065032399/the-tunnel // // Or if you are lazy and just want to hear it // http://soundcloud.com/schemawound/the-tunnel-1 // code: /* This code contains three sections, the first defines the synthdef. The second starts up the synth and the GUI for playing with the presets live. The third is used to render out the completed album version of the song. The song can be downloaded as part of the free compilation 'Far, Far Away', released by Waxen Wings. http://waxenwings.bandcamp.com/album/far-far-away I have written a blog post detailing the code and the revisions it went through http://schemawound.tumblr.com/post/21065032399/the-tunnel Or if you are lazy and just want to hear it http://soundcloud.com/schemawound/the-tunnel-1 */ (//----------Tunnel SynthDef---------- SynthDef(\TheTunnel, { | out = 0, amp = 1, lfo1Speed = 0.1, lfo1Depth = 100, lfo2Speed = 0.25, lfo2Depth = 600, osc1Freq = 7, loSineFreq = 30, loSineAmp = 0.5, clip1Amp = 6, clipModFreq = 500, clip2Amp = 6, verbLfoSpeed = 0.014, verbLfoDepth = 1, verbRoom = 1, verbDamp = 0.5 | var loSine = SinOsc.ar(loSineFreq, 0, loSineAmp); //Osc1 var osc1 = SinOsc.ar(osc1Freq); //Osc2 var lfo1 = LFSaw.ar(lfo1Speed, 0, 0.5, 0.5); //Make positve only var osc2 = SinOsc.ar(lfo1 * lfo1Depth); //Osc3 var lfo2 = LFSaw.ar(lfo2Speed, 0, 0.5, 0.5); //Make positve only var osc3 = SinOsc.ar(lfo2 * lfo2Depth); //Sum and Clip var clip1 = ((osc1 * osc2 * osc3) * clip1Amp).distort * SinOsc.ar(clipModFreq); //Output var output = (clip1 * clip2Amp).distort * 0.5 + loSine; var verbLfo = (SinOsc.ar(verbLfoSpeed) * 0.5 + 0.5) * verbLfoDepth; var verb1 = FreeVerb.ar(output, verbLfo, verbRoom, verbDamp, amp); Out.ar(out, verb1!2 * 0.5); }, [0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]).add; ) ( //----Start Synth---- ~tunnelSynth = Synth(\TheTunnel); //----Preset---- ~tunnelPreset = (); ~tunnelPreset.current = 0; ~tunnelPreset.list = [ // amp, lfo1Speed, lfo1Depth, lfo2Speed, lfo2Depth, osc1Freq, loSineFreq, loSineAmp, clip1Amp, clipModFreq, clip2Amp, verbLfoSpeed, verbLfoDepth, verbRoom, verbDamp /*00*/ [ 1, 0.1, 100, 0.25, 600, 7, 30, 0.5, 6, 500, 6, 0.014, 1, 1, 0.5 ], /*01*/ [ 1, 30.756, 628.79, 0.25, 600, 35.412, 11.8, 0.5, 6, 500, 6, 0.151, 0.204, 1, 1 ], /*02*/ [ 1, 48.345, 446.41, 45.021, 694.56, 14.97, 42.53, 0.14, 1.833, 168.49, 1, 0.014, 0.314, 1, 0 ], /*03*/ [ 1.163, 0.507, 1000, 6.285, 317.08, 34.579, 31.77, 0.5, 3.672, 44.59, 3.492, 0.316, 0.49, 0.461, 1 ], /*04*/ [ 1.392, 0.507, 288.03, 0.67, 317.08, 10.449, 88.06, 0.37, 2.557, 44.59, 3.492, 0.155, 1, 1, 1 ], /*05*/ [ 0.575, 100, 1000, 96.903, 1000, 50, 88.06, 1.22, 6, 127.37, 6, 0.167, 0.493, 1, 1 ], /*06*/ [ 3.2, 1, 101.3, 1.5, 74.79, 11.691, 5.2, 0, 3.225, 49.8, 2.754, 0.51, 0.494, 0.784, 0.497 ], /*07*/ [ 2.505, 0.001, 80.79, 100, 306.59, 11.691, 5.2, 0, 3.225, 49.8, 3.734, 0.273, 0.656, 0.784, 0.889 ], /*08*/ [ 0.9, 71.939, 631.92, 72.476, 427.99, 17.475, 96.68, 0.56, 4.298, 496.15, 5.649, 0.804, 0.694, 0.303, 0.461 ], /*09*/ [ 0.6, 34.043, 650.05, 29.176, 480.98, 30.836, 66.66, 1.13, 2.401, 205.91, 2.664, 0.173, 0.778, 0.517, 0.88 ], /*10*/ [ 0.54, 22.558, 217.5, 91.033, 520.13, 3.484, 84.09, 1.59, 2.731, 259.07, 5.919, 0.571, 0.988, 0.133, 0.0 ] ]; ~tunnelPreset.load = { |ev| var current = ev.current; ~tunnelSynth.set(\amp, ev.list[current][0]); ~tunnelSynth.set(\lfo1Speed, ev.list[current][1]); ~tunnelSynth.set(\lfo1Depth, ev.list[current][2]); ~tunnelSynth.set(\lfo2Speed, ev.list[current][3]); ~tunnelSynth.set(\lfo2Depth, ev.list[current][4]); ~tunnelSynth.set(\osc1Freq, ev.list[current][5]); ~tunnelSynth.set(\loSineFreq, ev.list[current][6]); ~tunnelSynth.set(\loSineAmp, ev.list[current][7]); ~tunnelSynth.set(\clip1Amp, ev.list[current][8]); ~tunnelSynth.set(\clipModFreq, ev.list[current][9]); ~tunnelSynth.set(\clip2Amp, ev.list[current][10]); ~tunnelSynth.set(\verbLfoSpeed, ev.list[current][11]); ~tunnelSynth.set(\verbLfoDepth, ev.list[current][12]); ~tunnelSynth.set(\verbRoom, ev.list[current][13]); ~tunnelSynth.set(\verbDamp, ev.list[current][14]); }; //----------Tunnel GUI---------- ~tunnelWindow = Window( "The Tunnel", Rect( 128, 230, 110, 140)); ~tunnelWindow.view.decorator = FlowLayout( ~tunnelWindow.view.bounds ); ~tunnelPreset.list.do({|each, count| (Button(~tunnelWindow, 30@30).states = [[count]]).action = {(~tunnelPreset.current = count).load;};}); ~tunnelWindow.front; ~tunnelWindow.onClose = {~tunnelSynth.free;}; //Kill the gui if the user kills the sound CmdPeriod.doOnce({ ~tunnelWindow.close; }); ) (//---------Perform Song---------- ~tunnelTask = Task({ ~tunnelSynth.free; s.recChannels = 2; s.recHeaderFormat = "AIFF"; s.recSampleFormat = "int24"; s.prepareForRecord("C:\\Users\\Jennifer\\Jon\\Code\\thetunnel.aiff"); s.record; ~tunnelSynth = Synth(\TheTunnel, [\amp, 0]); 1.wait; ~tunnelSynth.set(\amp, 1); 128.wait; ~tunnelSynth.set(\amp, 0.7); ~tunnelSynth.set(\clip1Amp, 100); ~tunnelSynth.set(\clip2Amp, 100); 30.wait; (~tunnelPreset.current = 2).load; 15.wait; (~tunnelPreset.current = 6).load; 30.wait; ~tunnelSynth.set(\amp, 0); 35.wait; ~tunnelSynth.free; s.stopRecording; }); ~tunnelTask.play; )