Chris has gotten me interested into an open source toolkit for creating sounds and making music called Overtone. Here’s a talk about demonstrates functional composition using clojure through music and overtone.
That talk made me want to play with overtone. Here’s the diary of my workstation setup.
Thinking I know what I’m doing I say “So, Overtone is in Clojure, right? So I’ll first install that.”. To which he replied “No, you need to install Leiningen.”. What?! I want to install clojure, why do I need this oddly named tool? Already my world has been turned upside down.
Leiningen is a package manager for Clojure. I can’t say I understand completely what it’s doing, but when I did a
sudo port install leiningen I saw Maven was being installed. Chris calmed me down and said that
lein hides the pain so I don’t have to worry about it.
Sure enough, the install works. I run
lein new mucmusic and a simple project structure is setup for me. I updated the
project.clj to refer to the 1.4.0 version of Clojure.
I then run
lein repl and see the package manager at work. It downloads Clojure for me and I’m in a repl. I try the most basic thing I know
(+ 1 1) and it works! I can only imagine what’s going on behind the scenes. I find it interesting that a package management tool is responsible for obtaining the language you’re going to develop in. It makes a whole lot of sense actually. It’s sort of like virtualenv, but not quite.
Since I’m still coming to grips on writing code in Clojure I can’t comment on the language, but what I really like so far is how accessible the documentation is. Simply evaluating
(doc +) will print the documentation for ‘+’ function and
(source +) prints out the source code. The REPL made it very easy to get started.
One thing that tripped me up was using a namespace I had defined. I learned the the ‘ character is used to indicate the following text is a symbol and not to be evaluated. Also, the first project I created had an underscore in it. In order to use that namespace I had to use a hyphen when using it.
Happy that I can write and evaluate Clojure code it was time to setup Overtone. This part was really nice. All I did was update the
project.clj file and added the overtone dependency. The next time I ran
lein repl it downloaded overtone and set everything up for me.
In the repl I loaded overtone via
(use 'overtone.live) and here’s the output:
reply.eval-modes.nrepl=> (use 'overtone.live) --> Loading Overtone... --> Booting internal SuperCollider server... --> Connecting to internal SuperCollider server... --> Connection established _____ __ / __ /_ _____ _____/ /_____ ____ ___ / / / / | / / _ \/ ___/ __/ __ \/ __ \/ _ \ / /_/ /| |/ / __/ / / /_/ /_/ / / / / __/ \____/ |___/\___/_/ \__/\____/_/ /_/\___/ Collaborative Programmable Music. v0.8 Hello ThoughtWorks, just take a moment to pause and focus your creative powers...
Woah! Booting internal SuperCollider server? Is Clojure so powerful that I can run my own atom smasher?
Turns out the answer is unknown on that, but what
overtone.live does is smartly start up
SuperCollider which is “an environment and programming language
for real time audio synthesis and algorithmic composition”. Ahh! So overtone needs this to actually
I continue to follow the README and make my first sound.
This code rewards me with the beautiful sound that is a sine wave. Curious as to what
do I load up the docs in the repl.
overtone.live/demo ([& body]) Macro Listen to an anonymous synth definition for a fixed period of time. Useful for experimentation. If the root node is not an out ugen, then it will add one automatically. You can specify a timeout in seconds as the first argument otherwise it defaults to *demo-time* ms. See #'run for a version of demo that does not add an out ugen. (demo (sin-osc 440)) ;=> plays a sine wave for *demo-time* ms (demo 0.5 (sin-osc 440)) ;=> plays a sine wave for half a second nil user=> (doc sin-osc) ------------------------- overtone.live/sin-osc ([freq phase]) Sine table lookup oscillator [freq 440.0, phase 0.0] freq - Frequency in Hertz phase - Phase offset or modulator in radians Outputs a sine wave with values oscillating between -1 and 1 similar to osc except that the table has already been fixed as a sine table of 8192 entries. Sine waves are often used for creating sub-basses or are mixed with other waveforms to add extra body or bottom end to a sound. They contain no harmonics and consist entirely of the fundamental frequency. This means that they're not suitable for subtractive synthesis i.e. passing through filters such as a hpf or lpf. However, they are useful for additive synthesis i.e. adding multiple sine waves together at different frequencies, amplitudes and phase to create new timbres. Categories: Generators -> Deterministic Rates: [ :ar, :kr ] Default rate: :ar
No wonder people love programming in clojure! This idea of the documentation living in the code is wonderful. I’m generally used to googling for a function name, but this makes that step unnecessary.
Chris, like myself, also uses Vim. So first thing I wanted to do is get some syntax highlighting. Chris points me to vimclojure-easy, but I didn’t want to replace my vim configuration. I already maintain my vim in a tidy and versioned way. Looking at the this repo gave me the direction I needed to set this up. I cloned VimClojure into my
~/.vim/bundle directory (and removed its .git directory). I launch vim on a clojure file and I have syntax highlighting!
lein-tarsier and nailgun
Thinking I was complete I tried some of the vim shortcuts to evaluate some clojure from within vim. Then I realized I’m not quite done (feels like my visit to the FRRO. This is now where the JVM comes in. Clojure is a JIT compiled language. In order to compile, it needs a JVM. Starting up a JVM all the time is a very slow and painful process.
Lein-tarsier (tarsier is the type of creature on the O’Reilly Vim book is a lein plugin that starts up a VimClojure server. To install this, I just added it to my lein profile. It didn’t work at first, but that was because MacPorts installs version 1.6 of lein. Nailgun was some C code that you have to download a compile and make reference to it in your vimrc. I’m sort of lost on how all these components work together.
lein upgrade got me to version 2.0. Then an execution of
lein vimclojure and the server is up and running.
After installing a bunch of oddly named things I was able to play the pieces from Chris’ talk in vim.
There were some details that I left out (and forgot). I don’t think I would have gotten this far without help from Chris
and the considerable documentation that’s in the README files and wikis. Part of me also thinks that it shouldn’t
require this much work. As a side project, I’m going to look into pulling all of these steps into a Vagrant
configuration management setup. I think it would be nice to go
vagrant up overtone and have a working overtone