@wcstack/midi 1.25.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.ja.md +190 -0
- package/README.md +190 -0
- package/dist/auto.js +3 -0
- package/dist/auto.min.js +1 -0
- package/dist/index.d.ts +407 -0
- package/dist/index.esm.js +757 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.esm.min.js +2 -0
- package/dist/index.esm.min.js.map +1 -0
- package/package.json +71 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/** operation error の phase(taxonomy)。 */
|
|
2
|
+
type WcsIoErrorPhase = "probe" | "start" | "execute" | "decode" | "commit" | "dispose";
|
|
3
|
+
/** serializable な error info(non-cloneable な cause とは分離。DevTools / remote へは info のみ)。 */
|
|
4
|
+
interface WcsIoErrorInfo {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
readonly phase: WcsIoErrorPhase;
|
|
7
|
+
readonly recoverable: boolean;
|
|
8
|
+
readonly capabilityId?: string;
|
|
9
|
+
readonly message: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Observation semantics of a `properties` entry.
|
|
14
|
+
*
|
|
15
|
+
* "state" — current value. A snapshot may cache it, and equality-based dedupe is safe.
|
|
16
|
+
* "event" — occurrence. Repeated identical payloads are distinct occurrences; never dedupe.
|
|
17
|
+
* "handle" — live / opaque resource with its own lifecycle (e.g. MediaStream). Not
|
|
18
|
+
* snapshot-safe and not necessarily serializable; consumers need an explicit
|
|
19
|
+
* ref / callback surface rather than a value slot.
|
|
20
|
+
*/
|
|
21
|
+
type WcBindableSemantics = "state" | "event" | "handle";
|
|
22
|
+
interface IWcBindableProperty {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly event: string;
|
|
25
|
+
readonly getter?: (event: Event) => any;
|
|
26
|
+
/**
|
|
27
|
+
* Optional, additive, forward-compatible. An absent value means **unspecified**, NOT
|
|
28
|
+
* "state": a reader that finds no `semantics` MUST keep the behavior it had before this
|
|
29
|
+
* field existed (deliver the update as-is; do not start deduping, caching or serializing
|
|
30
|
+
* on assumption). Only an explicit value licenses a reader to change its handling.
|
|
31
|
+
*/
|
|
32
|
+
readonly semantics?: WcBindableSemantics;
|
|
33
|
+
}
|
|
34
|
+
interface IWcBindableInput {
|
|
35
|
+
readonly name: string;
|
|
36
|
+
readonly attribute?: string;
|
|
37
|
+
}
|
|
38
|
+
interface IWcBindableCommand {
|
|
39
|
+
readonly name: string;
|
|
40
|
+
readonly async?: boolean;
|
|
41
|
+
}
|
|
42
|
+
interface IWcBindable {
|
|
43
|
+
readonly protocol: "wc-bindable";
|
|
44
|
+
/** Integer protocol version. All versions >= 1 are core-compatible. */
|
|
45
|
+
readonly version: number;
|
|
46
|
+
readonly properties: readonly IWcBindableProperty[];
|
|
47
|
+
readonly inputs?: readonly IWcBindableInput[];
|
|
48
|
+
readonly commands?: readonly IWcBindableCommand[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface ITagNames {
|
|
52
|
+
readonly midi: string;
|
|
53
|
+
}
|
|
54
|
+
interface IWritableTagNames {
|
|
55
|
+
midi?: string;
|
|
56
|
+
}
|
|
57
|
+
interface IConfig {
|
|
58
|
+
readonly tagNames: ITagNames;
|
|
59
|
+
}
|
|
60
|
+
interface IWritableConfig {
|
|
61
|
+
tagNames?: IWritableTagNames;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Permission surface for Web MIDI, mirroring the four-value shape used by
|
|
66
|
+
* `@wcstack/permission` / `geolocation` / `clipboard`.
|
|
67
|
+
*
|
|
68
|
+
* - `"unsupported"` — `navigator.requestMIDIAccess` is absent (Firefox with the
|
|
69
|
+
* pref off, Safari, or any non-secure context). Nothing to retry.
|
|
70
|
+
* - `"prompt"` / `"granted"` / `"denied"` — the Permissions API state when the
|
|
71
|
+
* browser can answer `query({ name: "midi" })`, otherwise inferred from the
|
|
72
|
+
* outcome of `request()`.
|
|
73
|
+
*/
|
|
74
|
+
type MidiPermissionState = "prompt" | "granted" | "denied" | "unsupported";
|
|
75
|
+
/**
|
|
76
|
+
* Normalized message kind. `"noteoff"` covers both a real note-off (status 0x8n)
|
|
77
|
+
* and the note-on-with-zero-velocity idiom (0x9n with data2 === 0), because they
|
|
78
|
+
* mean the same thing to every consumer — see README "velocity 0".
|
|
79
|
+
*/
|
|
80
|
+
type MidiMessageType = "noteon" | "noteoff" | "polyaftertouch" | "controlchange" | "programchange" | "aftertouch" | "pitchbend" | "sysex" | "other";
|
|
81
|
+
/**
|
|
82
|
+
* Fields decoded from a MIDI status byte. Members that do not apply to the
|
|
83
|
+
* message kind are `null` rather than 0, so `note === null` is distinguishable
|
|
84
|
+
* from note number 0 (C-1).
|
|
85
|
+
*/
|
|
86
|
+
interface IMidiParsed {
|
|
87
|
+
readonly type: MidiMessageType;
|
|
88
|
+
/** 1-16 for channel messages, `null` for system messages. */
|
|
89
|
+
readonly channel: number | null;
|
|
90
|
+
/** Note number 0-127 (note on/off and polyphonic aftertouch). */
|
|
91
|
+
readonly note: number | null;
|
|
92
|
+
/** Note velocity normalized to 0-1. */
|
|
93
|
+
readonly velocity: number | null;
|
|
94
|
+
/** Controller number 0-127 (control change only). */
|
|
95
|
+
readonly control: number | null;
|
|
96
|
+
/**
|
|
97
|
+
* Raw 0-127 payload for control change / program change / aftertouch, and the
|
|
98
|
+
* -1..1 normalized bend for pitch bend.
|
|
99
|
+
*/
|
|
100
|
+
readonly value: number | null;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* One incoming MIDI message. `data` is a freshly allocated copy on every
|
|
104
|
+
* message — the producer never mutates a published array (producer snapshot
|
|
105
|
+
* contract), so a consumer that retains it (RxJS replay, a React snapshot) is
|
|
106
|
+
* safe.
|
|
107
|
+
*/
|
|
108
|
+
interface IMidiMessage extends IMidiParsed {
|
|
109
|
+
readonly data: Uint8Array;
|
|
110
|
+
/** Id of the `MIDIInput` the message arrived on. */
|
|
111
|
+
readonly port: string;
|
|
112
|
+
readonly portName: string;
|
|
113
|
+
/** `MIDIMessageEvent.timeStamp` (page-relative milliseconds). */
|
|
114
|
+
readonly timestamp: number;
|
|
115
|
+
}
|
|
116
|
+
/** A MIDI port as published to bindings. Plain, serializable, snapshot-safe. */
|
|
117
|
+
interface IMidiDevice {
|
|
118
|
+
readonly id: string;
|
|
119
|
+
readonly name: string;
|
|
120
|
+
readonly manufacturer: string;
|
|
121
|
+
readonly direction: "input" | "output";
|
|
122
|
+
readonly state: "connected" | "disconnected";
|
|
123
|
+
}
|
|
124
|
+
/** Options accepted by `MidiCore.observe()` / `setOptions()`. */
|
|
125
|
+
interface IMidiOptions {
|
|
126
|
+
/** Port id or case-insensitive name prefix. Omitted = every input port. */
|
|
127
|
+
input?: string | null;
|
|
128
|
+
/** Port id or case-insensitive name prefix. Omitted = the first output port. */
|
|
129
|
+
output?: string | null;
|
|
130
|
+
/** Only deliver messages on this channel (1-16). Omitted = every channel. */
|
|
131
|
+
channel?: number | null;
|
|
132
|
+
/** Request the system-exclusive grant (a separate, more restricted permission). */
|
|
133
|
+
sysex?: boolean;
|
|
134
|
+
/** Request access as soon as `observe()` runs, instead of waiting for `request()`. */
|
|
135
|
+
auto?: boolean;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Value types for MidiCore (headless) — the observable state properties.
|
|
139
|
+
* Use with `bind()` from a wc-bindable binding core for compile-time checking.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* const core = new MidiCore();
|
|
144
|
+
* await core.request();
|
|
145
|
+
* bind(core, (name: keyof WcsMidiCoreValues, value) => { ... });
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
interface WcsMidiCoreValues {
|
|
149
|
+
message: IMidiMessage | null;
|
|
150
|
+
type: MidiMessageType | null;
|
|
151
|
+
channel: number | null;
|
|
152
|
+
note: number | null;
|
|
153
|
+
velocity: number | null;
|
|
154
|
+
control: number | null;
|
|
155
|
+
value: number | null;
|
|
156
|
+
devices: IMidiDevice[];
|
|
157
|
+
connected: boolean;
|
|
158
|
+
permission: MidiPermissionState;
|
|
159
|
+
error: string | null;
|
|
160
|
+
errorInfo: WcsIoErrorInfo | null;
|
|
161
|
+
}
|
|
162
|
+
/** Observable surface of the Shell (`<wcs-midi>`) — identical to the Core's. */
|
|
163
|
+
type WcsMidiValues = WcsMidiCoreValues;
|
|
164
|
+
/**
|
|
165
|
+
* Settable input surface for the Shell (`<wcs-midi>`) — the attributes mirrored
|
|
166
|
+
* as properties. Matches the `inputs` entries of the wc-bindable manifest.
|
|
167
|
+
*/
|
|
168
|
+
interface WcsMidiInputs {
|
|
169
|
+
input: string;
|
|
170
|
+
output: string;
|
|
171
|
+
channel: number | null;
|
|
172
|
+
sysex: boolean;
|
|
173
|
+
auto: boolean;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
declare function bootstrapMidi(userConfig?: IWritableConfig): void;
|
|
177
|
+
|
|
178
|
+
declare function getConfig(): IConfig;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Headless Web MIDI primitive: a framework-agnostic wrapper around
|
|
182
|
+
* `navigator.requestMIDIAccess()` exposed through the wc-bindable protocol.
|
|
183
|
+
*
|
|
184
|
+
* Direction is genuinely two-way, unlike `@wcstack/permission` (monitor only):
|
|
185
|
+
* incoming messages flow element → state as `event`-semantics occurrences, and
|
|
186
|
+
* `send()` is a command going the other way. Both live on one node because a
|
|
187
|
+
* page holds exactly one `MIDIAccess` — splitting input and output into two tags
|
|
188
|
+
* would only force them to coordinate over the same shared handle.
|
|
189
|
+
*
|
|
190
|
+
* Nothing starts on construction. `requestMIDIAccess()` can raise a permission
|
|
191
|
+
* prompt, so it is deliberately command-driven (`request()`), matching the
|
|
192
|
+
* `idle` / Generic Sensor family. `observe({ auto: true })` opts back into
|
|
193
|
+
* requesting immediately.
|
|
194
|
+
*
|
|
195
|
+
* The `MIDIAccess` handle itself is never published: the Core owns it and drops
|
|
196
|
+
* it in `close()` / `dispose()`, as `worker` / `websocket` / `broadcast` do with
|
|
197
|
+
* theirs. Only values cross the protocol boundary.
|
|
198
|
+
*/
|
|
199
|
+
declare class MidiCore extends EventTarget {
|
|
200
|
+
static wcBindable: IWcBindable;
|
|
201
|
+
private _target;
|
|
202
|
+
private _options;
|
|
203
|
+
private _access;
|
|
204
|
+
private _hookedInputs;
|
|
205
|
+
private _message;
|
|
206
|
+
private _devices;
|
|
207
|
+
private _connected;
|
|
208
|
+
private _permission;
|
|
209
|
+
private _error;
|
|
210
|
+
private _errorInfo;
|
|
211
|
+
private _permissionStatus;
|
|
212
|
+
private _gen;
|
|
213
|
+
private _ready;
|
|
214
|
+
constructor(options?: IMidiOptions | null, target?: EventTarget);
|
|
215
|
+
get message(): IMidiMessage | null;
|
|
216
|
+
get type(): MidiMessageType | null;
|
|
217
|
+
get channel(): number | null;
|
|
218
|
+
get note(): number | null;
|
|
219
|
+
get velocity(): number | null;
|
|
220
|
+
get control(): number | null;
|
|
221
|
+
get value(): number | null;
|
|
222
|
+
get devices(): IMidiDevice[];
|
|
223
|
+
get connected(): boolean;
|
|
224
|
+
get permission(): MidiPermissionState;
|
|
225
|
+
get granted(): boolean;
|
|
226
|
+
get denied(): boolean;
|
|
227
|
+
get unsupported(): boolean;
|
|
228
|
+
get error(): string | null;
|
|
229
|
+
get errorInfo(): WcsIoErrorInfo | null;
|
|
230
|
+
/** Resolves once the current (or initial) access attempt settles. */
|
|
231
|
+
get ready(): Promise<void>;
|
|
232
|
+
/**
|
|
233
|
+
* Store the options and, when `auto` is set, request access. Idempotent:
|
|
234
|
+
* calling it again with new options re-applies port selection to the live
|
|
235
|
+
* access without re-requesting.
|
|
236
|
+
*/
|
|
237
|
+
observe(options: IMidiOptions): Promise<void>;
|
|
238
|
+
/**
|
|
239
|
+
* Re-apply port selection / channel filtering. Cheap and safe at any time —
|
|
240
|
+
* with no access held it only records the options for a later `request()`.
|
|
241
|
+
*/
|
|
242
|
+
setOptions(options: IMidiOptions): void;
|
|
243
|
+
/**
|
|
244
|
+
* Acquire MIDI access. Never rejects: a refusal or a missing API surfaces as
|
|
245
|
+
* `permission` / `error` state (async-io-node-guidelines.md §3.6).
|
|
246
|
+
*/
|
|
247
|
+
request(): Promise<void>;
|
|
248
|
+
/**
|
|
249
|
+
* Release the access handle and detach every listener, keeping the observed
|
|
250
|
+
* permission state. A later `request()` re-acquires.
|
|
251
|
+
*/
|
|
252
|
+
close(): void;
|
|
253
|
+
/**
|
|
254
|
+
* Send a raw MIDI message to the selected output port (or the first available
|
|
255
|
+
* one). No-op when no output is reachable; a failing `send()` surfaces on
|
|
256
|
+
* `error` rather than throwing.
|
|
257
|
+
*
|
|
258
|
+
* Positional arguments pass through verbatim from command-token
|
|
259
|
+
* (docs/spec-proposal-command-token-arguments.md).
|
|
260
|
+
*/
|
|
261
|
+
send(data: number[] | Uint8Array, timestamp?: number): void;
|
|
262
|
+
/**
|
|
263
|
+
* Detach everything. Headless callers own this lifecycle themselves: without
|
|
264
|
+
* it the live `onmidimessage` handlers keep this instance reachable for as
|
|
265
|
+
* long as the ports are alive.
|
|
266
|
+
*/
|
|
267
|
+
dispose(): void;
|
|
268
|
+
private _resolveApi;
|
|
269
|
+
private _messageOf;
|
|
270
|
+
private _probePermission;
|
|
271
|
+
private _onPermissionChange;
|
|
272
|
+
private _matches;
|
|
273
|
+
private _selectedInputs;
|
|
274
|
+
private _resolveOutput;
|
|
275
|
+
private _hookInputs;
|
|
276
|
+
private _unhookInputs;
|
|
277
|
+
private _onStateChange;
|
|
278
|
+
private _onMidiMessage;
|
|
279
|
+
private _publishMessage;
|
|
280
|
+
private _publishDevices;
|
|
281
|
+
private _snapshotDevices;
|
|
282
|
+
private _sameDevices;
|
|
283
|
+
private _setConnected;
|
|
284
|
+
private _setPermission;
|
|
285
|
+
private _setError;
|
|
286
|
+
private _commitErrorInfo;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* `<wcs-midi>` — declarative Web MIDI input/output.
|
|
291
|
+
*
|
|
292
|
+
* Nothing happens on connect: `requestMIDIAccess()` can raise a permission
|
|
293
|
+
* prompt, so access is command-driven (`command.request`). Add the `auto`
|
|
294
|
+
* attribute to opt into requesting as soon as the element connects.
|
|
295
|
+
*/
|
|
296
|
+
declare class WcsMidi extends HTMLElement {
|
|
297
|
+
static hasConnectedCallbackPromise: boolean;
|
|
298
|
+
static observedAttributes: string[];
|
|
299
|
+
static wcBindable: IWcBindable;
|
|
300
|
+
private _core;
|
|
301
|
+
private _connectedCallbackPromise;
|
|
302
|
+
private _internals;
|
|
303
|
+
constructor();
|
|
304
|
+
get debugStates(): string[];
|
|
305
|
+
private _initInternals;
|
|
306
|
+
private _wireStates;
|
|
307
|
+
get input(): string;
|
|
308
|
+
set input(value: string);
|
|
309
|
+
get output(): string;
|
|
310
|
+
set output(value: string);
|
|
311
|
+
get channel(): number | null;
|
|
312
|
+
set channel(value: number | null);
|
|
313
|
+
get sysex(): boolean;
|
|
314
|
+
set sysex(value: boolean);
|
|
315
|
+
get auto(): boolean;
|
|
316
|
+
set auto(value: boolean);
|
|
317
|
+
get message(): IMidiMessage | null;
|
|
318
|
+
get type(): MidiMessageType | null;
|
|
319
|
+
get note(): number | null;
|
|
320
|
+
get velocity(): number | null;
|
|
321
|
+
get control(): number | null;
|
|
322
|
+
get value(): number | null;
|
|
323
|
+
get devices(): IMidiDevice[];
|
|
324
|
+
get connected(): boolean;
|
|
325
|
+
get permission(): MidiPermissionState;
|
|
326
|
+
get granted(): boolean;
|
|
327
|
+
get denied(): boolean;
|
|
328
|
+
get unsupported(): boolean;
|
|
329
|
+
get error(): string | null;
|
|
330
|
+
get errorInfo(): WcsIoErrorInfo | null;
|
|
331
|
+
/** Headless escape hatch: the Core backing this element. */
|
|
332
|
+
get core(): MidiCore;
|
|
333
|
+
get connectedCallbackPromise(): Promise<void>;
|
|
334
|
+
request(): Promise<void>;
|
|
335
|
+
close(): void;
|
|
336
|
+
send(data: number[] | Uint8Array, timestamp?: number): void;
|
|
337
|
+
private _options;
|
|
338
|
+
connectedCallback(): void;
|
|
339
|
+
disconnectedCallback(): void;
|
|
340
|
+
attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null): void;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Decode a raw MIDI message into the fields bindings actually want.
|
|
345
|
+
*
|
|
346
|
+
* Two normalizations are deliberate, because every consumer would otherwise
|
|
347
|
+
* repeat them:
|
|
348
|
+
*
|
|
349
|
+
* - **A note-on with velocity 0 is reported as `"noteoff"`.** Many controllers
|
|
350
|
+
* send running-status note-ons and never emit 0x8n at all; treating them as
|
|
351
|
+
* note-ons leaves stuck notes. The raw status byte is still available in
|
|
352
|
+
* `data[0]` for callers that care.
|
|
353
|
+
* - **Velocity is normalized to 0-1**, so it multiplies straight into a gain
|
|
354
|
+
* without the caller knowing about the 7-bit MIDI range. Controller values
|
|
355
|
+
* stay raw 0-127 (`value`), since their meaning is per-controller.
|
|
356
|
+
*
|
|
357
|
+
* Never throws: a truncated or nonsensical buffer decodes to `type: "other"`
|
|
358
|
+
* with every field `null` (async-io-node-guidelines.md §3.6).
|
|
359
|
+
*/
|
|
360
|
+
declare function parseMessage(data: Uint8Array | number[]): IMidiParsed;
|
|
361
|
+
/** Message kinds a caller may want to filter on, exported for tooling. */
|
|
362
|
+
declare const MIDI_MESSAGE_TYPES: readonly MidiMessageType[];
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* midiCapabilities.ts
|
|
366
|
+
*
|
|
367
|
+
* Web MIDI 固有の error code(taxonomy)と derivation。汎用の error info 型は
|
|
368
|
+
* `./platformCapability.js`(/io-core/ から copy-distribution される生成ファイル)
|
|
369
|
+
* から import する。
|
|
370
|
+
*
|
|
371
|
+
* この node の失敗は 2 箇所からしか来ない:
|
|
372
|
+
* 1. `requestMIDIAccess()` の rejection — 権限拒否・API 不在・sysex 拒否。
|
|
373
|
+
* 2. `MIDIOutput.send()` の throw — 不正なメッセージ・切断済みポート。
|
|
374
|
+
* `_setError` は screen-orientation と同じ discriminator 技法で、synthetic な
|
|
375
|
+
* `"unsupported"` / `"send"` ヒントと caught された `Error.name` を弁別する
|
|
376
|
+
* (message の文言に依存した分岐を作らない)。
|
|
377
|
+
*/
|
|
378
|
+
|
|
379
|
+
/** 安定した midi error code(taxonomy)。値は公開キーとして固定。 */
|
|
380
|
+
declare const WCS_MIDI_ERROR_CODE: {
|
|
381
|
+
/** `navigator.requestMIDIAccess` 自体が不在(synthetic "unsupported")。 */
|
|
382
|
+
readonly CapabilityMissing: "capability-missing";
|
|
383
|
+
/**
|
|
384
|
+
* `SecurityError` / `NotAllowedError` — ユーザーが拒否した、あるいは
|
|
385
|
+
* permissions policy / 非 secure context で許可されない。retry では回復しない。
|
|
386
|
+
*/
|
|
387
|
+
readonly NotAllowed: "not-allowed";
|
|
388
|
+
/** その他の `requestMIDIAccess()` 失敗。fresh な request は成功しうる。 */
|
|
389
|
+
readonly AccessError: "access-error";
|
|
390
|
+
/** `MIDIOutput.send()` の失敗(不正なメッセージ / 切断済みポート)。 */
|
|
391
|
+
readonly SendFailed: "send-failed";
|
|
392
|
+
};
|
|
393
|
+
/**
|
|
394
|
+
* Web MIDI の失敗を serializable な error taxonomy に写す。
|
|
395
|
+
*
|
|
396
|
+
* `name` は呼び出し側が渡す discriminator:
|
|
397
|
+
* - `"unsupported"` — API 不在 → phase="probe" / capability-missing。
|
|
398
|
+
* - `"send"` — 送信失敗 → phase="execute" / send-failed。recoverable(ポートが
|
|
399
|
+
* 戻れば成功しうる)。
|
|
400
|
+
* - `SecurityError` / `NotAllowedError` — 拒否 → phase="start" / not-allowed。
|
|
401
|
+
* - それ以外(`AbortError`、生の throw、`.name` 欠如等) → phase="start" /
|
|
402
|
+
* access-error。
|
|
403
|
+
*/
|
|
404
|
+
declare function deriveMidiErrorInfo(name: string | undefined, message: string): WcsIoErrorInfo;
|
|
405
|
+
|
|
406
|
+
export { MIDI_MESSAGE_TYPES, MidiCore, WCS_MIDI_ERROR_CODE, WcsMidi, bootstrapMidi, deriveMidiErrorInfo, getConfig, parseMessage };
|
|
407
|
+
export type { IMidiDevice, IMidiMessage, IMidiOptions, IMidiParsed, IWritableConfig, IWritableTagNames, MidiMessageType, MidiPermissionState, WcsIoErrorInfo, WcsMidiCoreValues, WcsMidiInputs, WcsMidiValues };
|