Controlling Browser Based Synths With Ableton
Code
https://glitch.com/edit/#!/ableton-monotron
Why
There are many amazing Javascript synthesisers that have been made possible by the Web Audio API. Check here for just a small sample https://github.com/alemangui/web-audio-resources#synths.
However, most producers still want to create music in their desktop DAW of choice (Ableton, Logic Pro, Cubase etc).
I wanted to see how hard/useful it would be to play a Javascript synth with Ableton triggering the MIDI notes. Please keep in mind this is just an experiment to proof the concept.
Getting it to work
Choosing a Javascript synth I want to play from Ableton
I found this emulation of a Monotron (https://noisehack.com/monotron/) that was awesome. I chose it because I actually own the real thing, its really fun to play and the code is really easy to extend. Plus there is a great write-up on how it was made here (https://noisehack.com/how-to-build-monotron-synth-web-audio-api/)
Audio MIDI setup
First I needed Ableton to be sending MIDI to a virtual MIDI port. On a Mac this can be done using the Audio MIDI setup utility (just search using Mac search). In the IAC driver properties, click the plus button to add a new port.
Ableton setup
Now in Ableton you will be able to set that new MIDI port as the output of a MIDI track.
Listening for MIDI in the browser
Modern browsers now have decent support for MIDI. I am going to use the webmidi Javascript library (https://github.com/djipco/webmidi) to make life easy. This is the only code I am going to write. The code takes a MIDI port to listen to (the one we create and that Ableton is outputting MIDI to). When our code detects a note on MIDI event from Ableton it will convert the note to a frequency and call the Monotron’s global public noteOn method. When you stop playing in Ableton then a the note off event is also sent to the Monotron.
A class to set up the MIDI listener events in the browser.
class MidiConector { constructor(inputName, noteOn, noteOff) { this.noteOn = noteOn; this.noteOff = noteOff; window.WebMidi.enable(err => { var input = window.WebMidi.getInputByName(inputName); this.setUpNoteOn(input);
this.setUpNoteOff(input); }); } setUpNoteOn(input) { input.addListener("noteon", "all", e => { const frequency = midiToFrequency(440)(e.note.number); this.noteOn(frequency); console.log( "Received 'noteon' message (" + e.note.name + e.note.octave + ")." ); }); } setUpNoteOff(input) { input.addListener("noteoff", "all", e => { this.noteOff(); console.log( "Received 'noteoff' message (" + e.note.name + e.note.octave + ")." ); }); } }export default MidiConector;
How to use the above code to connect to the Monotron’s public API
new MidiConector( "Name of your MIDI virtual port", frequency => { window.monotron.noteOn(frequency); }, frequency => { window.monotron.noteOff(frequency); });
To see the full experiment running, go here and fire up Ableton.
Conclusion
The end result is not too bad. You don’t really hear much audible latency. The next step would be somehow recording the audio back into Ableton.
Please check it out and feel free to ask me any questions.