Powering MIDI through JRuby.
gem install collavoce
Or get the repo and run `rake gem` to make your own gem to install. Or point bundler at it, or tweak your load path, your call really.
Oh, and this is JRuby only at the moment. MRI should be doable I just haven't gotten around to it yet.
Set up a MIDI Synth
If you already have a MIDI Synth hooked up on your system, you can skip this part. If not here's how to do it on a Mac.
First open “Audio MIDI Setup” and access your MIDI preferences under “Window > Show MIDI Window”. Then double click on your “IAC Driver”. This is a virtual MIDI bus that enables MIDI communication between programs running on your system. By default it has no ports, but if you click on the “+” next to “Add and Remove Ports” it will create one called “IAC Bus 1”.
To make some noise, download Pd-extended and open the file exmaples/synths.pd with it. This file is a simple PureData patch file that defines a sine wave oscelator on MIDI channel 1 and a triangle wave oscelator on MIDI channel 2.
Run the demo
Once you have a MIDI Synth set up you should be able to run:
Collavoce will select the first MIDI device with output channels. If you want to play on a different device, specify it at the top of examples/zelda.rb like this:
Collavoce.device_name = "My device name"
Writing your own songs
Right now this is still a little raw, but have a look at examples/zelda.rb to get a feel for it.
The basic idea is just a DSL for building melodies from arrays of strings. These notes and timings are then used to send MIDI events. Currently the MIDI device isn't configuratable (see lib/collavoce/voice.rb on that one). But that should get cleaned up soon.
The note syntax is inspired by jFugue. The pattern is:
NOTE - OCTAVE - TIMING
So note can be “C” or “C#” or “Ebb”. Follow that with an optional octave number (default is 4). Then timing characters. Options are “w”hole, “h”alf, “q”uarter, “s”ixteenth, “t”hirtysecond. And you can combine timings. So a dotted quarter note would be “qe”.
Additionall if you use “R” as the note it will produce a rest in the melody. Same timing pattern applies. Octave will be, of course, ignored.
So “Twinkle Twinkle little star” could be: %w(C C G G A A Gh)
Each Voice represents a part of the song. It gets a channel and notes, then you can put it in a tracker like this:
The tracker allows for multiple parallel tracks of voice sequences. This uses threading right now, but I could see moving to Ruck if timing ever got a little off.
If you want a Voice to have more interesting characteristics than just the notes you can override Voice#run and do whatever you want. I've included helpers for diminishing (half step down) and augmenting (half step up) sets of notes. So far this has been enough for me, but I'm sure we'll start adding more helpers once more people try making things with this.