2 //a study for recreating key (sound) aspects of data.microhelix by Ryoji Ikeda
3 //Batuhan Bozkurt 2009 http://www.earslap.com
5 //rhythm logic: very crude, times are 1/8's mixed with 1/4's (equal probability) plus 1/16.
6 //when 1/16 is chosen, we make sure they come in doubles so it sounds rhytmically nicer.
7 //we create 2 instances of these trigs so glitching sound will be independent between speakers.
8 //we use TDuty with Demand UGens to create this kind of sophisticated triggers (easier and more
9 //flexible dealing with pure noise generators).
14 Dxrand(((1/8!8) ++ (1/4!8) ++ [Dseq([1/16, 1/16], Drand([1, 2], inf))]) * 1.25, inf), //see above logic
16 Dwhite(0.5, 1, inf) //trigger values are between 0.5, 1
20 //the glitch/clicking noises: basically enveloped PinkNoise through bandpass filter with high rq (low q)
21 //here I'm modulating the decay time of the noise envelope with a LFNoise1.
22 //there are many diferent ways of approaching this, needs experimentation,
23 //dynamic center freq, rq etc. can be employed for example. This sounded nice to me, however.
28 PinkNoise.ar(Decay.ar(ctrigs, 0.001 * LFNoise1.ar(4).abs)), //decay time is modulated
31 25 * LFNoise1.ar(8).range(0, 1) //extreme amplification of glitches.
32 ).fold(-1, 1); //folding them back into [-1, 1] range (foldback distortion). I think it sounds nice.
34 //i don't really know what to call this sound, so its names snd1. 2 sine oscillators tuned by ear, with filtered
35 //background noise. nothing fancy. we will random-pan and envelope this later on.
39 SinOsc.ar(44.midicps, 0, 0.5) + SinOsc.ar(90.midicps, 0, 0.6),
41 ) + HPF.ar(LPF.ar(WhiteNoise.ar(0.008), 12000), 2400);
43 //the shaker-like sound in the background. in the original piece, the rhytmical logic for this sound
44 //is a lot more different, I'm using the same ctrigs here, for the sake of simplicity (and I'm a bit lazy).
45 //its basically an enveloped WhiteNoise through a bandpass filter with a random freq
49 WhiteNoise.ar(Decay2.ar(ctrigs * LFNoise1.ar(8, 0.5, 0.5), 0.02, 0.1) * 0.05),
50 TRand.ar(12000, 15000, ctrigs),
54 //the bass/kicky sound needs a lot of tuning (sound and envelope, some best be left to post processing maybe)
55 //2 sine oscillators, one has a low freq nad the other is an upper harmonic (quieter)
56 //the original piece uses a completely different (and very better) rhytmical logic for this sound.
57 //I'm using our ctrigs impulse generator here (first channel) for the sake of clarity.
58 //but since I don't want every trigger to activate this, I'm multiplying the trigger with
59 //a noise generator (rounded, so its -1, 0, or 1). so not all trigs pass through.
61 //the sine oscillator uses a trick I've learned from Josh Parmenter. the freq arguments of the
62 //sine oscillators are set to zero, and they are driven by the phase argument with a sweep.
63 //this makes the oscillator phase resettable which is very useful for having uniform attacks
64 //for low frequency kick-like sounds. or else, the envelope sounding the oscillators can kick
65 //in at any phase and the attack of the kicks will vary (in a bad way). here I reset the phase
66 //of the sine at each trigger. the speed of the phase driver ([52.8, 740]) determines the
67 //frequency of the oscillator here. I'm adding a phase of pi/3 to it so the phase resets to
68 //pi/3 instead of zero which produces an additional glitch. this is all about glitch after all right?
70 var trigMod = LFNoise0.ar(8).round;
73 SinOsc.ar(0, (Sweep.ar(ctrigs[0] * trigMod, 2pi * [52.8, 740]) + (pi/3)).wrap(-pi, pi), [2, 0.05]).mean.tanh *
74 EnvGen.ar(Env([0, 0.5, 0.4, 0], [0, 0.2, 0.01], -5), (ctrigs[0] * trigMod).abs)!2;
76 //panning and enveloping of snd1. I don't want to use every trigger for the envelope of this so
77 //i again multiply it with a random generator. not all trigs pass through. and some random panning.
81 snd1 * EnvGen.ar(Env([0, 1, 0.6, 0], [0.0001, 0.4, 0.01]), ctrigs * LFNoise0.ar(8)),
82 TRand.ar(-1, 1, ctrigs)
85 //i'm using limiter here because i'm lazy. one needs to get the
86 //gain scheduling right for a better sound. this especially kills the bass
87 //sometimes. I'm also boosting the freqs around 15000Hz.
88 //delete some sounds from the input of MidEQ to hear the sounds
89 //(glitches, bass etc) in isolation.
90 Limiter.ar(MidEQ.ar(clicks + snd1 + hiNoise + bass, 14000, 0.7, 8));