@huffduff/midi-writer-ts 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +24 -0
- package/.eslintignore +3 -0
- package/.eslintrc.js +18 -0
- package/.nvmrc +1 -0
- package/.travis.yml +3 -0
- package/LICENSE +21 -0
- package/README.md +200 -0
- package/browser/midiwriter.js +1367 -0
- package/build/index.cjs +1219 -0
- package/build/index.mjs +1217 -0
- package/build/types/abstract-event.d.ts +7 -0
- package/build/types/chunks/chunk.d.ts +5 -0
- package/build/types/chunks/header.d.ts +13 -0
- package/build/types/chunks/track.d.ts +139 -0
- package/build/types/constants.d.ts +16 -0
- package/build/types/main.d.ts +56 -0
- package/build/types/meta-events/copyright-event.d.ts +18 -0
- package/build/types/meta-events/cue-point-event.d.ts +18 -0
- package/build/types/meta-events/end-track-event.d.ts +16 -0
- package/build/types/meta-events/instrument-name-event.d.ts +18 -0
- package/build/types/meta-events/key-signature-event.d.ts +13 -0
- package/build/types/meta-events/lyric-event.d.ts +18 -0
- package/build/types/meta-events/marker-event.d.ts +18 -0
- package/build/types/meta-events/meta-event.d.ts +5 -0
- package/build/types/meta-events/tempo-event.d.ts +20 -0
- package/build/types/meta-events/text-event.d.ts +18 -0
- package/build/types/meta-events/time-signature-event.d.ts +13 -0
- package/build/types/meta-events/track-name-event.d.ts +18 -0
- package/build/types/midi-events/controller-change-event.d.ts +22 -0
- package/build/types/midi-events/midi-event.d.ts +7 -0
- package/build/types/midi-events/note-event.d.ts +31 -0
- package/build/types/midi-events/note-off-event.d.ts +36 -0
- package/build/types/midi-events/note-on-event.d.ts +36 -0
- package/build/types/midi-events/pitch-bend-event.d.ts +17 -0
- package/build/types/midi-events/program-change-event.d.ts +20 -0
- package/build/types/utils.d.ts +105 -0
- package/build/types/vexflow.d.ts +30 -0
- package/build/types/writer.d.ts +45 -0
- package/examples/chopin-prelude-e-minor.js +143 -0
- package/examples/hot-cross-buns.js +24 -0
- package/examples/mauro.giuliani-op.47-main-theme.js +136 -0
- package/examples/notes-by-start-tick.js +45 -0
- package/examples/zelda-main-theme.js +435 -0
- package/jsdoc.json +5 -0
- package/package.json +79 -0
- package/postinstall.js +1 -0
- package/rollup.config.js +22 -0
- package/runkit.js +18 -0
- package/test/main.js +339 -0
- package/test/vexflow.js +165 -0
- package/test/writer.js +59 -0
- package/tsconfig.json +13 -0
- package/typedoc.json +5 -0
package/test/main.js
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
const MidiWriter = require('..');
|
|
3
|
+
|
|
4
|
+
describe('MidiWriterJS', function() {
|
|
5
|
+
describe('#NoteEvent()', function () {
|
|
6
|
+
describe('#getTickDuration()', function () {
|
|
7
|
+
it('should create a dotted half note if passed three quarter notes.', function () {
|
|
8
|
+
const track = new MidiWriter.Track(); // Need to instantiate to build note object
|
|
9
|
+
const note = new MidiWriter.NoteEvent({pitch: 'C4', duration: ['4', '4', '4']});
|
|
10
|
+
track.addEvent(note);
|
|
11
|
+
const write = new MidiWriter.Writer(track);
|
|
12
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAADQCQPECDAIA8QAD/LwA=', write.base64());
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should create a note with duration of 50 ticks if passed T50', function () {
|
|
16
|
+
const track = new MidiWriter.Track(); // Need to instantiate to build note object
|
|
17
|
+
const note = new MidiWriter.NoteEvent({pitch: 'C4', duration: 'T50'});
|
|
18
|
+
track.addEvent(note);
|
|
19
|
+
const write = new MidiWriter.Writer(track);
|
|
20
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAADACQPEAygDxAAP8vAA==', write.base64());
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('#Track()', function() {
|
|
26
|
+
describe('#Time Signature', function() {
|
|
27
|
+
it('should return specific base64 string when time signature is 4/4', function() {
|
|
28
|
+
const track = new MidiWriter.Track();
|
|
29
|
+
track.setTimeSignature(4, 4);
|
|
30
|
+
const write = new MidiWriter.Writer(track);
|
|
31
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAADAD/WAQEAhgIAP8vAA==', write.base64());
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should return specific base64 string when time signature is 2/2', function() {
|
|
35
|
+
const track = new MidiWriter.Track();
|
|
36
|
+
track.setTimeSignature(2, 2);
|
|
37
|
+
const write = new MidiWriter.Writer(track);
|
|
38
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAADAD/WAQCARgIAP8vAA==', write.base64());
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should return specific base64 string when time signature is 2/8', function() {
|
|
42
|
+
const track = new MidiWriter.Track();
|
|
43
|
+
track.setTimeSignature(2, 8);
|
|
44
|
+
const write = new MidiWriter.Writer(track);
|
|
45
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAADAD/WAQCAxgIAP8vAA==', write.base64());
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should return specific base64 string when setting C major key signature', function() {
|
|
50
|
+
const track = new MidiWriter.Track();
|
|
51
|
+
track.setKeySignature('C');
|
|
52
|
+
const write = new MidiWriter.Writer(track);
|
|
53
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAACgD/WQIAAAD/LwA=', write.base64());
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should return specific base64 string when adding copyright', function() {
|
|
57
|
+
const track = new MidiWriter.Track();
|
|
58
|
+
track.addCopyright('2018 Garrett Grimm');
|
|
59
|
+
const write = new MidiWriter.Writer(track);
|
|
60
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAAGgD/AhIyMDE4IEdhcnJldHQgR3JpbW0A/y8A', write.base64());
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should return specific base64 string when adding text', function() {
|
|
64
|
+
const track = new MidiWriter.Track();
|
|
65
|
+
track.addText('MidiWriterJS is the bomb!');
|
|
66
|
+
const write = new MidiWriter.Writer(track);
|
|
67
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAAIQD/ARlNaWRpV3JpdGVySlMgaXMgdGhlIGJvbWIhAP8vAA==', write.base64());
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should return specific base64 string when adding a track name', function() {
|
|
71
|
+
const track = new MidiWriter.Track();
|
|
72
|
+
track.addTrackName('Name of a cool track');
|
|
73
|
+
const write = new MidiWriter.Writer(track);
|
|
74
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAAHAD/AxROYW1lIG9mIGEgY29vbCB0cmFjawD/LwA=', write.base64());
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should return specific base64 string when adding an instrument name', function() {
|
|
78
|
+
const track = new MidiWriter.Track();
|
|
79
|
+
track.addInstrumentName('Alto Saxophone');
|
|
80
|
+
const write = new MidiWriter.Writer(track);
|
|
81
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAAFgD/BA5BbHRvIFNheG9waG9uZQD/LwA=', write.base64());
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should return specific base64 string when adding a marker', function() {
|
|
85
|
+
const track = new MidiWriter.Track();
|
|
86
|
+
track.addMarker('This is my favorite part of the song.');
|
|
87
|
+
const write = new MidiWriter.Writer(track);
|
|
88
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAALQD/BiVUaGlzIGlzIG15IGZhdm9yaXRlIHBhcnQgb2YgdGhlIHNvbmcuAP8vAA==', write.base64());
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should return specific base64 string when adding a cue point', function() {
|
|
92
|
+
const track = new MidiWriter.Track();
|
|
93
|
+
track.addCuePoint('Here is a cue point.');
|
|
94
|
+
const write = new MidiWriter.Writer(track);
|
|
95
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAAHAD/BxRIZXJlIGlzIGEgY3VlIHBvaW50LgD/LwA=', write.base64());
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should return specific base64 string when adding a lyric', function() {
|
|
99
|
+
const track = new MidiWriter.Track();
|
|
100
|
+
track.addLyric('Oh say can you see.');
|
|
101
|
+
const write = new MidiWriter.Writer(track);
|
|
102
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAAGwD/BRNPaCBzYXkgY2FuIHlvdSBzZWUuAP8vAA==', write.base64());
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should return specific base64 string when adding a controller change event', function() {
|
|
106
|
+
const track = new MidiWriter.Track();
|
|
107
|
+
track.controllerChange(1, 127);
|
|
108
|
+
const write = new MidiWriter.Writer(track);
|
|
109
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAACACwAX8A/y8A', write.base64());
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should return specific base64 string when adding a controller change event with channel and delta specified', function() {
|
|
113
|
+
const track = new MidiWriter.Track();
|
|
114
|
+
track.controllerChange(1, 127, 16, 256);
|
|
115
|
+
const write = new MidiWriter.Writer(track);
|
|
116
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAACYIAvwF/AP8vAA==', write.base64());
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should create 3 triplet eights followed by a quarter - on correct ticks', function() {
|
|
120
|
+
const track = new MidiWriter.Track();
|
|
121
|
+
track.addEvent([
|
|
122
|
+
new MidiWriter.NoteEvent({pitch: ['D5', 'C5', 'B4'], duration: '8t', sequential: true}),
|
|
123
|
+
new MidiWriter.NoteEvent({pitch: ['B4'], duration: 'd2'}),
|
|
124
|
+
])
|
|
125
|
+
const builtTrack = track.buildData();
|
|
126
|
+
assert.equal(builtTrack.events[6].tick, 128)
|
|
127
|
+
assert.equal(builtTrack.events[7].tick, 512)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
/*
|
|
131
|
+
it('should create 3 triplet eights followed by a whole, after normal 6 eights - on correct ticks', function() {
|
|
132
|
+
const track = new MidiWriter.Track();
|
|
133
|
+
track.addEvent([
|
|
134
|
+
new MidiWriter.NoteEvent({pitch: ['G4', 'Gb4', 'C4', 'B3', 'Eb4', 'Gb4'], duration: '8', sequential:true}),
|
|
135
|
+
new MidiWriter.NoteEvent({pitch: ['D5', 'C5', 'B4'], duration: '8t', sequential: true}),
|
|
136
|
+
new MidiWriter.NoteEvent({pitch: ['B#4'], duration: '1'}),
|
|
137
|
+
])
|
|
138
|
+
const builtTrack = track.buildData();
|
|
139
|
+
|
|
140
|
+
// Reversing these events breaks this test since EndOfTrackEvent gets misplaced.
|
|
141
|
+
const lastEvents = [...builtTrack.events].reverse();
|
|
142
|
+
// 2nd bar:
|
|
143
|
+
assert.equal(lastEvents[2].tick, 128 * 4);
|
|
144
|
+
// 3rd bar:
|
|
145
|
+
assert.equal(lastEvents[1].tick, 128 * 8);
|
|
146
|
+
})
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
it('should write 14 bars where certain notes should start exactly at the beginning of each bar', function() {
|
|
150
|
+
const track = new MidiWriter.Track();
|
|
151
|
+
track
|
|
152
|
+
.setTempo(60)
|
|
153
|
+
.addEvent([
|
|
154
|
+
new MidiWriter.ProgramChangeEvent({instrument : 1}),
|
|
155
|
+
new MidiWriter.NoteEvent({pitch: ['B4'], duration: 'd2'}),
|
|
156
|
+
new MidiWriter.NoteEvent({pitch: ['C5'], duration: '4'}),
|
|
157
|
+
new MidiWriter.NoteEvent({pitch: ['B4'], duration: 'd2'}),
|
|
158
|
+
new MidiWriter.NoteEvent({pitch: ['C5'], duration: '4'}),
|
|
159
|
+
new MidiWriter.NoteEvent({pitch: ['B4'], duration: 'd2'}),
|
|
160
|
+
new MidiWriter.NoteEvent({pitch: ['C5'], duration: '4'}),
|
|
161
|
+
new MidiWriter.NoteEvent({pitch: ['B4'], duration: 'd2'}),
|
|
162
|
+
new MidiWriter.NoteEvent({pitch: ['Bb4'], duration: '4'}),
|
|
163
|
+
new MidiWriter.NoteEvent({pitch: ['A4'], duration: 'd2'}),
|
|
164
|
+
new MidiWriter.NoteEvent({pitch: ['B4'], duration: '4'}),
|
|
165
|
+
new MidiWriter.NoteEvent({pitch: ['A4'], duration: 'd2'}),
|
|
166
|
+
new MidiWriter.NoteEvent({pitch: ['B4'], duration: '4'}),
|
|
167
|
+
new MidiWriter.NoteEvent({pitch: ['A4'], duration: 'd2'}),
|
|
168
|
+
new MidiWriter.NoteEvent({pitch: ['B4'], duration: 'd8'}),
|
|
169
|
+
new MidiWriter.NoteEvent({pitch: ['A4'], duration: '16'}),
|
|
170
|
+
new MidiWriter.NoteEvent({pitch: ['A4'], duration: 'd2'}),
|
|
171
|
+
new MidiWriter.NoteEvent({pitch: ['Ab4'], duration: '2'}),
|
|
172
|
+
new MidiWriter.NoteEvent({pitch: ['A4', 'B4', 'D5', 'C5', 'E4', 'A4'], duration: '8', sequential:true}),
|
|
173
|
+
new MidiWriter.NoteEvent({pitch: ['Gb4'], duration: 'd2'}),
|
|
174
|
+
new MidiWriter.NoteEvent({pitch: ['A4'], duration: '4'}),
|
|
175
|
+
new MidiWriter.NoteEvent({pitch: ['Gb4'], duration: 'd2'}),
|
|
176
|
+
new MidiWriter.NoteEvent({pitch: ['A4'], duration: '4'}),
|
|
177
|
+
new MidiWriter.NoteEvent({pitch: ['G1', 'Gb4', 'C4', 'B3', 'Eb4', 'Gb4'], duration: '8', sequential: true}),
|
|
178
|
+
new MidiWriter.NoteEvent({pitch: ['D5', 'C5', 'B5'], duration: '8t', sequential: true}),
|
|
179
|
+
// 4x quintuplets
|
|
180
|
+
new MidiWriter.NoteEvent({pitch: ['B1', 'A4', 'A4', 'A4', 'A4'], duration: '8t5', sequential: true}),
|
|
181
|
+
new MidiWriter.NoteEvent({pitch: ['A4', 'A4', 'A4', 'A4', 'A4'], duration: '8t5', sequential: true}),
|
|
182
|
+
new MidiWriter.NoteEvent({pitch: ['A4', 'A4', 'A4', 'A4', 'A4'], duration: '8t5', sequential: true}),
|
|
183
|
+
new MidiWriter.NoteEvent({pitch: ['A4', 'A4', 'A4', 'A4', 'A4'], duration: '8t5', sequential: true}),
|
|
184
|
+
new MidiWriter.NoteEvent({pitch: ['F1'], duration: '1'}),
|
|
185
|
+
]);
|
|
186
|
+
|
|
187
|
+
const builtTrack = track.buildData();
|
|
188
|
+
const twelvethBarEvent = builtTrack.events.find((event) => event.pitch === 'G1')
|
|
189
|
+
const thirteenthBarEvent = builtTrack.events.find((event) => event.pitch === 'B1');
|
|
190
|
+
const fourteenthBarEvent = builtTrack.events.find((event) => event.pitch === 'F1');
|
|
191
|
+
// 12th bar:
|
|
192
|
+
assert.equal(twelvethBarEvent.tick, 512 * 11);
|
|
193
|
+
// 13th bar:
|
|
194
|
+
assert.equal(thirteenthBarEvent.tick, 512 * 12);
|
|
195
|
+
// 14th bar:
|
|
196
|
+
assert.equal(fourteenthBarEvent.tick, 512 * 13);
|
|
197
|
+
// console.log(builtTrack.events)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
it('3 triplets and 1 dotted is the duration as one whole - next bar starts in the correct place', function() {
|
|
201
|
+
const track = new MidiWriter.Track();
|
|
202
|
+
|
|
203
|
+
track
|
|
204
|
+
.addEvent([
|
|
205
|
+
new MidiWriter.ProgramChangeEvent({instrument : 1}),
|
|
206
|
+
new MidiWriter.NoteEvent({pitch: ['D5', 'G5', 'B4'], duration: '8t', sequential: true}),
|
|
207
|
+
new MidiWriter.NoteEvent({pitch: ['B4'], duration: 'd2'}),
|
|
208
|
+
new MidiWriter.NoteEvent({pitch: ['C5'], duration: '4'}),
|
|
209
|
+
]);
|
|
210
|
+
|
|
211
|
+
const builtTrack = track.buildData();
|
|
212
|
+
const bar2note = builtTrack.events.find((event) => event.pitch === 'C5');
|
|
213
|
+
|
|
214
|
+
const track2 = new MidiWriter.Track();
|
|
215
|
+
|
|
216
|
+
track2
|
|
217
|
+
.addEvent([
|
|
218
|
+
new MidiWriter.ProgramChangeEvent({instrument : 1}),
|
|
219
|
+
new MidiWriter.NoteEvent({pitch: ['D5'], duration: '1'}),
|
|
220
|
+
new MidiWriter.NoteEvent({pitch: ['C5'], duration: '4'}),
|
|
221
|
+
]);
|
|
222
|
+
|
|
223
|
+
const builtTrack2 = track2.buildData();
|
|
224
|
+
const bar2note2 = builtTrack2.events.find((event) => event.pitch === 'C5');
|
|
225
|
+
|
|
226
|
+
assert.equal(JSON.stringify(bar2note, null, 2), JSON.stringify(bar2note2, null, 2));
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
it('should return specific base64 string when manually adding EndTrackEvent', function() {
|
|
230
|
+
const track = new MidiWriter.Track();
|
|
231
|
+
|
|
232
|
+
track.addEvent([
|
|
233
|
+
new MidiWriter.NoteEvent({pitch: ['C5', 'E5', 'G4'], duration: '4'}),
|
|
234
|
+
new MidiWriter.EndTrackEvent({delta: 5000}),
|
|
235
|
+
]);
|
|
236
|
+
|
|
237
|
+
const write = new MidiWriter.Writer(track);
|
|
238
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAAHgCQSEAAkExAAJBDQIEAgEhAAIBMQACAQ0CnCP8vAA==', write.base64());
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
it('should return specific base64 string when removing events by name', function() {
|
|
242
|
+
const track = new MidiWriter.Track();
|
|
243
|
+
|
|
244
|
+
track.addEvent(new MidiWriter.CopyrightEvent({text: "Garrett Grimm"}));
|
|
245
|
+
track.removeEventsByName('CopyrightEvent');
|
|
246
|
+
track.addEvent(new MidiWriter.NoteEvent({pitch: ["C4", "D4", "E4"], sequential: true}));
|
|
247
|
+
|
|
248
|
+
const write = new MidiWriter.Writer([track]);
|
|
249
|
+
|
|
250
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAAHwCQPECBAIA8QACQPkCBAIA+QACQQECBAIBAQAD/LwA=', write.base64());
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('should return specific base64 string when merging two tracks', function() {
|
|
254
|
+
const track = new MidiWriter.Track();
|
|
255
|
+
|
|
256
|
+
track.addEvent([
|
|
257
|
+
new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4', sequential: true}),
|
|
258
|
+
new MidiWriter.NoteEvent({pitch: 'C4', duration: '2'})
|
|
259
|
+
]);
|
|
260
|
+
|
|
261
|
+
const track2 = new MidiWriter.Track();
|
|
262
|
+
|
|
263
|
+
track2.addEvent([
|
|
264
|
+
new MidiWriter.NoteEvent({pitch: ['G4','F4'], duration: '4', sequential: true}),
|
|
265
|
+
new MidiWriter.NoteEvent({pitch: 'E4', duration: '2'})
|
|
266
|
+
]);
|
|
267
|
+
|
|
268
|
+
track.mergeTrack(track2);
|
|
269
|
+
const write = new MidiWriter.Writer([track]);
|
|
270
|
+
|
|
271
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAANwCQQEAAkENAgQCAQEAAkD5AAIBDQACQQUCBAIA+QACQPEAAgEFAAJBAQIIAgDxAAIBAQAD/LwA=', write.base64());
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
describe('#Utils()', function() {
|
|
276
|
+
describe('#stringToBytes()', function () {
|
|
277
|
+
it('should return [116, 101, 115, 116] when "test" is passed.', function () {
|
|
278
|
+
assert.equal([116, 101, 115, 116].toString(), MidiWriter.Utils.stringToBytes('test').toString());
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
describe('#isNumeric()', function () {
|
|
283
|
+
it('should return false when "t" is passed.', function () {
|
|
284
|
+
assert.equal(false, MidiWriter.Utils.isNumeric('t'));
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
describe('#getPitch()', function () {
|
|
289
|
+
it('should return 101 when "F7" is passed.', function () {
|
|
290
|
+
assert.equal(101, MidiWriter.Utils.getPitch('F7'));
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('should return 98 when "D6" is passed and middle C is set to "C3".', function () {
|
|
294
|
+
assert.equal(98, MidiWriter.Utils.getPitch('D6', 'C3'));
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it('should return 72 (C5) when "B#4" is passed.', function () {
|
|
298
|
+
assert.equal(72, MidiWriter.Utils.getPitch('B#4'));
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
describe('#stringByteCount()', function () {
|
|
303
|
+
it('should return 7 when "Garrett" is passed.', function () {
|
|
304
|
+
assert.equal(7, MidiWriter.Utils.stringByteCount('Garrett'));
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
describe('#numberFromBytes()', function () {
|
|
309
|
+
it('should return 8463 when [0x21, 0x0f] is passed.', function () {
|
|
310
|
+
assert.equal(8463, MidiWriter.Utils.numberFromBytes([0x21, 0x0f]));
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
describe('#numberToBytes()', function () {
|
|
315
|
+
it('should return [0, 5] when converting the number 5 into two bytes.', function() {
|
|
316
|
+
assert.equal([0, 5].toString(), MidiWriter.Utils.numberToBytes(5, 2));
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
describe('#getDurationMultiplier()', function () {
|
|
321
|
+
it('should return 1 for a quarter note.', function () {
|
|
322
|
+
const note = new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'});
|
|
323
|
+
assert.equal(MidiWriter.Utils.getDurationMultiplier(note.duration), 1);
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
describe('#getTickDuration()', function () {
|
|
328
|
+
it('should return 128 for a quarter note.', function () {
|
|
329
|
+
const note = new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'});
|
|
330
|
+
assert.equal(MidiWriter.Utils.getTickDuration(note.duration), 128);
|
|
331
|
+
});
|
|
332
|
+
it('should return 128 for 3 triplet eights.', function () {
|
|
333
|
+
const note = new MidiWriter.NoteEvent({pitch: 'C4', duration: ['8t', '8t', '8t']});
|
|
334
|
+
assert.equal(MidiWriter.Utils.getTickDuration(note.duration), 128);
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
});
|
|
339
|
+
});
|
package/test/vexflow.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
const MidiWriter = require('..');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Mock a VexFlow StaveNote
|
|
6
|
+
* @param {String} noteType
|
|
7
|
+
* @param {String} duration
|
|
8
|
+
* @param {[String]} keys
|
|
9
|
+
* @param {boolean} isDotted
|
|
10
|
+
*/
|
|
11
|
+
function mockNote(noteType='n', duration='8', keys=['c/4'], dots=0, tuplet=null, accidentals=null) {
|
|
12
|
+
const result = {
|
|
13
|
+
noteType,
|
|
14
|
+
duration,
|
|
15
|
+
keys,
|
|
16
|
+
dots,
|
|
17
|
+
tuplet,
|
|
18
|
+
getAccidentals() {
|
|
19
|
+
return accidentals;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe('MidiWriterJS', function() {
|
|
26
|
+
describe('#VexFlow()', function() {
|
|
27
|
+
it('instantiates', function() {
|
|
28
|
+
const v = new MidiWriter.VexFlow();
|
|
29
|
+
assert.notStrictEqual(typeof v, 'undefined');
|
|
30
|
+
assert.strictEqual(v instanceof MidiWriter.VexFlow, true);
|
|
31
|
+
});
|
|
32
|
+
describe('#trackFromVoice', function() {
|
|
33
|
+
it('converts a VexFlow voice into a track', function() {
|
|
34
|
+
const mockVoice = {
|
|
35
|
+
tickables: [
|
|
36
|
+
mockNote('n', '8', ['g#/3']),
|
|
37
|
+
mockNote('n', '8', ['b/3']),
|
|
38
|
+
mockNote('n', '8', ['c#/3']),
|
|
39
|
+
mockNote('r'),
|
|
40
|
+
mockNote('n', '8', ['b/3']),
|
|
41
|
+
mockNote('r'),
|
|
42
|
+
mockNote('n', '8', ['c#/3']),
|
|
43
|
+
mockNote('n', '8', ['b/3']),
|
|
44
|
+
mockNote('n', '8', ['a#/3']),
|
|
45
|
+
mockNote('r'),
|
|
46
|
+
mockNote('n', '8', ['b/3']),
|
|
47
|
+
mockNote('r')
|
|
48
|
+
]
|
|
49
|
+
};
|
|
50
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
51
|
+
const track = vexFlow.trackFromVoice(mockVoice);
|
|
52
|
+
const write = new MidiWriter.Writer(track);
|
|
53
|
+
assert.strictEqual(write.base64(), 'TVRoZAAAAAYAAAABAIBNVHJrAAAATACQOEBAgDhAAJA7QECAO0AAkDFAQIAxQECQO0BAgDtAQJAxQECAMUAAkDtAQIA7QACQOkBAgDpAQJA7QECAO0BAkAAAAIAAAAD/LwA=');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('preserves multiple rests', function() {
|
|
57
|
+
const mockVoice = {
|
|
58
|
+
tickables: [
|
|
59
|
+
mockNote(),
|
|
60
|
+
mockNote('r'),
|
|
61
|
+
mockNote('r'),
|
|
62
|
+
mockNote('')
|
|
63
|
+
]
|
|
64
|
+
};
|
|
65
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
66
|
+
const track = vexFlow.trackFromVoice(mockVoice);
|
|
67
|
+
const write = new MidiWriter.Writer(track);
|
|
68
|
+
assert.strictEqual(write.base64(), 'TVRoZAAAAAYAAAABAIBNVHJrAAAAFQCQPEBAgDxAgQCQAAAAgAAAAP8vAA==');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('appends trailing rests with a silent note', function() {
|
|
72
|
+
const mockVoice = {
|
|
73
|
+
tickables: [
|
|
74
|
+
mockNote(),
|
|
75
|
+
mockNote(),
|
|
76
|
+
mockNote('r'),
|
|
77
|
+
mockNote('r')
|
|
78
|
+
]
|
|
79
|
+
};
|
|
80
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
81
|
+
const track = vexFlow.trackFromVoice(mockVoice);
|
|
82
|
+
const write = new MidiWriter.Writer(track);
|
|
83
|
+
assert.strictEqual(write.base64(), 'TVRoZAAAAAYAAAABAIBNVHJrAAAAHQCQPEBAgDxAAJA8QECAPECBAJAAAACAAAAA/y8A');
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe('#convertPitch()', function() {
|
|
88
|
+
it('converts pitch', function () {
|
|
89
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
90
|
+
const tickable = mockNote('n', 'h', ['c/4']);
|
|
91
|
+
assert.deepStrictEqual(tickable.keys.map((pitch, index) => vexFlow.convertPitch(pitch, index, tickable)), ['c4']);
|
|
92
|
+
});
|
|
93
|
+
it('converts multiple pitch', function() {
|
|
94
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
95
|
+
const tickable = mockNote('n', 'h', ['b/4', 'c/4']);
|
|
96
|
+
assert.deepStrictEqual(tickable.keys.map((pitch, index) => vexFlow.convertPitch(pitch, index, tickable)), ['b4', 'c4']);
|
|
97
|
+
});
|
|
98
|
+
it('converts accidentals pitch', function() {
|
|
99
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
100
|
+
const tickable = mockNote('n', 'h', ['b#/4', 'cb/4', 'dn/4']);
|
|
101
|
+
assert.deepStrictEqual(tickable.keys.map((pitch, index) => vexFlow.convertPitch(pitch, index, tickable)), ['b#4', 'cb4', 'd4']);
|
|
102
|
+
});
|
|
103
|
+
it('converts rendered accidentals pitch', function() {
|
|
104
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
105
|
+
const tickable = mockNote('n', 'h', ['b/4', 'c/4'], 0, null, [{index: 0, type: '#'}, {index: 1, type: 'b'}]);
|
|
106
|
+
assert.deepStrictEqual(tickable.keys.map((pitch, index) => vexFlow.convertPitch(pitch, index, tickable, true)), ['b#4', 'cb4']);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
describe('#convertDuration()', function() {
|
|
111
|
+
it('converts whole, half, quarter and eighth durations', function () {
|
|
112
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
113
|
+
const tickable = mockNote('n', 'w');
|
|
114
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), '1');
|
|
115
|
+
tickable.duration = 'h'
|
|
116
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), '2');
|
|
117
|
+
tickable.duration = 'q'
|
|
118
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), '4');
|
|
119
|
+
tickable.duration = '8'
|
|
120
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), '8');
|
|
121
|
+
});
|
|
122
|
+
it('converts dotted half, quarter and eighth durations', function () {
|
|
123
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
124
|
+
const tickable = mockNote('n', 'h', ['c/4'], 1);
|
|
125
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), 'd2');
|
|
126
|
+
tickable.duration = 'q'
|
|
127
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), 'd4');
|
|
128
|
+
tickable.duration = '8'
|
|
129
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), 'd8');
|
|
130
|
+
});
|
|
131
|
+
it('converts multiple dotted durations', function() {
|
|
132
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
133
|
+
const tickable = mockNote('n', 'h', ['c/4'], 2);
|
|
134
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), 'dd2');
|
|
135
|
+
tickable.dots = 3
|
|
136
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), 'ddd2');
|
|
137
|
+
tickable.dots = 4
|
|
138
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), 'dddd2');
|
|
139
|
+
});
|
|
140
|
+
it('converts tuplet durations', function() {
|
|
141
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
142
|
+
const tickable = mockNote('n', 'h', ['c/4'], 0, {num_notes: 3});
|
|
143
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), '2t3');
|
|
144
|
+
tickable.tuplet.num_notes = 5
|
|
145
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), '2t5');
|
|
146
|
+
tickable.tuplet.num_notes = 7
|
|
147
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), '2t7');
|
|
148
|
+
});
|
|
149
|
+
it('converts dotted tuplet durations', function() {
|
|
150
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
151
|
+
const tickable = mockNote('n', 'h', ['c/4'], 1, {num_notes: 3});
|
|
152
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), 'd2t3');
|
|
153
|
+
tickable.tuplet.num_notes = 5
|
|
154
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), 'd2t5');
|
|
155
|
+
tickable.dots = 2
|
|
156
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), 'dd2t5');
|
|
157
|
+
});
|
|
158
|
+
it('returns other durations', function () {
|
|
159
|
+
const vexFlow = new MidiWriter.VexFlow();
|
|
160
|
+
const tickable = mockNote('n', '64', ['c/4']);
|
|
161
|
+
assert.strictEqual(vexFlow.convertDuration(tickable), '64');
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
});
|
package/test/writer.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
const MidiWriter = require('..');
|
|
3
|
+
|
|
4
|
+
describe('MidiWriterJS', function() {
|
|
5
|
+
describe('#Writer()', function() {
|
|
6
|
+
describe('#base64()', function() {
|
|
7
|
+
it('should return specific base64 string when a single C4 quarter note is created.', function () {
|
|
8
|
+
const track = new MidiWriter.Track();
|
|
9
|
+
const note = new MidiWriter.NoteEvent({pitch: 'C4', duration: '4'});
|
|
10
|
+
track.addEvent(note);
|
|
11
|
+
const write = new MidiWriter.Writer(track);
|
|
12
|
+
assert.equal('TVRoZAAAAAYAAAABAIBNVHJrAAAADQCQPECBAIA8QAD/LwA=', write.base64());
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('#Hot Cross Buns', function() {
|
|
17
|
+
it('should return specific base64 string when hot cross buns is created.', function () {
|
|
18
|
+
const midi = require('../examples/hot-cross-buns.js');
|
|
19
|
+
assert.equal('data:audio/midi;base64,TVRoZAAAAAYAAAABAIBNVHJrAAAAlQCQQECBAIBAQACQPkCBAIA+QACQPECCAIA8QACQQECBAIBAQACQPkCBAIA+QACQPECCAIA8QACQPEBAgDxAAJA8QECAPEAAkDxAQIA8QACQPEBAgDxAAJA+QECAPkAAkD5AQIA+QACQPkBAgD5AAJA+QECAPkAAkEBAgQCAQEAAkD5AgQCAPkAAkDxAggCAPEAA/y8A', midi.dataUri());
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('#setMiddleC()', function() {
|
|
24
|
+
it('should return specific base64 when setting middle C to C3 in Hot Cross Buns example.', function() {
|
|
25
|
+
const midi = require('../examples/hot-cross-buns.js');
|
|
26
|
+
assert.equal('data:audio/midi;base64,TVRoZAAAAAYAAAABAIBNVHJrAAAAlQCQTECBAIBMQACQSkCBAIBKQACQSECCAIBIQACQTECBAIBMQACQSkCBAIBKQACQSECCAIBIQACQSEBAgEhAAJBIQECASEAAkEhAQIBIQACQSEBAgEhAAJBKQECASkAAkEpAQIBKQACQSkBAgEpAAJBKQECASkAAkExAgQCATEAAkEpAgQCASkAAkEhAggCASEAA/y8A', midi.setOption('middleC', 'C3').dataUri());
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('#Maruo Giuliani', function() {
|
|
31
|
+
it('should return specific base64 string when Maruo Giuliani example is created.', function () {
|
|
32
|
+
const midi = require('../examples/mauro.giuliani-op.47-main-theme.js');
|
|
33
|
+
assert.equal('data:audio/midi;base64,TVRoZAAAAAYAAQADAIBNVHJrAAAAEwD/WAQDAhgIAP9RAwknwAD/LwBNVHJrAAACFwCQSUAAkExAggCASUAAgExAAJBJQACQTECBAIBJQACATEAAkElAAJBMQIIAgElAAIBMQACQRUAAkElAgQCARUAAgElAAJBHQACQSkCCAIBHQACASkAAkERAAJBMQIEAgERAAIBMQACQRUAAkElAggCARUAAgElAAJBFQIEAgEVAAJBJQACQTECCAIBJQACATEAAkElAAJBMQIEAgElAAIBMQACQSUAAkExAggCASUAAgExAAJBFQACQSUCBAIBFQACASUAAkEdAAJBKQIIAgEdAAIBKQACQREAAkExAgQCAREAAgExAAJBFQACQSUCCAIBFQACASUCBAJBMQACQTECBAIBMQACATEAAkEtAAJBOQIEAgEtAAIBOQACQSkAAkFBAgQCASkAAgFBAAJBJQACQUUCCAIBJQACAUUAAkExAgQCATEAAkExAAJBMQIEAgExAAIBMQACQS0AAkE5AgQCAS0AAgE5AAJBKQACQUECBAIBKQACAUEAAkElAAJBRQIIAgElAAIBRQIEAkElAAJBMQIIAgElAAIBMQACQSUAAkExAgQCASUAAgExAAJBJQACQTECBAIBJQACATEAAkFFAgQCAUUAAkEVAAJBJQIEAgEVAAIBJQACQSUAAkExAgQCASUAAgExAAJBHQACQSkCBAIBHQACASkAAkERAAJBHQIEAgERAAIBHQACQRUCCAIBFQAD/LwBNVHJrAAAAowCQOUCCAIA5QIEAkDlAggCAOUCBAJA0QIIAgDRAgQCQOUCCAIA5QIEAkDlAggCAOUCBAJA5QIIAgDlAgQCQNECCAIA0QIEAkDlAggCAOUCBAJA0QIIAgDRAgQCQOUCCAIA5QIEAkDRAggCANECBAJA5QIIAgDlAgQCQOUCCAIA5QIEAkDlAggCAOUCBAJA0QIIAgDRAgQCQOUCCAIA5QAD/LwA=', midi.dataUri());
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('#Chopin Prelude', function() {
|
|
38
|
+
it('should return specific base64 string when chopin prelude is created.', function () {
|
|
39
|
+
const midi = require('../examples/chopin-prelude-e-minor.js');
|
|
40
|
+
assert.equal('data:audio/midi;base64,TVRoZAAAAAYAAQACAIBNVHJrAAAC3gD/UQMPQkAAwAEAkEd/gwCAR38AkEh/gQCASH8AkEd/gwCAR38AkEh/gQCASH8AkEd/gwCAR38AkEh/gQCASH8AkEd/gwCAR38AkEZ/gQCARn8AkEV/gwCARX8AkEd/gQCAR38AkEV/gwCARX8AkEd/gQCAR38AkEV/gwCARX8AkEd/YIBHfwCQRX8ggEV/AJBFf4MAgEV/AJBEf4IAgER/AJBFf0CARX8AkEd/QIBHfwCQSn9AgEp/AJBIf0CASH8AkEB/QIBAfwCQRX9AgEV/AJBCf4MAgEJ/AJBFf4EAgEV/AJBCf4MAgEJ/AJBFf4EAgEV/AJBDf0CAQ38AkEJ/QIBCfwCQPH9AgDx/AJA7f0CAO38AkD9/QIA/fwCQQn9AgEJ/AJBKfyuASn8AkEh/KoBIfwCQR38rgEd/AJBHf4MAgEd/AJBIf4EAgEh/AJBHf4MAgEd/AJBIf4EAgEh/AJBHf4MAgEd/AJBIf4EAgEh/AJBHf2CAR38AkEZ/IIBGfwCQRn+BAIBGfwCQT3+BAIBPfwCQTn9ggE5/AJBMfyCATH8AkEx/QIBMfwCQS39AgEt/AJBUf0CAVH8AkEt/QIBLfwCQS39AgEt/AJBMf0CATH8AkE9/QIBPfwCQR39AgEd/AJBKf0CASn8AkEh/QIBIfwCQTH8rgEx/AJBAfyqAQH8AkEV/K4BFfwCQQn+BQIBCfwCQRX9AgEV/AJBCf4MAgEJ/AJBFf4EAgEV/AJBCf4MAgEJ/AJBCf2CAQn8AkEB/IIBAfwCQQH+DAIBAfwCQQn+BAIBCfwCQQH+DAIBAfwCQQn+BAIBCfwCQQH+CAIBAf4IAkFR/AJBPfwCQSn8AkEh/ggCAVH8AgE9/AIBKfwCASH8AkFR/AJBPfwCQSn8AkEh/ggCAVH8AgE9/AIBKfwCASH8AkFR/AJBPfwCQTH8AkEh/gQCAVH8AgE9/AIBMfwCASH8A/y8ATVRyawAAED4AwAEAkEBAAJA7QACQN0BAgEBAAIA7QACAN0AAkEBAAJA7QACQN0BAgEBAAIA7QACAN0AAkEBAAJA7QACQN0BAgEBAAIA7QACAN0AAkEBAAJA7QACQN0BAgEBAAIA7QACAN0AAkEBAAJA7QACQN0BAgEBAAIA7QACAN0AAkEBAAJA7QACQN0BAgEBAAIA7QACAN0AAkEBAAJA7QACQN0BAgEBAAIA7QACAN0AAkEBAAJA7QACQN0BAgEBAAIA7QACAN0AAkEBAAJA5QACQNkBAgEBAAIA5QACANkAAkEBAAJA5QACQNkBAgEBAAIA5QACANkAAkEBAAJA5QACQNkBAgEBAAIA5QACANkAAkEBAAJA5QACQNkBAgEBAAIA5QACANkAAkD9AAJA5QACQNkBAgD9AAIA5QACANkAAkD9AAJA5QACQNkBAgD9AAIA5QACANkAAkD9AAJA5QACQNkBAgD9AAIA5QACANkAAkD9AAJA5QACQNkBAgD9AAIA5QACANkAAkD9AAJA5QACQNUBAgD9AAIA5QACANUAAkD9AAJA5QACQNUBAgD9AAIA5QACANUAAkD9AAJA5QACQNUBAgD9AAIA5QACANUAAkD9AAJA5QACQNUBAgD9AAIA5QACANUAAkD5AAJA5QACQNUBAgD5AAIA5QACANUAAkD5AAJA5QACQNUBAgD5AAIA5QACANUAAkD5AAJA4QACQNUBAgD5AAIA4QACANUAAkD5AAJA4QACQNUBAgD5AAIA4QACANUAAkD5AAJA4QACQNEBAgD5AAIA4QACANEAAkD5AAJA4QACQNEBAgD5AAIA4QACANEAAkD5AAJA4QACQNEBAgD5AAIA4QACANEAAkD5AAJA4QACQNEBAgD5AAIA4QACANEAAkD5AAJA3QACQNEBAgD5AAIA3QACANEAAkD5AAJA3QACQNEBAgD5AAIA3QACANEAAkD1AAJA3QACQNEBAgD1AAIA3QACANEAAkD1AAJA3QACQNEBAgD1AAIA3QACANEAAkDxAAJA3QACQNEBAgDxAAIA3QACANEAAkDxAAJA3QACQNEBAgDxAAIA3QACANEAAkDxAAJA3QACQNEBAgDxAAIA3QACANEAAkDxAAJA3QACQNEBAgDxAAIA3QACANEAAkDxAAJA2QACQNEBAgDxAAIA2QACANEAAkDxAAJA2QACQNEBAgDxAAIA2QACANEAAkDxAAJA2QACQNEBAgDxAAIA2QACANEAAkDxAAJA2QACQNEBAgDxAAIA2QACANEAAkDxAAJA2QACQNEBAgDxAAIA2QACANEAAkDxAAJA2QACQNEBAgDxAAIA2QACANEAAkDxAAJA2QACQNEBAgDxAAIA2QACANEAAkDxAAJA2QACQNEBAgDxAAIA2QACANEAAkDxAAJA2QACQM0BAgDxAAIA2QACAM0AAkDxAAJA2QACQM0BAgDxAAIA2QACAM0AAkDxAAJA2QACQM0BAgDxAAIA2QACAM0AAkDxAAJA2QACQM0BAgDxAAIA2QACAM0AAkDxAAJA2QACQMkBAgDxAAIA2QACAMkAAkDxAAJA2QACQMkBAgDxAAIA2QACAMkAAkDxAAJA2QACQMkBAgDxAAIA2QACAMkAAkDxAAJA2QACQMkBAgDxAAIA2QACAMkAAkDxAAJA2QACQMkBAgDxAAIA2QACAMkAAkDxAAJA2QACQMkBAgDxAAIA2QACAMkAAkDxAAJA2QACQMkBAgDxAAIA2QACAMkAAkDxAAJA2QACQMkBAgDxAAIA2QACAMkAAkDxAAJA1QACQMkBAgDxAAIA1QACAMkAAkDxAAJA1QACQMkBAgDxAAIA1QACAMkAAkDxAAJA1QACQMkBAgDxAAIA1QACAMkAAkDxAAJA1QACQMkBAgDxAAIA1QACAMkAAkEdAAJA1QACQMkBAgEdAAIA1QACAMkAAkEdAAJA1QACQMkBAgEdAAIA1QACAMkAAkEdAAJA1QACQMkBAgEdAAIA1QACAMkAAkEdAAJA1QACQMkBAgEdAAIA1QACAMkAAkEdAAJA0QACQMEBAgEdAAIA0QACAMEAAkEdAAJA0QACQMEBAgEdAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQO0BAgEVAAIA0QACAO0AAkEVAAJA0QACQO0BAgEVAAIA0QACAO0AAkEVAAJAzQACQO0BAgEVAAIAzQACAO0AAkEVAAJAzQACQO0BAgEVAAIAzQACAO0AAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJAzQACQO0BAgEVAAIAzQACAO0AAkEVAAJAzQACQO0BAgEVAAIAzQACAO0AAkEVAAJAzQACQO0BAgEVAAIAzQACAO0AAkEVAAJAzQACQO0BAgEVAAIAzQACAO0AAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJA0QACQMEBAgEVAAIA0QACAMEAAkEVAAJAzQACQO0CBAIBFQACAM0AAgDtAgwCQQEAAkDtAAJA3QECAQEAAgDtAAIA3QACQQEAAkDtAAJA3QECAQEAAgDtAAIA3QACQQEAAkDtAAJA3QECAQEAAgDtAAIA3QACQQEAAkDtAAJA3QECAQEAAgDtAAIA3QACQQEAAkDtAAJA3QECAQEAAgDtAAIA3QACQQEAAkDtAAJA3QECAQEAAgDtAAIA3QACQQEAAkDtAAJA3QECAQEAAgDtAAIA3QACQQEAAkDtAAJA3QECAQEAAgDtAAIA3QACQQEAAkDlAAJA2QECAQEAAgDlAAIA2QACQQEAAkDlAAJA2QECAQEAAgDlAAIA2QACQQEAAkDlAAJA2QECAQEAAgDlAAIA2QACQQEAAkDlAAJA2QECAQEAAgDlAAIA2QACQP0AAkDlAAJA1QECAP0AAgDlAAIA1QACQP0AAkDlAAJA1QECAP0AAgDlAAIA1QACQP0AAkDlAAJA1QECAP0AAgDlAAIA1QACQP0AAkDlAAJA1QECAP0AAgDlAAIA1QACQP0AAkDhAAJA1QECAP0AAgDhAAIA1QACQP0AAkDhAAJA1QECAP0AAgDhAAIA1QACQPkAAkDhAAJA1QECAPkAAgDhAAIA1QACQPkAAkDhAAJA1QECAPkAAgDhAAIA1QACQPkAAkDdAAJA0QECAPkAAgDdAAIA0QACQPkAAkDdAAJA0QECAPkAAgDdAAIA0QACQPkAAkDdAAJA0QECAPkAAgDdAAIA0QACQPkAAkDdAAJA0QECAPkAAgDdAAIA0QACQPkAAkDdAAJA0QECAPkAAgDdAAIA0QACQPkAAkDdAAJA0QECAPkAAgDdAAIA0QACQPUAAkDdAAJA0QECAPUAAgDdAAIA0QACQPUAAkDdAAJA0QECAPUAAgDdAAIA0QACQRkAAkDRAAJAxQECARkAAgDRAAIAxQACQRkAAkDRAAJAxQECARkAAgDRAAIAxQACQRUAAkDRAAJAwQECARUAAgDRAAIAwQACQRUAAkDRAAJAwQECARUAAgDRAAIAwQACQO0AAkC9AQIA7QACAL0AAkFFAAJBOQACQPEAAkEVAQIBRQACATkAAgDxAAIBFQACQUUAAkE5AAJA8QACQRUBAgFFAAIBOQACAPEAAgEVAAJBRQACQTkAAkDxAAJBFQECAUUAAgE5AAIA8QACARUAAkE5AAJBLQACQR0AAkENAQIBOQACAS0AAgEdAAIBDQACQTEAAkEdAAJBDQECATEAAgEdAAIBDQACQTEAAkEdAAJBDQECATEAAgEdAAIBDQACQTEAAkEdAAJBDQECATEAAgEdAAIBDQACQTEAAkDxAAJBFQECATEAAgDxAAIBFQACQTEAAkDxAAJBFQECATEAAgDxAAIBFQACQOUBAgDlAAJA8QACQNkAAkDRAQIA8QACANkAAgDRAAJBHQACQNEAAkDtAQIBHQACANEAAgDtAAJBHQACQNEAAkDtAQIBHQACANEAAgDtAAJBFQACQNEAAkDBAQIBFQACANEAAgDBAAJBFQACQNEAAkDBAQIBFQACANEAAgDBAAJA7QACQNEAAkC9AQIA7QACANEAAgC9AAJA7QACQNEAAkC9AQIA7QACANEAAgC9AAJA7QACQNEAAkC9AQIA7QACANEAAgC9AAJA7QACQNEAAkC9AQIA7QACANEAAgC9AAJA5QACQNEAAkDBAQIA5QACANEAAgDBAAJA5QACQNEAAkDBAQIA5QACANEAAgDBAAJA5QACQNEAAkDBAQIA5QACANEAAgDBAAJA5QACQNEAAkDBAQIA5QACANEAAgDBAAJA7QACQNEAAkC9AQIA7QACANEAAgC9AAJA7QACQNEAAkC9AQIA7QACANEAAgC9AAJA7QACQNEAAkC9AQIA7QACANEAAgC9AAJA7QACQNEAAkC9AQIA7QACANEAAgC9AAJA7QACQM0AAkDtAQIA7QACAM0AAgDtAAJA7QACQM0AAkDtAQIA7QACAM0AAgDtAAJA5QACQM0AAkDtAQIA5QACAM0AAgDtAAJA5QACQM0AAkDtAQIA5QACAM0AAgDtAAJA3QACQNEAAkDBAQIA3QACANEAAgDBAAJA3QACQNEAAkDBAQIA3QACANEAAgDBAAJA3QACQNEAAkDBAQIA3QACANEAAgDBAAJA3QACQNEAAkDBAQIA3QACANEAAgDBAAJA6QACQNEAAkDBAQIA6QACANEAAgDBAAJA6QACQNEAAkDBAQIA6QACANEAAgDBAAJA5QACQNEAAkDBAQIA5QACANEAAgDBAAJA5QACQNEAAkDBAQIA5QACANEAAgDBAAJA5QACQNEAAkDtAQIA5QACANEAAgDtAAJA5QACQNEAAkDtAQIA5QACANEAAgDtAAJA4QACQNEAAkDtAQIA4QACANEAAgDtAAJA4QACQNEAAkDtAQIA4QACANEAAgDtAAJA3QACQNEAAkDtAQIA3QACANEAAgDtAAJA3QACQNEAAkDtAQIA3QACANEAAgDtAAJA3QACQNEAAkDtAQIA3QACANEAAgDtAAJA3QACQNEAAkDtAQIA3QACANEAAgDtAAJA3QACQMEAAkDpAggCAN0AAgDBAAIA6QIIAkDtAAJAvQIIAgDtAAIAvQACQO0AAkDZAAJAvQIIAgDtAAIA2QACAL0AAkChAAJAcQIQAgChAAIAcQAD/LwA=', midi.dataUri());
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('#Zelda Theme', function() {
|
|
45
|
+
it('should return specific base64 string when zelda theme is created.', function () {
|
|
46
|
+
const midi = require('../examples/zelda-main-theme.js');
|
|
47
|
+
assert.equal('data:audio/midi;base64,TVRoZAAAAAYAAQACAIBNVHJrAAADoQDAAQCQRn+CAIBGfwCQRn9AgEZ/AJBBf0CAQX8AkEF/QIBBfwCQRn9AgEZ/AJBEfyCARH8AkEJ/IIBCfwCQRH+DAIBEf0CQRn+CAIBGfwCQRn9AgEZ/AJBBf0CAQX8AkEF/QIBBfwCQRn9AgEZ/AJBFfyCARX8AkEN/IIBDfwCQRX+BQIBFf4IAkEUBhACARQGEAJBGf4EAgEZ/AJBBf4FAgEF/AJBGf0CARn8AkEZ/IIBGfwCQSH8ggEh/AJBKfyCASn8AkEt/IIBLfwCQTX+CAIBNf0CQTX9AgE1/AJBNf0CATX8AkE5/IIBOfwCQUH8ggFB/AJBSf4IAgFJ/QJBSf0CAUn8AkFJ/QIBSfwCQUH8ggFB/AJBOfyCATn8AkFB/YIBQfwCQTn8ggE5/AJBNf4IAgE1/AJBNf4EAgE1/AJBLf2CAS38AkE1/IIBNfwCQTn+CAIBOfwCQTX9AgE1/AJBLf0CAS38AkEl/YIBJfwCQS38ggEt/AJBNf4IAgE1/AJBLf0CAS38AkEl/QIBJfwCQSH9ggEh/AJBKfyCASn8AkEx/ggCATH8AkE9/gQCAT38AkE1/QIBNfwCQQX8ggEF/AJBBfyCAQX8AkEF/QIBBfwCQQX8ggEF/AJBBfyCAQX8AkEF/QIBBfwCQQX8ggEF/AJBBfyCAQX8AkEF/QIBBfwCQQX9AgEF/AJBGf4EAgEZ/AJBBf4FAgEF/AJBGf0CARn8AkEZ/IIBGfwCQSH8ggEh/AJBKfyCASn8AkEt/IIBLfwCQTX+CAIBNf0CQTX9AgE1/AJBNf0CATX8AkE5/IIBOfwCQUH8ggFB/AJBSf4MAgFJ/AJBVf4EAgFV/AJBUf4EAgFR/AJBRf4IAgFF/AJBNf4EAgE1/AJBOf4MAgE5/AJBSf4EAgFJ/AJBRf4EAgFF/AJBNf4IAgE1/AJBNf4EAgE1/AJBOf4MAgE5/AJBSf4EAgFJ/AJBRf4EAgFF/AJBNf4IAgE1/AJBKf4EAgEp/AJBLf4MAgEt/AJBOf4EAgE5/AJBNf4EAgE1/AJBJf4IAgEl/AJBGf4EAgEZ/AJBIf2CASH8AkEp/IIBKfwCQTH+CAIBMfwCQT3+BAIBPfwCQTX9AgE1/AJBBfyCAQX8AkEF/IIBBfwCQQX9AgEF/AJBBfyCAQX8AkEF/IIBBfwCQQX9AgEF/AJBBfyCAQX8AkEF/IIBBfwCQQX9AgEF/AJBBf0CAQX8A/y8ATVRyawAACUMAwAEAkCpAgQCAKkAAkDVAgQCANUAAkDpAggCAOkAAkClAgQCAKUAAkDNAgQCAM0AAkDhAggCAOEAAkCdAgQCAJ0AAkDFAgQCAMUAAkDpAggCAOkAAkCpAgQCAKkAAkDVAgQCANUAAkDpAggCAOkAAkC5AQIAuQACQLkAggC5AAJApQCCAKUAAkC5AQIAuQACQLkAggC5AAJApQCCAKUAAkC5AQIAuQACQLkAggC5AAJApQCCAKUAAkC5AIIAuQACQKUAggClAAJAuQCCALkAAkClAIIApQACQLkBAgC5AAJAuQCCALkAAkClAIIApQACQLkBAgC5AAJAuQCCALkAAkClAIIApQACQLkBAgC5AAJAuQCCALkAAkClAIIApQACQLkAggC5AAJApQCCAKUAAkC5AIIAuQACQKUAggClAAJAuQECALkAAkC5AIIAuQACQKUAggClAAJAuQECALkAAkC5AIIAuQACQKUAggClAAJAuQECALkAAkC5AIIAuQACQKUAggClAAJAuQCCALkAAkClAIIApQACQLkAggC5AAJApQCCAKUAAkCxAQIAsQACQLEAggCxAAJAnQCCAJ0AAkCxAQIAsQACQLEAggCxAAJAnQCCAJ0AAkCxAQIAsQACQLEAggCxAAJAnQCCAJ0AAkCxAIIAsQACQJ0AggCdAAJAsQCCALEAAkCdAIIAnQACQKkBAgCpAAJAqQCCAKkAAkCVAIIAlQACQKkBAgCpAAJAqQCCAKkAAkCVAIIAlQACQKkBAgCpAAJAqQCCAKkAAkCVAIIAlQACQKkAggCpAAJAlQCCAJUAAkCpAIIAqQACQJUAggCVAAJAxQECAMUAAkDFAIIAxQACQLEAggCxAAJAxQECAMUAAkDFAIIAxQACQLEAggCxAAJAxQECAMUAAkDFAIIAxQACQLEAggCxAAJAxQCCAMUAAkCxAIIAsQACQMUAggDFAAJAsQCCALEAAkC9AQIAvQACQL0AggC9AAJAqQCCAKkAAkC9AQIAvQACQL0AggC9AAJAqQCCAKkAAkC9AQIAvQACQL0AggC9AAJAqQCCAKkAAkC9AIIAvQACQKkAggCpAAJAvQCCAL0AAkCpAIIAqQACQLkBAgC5AAJAuQCCALkAAkClAIIApQACQLkBAgC5AAJAuQCCALkAAkClAIIApQACQLkBAgC5AAJAuQCCALkAAkClAIIApQACQLkAggC5AAJApQCCAKUAAkC5AIIAuQACQKUAggClAAJAwQECAMEAAkDBAIIAwQACQK0AggCtAAJAwQECAMEAAkDBAIIAwQACQK0AggCtAAJAwQECAMEAAkDBAIIAwQACQK0AggCtAAJAwQCCAMEAAkCtAIIArQACQMEAggDBAAJArQCCAK0AAkClAQIApQACQOUAggDlAAJA5QCCAOUAAkDhAQIA4QACQOEAggDhAAJA4QCCAOEAAkDdAQIA3QACQN0AggDdAAJA3QCCAN0AAkDZAQIA2QACQKUBAgClAAJAuQECALkAAkC5AIIAuQACQKUAggClAAJAuQECALkAAkC5AIIAuQACQKUAggClAAJAuQECALkAAkC5AIIAuQACQKUAggClAAJAuQCCALkAAkClAIIApQACQLkAggC5AAJApQCCAKUAAkCxAQIAsQACQLEAggCxAAJAnQCCAJ0AAkCxAQIAsQACQLEAggCxAAJAnQCCAJ0AAkCxAQIAsQACQLEAggCxAAJAnQCCAJ0AAkCxAIIAsQACQJ0AggCdAAJAsQCCALEAAkCdAIIAnQACQKkBAgCpAAJAqQCCAKkAAkCpAIIAqQACQKkBAgCpAAJAqQCCAKkAAkCpAIIAqQACQKkBAgCpAAJAqQCCAKkAAkCpAIIAqQACQKkAggCpAAJAqQCCAKkAAkCpAIIAqQACQKkAggCpAAJApQECAKUAAkClAIIApQACQKUAggClAAJApQECAKUAAkClAIIApQACQKUAggClAAJApQECAKUAAkClAIIApQACQKUAggClAAJApQCCAKUAAkClAIIApQACQKUAggClAAJApQCCAKUAAkChAQIAoQACQKEAggChAAJAoQCCAKEAAkChAQIAoQACQKEAggChAAJAoQCCAKEAAkChAQIAoQACQKEAggChAAJAoQCCAKEAAkChAIIAoQACQKEAggChAAJAoQCCAKEAAkChAIIAoQACQKUBAgClAAJApQCCAKUAAkClAIIApQACQKUBAgClAAJApQCCAKUAAkClAIIApQACQKUBAgClAAJApQCCAKUAAkClAIIApQACQKUAggClAAJApQCCAKUAAkClAIIApQACQKUAggClAAJAoQECAKEAAkChAIIAoQACQKEAggChAAJAoQECAKEAAkChAIIAoQACQKEAggChAAJAoQECAKEAAkChAIIAoQACQKEAggChAAJAoQCCAKEAAkChAIIAoQACQKEAggChAAJAoQCCAKEAAkClAQIApQACQKUAggClAAJApQCCAKUAAkClAQIApQACQKUAggClAAJApQCCAKUAAkClAQIApQACQKUAggClAAJApQCCAKUAAkClAIIApQACQKUAggClAAJApQCCAKUAAkClAIIApQACQL0BAgC9AAJAvQCCAL0AAkC9AIIAvQACQL0BAgC9AAJAvQCCAL0AAkC9AIIAvQACQL0BAgC9AAJAvQCCAL0AAkC9AIIAvQACQL0AggC9AAJAvQCCAL0AAkC9AIIAvQACQL0AggC9AAJAuQECALkAAkC5AIIAuQACQLkAggC5AAJAuQECALkAAkC5AIIAuQACQLkAggC5AAJAuQECALkAAkC5AIIAuQACQLkAggC5AAJAuQCCALkAAkC5AIIAuQACQLkAggC5AAJAuQCCALkAAkDBAQIAwQACQMEAggDBAAJAwQCCAMEAAkDBAQIAwQACQMEAggDBAAJAwQCCAMEAAkDBAQIAwQACQMEAggDBAAJAwQCCAMEAAkDBAIIAwQACQMEAggDBAAJAwQCCAMEAAkDBAIIAwQACQKUBAgClAAJA5QCCAOUAAkDlAIIA5QACQOEBAgDhAAJA4QCCAOEAAkDhAIIA4QACQN0BAgDdAAJA3QCCAN0AAkDdAIIA3QACQNkBAgDZAAJApQECAKUAA/y8A', midi.dataUri());
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('#Notes by Start Tick', function() {
|
|
52
|
+
it('should return specific base64 string when notes by start tick example is created.', function () {
|
|
53
|
+
const midi = require('../examples/notes-by-start-tick.js');
|
|
54
|
+
assert.equal('data:audio/midi;base64,TVRoZAAAAAYAAAABAIBNVHJrAAAARACQPEAygDxAAJBAQDKAQEAAkENAAJBHQDKAQ0AAgEdAAJBIQDKASEAAkEpAMoBKQACQTUAygE1AAJBRQDKAUUAA/y8A', midi.dataUri());
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
});
|
package/tsconfig.json
ADDED