Skip to content

Instantly share code, notes, and snippets.

@tnayuki
Created November 24, 2017 03:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tnayuki/3abb6b95ba642b679dd4ec523087e2ae to your computer and use it in GitHub Desktop.
Save tnayuki/3abb6b95ba642b679dd4ec523087e2ae to your computer and use it in GitHub Desktop.
const Docker = require('dockerode');
const fs = require('fs');
const midi = require('midi');
const parseMidi = require('midi-file').parseMidi;
const docker = new Docker();
const midiOutput = new midi.output();
const midiInput = new midi.input();
function noteNumberToNoteName(noteNumber) {
return ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" ][noteNumber % 12];
}
midiOutput.openPort(0);
midiInput.openPort(1);
midiInput.on('message', function(deltaTime, message) {
if (message[0] == 144 && message[2] != 0) {
console.log("Input: " + noteNumberToNoteName(message[1]));
const p = Promise.resolve();
p.then(() => {
/*
return docker.pull('tensorflow/magenta');
}).then(() => {
*/
return docker.run('tensorflow/magenta', [
'melody_rnn_generate',
'--config=lookback_rnn',
'--bundle_file=/magenta-models/lookback_rnn.mag',
'--output_dir=/magenta-data/lookback_rnn/generated',
'--num_outputs=1',
'--num_steps=64',
'--primer_melody=[' + message[1] + ']'
], null, {
Binds: [ "/tmp/magenta:/magenta-data:rw" ]
});
}).then(() => {
noteQueue.splice(0, noteQueue.length);
fs.readdir("/tmp/magenta/lookback_rnn/generated", (err, list) => {
list.forEach((file) => {
const midiFile = parseMidi(fs.readFileSync("/tmp/magenta/lookback_rnn/generated/" + file));
output = "";
midiFile.tracks[1].forEach((packet) => {
if (packet.type == "noteOn") {
noteQueue.push(packet.noteNumber);
output += noteNumberToNoteName(packet.noteNumber) + " ";
}
});
console.log("Output: " + output);
fs.unlinkSync("/tmp/magenta/lookback_rnn/generated/" + file);
});
});
});
}
});
const noteQueue = [ ];
setInterval(() => {
if (noteQueue.length) {
const noteNumber = noteQueue.shift();
// NOTE ON
midiOutput.sendMessage([ 144, noteNumber, 127 ]);
// NOTE OFF
setTimeout((noteNumber) => {
midiOutput.sendMessage([ 128, noteNumber, 0 ]);
}, 60 / 135 * 1000, noteNumber)
}
}, 60 / 135 * 1000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment