File size: 1,890 Bytes
af6912c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
55
56
57
58
59
60
// Convert the input structure to a more useful structure where each item has a length of its own.

var instrumentIndexToName = require('./instrument-index-to-name');

var createNoteMap = function(sequence) {
	var map = [];
	for (var i = 0; i < sequence.tracks.length; i++)
		map.push([]);

	// TODO-PER: handle more than one note in a track
	var nextNote = {};
	var currentInstrument = instrumentIndexToName[0];
	// ev.start and ev.duration are in whole notes. Need to turn them into
	sequence.tracks.forEach(function(track, i) {
		track.forEach(function(ev) {
			switch (ev.cmd) {
				case "note":
					// ev contains:
					// {"cmd":"note","pitch":72,"volume":95,"start":0.125,"duration":0.25,"instrument":0,"gap":0}
					// where start and duration are in whole notes, gap is in 1/1920 of a second (i.e. MIDI ticks)
					var inst = ev.instrument !== undefined ? instrumentIndexToName[ev.instrument] : currentInstrument
					if (ev.duration > 0) {
						var gap = ev.gap ? ev.gap : 0;
						var len = ev.duration;
						gap = Math.min(gap, len * 2 / 3);
						var obj = {
							pitch: ev.pitch,
							instrument: inst,
							start: Math.round((ev.start) * 1000000)/1000000,
							end: Math.round((ev.start + len - gap) * 1000000)/1000000,
							volume: ev.volume
						};
						if (ev.startChar)
							obj.startChar = ev.startChar;
						if (ev.endChar)
							obj.endChar = ev.endChar;
						if (ev.style)
							obj.style = ev.style;
						if (ev.cents)
							obj.cents = ev.cents;
						map[i].push(obj);
					}
					break;
				case "program":
					currentInstrument = instrumentIndexToName[ev.instrument];
					break;
				case "text":
					// Ignore the track names - that is just for midi files.
					break;
				default:
					// TODO-PER: handle other event types
					console.log("Unhandled midi event", ev);
			}
		});
	});
	return map;
};

module.exports = createNoteMap;