For a while now, I've been a little interested in Overtone and Emacs Live... but I haven't been particularly feeling the magic... for one thing, there are just too many hands in the pot. The "Emacs Live" experience is horribly unfamiliar, as it provides a "highly-cultivated Emacs experience" to somebody who already has a truly highly cultivated Emacs experience. The principles are poorly laid out. I don't have much time to dedicate to this, so I'm not too crazy on the idea of having to create my own sounds out of sine waves or using predefined goodies. It's cool that you can create otherworldly sounds or whatevs, but that's not for me.
My goal is to simply compose and play music on the fly.
So, where did Overtone go wrong? Well, it's too fucking complicated, for one thing. The whole damn thing should be convenience methods all the way down. Seriously. That's all I need.
Using Clojure (not lein, Emacs, cider or anything else), you can set up a primitive MIDI synthesizer in a few short lines of code:
(import 'javax.sound.midi.MidiSystem) (def synth (MidiSystem/getSynthesizer)) (def instruments (.getAvailableInstruments synth)) ; Convenience for later (def channel (nth (.getChannels synth) 0)) ; Just use one channel for now. (.programChange channel 9) ; Cool bell instrument (.noteOn channel 65 200) ; Play note 65
Oh! You wanna change instruments? First you've gotta find a new one. Easy enough:
(dotimes [i (count instruments)] (println (str i "-" (nth instruments i))))
That's just ugly enough that I want a convenience function. And I want it Emacs-convenient. Instead of using that println, the answer's almost assuredly going to be using let with a StringBuilder, then returning the sb.toString(). Anyhow, I get ahead of myself. The number can be used with the programChange for the channel. PROTIP: Reading the documentation in that tutorial really really helps... otherwise I'd not have known that using a method called loadInstrument has nothing to do with loading an instrument into a channel.
On that note, playing notes needs to be more convenient. Also, setting up a drumbeat with threads seems totally possible, but the code for it is, again, non-trivial. My imagination here tells me that the project really needs just a handful of defns, some Emacs keybindings for (insert ...) them really quickly into the current buffer/REPL, and a kickass tutorial explaining things.
As it stands, using Overtone to simply change instruments is a chore. For actually playing music, it sucks some pretty serious balls.
Here's the brainstorm, then: the project needs two parts: One for Emacs, and one for Clojure. The Clojure half could be used on its own. Despite Leiningen being a pretty cool means of organizing a project, maybe minimalism would be even better. A single .clj file is all that's really needed. It's going to have convenience stuff for the Java Interop required to make this thing go. Next, Emacs' half will be similarly light. I just need keyboard macros, mainly, for getting stuff into defs quickly.
I know some of the aspects of this project are appropriately cringe-worthy. We're not using Clojure for its awesome data structures (though melodies would fit really well in a list that gets interpreted for notes and timing cues), but merely as a means to get to Java. Likewise, we're manhandling Emacs to get to a presentation layer capable of generating music in a live environment. Cider is about the only thing that's being used correctly.
Anyway, this is all a bit of a daydream. Using cider-jack-in to start a Lein instance, then cider-mode to get the C-x C-e Emacs evaluation is certainly a good way to get inspired and try this crazy nouveau-Overtone out.
PS: I'll be back to "Beyond the Frontier" soon.