@jeffy-g/live-midi-types 0.10.0 → 0.11.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/README.md +208 -106
- package/{ESMFEventType.d.ts → dist/ESMFEventType.d.ts} +26 -40
- package/dist/ESMFEventType.js +11 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/midi-clip.d.ts +6 -4
- package/dist/midi10-smf-io.d.ts +12 -0
- package/dist/midi10-smf-io.js +12 -0
- package/dist/midi10-smf-types.d.ts +40 -25
- package/dist/midi10-smf-types.js +0 -1
- package/dist/project.d.ts +4 -2
- package/dist/smf-parser.d.ts +22 -0
- package/dist/smf-parser.js +287 -0
- package/dist/smf-writer.d.ts +53 -0
- package/dist/smf-writer.js +473 -0
- package/package.json +9 -8
package/README.md
CHANGED
|
@@ -1,164 +1,266 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @jeffy-g/live-midi-types
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@jeffy-g/live-midi-types)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Shared TypeScript types and small runtime helpers for Ableton Live MIDI clip data, project summaries, and Standard MIDI Files.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## Scope
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
The package provides three related contracts:
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- beat-based MIDI events and clip data extracted from Ableton Live Sets;
|
|
13
|
+
- application-facing clip, track, and project summaries;
|
|
14
|
+
- numeric MIDI 1.0 SMF event types for parsers and writers.
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
The Ableton data shapes were reverse engineered from observed Live 11 and Live 12 `.als` documents. Ableton does not publish an official `.als` specification, so consumers should expect the model to grow as more real projects are inspected.
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
These definitions were **reverse engineered** from Ableton Live 11 `.als` files.
|
|
19
|
-
Ableton publishes no official specification, so some fields may be missing or misinterpreted.
|
|
20
|
-
If you encounter inaccuracies, please open an issue or pull request.
|
|
21
|
-
|
|
22
|
-
> ## Directory Structure
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
src/
|
|
26
|
-
├─ midi-event.ts # basic note, control change, and tempo events
|
|
27
|
-
├─ midi-clip.ts # builds on midi-event to describe clips
|
|
28
|
-
├─ project.ts # aggregates clips into a project
|
|
29
|
-
├─ ableton-colors.ts # color utilities
|
|
30
|
-
└─ index.ts # public exports
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Dependencies flow upward: `midi-event` → `midi-clip` → `project`, while `ableton-colors` stands alone.
|
|
34
|
-
|
|
35
|
-
> ## Installation
|
|
36
|
-
|
|
37
|
-
You can install the package using npm or yarn:
|
|
18
|
+
## Installation
|
|
38
19
|
|
|
39
20
|
```sh
|
|
40
21
|
npm install @jeffy-g/live-midi-types
|
|
41
22
|
```
|
|
42
23
|
|
|
43
|
-
|
|
24
|
+
## Entry points
|
|
44
25
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
26
|
+
| Entry point | Contents |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `@jeffy-g/live-midi-types` | Ableton MIDI events, clip data, project summaries, color helpers, and runtime utilities |
|
|
29
|
+
| `@jeffy-g/live-midi-types/midi10-smf-types` | MIDI 1.0 SMF header, event, file, and writer option types |
|
|
30
|
+
| `@jeffy-g/live-midi-types/midi10-smf-io` | MIDI 1.0 SMF parser, writer, and VLQ size helper |
|
|
31
|
+
| `@jeffy-g/live-midi-types/ESMFEventType` | Runtime numeric SMF event type constants |
|
|
48
32
|
|
|
49
|
-
|
|
33
|
+
## Ableton MIDI clip data
|
|
50
34
|
|
|
51
|
-
|
|
35
|
+
`TMidiClipData` stores beat-based source data. MIDI CC events are grouped by controller in `ccMap`; `knownCCEvents` determines which controller buckets are present and their traversal order.
|
|
52
36
|
|
|
53
37
|
```ts
|
|
54
|
-
import
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
38
|
+
import {
|
|
39
|
+
flattenCCEventMap,
|
|
40
|
+
type ControlChangeEvent,
|
|
41
|
+
type NoteEvent,
|
|
42
|
+
type TMidiClipData,
|
|
43
|
+
} from "@jeffy-g/live-midi-types";
|
|
44
|
+
|
|
45
|
+
const note: NoteEvent = {
|
|
46
|
+
time: 0,
|
|
47
|
+
duration: 1,
|
|
60
48
|
pitch: 60,
|
|
61
|
-
velocity: 100
|
|
49
|
+
velocity: 100,
|
|
62
50
|
};
|
|
63
51
|
|
|
64
|
-
|
|
65
|
-
const cc = {
|
|
52
|
+
const sustain: ControlChangeEvent = {
|
|
66
53
|
time: 0.5,
|
|
67
54
|
controller: 64,
|
|
68
55
|
value: 127,
|
|
69
|
-
source: "
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/** @type {TempoEvent} */
|
|
73
|
-
const tempo = {
|
|
74
|
-
time: 0.0,
|
|
75
|
-
bpm: 120
|
|
56
|
+
source: "linear",
|
|
76
57
|
};
|
|
77
58
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
clipLength: 16,
|
|
59
|
+
const clip: TMidiClipData = {
|
|
60
|
+
clipStartInBeats: 8,
|
|
61
|
+
clipLength: 4,
|
|
82
62
|
adjustTimeOftempee: 0,
|
|
83
|
-
knownCCEvents: [64
|
|
63
|
+
knownCCEvents: [64],
|
|
84
64
|
notes: [note],
|
|
85
|
-
|
|
65
|
+
ccMap: {
|
|
66
|
+
"64": [sustain],
|
|
67
|
+
},
|
|
68
|
+
pitchBends: [
|
|
69
|
+
{ time: 1, value: -4096 },
|
|
70
|
+
{ time: 2, value: 4096, source: "bezier" },
|
|
71
|
+
],
|
|
72
|
+
channelPressures: [
|
|
73
|
+
{ time: 1.5, value: 96 },
|
|
74
|
+
],
|
|
86
75
|
};
|
|
76
|
+
|
|
77
|
+
const controlChanges = flattenCCEventMap(
|
|
78
|
+
clip.ccMap,
|
|
79
|
+
clip.knownCCEvents,
|
|
80
|
+
);
|
|
87
81
|
```
|
|
88
82
|
|
|
89
|
-
|
|
83
|
+
### Event value contracts
|
|
84
|
+
|
|
85
|
+
All event `time` values are floating point quarter-note beats relative to the start of the clip.
|
|
86
|
+
|
|
87
|
+
| Type | Value contract |
|
|
88
|
+
|---|---|
|
|
89
|
+
| `NoteEvent` | `duration` and `velocity` may be fractional; `pitch` is an integer from `0` to `127` |
|
|
90
|
+
| `ControlChangeEvent` | `controller` is an integer from `0` to `127`; `value` may remain fractional in the `0..127` range |
|
|
91
|
+
| `ChannelPressureEvent` | `value` may remain fractional in the `0..127` range |
|
|
92
|
+
| `PitchBendEvent` | signed, possibly fractional Live value from `-8192` to `8191` |
|
|
93
|
+
| `TempoEvent` | floating point BPM |
|
|
94
|
+
|
|
95
|
+
`BaseEvent.source` is optional interpolation metadata. It is either `"linear"` or `"bezier"` and is normally omitted for original or discrete events.
|
|
96
|
+
|
|
97
|
+
`TEnvelopeEvent` is the shared processing shape for Control Change, Channel Pressure, and Pitch Bend envelopes. Its `controller` property is present only for Control Change. Pitch Bend and Channel Pressure remain in their dedicated arrays and do not use negative controller numbers in serialized event data.
|
|
98
|
+
|
|
99
|
+
`TMidiClipData.cc?()` is an optional compatibility helper. New code should treat `ccMap` as the stored representation and call `flattenCCEventMap()` when it needs one time-sorted CC array.
|
|
100
|
+
|
|
101
|
+
### Clip metadata
|
|
102
|
+
|
|
103
|
+
The following optional event collections were added in version 0.10:
|
|
104
|
+
|
|
105
|
+
- `pitchBends?: PitchBendEvent[]`
|
|
106
|
+
- `channelPressures?: ChannelPressureEvent[]`
|
|
107
|
+
- `meta?: MetaTextEvent[]`
|
|
108
|
+
|
|
109
|
+
The root entry point also exports `TimeSignatureEvent` and `KeySignatureEvent` for project-level musical metadata.
|
|
110
|
+
|
|
111
|
+
## Project summaries
|
|
112
|
+
|
|
113
|
+
The project types add application IDs and display metadata to clip data. `TTrackInfo.clips` is a map keyed by each `TClipSummary.id`.
|
|
90
114
|
|
|
91
115
|
```ts
|
|
92
|
-
import {
|
|
116
|
+
import type {
|
|
117
|
+
TMidiClipData,
|
|
118
|
+
TClipSummary,
|
|
119
|
+
TParsedAbletonLiveSet,
|
|
120
|
+
TTrackInfo,
|
|
121
|
+
} from "@jeffy-g/live-midi-types";
|
|
122
|
+
|
|
123
|
+
declare const clip: TMidiClipData;
|
|
124
|
+
|
|
125
|
+
const clipSummary: TClipSummary<TMidiClipData> = {
|
|
126
|
+
originId: "0",
|
|
127
|
+
id: "clip-6e8c",
|
|
128
|
+
color: "0",
|
|
129
|
+
disabled: false,
|
|
130
|
+
clipName: "Piano",
|
|
131
|
+
trackName: "Track 1",
|
|
132
|
+
annotation: "",
|
|
133
|
+
...clip,
|
|
134
|
+
};
|
|
93
135
|
|
|
94
|
-
const
|
|
136
|
+
const track: TTrackInfo<TMidiClipData> = {
|
|
137
|
+
originId: "12",
|
|
138
|
+
id: "track-91d2",
|
|
139
|
+
name: "Track 1",
|
|
140
|
+
color: "0",
|
|
141
|
+
annotation: "",
|
|
142
|
+
clips: {
|
|
143
|
+
[clipSummary.id]: clipSummary,
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const project: TParsedAbletonLiveSet<TMidiClipData> = {
|
|
148
|
+
alsName: "MyProject",
|
|
149
|
+
ticksPerQuarter: 480,
|
|
150
|
+
tracks: [track],
|
|
151
|
+
tempoAutomation: [{ time: 0, bpm: 120 }],
|
|
152
|
+
};
|
|
95
153
|
```
|
|
96
154
|
|
|
97
|
-
|
|
155
|
+
`color` is the Ableton palette index stored as a string. Convert it to a CSS color with `getColorFromIndex()`.
|
|
156
|
+
|
|
157
|
+
## MIDI 1.0 SMF types
|
|
158
|
+
|
|
159
|
+
SMF types use numeric `ESMFEventType` discriminants. Meta events do not carry a separate marker property; their numeric `type` identifies them. Import the runtime constants and type declarations from their dedicated entry points.
|
|
98
160
|
|
|
99
161
|
```ts
|
|
100
|
-
import
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
162
|
+
import { ESMFEventType } from "@jeffy-g/live-midi-types/ESMFEventType";
|
|
163
|
+
import type {
|
|
164
|
+
MidiData,
|
|
165
|
+
MidiEndOfTrackEvent,
|
|
166
|
+
MidiNoteOnEvent,
|
|
167
|
+
} from "@jeffy-g/live-midi-types/midi10-smf-types";
|
|
168
|
+
|
|
169
|
+
const noteOn: MidiNoteOnEvent = {
|
|
170
|
+
deltaTime: 0,
|
|
171
|
+
type: ESMFEventType.noteOn,
|
|
172
|
+
channel: 0,
|
|
173
|
+
noteNumber: 60,
|
|
174
|
+
velocity: 100,
|
|
110
175
|
};
|
|
111
176
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
color: "#ff94a6",
|
|
116
|
-
clips: {
|
|
117
|
-
"Piano": clipSummary
|
|
118
|
-
}
|
|
177
|
+
const endOfTrack: MidiEndOfTrackEvent = {
|
|
178
|
+
deltaTime: 480,
|
|
179
|
+
type: ESMFEventType.endOfTrack,
|
|
119
180
|
};
|
|
120
181
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
182
|
+
const midi: MidiData = {
|
|
183
|
+
header: {
|
|
184
|
+
format: 0,
|
|
185
|
+
numTracks: 1,
|
|
186
|
+
ticksPerBeat: 480,
|
|
187
|
+
},
|
|
188
|
+
tracks: [[noteOn, endOfTrack]],
|
|
126
189
|
};
|
|
127
190
|
```
|
|
128
191
|
|
|
129
|
-
|
|
192
|
+
### SMF parser and writer
|
|
193
|
+
|
|
194
|
+
The codec entry point parses MIDI bytes into `MidiData` and writes the same numeric event contract back to a `Uint8Array`.
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
import {
|
|
198
|
+
parseMidi,
|
|
199
|
+
writeMidi,
|
|
200
|
+
} from "@jeffy-g/live-midi-types/midi10-smf-io";
|
|
201
|
+
|
|
202
|
+
declare const source: Uint8Array;
|
|
203
|
+
|
|
204
|
+
const parsed = parseMidi(source);
|
|
205
|
+
const encoded = writeMidi(parsed, {
|
|
206
|
+
running: true,
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`getVarIntSize()` is also exported from this entry point for code that needs to calculate the encoded byte size of an SMF variable-length quantity.
|
|
130
211
|
|
|
131
|
-
|
|
212
|
+
The SMF contract includes:
|
|
132
213
|
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
214
|
+
- format 0, 1, and 2 headers;
|
|
215
|
+
- channel voice events, including Note On/Off, CC, Program Change, Channel Aftertouch, and signed Pitch Bend;
|
|
216
|
+
- tempo, time signature, key signature, text, and other meta events;
|
|
217
|
+
- SysEx, sequencer-specific, and unknown meta events;
|
|
218
|
+
- running-status and velocity-zero Note On writer options.
|
|
136
219
|
|
|
137
|
-
|
|
220
|
+
SMF event values are wire-boundary values. In particular, `MidiPitchBendEvent.value` remains signed from `-8192` to `8191`; a writer performs the 14-bit unsigned conversion when encoding the two data bytes.
|
|
138
221
|
|
|
139
|
-
|
|
140
|
-
- `clipStartInBeats`: Start time in beats.
|
|
141
|
-
- `clipLength`: Duration in beats.
|
|
142
|
-
- `adjustTimeOftempee`: Time adjustment for tempo mapping.
|
|
143
|
-
- `knownCCEvents`: Array of CC numbers present in the clip.
|
|
144
|
-
- `notes`: Array of `NoteEvent`.
|
|
145
|
-
- `cc`: Array of `ControlChangeEvent`.
|
|
222
|
+
## Runtime helpers
|
|
146
223
|
|
|
147
|
-
|
|
224
|
+
The root entry point includes a small set of runtime exports:
|
|
148
225
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
226
|
+
```ts
|
|
227
|
+
import {
|
|
228
|
+
abletonColorPalette,
|
|
229
|
+
eventsIs,
|
|
230
|
+
flattenCCEventMap,
|
|
231
|
+
getColorFromIndex,
|
|
232
|
+
version,
|
|
233
|
+
} from "@jeffy-g/live-midi-types";
|
|
234
|
+
|
|
235
|
+
const color = getColorFromIndex(5); // "#1aff2f"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
- `flattenCCEventMap()` flattens the listed controller buckets and sorts the result by event time.
|
|
239
|
+
- `eventsIs()` identifies note, CC, or tempo event arrays from their first event.
|
|
240
|
+
- `getColorFromIndex()` returns the Ableton palette color or `"#888"` for an unknown index.
|
|
241
|
+
- `version` exposes the package source version string.
|
|
152
242
|
|
|
153
|
-
|
|
243
|
+
## Source layout
|
|
154
244
|
|
|
155
|
-
|
|
156
|
-
|
|
245
|
+
```text
|
|
246
|
+
src/
|
|
247
|
+
├─ midi-event.ts # beat-based Ableton event contracts
|
|
248
|
+
├─ midi-clip.ts # clip data and CC map flattening
|
|
249
|
+
├─ project.ts # clip, track, and project summaries
|
|
250
|
+
├─ midi10-smf-types.ts # MIDI 1.0 SMF type declarations
|
|
251
|
+
├─ midi10-smf-io.ts # SMF codec entry point
|
|
252
|
+
├─ smf-parser.ts # numeric SMF parser
|
|
253
|
+
├─ smf-writer.ts # numeric SMF writer
|
|
254
|
+
├─ ESMFEventType.ts # numeric SMF enum declarations
|
|
255
|
+
├─ smf-event-type.ts # runtime numeric SMF constants
|
|
256
|
+
├─ ableton-colors.ts # Live palette and color lookup
|
|
257
|
+
└─ index.ts # root package exports
|
|
258
|
+
```
|
|
157
259
|
|
|
158
|
-
|
|
260
|
+
## Related project
|
|
159
261
|
|
|
160
|
-
|
|
262
|
+
- [live-midi-export](https://github.com/jeffy-g/live-midi-export) extracts MIDI clips and project metadata from Ableton Live Sets.
|
|
161
263
|
|
|
162
|
-
|
|
264
|
+
## License
|
|
163
265
|
|
|
164
|
-
|
|
266
|
+
MIT
|
|
@@ -6,114 +6,100 @@
|
|
|
6
6
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
|
-
* @file live-midi-types/ESMFEventType.
|
|
9
|
+
* @file live-midi-types/src/ESMFEventType.ts
|
|
10
10
|
*/
|
|
11
|
-
|
|
12
|
-
declare const enum ESMFEventType {
|
|
13
|
-
// Miscellaneous meta events
|
|
11
|
+
export declare const enum ESMFEventType {
|
|
14
12
|
/**
|
|
15
13
|
* ```
|
|
16
14
|
* 0x00
|
|
17
15
|
* ```
|
|
18
16
|
*/
|
|
19
17
|
sequenceNumber = 0,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// Channel voice events
|
|
31
|
-
noteOff = 0x08, // 8
|
|
32
|
-
noteOn, // velocity === 0 ? 'noteOff' : 'noteOn'
|
|
33
|
-
noteAftertouch, // 10
|
|
18
|
+
text = 1, // 1
|
|
19
|
+
copyrightNotice = 2, // 2
|
|
20
|
+
trackName = 3, // 3
|
|
21
|
+
instrumentName = 4, // 4
|
|
22
|
+
lyrics = 5, // 5
|
|
23
|
+
marker = 6, // 6
|
|
24
|
+
cuePoint = 7, // 7
|
|
25
|
+
noteOff = 8, // 8
|
|
26
|
+
noteOn = 9, // velocity === 0 ? 'noteOff' : 'noteOn'
|
|
27
|
+
noteAftertouch = 10, // 10
|
|
34
28
|
/**
|
|
35
29
|
* means control change event type.
|
|
36
30
|
* ```
|
|
37
31
|
* [0xb0 | event.channel][controllerType:0..127][value:0..127]
|
|
38
32
|
* ```
|
|
39
33
|
*/
|
|
40
|
-
controller,
|
|
34
|
+
controller = 11, // 11
|
|
41
35
|
/**
|
|
42
36
|
* ```
|
|
43
37
|
* [0xc0 | event.channel][programNumber:0..127]
|
|
44
38
|
* ```
|
|
45
39
|
* @see {@linkcode https://midiprog.com/program-numbers/ Program Change Numbers}
|
|
46
40
|
*/
|
|
47
|
-
programChange,
|
|
41
|
+
programChange = 12, // 12
|
|
48
42
|
/**
|
|
49
43
|
* ```
|
|
50
44
|
* [0xd0 | event.channel][0..127]
|
|
51
45
|
* ```
|
|
52
46
|
*/
|
|
53
|
-
channelAftertouch
|
|
47
|
+
channelAftertouch = 13, // 13
|
|
54
48
|
/**
|
|
55
49
|
* ```
|
|
56
50
|
* [0xe0 | event.channel][LSB:0..127][MSB:0..127]
|
|
57
51
|
* ```
|
|
58
52
|
*/
|
|
59
|
-
pitchBend,
|
|
60
|
-
|
|
61
|
-
// Tempo and channel prefix meta events
|
|
53
|
+
pitchBend = 14, // 14
|
|
62
54
|
/**
|
|
63
55
|
* ```
|
|
64
56
|
* 0x20
|
|
65
57
|
* ```
|
|
66
58
|
*/
|
|
67
|
-
channelPrefix =
|
|
68
|
-
portPrefix,
|
|
59
|
+
channelPrefix = 32, //
|
|
60
|
+
portPrefix = 33, // 33
|
|
69
61
|
/**
|
|
70
62
|
* ```
|
|
71
63
|
* 0x2F
|
|
72
64
|
* ```
|
|
73
65
|
*/
|
|
74
|
-
endOfTrack =
|
|
66
|
+
endOfTrack = 47, // 47
|
|
75
67
|
/**
|
|
76
68
|
* ```
|
|
77
69
|
* 0x51
|
|
78
70
|
* ```
|
|
79
71
|
*/
|
|
80
|
-
setTempo =
|
|
81
|
-
|
|
82
|
-
// Meta utility events
|
|
72
|
+
setTempo = 81, // 81
|
|
83
73
|
/**
|
|
84
74
|
* ```
|
|
85
75
|
* 0x54
|
|
86
76
|
* ```
|
|
87
77
|
*/
|
|
88
|
-
smpteOffset =
|
|
78
|
+
smpteOffset = 84, // 84
|
|
89
79
|
/**
|
|
90
80
|
* ```
|
|
91
81
|
* 0x58
|
|
92
82
|
* ```
|
|
93
83
|
*/
|
|
94
|
-
timeSignature =
|
|
95
|
-
keySignature,
|
|
96
|
-
|
|
97
|
-
// System-exclusive events
|
|
84
|
+
timeSignature = 88, // 88
|
|
85
|
+
keySignature = 89, //
|
|
98
86
|
/**
|
|
99
87
|
* ```
|
|
100
88
|
* 0x7F
|
|
101
89
|
* ```
|
|
102
90
|
*/
|
|
103
|
-
sequencerSpecific =
|
|
91
|
+
sequencerSpecific = 127, //127
|
|
104
92
|
/**
|
|
105
93
|
* ```
|
|
106
94
|
* 0xF0
|
|
107
95
|
* ```
|
|
108
96
|
*/
|
|
109
|
-
sysEx =
|
|
97
|
+
sysEx = 240, // 240 eventTypeByte
|
|
110
98
|
/**
|
|
111
99
|
* ```
|
|
112
100
|
* 0xF7
|
|
113
101
|
* ```
|
|
114
102
|
*/
|
|
115
|
-
endSysEx =
|
|
116
|
-
|
|
117
|
-
// Miscellaneous meta events
|
|
103
|
+
endSysEx = 247, // 247 eventTypeByte
|
|
118
104
|
unknownMeta = -1,
|
|
119
105
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
// Copyright (C) 2026 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
// Released under the MIT license
|
|
5
|
+
// https://opensource.org/licenses/mit-license.php
|
|
6
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* @file live-midi-types/src/ESMFEventType.ts
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/midi-clip.d.ts
CHANGED
|
@@ -31,8 +31,8 @@ export type TMidiClipData = {
|
|
|
31
31
|
*
|
|
32
32
|
* ```
|
|
33
33
|
* // e.g. obtain `midiClip` object
|
|
34
|
-
* // xpath: "/Ableton/LiveSet/Tracks/MidiTrack[
|
|
35
|
-
* const midiClip = Ableton.LiveSet.Tracks.MidiTrack[
|
|
34
|
+
* // xpath: "/Ableton/LiveSet/Tracks/MidiTrack[1]/DeviceChain/MainSequencer/ClipTimeable/ArrangerAutomation/Events/MidiClip[1]"
|
|
35
|
+
* const midiClip = Ableton.LiveSet.Tracks.MidiTrack[1].DeviceChain.MainSequencer.ClipTimeable.ArrangerAutomation.Events.MidiClip[1];
|
|
36
36
|
* // clip start position in Live arrangement view
|
|
37
37
|
* const clipStart = midiClip.CurrentStart.Value;
|
|
38
38
|
* // clip end position in Live arrangement view
|
|
@@ -57,10 +57,12 @@ export type TMidiClipData = {
|
|
|
57
57
|
*/
|
|
58
58
|
notes: NoteEvent[];
|
|
59
59
|
/**
|
|
60
|
-
* Control change event map. (key: cc number)
|
|
60
|
+
* Control change event map. (key: cc number, `0..127`)
|
|
61
61
|
* @version 0.8.0
|
|
62
62
|
*/
|
|
63
|
-
ccMap:
|
|
63
|
+
ccMap: {
|
|
64
|
+
[ccNumber: `${number}`]: ControlChangeEvent[];
|
|
65
|
+
};
|
|
64
66
|
/**
|
|
65
67
|
* Array of extracted control change events. (flatten {@link TMidiClipData.ccMap __`ccMap`__}, sort by time)
|
|
66
68
|
* + use `flattenCCEventMap` (recommended)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
// Copyright (C) 2026 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
// Released under the MIT license
|
|
5
|
+
// https://opensource.org/licenses/mit-license.php
|
|
6
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* @file live-midi-types/src/midi10-smf-io.ts
|
|
10
|
+
*/
|
|
11
|
+
export * from "./smf-parser.js";
|
|
12
|
+
export * from "./smf-writer.js";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
3
|
+
// Copyright (C) 2026 jeffy-g <hirotom1107@gmail.com>
|
|
4
|
+
// Released under the MIT license
|
|
5
|
+
// https://opensource.org/licenses/mit-license.php
|
|
6
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* @file live-midi-types/src/midi10-smf-io.ts
|
|
10
|
+
*/
|
|
11
|
+
export * from "./smf-parser.js";
|
|
12
|
+
export * from "./smf-writer.js";
|