Overtone Adventures 2

Created 2013-12-25 / Edited 2015-10-18

Tags: Clojure, Overtone, Music

Today I'm watching Overtone and ClojureScript which is a coding session of someone setting up an web UI to play Overtone stuff. Building a UI like this reminds me of the one-string guitar that I got at an art festival the other day. Clearly home-made, including an energy drink as the echo chamber. And very awesome. Also fun to see someone iterate through their development. Lots of interesting things in there, most of them I can read more or less but doesn't mean I could write them. One thing I noticed was (:use ...) to pull in instrument libs. I'll try that.

The Cheat Sheet is interesting, but I don't know enough to actually use a lot of the things on there. Current mission is to get the instruments working.

Ah! I need to do (use 'overtone.inst.piano) not (:use overtone.inst.piano).

  • Now (piano) plays a note!
  • (odoc note) shows that it takes a bunch of params
  • (piano 60), (piano 65), etc plays some nice piano notes
  • I looked up named parameteters in clojure. (piano 65) does what I want
  • Achievement unlocked ... I can now use all the intstruments on the cheat sheet!
  • Now when I do "(piano 60) (piano 65) (piano 69)" (still in REPL) it plays all three notes at once. Need to learn how to sequence things.
  • I think I'll go back to that workshop video
  • At 13:40 they talk about sequencing things
  • Play a piano note in 1 second (at (+ 1000 (now)) (piano))
  • From their tutorial, I created:
    ** (defn loop-beats time (at (+ 500 time) (kick)) (at (+ 1000 time) (open-hat)) (apply-at (+ 1500 time) loop-beats (+ 1500 time) ))
    ** (loop-beats (now))
    ** (stop)
    ** I don't know exactly what that last is for. (odoc apply-at) says it is "argseq" but gives no explanation.
    ** In general this is "temorial recursion" -- delays a bit before calling back
    ** As far as I can tell this does create new stack frames! Will eventually run out. I know this because I accidentally put the loop-beats recursion in parens which invoked it.
  • Following the tutorial, I transformed it to use a metronome:
    ** (def metro (metronome 180))
    ** (defn loop-beats m beat-num (at (m (+ 0 beat-num)) (kick)) (at (m (+ 1 beat-num)) (open-hat)) (apply-at (m (+ 2 beat-num)) loop-beats m (+ 2 beat-num) ))
    ** Get it started: (loop-beats metro (metro))
    ** Change the temp live! (metro 200)
    ** Stop it (stop)
  • Instruments take 'notes' (midi numbers), though some things take hz
  • Symbolic notes can be turned into midi numbers via (note )
  • Can map a sequence of symbolic notes to midi numbers (map note )
  • Now I can make a general purpose play-note-sequence function. I'll just make it play on the beat.
(defn play-song [metro beat-num notes] (map-indexed (fn [index n] (at (metro (+ index beat-num)) (piano :note (note n))) ) notes) ) ```
  • (play-song metro (metro) )
  • OK. Midi time! Looking at Overtone wiki MIDI page
  • Fired up jack-keyboard (software midi keyboard) since I'm not at home
  • Apparently software midi doesn't get immediately detected. "modprobe snd-virmidi" gave me something I can connect to in jack
  • Had to restart overtone
  • Now I have BUNCHES of midi connections when I do (midi-connected-devices) -- like 64 of them. Too many.