‹ Audiovisuals with SC - Example15 - whitney ballsAudiovisuals with SC - Example17 - ffttrack ›

Audiovisuals with SC - Example16 - amptrack

See /f0blog/audiovisuals-with-sc/

//Example16 - amptrack
(
s.latency= 0.05;
s.waitForBoot{
  c= Buffer.read(s, Platform.resourceDir+/+"sounds/a11wlk01.wav");
  SynthDef(\avTrk, {|in, t_trig, time= 0.01, cutoff= 400, index= 0|
    var z= In.ar(in, 1);
    var val= Amplitude.kr(BPF.ar(BPF.ar(z, cutoff, 0.1, 5), cutoff, 0.1, 5), time, time);
    SendTrig.kr(t_trig, index, val);
  }).add;
  SynthDef(\avSnd, {|out= 0, bufnum|
    var z= PlayBuf.ar(
      1,
      bufnum,
      BufRateScale.ir(bufnum)*LFPulse.kr(0.05, 0, 0.5, 0.2, -1.5),
      Impulse.kr(LFPulse.kr(0.1, 0, 0.1, 2, 1)),
      BufFrames.ir(bufnum)*LFNoise0.kr(0.2, 0.5, 0.5).round(0.2),
      1
    );
    Out.ar(out, Pan2.ar(z));
  }).add;
};
)

(
//--window setup
var width= 500, height= 500;
var w= Window("Example16 - amptrack", Rect(99, 99, width, height), false);
var u= UserView(w, Rect(0, 0, width, height));

//--variables
var num= 100;  //number of tuned filter synths
var cnt= 0;  //vertical drawing position
var amps= 0.dup(num);  //array of current amplitudes
var o= OSCFunc({|m| amps= amps.put(m[2], m[3])}, '/tr', s.addr);
var syns= {|i|  //each tracker with an unique peakfilter
  Synth(\avTrk, [\in, 0, \index, i, \cutoff, i.linexp(0, num-1, 200, 6000)]);
}.dup(num);
var snd= Synth(\avSnd, [\out, 0, \bufnum, c]);  //something that generates sound

//--interface
~width= 120;
~speed= 1;
~version= 1;

//--main loop
u.drawFunc= {
  var wn= width/num;
  switch(~version,
    0, {
      Pen.translate(wn*0.5, cnt%height);
      amps.do{|amp, i|
        Pen.fillColor= Color.grey((amp).clip(0, 1));
        Pen.fillRect(Rect.aboutPoint(Point(wn*i, 0), wn*0.5, ~width));
      };
      cnt= cnt+~speed;
    },
    1, {
      amps.do{|amp, i|
        Pen.rotate(cnt, width*0.5, height*0.5);
        Pen.strokeColor= Color.grey(amp.clip(0, 1));
        Pen.strokeRect(Rect.aboutPoint(Point(wn*i, 0), ~width*0.1, ~width));
        cnt= cnt+(~speed*0.000001);
      };
    },
    2, {
      Pen.rotate(cnt, width*0.5, height*0.5);
      Pen.translate(width*0.5, height*0.5);

      amps.do{|amp, i|
        Pen.strokeColor= Color.grey(amp.clip(0, 1));
        Pen.strokeOval(Rect.aboutPoint(Point(i*~speed, 0), ~width*0.5, ~width*0.5));
      };
      cnt= cnt+(~speed*0.01);
    }
  );
  syns.do{|x| x.set(\t_trig, 1)};  //request amp data
};

//--window management
u.clearOnRefresh= false;  //do not erase - just draw on top of
w.onClose= {
  snd.free;
  syns.do{|x| x.free};
  o.free;
};
w.front;
CmdPeriod.doOnce({w.close});
Routine({
  var nextTime;
  while({w.isClosed.not}, {
    nextTime= Main.elapsedTime+(1/60);
    u.refresh;
    (nextTime-Main.elapsedTime).max(0.001).wait;
  });
}).play(AppClock);
)

//change these while the program is running
~width= 220;
~speed= 2;
~speed= -0.1;
~speed= pi;
~version= 0;
~width= 1;
~speed= 1;
~width= 10;
~speed= 10;
~width= 500;
~version= 2;
~width= 100;
~speed= 1;
~speed= -1.5;
~width= 20;

//close the window to stop or press cmd+.
c.free;  //free the sound file buffer