Skip to content

Instantly share code, notes, and snippets.

@rndmcnlly
Created May 4, 2012 22:34
Show Gist options
  • Save rndmcnlly/2598145 to your computer and use it in GitHub Desktop.
Save rndmcnlly/2598145 to your computer and use it in GitHub Desktop.
snapshot of cfml in scala
package as.adamsmith.riddle.instructions
import java.util.concurrent._
object InstructionBuilders {
def after[A](children: Instruction[A]*) = children.reduce(After(_, _))
def during[A](children: Instruction[A]*) = children.reduce(During(_, _))
def choose[A](children: Instruction[A]*) =
Resolve(() => children((math.random * children.length).asInstanceOf[Int]) )
def call[A](f: => Instruction[A]) = Resolve(() => f)
def halt[A] = Halt[A]()
def nop[A] = Nop[A]()
def pulse[A](count: Int, duration: Long, job: A => Unit): Instruction[A] =
repeat(count, after(delay(duration), exec(job)))
def rotate[A](children: Instruction[A]*) = {
var i: Int = 0
Resolve(() => {
val kid = children(i % children.length)
i += 1
kid
})
}
def loopWhile[A](pred: => Boolean, child: Instruction[A]): Instruction[A] =
Resolve(() =>
if (pred) After(child, loopWhile(pred, child)) else Nop()
)
def repeat[A](count: Int, child: Instruction[A]) =
List.fill(count)(child).reduce(After(_,_))
def forever[A](child: Instruction[A]): Instruction[A] =
after(child, Resolve(() => forever(child)))
def exec[A](f: A => Unit) = Exec[A]((s,t) => f(s))
def tweak[A](f: A => A, child: Instruction[A]) = Tweak[A]((s,t) => f(s), child)
def delay[A](dur: Long) = Delay[A](dur)
}
object Instruction {
def now: Long = System.currentTimeMillis
val anticipationMillis = 0L
private var service: Option[ScheduledExecutorService] = None
private def ensureServiceable {
synchronized {
if (service.isEmpty) {
service = Some(Executors.newSingleThreadScheduledExecutor())
}
}
}
def schedule(cmd: () => Unit, whenMillis: Long) {
synchronized {
assume(service.isDefined)
service.get.schedule(new Runnable {
def run() = cmd()
}, whenMillis - now, TimeUnit.MILLISECONDS)
}
}
def shutdown() {
synchronized {
assume(service.isDefined)
service.get.shutdownNow()
service = None
}
}
def launch[A](instruction: Instruction[A], initialState: A, onComplete: () => Unit) {
ensureServiceable
schedule(() => execute(instruction, initialState, now, { t => onComplete() }), now)
}
def execute[S](instruction: Instruction[S], s: S, t: Long, k: Long => Unit): Unit = {
instruction match {
case Halt() => Instruction.schedule(() => shutdown(), t)
case Nop() => k(t)
case Spawn(child) => {
execute(child, s, t, _=>())
k(t)
}
case Exec(f) => {
schedule(() => f(s, t), t)
k(t)
}
case Delay(dur) =>
schedule(() => k(t + dur), t + dur - anticipationMillis)
case During(left, right) => {
var other: Option[Long] = None
def complete(dur: Long) =
other match {
case None => other = Some(dur)
case Some(otherDur) => k(math.max(dur, otherDur))
}
execute(left, s, t, complete)
execute(right, s, t, complete)
}
case After(l, r) => execute(l, s, t, { later => execute(r, s, later, k) })
case Resolve(thunk) => execute(thunk(), s, t, k)
case Tweak(f, child) => execute(child, f(s, t), t, k)
}
}
}
sealed trait Instruction[A]
case class Halt[A]() extends Instruction[A]
case class Nop[A]() extends Instruction[A]
case class Spawn[A](child: Instruction[A]) extends Instruction[A]
case class Exec[A](f: (A, Long) => Unit) extends Instruction[A]
case class Delay[A](dur: Long) extends Instruction[A]
case class After[A](left: Instruction[A], right: Instruction[A]) extends Instruction[A]
case class During[A](left: Instruction[A], right: Instruction[A]) extends Instruction[A]
case class Resolve[A](thunk: () => Instruction[A]) extends Instruction[A]
case class Tweak[A](f: (A, Long) => A, child: Instruction[A]) extends Instruction[A]
package as.adamsmith.riddle
import as.adamsmith.riddle.instructions._
import as.adamsmith.riddle.instructions.InstructionBuilders._
import net.beadsproject.beads.core._
import net.beadsproject.beads.ugens._
import net.beadsproject.beads.data._
object Main extends App {
val filename =
"39914__digifishmusic__katy-sings-laaoooaaa.wav"
val samp = SampleManager.sample(getClass.getClassLoader.getResourceAsStream(filename))
val ac = new AudioContext()
val players = List(
new SamplePlayer(ac, samp),
new SamplePlayer(ac, samp) { setPitch(new Static(ac, 1.5f)) },
new SamplePlayer(ac, samp) { setPitch(new Static(ac, 0.5f)) })
val rev = new Reverb(ac, 2) {
setDamping(0f)
}
val g = new Gain(ac, 1, 1.5f)
players foreach (rev addInput _)
g addInput rev
ac.out addInput g
ac.start()
def doSkip(s: Map[SamplePlayer,Float]) =
for ((player, pos) <- s)
player.setPosition(pos)
def shiftSkip(s: Map[SamplePlayer,Float]) =
(for(p <- players) yield p -> (samp.getLength*math.random).toFloat).toMap
val root: Instruction[Map[SamplePlayer,Float]] =
forever(tweak(shiftSkip, pulse(32, 125L, doSkip)))
Instruction.launch(
root,
(for(p <- players) yield p -> 0f).toMap,
{ () => ac.stop(); System.exit(0) })
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment