ScalaCollider

hey,

just to let you know i’m working a bit on a scala based supercollider client; part of it is a base platform with all the standard ugen graph creation you know from sclang. this base platform is still quite “alpha”, but for example i got all the examples from SC2-examples_1.scd running now. lot’s of ugens missing still, and most of the buffer stuff.

check out the code at

http://github.com/Sciss/ScalaCollider

see the readme for requirements. feel to contact me if you like to be working along on this.

below is a bit (to be executed in the REPL) to show you that some stuff can be almost as concise and almost the same syntax as sclang.

ciao, -sciss-

s.boot

// analog bubbles
val x = play {
   val f = LFSaw.kr(0.4).madd(24, LFSaw.kr(List(8, 7.23)).madd(3, 80)).midicps; // glissando function
   CombN.ar(SinOsc.ar(f)*0.04, 0.2, 0.2, 4) // echoing sine wave
}

x.free

// harmonic swimming
val x = play {
   val f = 50       // fundamental frequency
   val p = 20       // number of partials per channel
   var z: GE = 0.0  // start of oscil daisy chain
   val offset = Line.kr(0, -0.02, 60)    // causes sound to separate and fade
   for( i <- 0 until p ) {
       z = FSinOsc.ar( f * (i+1) ).madd( // freq of partial
           LFNoise1.kr(
               List( Rand( 2, 10 ), Rand( 2, 10 ))).madd(  // amplitude rate
               0.02,    // amplitude scale
              offset    // amplitude offset
           ).max( 0 ),  // clip negative amplitudes to zero
           z
       )
   }
   z
}

x.free

// aleatoric quartet
// mouse x controls density
val x = play {
   val amp = 0.07
   val density = MouseX.kr(0.01,1)   // mouse determines density of excitation

   // calculate multiply and add for excitation probability
   val dmul = density.reciprocal * 0.5 * amp
   val dadd = dmul.neg + amp

   var signal = Mix.fill(4) {   // mix an array of 4 instruments
       val excitation = PinkNoise.ar(
           // if amplitude is below zero it is clipped
           // density determines the probability of being above zero
           max(0, LFNoise1.kr(8).madd(dmul, dadd))
       )

       val freq = Lag.kr(             // lag the pitch so it glissandos between pitches
           LFNoise0.kr(               // use low freq step noise as a pitch control
               Array(1, 0.5, 0.25)(   // choose a frequency of pitch change
                   scala.util.Random.nextInt(3))).madd(
               7,                     // +/- 7 semitones
               IRand(36, 96)          // random center note
           ).round(1),                // round to nearest semitone
           0.2                        // gliss time
       ).midicps                      // convert to hertz

       Pan2.ar(    // pan each intrument
           CombL.ar(excitation, 0.02, freq.reciprocal, 3),    // comb delay simulates string
           Rand(-1,1)    // random pan position
       )
   }

   // add some reverb via allpass delays
   for(i <- 1 to 5) { signal = AllpassN.ar(signal, 0.05, List(Rand(0,0.05),Rand(0,0.05)), 1) }
   LeakDC.ar( signal, 0.995)    // delays build up a lot of DC, so leak it out here.
}
 

Leave a Comment.

This site uses Akismet to reduce spam. Learn how your comment data is processed.