@huffduff/midi-writer-ts 3.2.0 → 3.2.2
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/README.md +27 -28
- package/build/index.cjs +24 -26
- package/build/index.mjs +1 -26
- package/build/types/main.d.ts +2 -35
- package/package.json +9 -2
- package/src/abstract-event.ts +8 -0
- package/src/chunks/chunk.ts +6 -0
- package/src/chunks/header.ts +29 -0
- package/src/chunks/track.ts +345 -0
- package/src/constants.ts +18 -0
- package/src/main.ts +48 -0
- package/src/meta-events/copyright-event.ts +35 -0
- package/src/meta-events/cue-point-event.ts +35 -0
- package/src/meta-events/end-track-event.ts +29 -0
- package/src/meta-events/instrument-name-event.ts +35 -0
- package/src/meta-events/key-signature-event.ts +73 -0
- package/src/meta-events/lyric-event.ts +35 -0
- package/src/meta-events/marker-event.ts +35 -0
- package/src/meta-events/meta-event.ts +7 -0
- package/src/meta-events/tempo-event.ts +37 -0
- package/src/meta-events/text-event.ts +35 -0
- package/src/meta-events/time-signature-event.ts +32 -0
- package/src/meta-events/track-name-event.ts +35 -0
- package/src/midi-events/controller-change-event.ts +30 -0
- package/src/midi-events/midi-event.ts +11 -0
- package/src/midi-events/note-event.ts +164 -0
- package/src/midi-events/note-off-event.ts +55 -0
- package/src/midi-events/note-on-event.ts +69 -0
- package/src/midi-events/pitch-bend-event.ts +40 -0
- package/src/midi-events/program-change-event.ts +28 -0
- package/src/utils.ts +263 -0
- package/src/vexflow.ts +96 -0
- package/src/writer.ts +99 -0
- package/.editorconfig +0 -24
- package/.eslintignore +0 -3
- package/.eslintrc.js +0 -18
- package/.nvmrc +0 -1
- package/.travis.yml +0 -3
- package/browser/midiwriter.js +0 -1367
- package/jsdoc.json +0 -5
- package/postinstall.js +0 -1
- package/rollup.config.js +0 -22
- package/runkit.js +0 -18
- package/tsconfig.json +0 -13
- package/typedoc.json +0 -5
package/src/constants.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MIDI file format constants.
|
|
3
|
+
* @return {Constants}
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const Constants = {
|
|
7
|
+
VERSION : '3.1.1',
|
|
8
|
+
HEADER_CHUNK_TYPE : [0x4d, 0x54, 0x68, 0x64], // Mthd
|
|
9
|
+
HEADER_CHUNK_LENGTH : [0x00, 0x00, 0x00, 0x06], // Header size for SMF
|
|
10
|
+
HEADER_CHUNK_FORMAT0 : [0x00, 0x00], // Midi Type 0 id
|
|
11
|
+
HEADER_CHUNK_FORMAT1 : [0x00, 0x01], // Midi Type 1 id
|
|
12
|
+
HEADER_CHUNK_DIVISION : [0x00, 0x80], // Defaults to 128 ticks per beat
|
|
13
|
+
TRACK_CHUNK_TYPE : [0x4d, 0x54, 0x72, 0x6b], // MTrk,
|
|
14
|
+
META_EVENT_ID : 0xFF,
|
|
15
|
+
META_SMTPE_OFFSET : 0x54
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export {Constants};
|
package/src/main.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
|
|
2
|
+
import { Constants } from './constants';
|
|
3
|
+
import { ControllerChangeEvent } from './midi-events/controller-change-event';
|
|
4
|
+
import { CopyrightEvent } from './meta-events/copyright-event';
|
|
5
|
+
import { CuePointEvent } from './meta-events/cue-point-event';
|
|
6
|
+
import { EndTrackEvent } from './meta-events/end-track-event';
|
|
7
|
+
import { InstrumentNameEvent } from './meta-events/instrument-name-event';
|
|
8
|
+
import { KeySignatureEvent } from './meta-events/key-signature-event';
|
|
9
|
+
import { LyricEvent } from './meta-events/lyric-event';
|
|
10
|
+
import { MarkerEvent } from './meta-events/marker-event';
|
|
11
|
+
import { NoteOnEvent } from './midi-events/note-on-event';
|
|
12
|
+
import { NoteOffEvent } from './midi-events/note-off-event';
|
|
13
|
+
import { NoteEvent } from './midi-events/note-event';
|
|
14
|
+
import { PitchBendEvent } from './midi-events/pitch-bend-event';
|
|
15
|
+
import { ProgramChangeEvent } from './midi-events/program-change-event';
|
|
16
|
+
import { TempoEvent } from './meta-events/tempo-event';
|
|
17
|
+
import { TextEvent } from './meta-events/text-event';
|
|
18
|
+
import { TimeSignatureEvent } from './meta-events/time-signature-event';
|
|
19
|
+
import { Track } from './chunks/track';
|
|
20
|
+
import { TrackNameEvent } from './meta-events/track-name-event';
|
|
21
|
+
import { Utils } from './utils';
|
|
22
|
+
import { VexFlow } from './vexflow';
|
|
23
|
+
import { Writer } from './writer';
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
Constants,
|
|
27
|
+
ControllerChangeEvent,
|
|
28
|
+
CopyrightEvent,
|
|
29
|
+
CuePointEvent,
|
|
30
|
+
EndTrackEvent,
|
|
31
|
+
InstrumentNameEvent,
|
|
32
|
+
KeySignatureEvent,
|
|
33
|
+
LyricEvent,
|
|
34
|
+
MarkerEvent,
|
|
35
|
+
NoteOnEvent,
|
|
36
|
+
NoteOffEvent,
|
|
37
|
+
NoteEvent,
|
|
38
|
+
PitchBendEvent,
|
|
39
|
+
ProgramChangeEvent,
|
|
40
|
+
TempoEvent,
|
|
41
|
+
TextEvent,
|
|
42
|
+
TimeSignatureEvent,
|
|
43
|
+
Track,
|
|
44
|
+
TrackNameEvent,
|
|
45
|
+
Utils,
|
|
46
|
+
VexFlow,
|
|
47
|
+
Writer
|
|
48
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {Constants} from '../constants';
|
|
2
|
+
import {MetaEvent} from './meta-event';
|
|
3
|
+
import {Utils} from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Object representation of a tempo meta event.
|
|
7
|
+
* @param {object} fields {text: string, delta: integer}
|
|
8
|
+
* @return {CopyrightEvent}
|
|
9
|
+
*/
|
|
10
|
+
class CopyrightEvent implements MetaEvent {
|
|
11
|
+
data: number[];
|
|
12
|
+
delta: number;
|
|
13
|
+
name: string;
|
|
14
|
+
text: string;
|
|
15
|
+
type: 0x02;
|
|
16
|
+
|
|
17
|
+
constructor(fields: { text: string; delta?: number; }) {
|
|
18
|
+
this.delta = fields.delta || 0x00;
|
|
19
|
+
this.name = 'CopyrightEvent';
|
|
20
|
+
this.text = fields.text;
|
|
21
|
+
this.type = 0x02;
|
|
22
|
+
|
|
23
|
+
const textBytes = Utils.stringToBytes(this.text);
|
|
24
|
+
|
|
25
|
+
// Start with zero time delta
|
|
26
|
+
this.data = Utils.numberToVariableLength(this.delta).concat(
|
|
27
|
+
Constants.META_EVENT_ID,
|
|
28
|
+
this.type,
|
|
29
|
+
Utils.numberToVariableLength(textBytes.length), // Size
|
|
30
|
+
textBytes, // Text
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {CopyrightEvent};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {Constants} from '../constants';
|
|
2
|
+
import {MetaEvent} from './meta-event';
|
|
3
|
+
import {Utils} from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Object representation of a cue point meta event.
|
|
7
|
+
* @param {object} fields {text: string, delta: integer}
|
|
8
|
+
* @return {CuePointEvent}
|
|
9
|
+
*/
|
|
10
|
+
class CuePointEvent implements MetaEvent {
|
|
11
|
+
data: number[];
|
|
12
|
+
delta: number;
|
|
13
|
+
name: string;
|
|
14
|
+
text: string;
|
|
15
|
+
type: 0x07;
|
|
16
|
+
|
|
17
|
+
constructor(fields: { text: string; delta?: number; }) {
|
|
18
|
+
this.delta = fields.delta || 0x00;
|
|
19
|
+
this.name = 'CuePointEvent';
|
|
20
|
+
this.text = fields.text;
|
|
21
|
+
this.type = 0x07;
|
|
22
|
+
|
|
23
|
+
const textBytes = Utils.stringToBytes(this.text);
|
|
24
|
+
|
|
25
|
+
// Start with zero time delta
|
|
26
|
+
this.data = Utils.numberToVariableLength(this.delta).concat(
|
|
27
|
+
Constants.META_EVENT_ID,
|
|
28
|
+
this.type,
|
|
29
|
+
Utils.numberToVariableLength(textBytes.length), // Size
|
|
30
|
+
textBytes, // Text
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {CuePointEvent};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {Constants} from '../constants';
|
|
2
|
+
import {MetaEvent} from './meta-event';
|
|
3
|
+
import {Utils} from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Object representation of a end track meta event.
|
|
7
|
+
* @param {object} fields {delta: integer}
|
|
8
|
+
* @return {EndTrackEvent}
|
|
9
|
+
*/
|
|
10
|
+
class EndTrackEvent implements MetaEvent {
|
|
11
|
+
data: number[];
|
|
12
|
+
delta: number;
|
|
13
|
+
name: string;
|
|
14
|
+
type: [0x2F, 0x00];
|
|
15
|
+
|
|
16
|
+
constructor(fields?: { delta: number; }) {
|
|
17
|
+
this.delta = fields?.delta || 0x00;
|
|
18
|
+
this.name = 'EndTrackEvent';
|
|
19
|
+
this.type = [0x2F, 0x00];
|
|
20
|
+
|
|
21
|
+
// Start with zero time delta
|
|
22
|
+
this.data = Utils.numberToVariableLength(this.delta).concat(
|
|
23
|
+
Constants.META_EVENT_ID,
|
|
24
|
+
this.type
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export {EndTrackEvent};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {Constants} from '../constants';
|
|
2
|
+
import {MetaEvent} from './meta-event';
|
|
3
|
+
import {Utils} from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Object representation of an instrument name meta event.
|
|
7
|
+
* @param {object} fields {text: string, delta: integer}
|
|
8
|
+
* @return {InstrumentNameEvent}
|
|
9
|
+
*/
|
|
10
|
+
class InstrumentNameEvent implements MetaEvent {
|
|
11
|
+
data: number[];
|
|
12
|
+
delta: number;
|
|
13
|
+
name: string;
|
|
14
|
+
text: string;
|
|
15
|
+
type: 0x04;
|
|
16
|
+
|
|
17
|
+
constructor(fields: { text: string; delta?: number; }) {
|
|
18
|
+
this.delta = fields.delta || 0x00;
|
|
19
|
+
this.name = 'InstrumentNameEvent';
|
|
20
|
+
this.text = fields.text;
|
|
21
|
+
this.type = 0x04;
|
|
22
|
+
|
|
23
|
+
const textBytes = Utils.stringToBytes(this.text);
|
|
24
|
+
|
|
25
|
+
// Start with zero time delta
|
|
26
|
+
this.data = Utils.numberToVariableLength(this.delta).concat(
|
|
27
|
+
Constants.META_EVENT_ID,
|
|
28
|
+
this.type,
|
|
29
|
+
Utils.numberToVariableLength(textBytes.length), // Size
|
|
30
|
+
textBytes, // Instrument name
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {InstrumentNameEvent};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {Constants} from '../constants';
|
|
2
|
+
import {MetaEvent} from './meta-event';
|
|
3
|
+
import {Utils} from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Object representation of a key signature meta event.
|
|
7
|
+
* @return {KeySignatureEvent}
|
|
8
|
+
*/
|
|
9
|
+
class KeySignatureEvent implements MetaEvent {
|
|
10
|
+
data: number[];
|
|
11
|
+
delta: number;
|
|
12
|
+
name: string;
|
|
13
|
+
type: 0x59;
|
|
14
|
+
|
|
15
|
+
constructor(sf, mi) {
|
|
16
|
+
this.name = 'KeySignatureEvent';
|
|
17
|
+
this.type = 0x59;
|
|
18
|
+
|
|
19
|
+
let mode = mi || 0;
|
|
20
|
+
sf = sf || 0;
|
|
21
|
+
|
|
22
|
+
// Function called with string notation
|
|
23
|
+
if (typeof mi === 'undefined') {
|
|
24
|
+
const fifths = [
|
|
25
|
+
['Cb', 'Gb', 'Db', 'Ab', 'Eb', 'Bb', 'F', 'C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#'],
|
|
26
|
+
['ab', 'eb', 'bb', 'f', 'c', 'g', 'd', 'a', 'e', 'b', 'f#', 'c#', 'g#', 'd#', 'a#']
|
|
27
|
+
];
|
|
28
|
+
const _sflen = sf.length;
|
|
29
|
+
let note = sf || 'C';
|
|
30
|
+
|
|
31
|
+
if (sf[0] === sf[0].toLowerCase()) mode = 1
|
|
32
|
+
|
|
33
|
+
if (_sflen > 1) {
|
|
34
|
+
switch (sf.charAt(_sflen - 1)) {
|
|
35
|
+
case 'm':
|
|
36
|
+
mode = 1;
|
|
37
|
+
note = sf.charAt(0).toLowerCase();
|
|
38
|
+
note = note.concat(sf.substring(1, _sflen - 1));
|
|
39
|
+
break;
|
|
40
|
+
case '-':
|
|
41
|
+
mode = 1;
|
|
42
|
+
note = sf.charAt(0).toLowerCase();
|
|
43
|
+
note = note.concat(sf.substring(1, _sflen - 1));
|
|
44
|
+
break;
|
|
45
|
+
case 'M':
|
|
46
|
+
mode = 0;
|
|
47
|
+
note = sf.charAt(0).toUpperCase();
|
|
48
|
+
note = note.concat(sf.substring(1, _sflen - 1));
|
|
49
|
+
break;
|
|
50
|
+
case '+':
|
|
51
|
+
mode = 0;
|
|
52
|
+
note = sf.charAt(0).toUpperCase();
|
|
53
|
+
note = note.concat(sf.substring(1, _sflen - 1));
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const fifthindex = fifths[mode].indexOf(note);
|
|
59
|
+
sf = fifthindex === -1 ? 0 : fifthindex - 7;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Start with zero time delta
|
|
63
|
+
this.data = Utils.numberToVariableLength(0x00).concat(
|
|
64
|
+
Constants.META_EVENT_ID,
|
|
65
|
+
this.type,
|
|
66
|
+
[0x02], // Size
|
|
67
|
+
Utils.numberToBytes(sf, 1), // Number of sharp or flats ( < 0 flat; > 0 sharp)
|
|
68
|
+
Utils.numberToBytes(mode, 1), // Mode: 0 major, 1 minor
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export {KeySignatureEvent};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {Constants} from '../constants';
|
|
2
|
+
import {MetaEvent} from './meta-event';
|
|
3
|
+
import {Utils} from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Object representation of a lyric meta event.
|
|
7
|
+
* @param {object} fields {text: string, delta: integer}
|
|
8
|
+
* @return {LyricEvent}
|
|
9
|
+
*/
|
|
10
|
+
class LyricEvent implements MetaEvent {
|
|
11
|
+
data: number[];
|
|
12
|
+
delta: number;
|
|
13
|
+
name: string;
|
|
14
|
+
text: string;
|
|
15
|
+
type: 0x05;
|
|
16
|
+
|
|
17
|
+
constructor(fields: { text: string; delta?: number; }) {
|
|
18
|
+
this.delta = fields.delta || 0x00;
|
|
19
|
+
this.name = 'LyricEvent';
|
|
20
|
+
this.text = fields.text;
|
|
21
|
+
this.type = 0x05;
|
|
22
|
+
|
|
23
|
+
const textBytes = Utils.stringToBytes(this.text);
|
|
24
|
+
|
|
25
|
+
// Start with zero time delta
|
|
26
|
+
this.data = Utils.numberToVariableLength(this.delta).concat(
|
|
27
|
+
Constants.META_EVENT_ID,
|
|
28
|
+
this.type,
|
|
29
|
+
Utils.numberToVariableLength(textBytes.length), // Size
|
|
30
|
+
textBytes, // Text
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {LyricEvent};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {Constants} from '../constants';
|
|
2
|
+
import {MetaEvent} from './meta-event';
|
|
3
|
+
import {Utils} from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Object representation of a marker meta event.
|
|
7
|
+
* @param {object} fields {text: string, delta: integer}
|
|
8
|
+
* @return {MarkerEvent}
|
|
9
|
+
*/
|
|
10
|
+
class MarkerEvent implements MetaEvent {
|
|
11
|
+
data: number[];
|
|
12
|
+
delta: number;
|
|
13
|
+
name: string;
|
|
14
|
+
text: string;
|
|
15
|
+
type: 0x06;
|
|
16
|
+
|
|
17
|
+
constructor(fields: { text: string; delta?: number; }) {
|
|
18
|
+
this.delta = fields.delta || 0x00;
|
|
19
|
+
this.name = 'MarkerEvent';
|
|
20
|
+
this.text = fields.text;
|
|
21
|
+
this.type = 0x06;
|
|
22
|
+
|
|
23
|
+
const textBytes = Utils.stringToBytes(this.text);
|
|
24
|
+
|
|
25
|
+
// Start with zero time delta
|
|
26
|
+
this.data = Utils.numberToVariableLength(this.delta).concat(
|
|
27
|
+
Constants.META_EVENT_ID,
|
|
28
|
+
this.type,
|
|
29
|
+
Utils.numberToVariableLength(textBytes.length), // Size
|
|
30
|
+
textBytes, // Text
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {MarkerEvent};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {Constants} from '../constants';
|
|
2
|
+
import {MetaEvent} from './meta-event';
|
|
3
|
+
import {Utils} from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Object representation of a tempo meta event.
|
|
7
|
+
* @param {object} fields {bpm: integer, delta: integer}
|
|
8
|
+
* @return {TempoEvent}
|
|
9
|
+
*/
|
|
10
|
+
class TempoEvent implements MetaEvent {
|
|
11
|
+
bpm: number;
|
|
12
|
+
data: number[];
|
|
13
|
+
delta: number;
|
|
14
|
+
name: string;
|
|
15
|
+
tick: number;
|
|
16
|
+
type: 0x51;
|
|
17
|
+
|
|
18
|
+
constructor(fields: { bpm: number; tick?: number; delta?: number; }) {
|
|
19
|
+
this.bpm = fields.bpm;
|
|
20
|
+
this.delta = fields.delta || 0x00;
|
|
21
|
+
this.tick = fields.tick;
|
|
22
|
+
this.name = 'TempoEvent';
|
|
23
|
+
this.type = 0x51;
|
|
24
|
+
|
|
25
|
+
const tempo = Math.round(60000000 / this.bpm);
|
|
26
|
+
|
|
27
|
+
// Start with zero time delta
|
|
28
|
+
this.data = Utils.numberToVariableLength(this.delta).concat(
|
|
29
|
+
Constants.META_EVENT_ID,
|
|
30
|
+
this.type,
|
|
31
|
+
[0x03], // Size
|
|
32
|
+
Utils.numberToBytes(tempo, 3), // Tempo, 3 bytes
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export {TempoEvent};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {Constants} from '../constants';
|
|
2
|
+
import {MetaEvent} from './meta-event';
|
|
3
|
+
import {Utils} from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Object representation of a tempo meta event.
|
|
7
|
+
* @param {object} fields {text: string, delta: integer}
|
|
8
|
+
* @return {TextEvent}
|
|
9
|
+
*/
|
|
10
|
+
class TextEvent implements MetaEvent {
|
|
11
|
+
data: number[];
|
|
12
|
+
delta: number;
|
|
13
|
+
name: string;
|
|
14
|
+
text: string;
|
|
15
|
+
type: 0x01;
|
|
16
|
+
|
|
17
|
+
constructor(fields: { text: string; delta?: number; }) {
|
|
18
|
+
this.delta = fields.delta || 0x00;
|
|
19
|
+
this.text = fields.text;
|
|
20
|
+
this.name = 'TextEvent';
|
|
21
|
+
this.type = 0x01;
|
|
22
|
+
|
|
23
|
+
const textBytes = Utils.stringToBytes(this.text);
|
|
24
|
+
|
|
25
|
+
// Start with zero time delta
|
|
26
|
+
this.data = Utils.numberToVariableLength(fields.delta).concat(
|
|
27
|
+
Constants.META_EVENT_ID,
|
|
28
|
+
this.type,
|
|
29
|
+
Utils.numberToVariableLength(textBytes.length), // Size
|
|
30
|
+
textBytes, // Text
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {TextEvent};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {Constants} from '../constants';
|
|
2
|
+
import {MetaEvent} from './meta-event';
|
|
3
|
+
import {Utils} from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Object representation of a time signature meta event.
|
|
7
|
+
* @return {TimeSignatureEvent}
|
|
8
|
+
*/
|
|
9
|
+
class TimeSignatureEvent implements MetaEvent {
|
|
10
|
+
data: number[];
|
|
11
|
+
delta: number;
|
|
12
|
+
name: string;
|
|
13
|
+
type: 0x58;
|
|
14
|
+
|
|
15
|
+
constructor(numerator, denominator, midiclockspertick, notespermidiclock) {
|
|
16
|
+
this.name = 'TimeSignatureEvent';
|
|
17
|
+
this.type = 0x58;
|
|
18
|
+
|
|
19
|
+
// Start with zero time delta
|
|
20
|
+
this.data = Utils.numberToVariableLength(0x00).concat(
|
|
21
|
+
Constants.META_EVENT_ID,
|
|
22
|
+
this.type,
|
|
23
|
+
[0x04], // Size
|
|
24
|
+
Utils.numberToBytes(numerator, 1), // Numerator, 1 bytes
|
|
25
|
+
Utils.numberToBytes(Math.log2(denominator), 1), // Denominator is expressed as pow of 2, 1 bytes
|
|
26
|
+
Utils.numberToBytes(midiclockspertick || 24, 1), // MIDI Clocks per tick, 1 bytes
|
|
27
|
+
Utils.numberToBytes(notespermidiclock || 8, 1), // Number of 1/32 notes per MIDI clocks, 1 bytes
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export {TimeSignatureEvent};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {Constants} from '../constants';
|
|
2
|
+
import {MetaEvent} from './meta-event';
|
|
3
|
+
import {Utils} from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Object representation of a tempo meta event.
|
|
7
|
+
* @param {object} fields {text: string, delta: integer}
|
|
8
|
+
* @return {TrackNameEvent}
|
|
9
|
+
*/
|
|
10
|
+
class TrackNameEvent implements MetaEvent {
|
|
11
|
+
data: number[];
|
|
12
|
+
delta: number;
|
|
13
|
+
name: string;
|
|
14
|
+
text: string;
|
|
15
|
+
type: 0x03;
|
|
16
|
+
|
|
17
|
+
constructor(fields: { text: string; delta?: number; }) {
|
|
18
|
+
this.delta = fields.delta || 0x00;
|
|
19
|
+
this.name = 'TrackNameEvent';
|
|
20
|
+
this.text = fields.text;
|
|
21
|
+
this.type = 0x03;
|
|
22
|
+
|
|
23
|
+
const textBytes = Utils.stringToBytes(this.text);
|
|
24
|
+
|
|
25
|
+
// Start with zero time delta
|
|
26
|
+
this.data = Utils.numberToVariableLength(this.delta).concat(
|
|
27
|
+
Constants.META_EVENT_ID,
|
|
28
|
+
this.type,
|
|
29
|
+
Utils.numberToVariableLength(textBytes.length), // Size
|
|
30
|
+
textBytes, // Text
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {TrackNameEvent};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {MidiEvent} from './midi-event';
|
|
2
|
+
import {Utils} from '../utils';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Holds all data for a "controller change" MIDI event
|
|
6
|
+
* @param {object} fields {controllerNumber: integer, controllerValue: integer, delta: integer}
|
|
7
|
+
* @return {ControllerChangeEvent}
|
|
8
|
+
*/
|
|
9
|
+
class ControllerChangeEvent implements MidiEvent {
|
|
10
|
+
channel: number;
|
|
11
|
+
controllerNumber: number;
|
|
12
|
+
controllerValue: number;
|
|
13
|
+
data: number[];
|
|
14
|
+
delta: number;
|
|
15
|
+
name: string;
|
|
16
|
+
status: 0xB0;
|
|
17
|
+
|
|
18
|
+
constructor(fields: { controllerNumber: number; controllerValue: number; channel?: number; delta?: number; }) {
|
|
19
|
+
this.channel = fields.channel - 1 || 0;
|
|
20
|
+
this.controllerValue = fields.controllerValue;
|
|
21
|
+
this.controllerNumber = fields.controllerNumber;
|
|
22
|
+
this.delta = fields.delta || 0x00;
|
|
23
|
+
this.name = 'ControllerChangeEvent';
|
|
24
|
+
this.status = 0xB0;
|
|
25
|
+
|
|
26
|
+
this.data = Utils.numberToVariableLength(fields.delta).concat(this.status | this.channel, this.controllerNumber, this.controllerValue);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export {ControllerChangeEvent};
|