Saturday, August 25, 2012

Using tmux to hack Clojure in a shared terminal

After our experiences trying and failing to get swarm working at the recent Clojure dojo (probably because I don't have emacs 24), we had a play with using tmux directly, which seemed to work quite well. Here are the steps that we went through

First, you need tmux. I'm not sure about other platforms but, on Ubuntu, it's available in the default repositories:

$ sudo apt-get install tmux

Next, you'll need a user id to run the terminal in, unless you really trust your friends. We used the user id that we had already created in our failed attempt to run swarm:

$ sudo useradd swarm

Once your new user account is set up the way that you want, you can su to that user and run the following to create your tmux session:

$ tmux new -s swarm

Your friends can now ssh to your machine (you'll need to share a password or set up some other form of authentication) and run the following to connect to the session:

$ tmux attach-session -t swarm

We were then able to run emacs -nw to launch emacs within the terminal; it should be possible to run vi  just as easily.

One slight annoyance was having to set up emacs starter kit and leiningen for the new user id but it wasn't too onerous.

Once all that was done, you get something that looks like this:

It's not insanely flashy but it's enough to give you something to share on a projector screen and start coding.

You could probably improve this massively by configuring the user id to connect to the tmux session at login time but, for now, this was enough for us and our little dojo.

Thursday, August 16, 2012

Jamming With Overtone at the London Clojure Dojo

At Wednesday's Clojure Dojo, we succeeded in connecting multiple slime clients to one swank server, enabling us to "jam" together in Overtone, with me controlling the bass and Jen playing notes and samples over the top. There was some interest in how we got this working so here it is:

Firstly, we needed some ready-made code to start playing with so we cloned Overtone from here onto my laptop:

Next, we decided to use Sam Aaron's internal sequencer example which you can see in this video:

The example is located in the overtone source tree so I opened it in emacs: src/overtone/examples/timing/internal_sequencer.clj

Next, I added the following to my project.clj in order to enable the leiningen swank plugin:

:plugins [[lein-swank "1.4.4"]]

Back in emacs, I ran M-x clojure-jack-in to start the swank server and connect to it. This worked fine but the others weren't able to connect because the swank server started by clojure-jack-in very sensibly listens for connections only from localhost.

I therefore disconnected from the swank server by running M-x slime-disconnect. I didn't kill the repl buffer at this point for reasons that will become clear in a moment.

Next, I returned to the command line and ran:

lein swank 4005

This tells the swank server to listen for connections on port 4005 from any host. After opening up that port in the firewall, the others were able to connect.

Having done that, we were all able to connect to the server by running M-x slime-connect in emacs and giving it my ip address and port 4005. Note that we needed to have left the repl buffer open previously because, being emacs noobs, we haven't figured out how to get a repl buffer to open when we do slime-connect.

It should be pointed out at this point that swank isn't secure and, while it was running, it would have been possible for someone to connect and evaluate:

(.. Runtime (getRuntime) (exec "rm -r ~/*"))

Worse, they could have screwed around with our synths!

The hacking was now ready to begin. Our version of Sam Aaron's internal sequencer example can be found here:

We only made a few changes to it. The first was to load in some awesome samples:

(def something-s (sample (freesound-path 8323)))
(def heart-s (sample (freesound-path 16309)))
(def bovine-cow-s (sample (freesound-path 16568)))
(def jet-s (sample (freesound-path 9088)))
(def cackle-s (sample (freesound-path 80187)))

... which Jen could then play by evaluating the samples like a function in order to really get in touch with our totem animals:


I created a few really short functions so that I could control the bass and treble on the fly:

(defn b [note]
  (ctl dubstep
     :note note
     :wobble (* BEAT-FRACTION 1.2)
     :lag-delay 0.5
     :hi-man 0
     :lo-man 1
     :deci-man 0)
(defn t [note]
  (supersaw2 (midi->hz note) :amp 1 :fil-mul ssaw-fil-mul :rq ssaw-rq)

I was then able to get on stage and "wow" everyone with simple basslines while Jen played samples over wireless from back in the audience. While it was pretty simple stuff in the grand scheme of things, I'm quite pleased with how easy it is to do totally awesome things in Overtone with (in my case) little experience. Overtone rocks.

The only thing that I wasn't happy with was our inability to get a repl to come up when we did slime-connect. If anyone knows a bit more about emacs and slime than me and has this figured out then please let me know!