-
Notifications
You must be signed in to change notification settings - Fork 0
/
play_midi.js
52 lines (44 loc) · 2.07 KB
/
play_midi.js
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
/**
* An experiment to see if I could get midis to run properly in a tracker-style
* structure like that. Turns out MIDI does its timing in a mostly arbitrary way,
* so I'd have to bypass the sc_player interface to get that wor work correctly.
*/
var {SteamControllerSequence, SteamControllerPlayer} = require("steam-controller-player");
var {StopRoutine, ArpeggioNote, FlatNote} = require("./sc_music.js");
var Promise = require("bluebird");
var midiFileLib = require('midifile');
var MIDIEvents = require('midievents');
var _ = require('lodash');
var tmpFilePathVar = './Doom Theme For SC.mid';
var readFile = Promise.promisify(require('fs').readFile)
readFile(tmpFilePathVar).then(function(data) {
return new midiFileLib(data.buffer);
}).then(function(midiFile){
var speed = midiFile.header.getTicksPerBeat(); // How many ticks in a *quarter*-note
var sequence = new SteamControllerSequence();
var channels = SteamControllerPlayer.channels;
// Delta-timing works on a per-track basis
midiFile.tracks.forEach(function(midiTrack){
var midiEvents = MIDIEvents.createParser(midiTrack.getTrackContent(), 0);
var position = 0;
var channelNote = new Array(channels.length);
var midiEvent;
while (midiEvent = midiEvents.next()) {
if(midiEvent.type === MIDIEvents.EVENT_META && midiEvent.subtype === MIDIEvents.EVENT_META_SET_TEMPO) {
sequence.setTime(position, (midiEvent.tempo/250000) * speed); // tempo is in µs par quarter-note
} else if (midiEvent.type === MIDIEvents.EVENT_MIDI &&
midiEvent.channel >= 0 && midiEvent.channel < channels.length) {
if (midiEvent.subtype === MIDIEvents.EVENT_MIDI_NOTE_OFF) {
// Ignore for now
//sequence.add(position, channels[midiEvent.channel], new StopRoutine());
} else if (midiEvent.subtype === MIDIEvents.EVENT_MIDI_NOTE_ON) {
channelNote[midiEvent.channel] = midiEvent.param1;
sequence.add(position, channels[midiEvent.channel], new FlatNote(midiEvent.param1));
}
}
position += midiEvent.delta/4;
}
}, this)
//console.log(sequence)
return SteamControllerPlayer.playSequence(sequence, 120, 4, 1);
})