A simple goal, to directly connect Emacs to running hardware and software synthesisers with realtime control. Emacs as a musical instrument.
I already use code to control synths (as Repl-Electric) but there is a level of indirection between the code and the effect on the music. You push keys on your computer keyboard and nothing happens. Only when you run the code does the music change. I wanted to add realtime control to my performances while still remaining in code and Emacs. Bringing the performance closer to musical instruments were instant feedback is a core part of the performance experience.
I could use external hardware, like a MidiFighterTwister (https://www.midifighter.com/#Twister) or TouchOSC (https://hexler.net/software/touchosc) but Iβve found the context switch of moving between coding to twiddling dials on hardware expensive. The code is my composition process, so it makes sense for the direct control to also be there.
Playing the Emacs
Sculpting sound live with Emacs.
Scratching Samples with Emacs
Doing crazy things with Emacs starts to open more doors in musical expression. Since we can control music hardware with Emacs, we can control the playhead position within a sample. Much like the needle of a record player.
Say we map the position of your cursor in the Emacs buffer to the position of the playback head. By moving around in your buffer you can scratch the sample.
Emacs sending Musical Controls
Sending messages to musical synths using midi and OSC.
Emacs Communicating with Open Sound Control
First we need a client within Emacs which will send OSC (https://en.wikipedia.org/wiki/Open_Sound_Control) using UDP packets. There is thankfully already an Emacs package for this: osc: https://delysid.org/emacs/osc.html
Creating a client and sending OSC messages:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Emacs Communicating with Midi
A lot of musical hardware and software only supports midi. We are sending OSC π. Hence we need a quick way of converting our OSC message to a midi message. Why donβt you send midi from Emacs directly? It’s not a new thought (https://www.emacswiki.org/emacs/EmacsMidi), but Iβve seen no examples of getting it working. My answer here is path of least resistance, and I donβt feel like implementing the midi standard in Elisp.
Luis Lloret (https://github.com/llloret) has create the lovely C++ lib osmid
(https://github.com/llloret/osmid) for converting between midi and OSC. And its FAST.
It compiles into two binary servers:
- m2o – midi to OSC
- o2m – OSC to midi
We launch the o2m server in a shell which will be listening on port 4561
and will forward on OSC messages as midi.
1
|
|
Midi has a fixed argument format while OSC is very flexible. Hence this a little jiggery pokery in get the source OSC message mapping to the midi arguments.
OSC message format:
1
|
|
For MIDI_HOST Iβm using the Inter-application communication
(IAC) driver on Mac. This registers IAC Bus 1
as a midi device. Iβm also sending a control change
message, shaping the parameters rather than triggering notes. This could be any of the supported midi messages (note_on
, note_off
, pitch_bend
, poly_pressure
, etc).
Example of OSC to midi message:
1
|
|
The channel 9
and control code 100
seem magical. Iβm routing those to synths via Ableton Live.
Any DAW would support this or you could send direct to a synth and not use IAC
. Your MIDI_HOST would be the name your midi device registers as.
Emacs GUI for Musical Controls
We have the backend for sending live midi controls to hardware. Now we need some interface within Emacs to trigger it.
Modelling Encoders in Emacs
The design is based on the idea of dial encoders commonly found in music hardware.
Our dials in code are float numbers. To turn our dials we borrow the idea from the Chrome inspector of scrolling through possible numeric values with the arrow keys.
In our case every increment/decrement will send a live message to our synths.
We need to extract from the active Emacs buffer the thing we are trying to control. Finding the:
- Synth (the musical instrument)
- Parameter (ie. amp, pan, lfo, filter)
- Value 0-127 (whatever value we want to set param)
Example changing the filter param:
1 2 3 4 5 |
|
Here comes a lot of Elisp and some hairy regexes.
Emacs Code
Thingatpt (https://www.emacswiki.org/emacs/ThingAtPoint) which is part of the standard lib is extremely useful here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
|
We map our synth-and-param
to the correct midi port and channel.
1 2 3 4 5 6 7 8 |
|
Finally the keybindings that trigger our instrument mode:
1 2 |
|
Encoder ASCII Art
We are almost done. For fun Iβve added a visually aid to the position of the float encoder. Midi messages are generally limited to 0-127 values, so if we map that to 0-100% we can create a visual representation of the current setting.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
|
The Ascii dials:
1 2 3 |
|
Binding into a Performance
All this work was used in my recent performance:
βYou Fall into Your Screenβ: https://vimeo.com/replelectric/you-fall-into-your-screen
Iβm using Emacs to simultaneous control Synths and Unity3D in much the same way discussed in this post. It feels pretty amazing to augment the performance with this live control.