0
# Constants and Enumerations
1
2
The Enumerations class provides MIDI specification constants and enumerations for all message types, control change mappings, and system messages. These constants ensure consistent and correct MIDI communication.
3
4
## Capabilities
5
6
### Channel Message Constants
7
8
Constants for MIDI channel messages (0x80-0xEF).
9
10
```javascript { .api }
11
class Enumerations {
12
/**
13
* Channel message type constants
14
*/
15
static readonly CHANNEL_MESSAGES: {
16
noteoff: number;
17
noteon: number;
18
keyaftertouch: number;
19
controlchange: number;
20
programchange: number;
21
channelaftertouch: number;
22
pitchbend: number;
23
};
24
25
/**
26
* MIDI channel message constants (with MIDI channel values 0-15)
27
*/
28
static readonly MIDI_CHANNEL_MESSAGES: {
29
noteoff: number;
30
noteon: number;
31
keyaftertouch: number;
32
controlchange: number;
33
programchange: number;
34
channelaftertouch: number;
35
pitchbend: number;
36
};
37
}
38
```
39
40
**Usage Examples:**
41
42
```javascript
43
import { Enumerations } from "webmidi";
44
45
// Channel message constants
46
console.log(Enumerations.CHANNEL_MESSAGES.noteon); // 9
47
console.log(Enumerations.CHANNEL_MESSAGES.noteoff); // 8
48
console.log(Enumerations.CHANNEL_MESSAGES.controlchange); // 11
49
console.log(Enumerations.CHANNEL_MESSAGES.programchange); // 12
50
console.log(Enumerations.CHANNEL_MESSAGES.pitchbend); // 14
51
52
// MIDI channel message constants (base values)
53
console.log(Enumerations.MIDI_CHANNEL_MESSAGES.noteon); // 144 (0x90)
54
console.log(Enumerations.MIDI_CHANNEL_MESSAGES.noteoff); // 128 (0x80)
55
```
56
57
### Channel Numbers
58
59
Valid channel number constants.
60
61
```javascript { .api }
62
/**
63
* Valid channel numbers (1-16)
64
*/
65
static readonly CHANNEL_NUMBERS: number[];
66
67
/**
68
* MIDI channel numbers (0-15)
69
*/
70
static readonly MIDI_CHANNEL_NUMBERS: number[];
71
```
72
73
**Usage Examples:**
74
75
```javascript
76
// User-facing channel numbers (1-16)
77
console.log(Enumerations.CHANNEL_NUMBERS); // [1, 2, 3, ..., 16]
78
79
// MIDI protocol channel numbers (0-15)
80
console.log(Enumerations.MIDI_CHANNEL_NUMBERS); // [0, 1, 2, ..., 15]
81
82
// Validate channel numbers
83
function isValidChannel(channel) {
84
return Enumerations.CHANNEL_NUMBERS.includes(channel);
85
}
86
87
function isValidMidiChannel(channel) {
88
return Enumerations.MIDI_CHANNEL_NUMBERS.includes(channel);
89
}
90
```
91
92
### Control Change Messages
93
94
Comprehensive control change message mappings.
95
96
```javascript { .api }
97
/**
98
* Control change message constants with descriptive names
99
*/
100
static readonly CONTROL_CHANGE_MESSAGES: {
101
bankselectcoarse: number;
102
modulationwheelcoarse: number;
103
breathcontrollercoarse: number;
104
footcontrollercoarse: number;
105
portamentotimecoarse: number;
106
dataentrycoarse: number;
107
volumecoarse: number;
108
balancecoarse: number;
109
pancoarse: number;
110
expressioncoarse: number;
111
effectcontrol1coarse: number;
112
effectcontrol2coarse: number;
113
generalpurposecontroller1: number;
114
generalpurposecontroller2: number;
115
generalpurposecontroller3: number;
116
generalpurposecontroller4: number;
117
bankselectfine: number;
118
modulationwheelfine: number;
119
breathcontrollerfine: number;
120
footcontrollerfine: number;
121
portamentotimefine: number;
122
dataentryfine: number;
123
volumefine: number;
124
balancefine: number;
125
panfine: number;
126
expressionfine: number;
127
effectcontrol1fine: number;
128
effectcontrol2fine: number;
129
sustain: number;
130
portamento: number;
131
sostenuto: number;
132
softpedal: number;
133
legatofootswitch: number;
134
hold2: number;
135
soundvariation: number;
136
resonance: number;
137
releasetime: number;
138
attacktime: number;
139
brightness: number;
140
decaytime: number;
141
vibratorate: number;
142
vibratodepth: number;
143
vibratodelay: number;
144
generalpurposecontroller5: number;
145
generalpurposecontroller6: number;
146
generalpurposecontroller7: number;
147
generalpurposecontroller8: number;
148
portamentocontrol: number;
149
effects1depth: number;
150
effects2depth: number;
151
effects3depth: number;
152
effects4depth: number;
153
effects5depth: number;
154
dataincrement: number;
155
datadecrement: number;
156
nonregisteredparametercoarse: number;
157
nonregisteredparameterfine: number;
158
registeredparametercoarse: number;
159
registeredparameterfine: number;
160
allsoundoff: number;
161
resetallcontrollers: number;
162
localcontrol: number;
163
allnotesoff: number;
164
omnimodeoff: number;
165
omnimodeon: number;
166
monomodeon: number;
167
polymodeon: number;
168
};
169
170
/**
171
* MIDI control change message constants (CC numbers 0-127)
172
*/
173
static readonly MIDI_CONTROL_CHANGE_MESSAGES: object;
174
```
175
176
**Usage Examples:**
177
178
```javascript
179
// Common control changes
180
console.log(Enumerations.CONTROL_CHANGE_MESSAGES.volumecoarse); // 7
181
console.log(Enumerations.CONTROL_CHANGE_MESSAGES.pancoarse); // 10
182
console.log(Enumerations.CONTROL_CHANGE_MESSAGES.sustain); // 64
183
console.log(Enumerations.CONTROL_CHANGE_MESSAGES.effects1depth); // 91 (reverb)
184
console.log(Enumerations.CONTROL_CHANGE_MESSAGES.effects3depth); // 93 (chorus)
185
186
// Channel mode messages
187
console.log(Enumerations.CONTROL_CHANGE_MESSAGES.allsoundoff); // 120
188
console.log(Enumerations.CONTROL_CHANGE_MESSAGES.allnotesoff); // 123
189
console.log(Enumerations.CONTROL_CHANGE_MESSAGES.resetallcontrollers); // 121
190
191
// Use in code
192
function sendVolume(output, channel, volume) {
193
const ccNumber = Enumerations.CONTROL_CHANGE_MESSAGES.volumecoarse;
194
output.sendControlChange(ccNumber, volume, { channels: channel });
195
}
196
197
function enableSustain(output, channel) {
198
const ccNumber = Enumerations.CONTROL_CHANGE_MESSAGES.sustain;
199
output.sendControlChange(ccNumber, 127, { channels: channel });
200
}
201
```
202
203
### Channel Mode Messages
204
205
Channel mode message constants for voice and mode control.
206
207
```javascript { .api }
208
/**
209
* Channel mode message constants
210
*/
211
static readonly CHANNEL_MODE_MESSAGES: {
212
allsoundoff: number;
213
resetallcontrollers: number;
214
localcontrol: number;
215
allnotesoff: number;
216
omnimodeoff: number;
217
omnimodeon: number;
218
monomodeon: number;
219
polymodeon: number;
220
};
221
222
/**
223
* MIDI channel mode message constants
224
*/
225
static readonly MIDI_CHANNEL_MODE_MESSAGES: object;
226
```
227
228
**Usage Examples:**
229
230
```javascript
231
// Channel mode constants
232
console.log(Enumerations.CHANNEL_MODE_MESSAGES.allsoundoff); // 120
233
console.log(Enumerations.CHANNEL_MODE_MESSAGES.allnotesoff); // 123
234
console.log(Enumerations.CHANNEL_MODE_MESSAGES.resetallcontrollers); // 121
235
console.log(Enumerations.CHANNEL_MODE_MESSAGES.localcontrol); // 122
236
237
// Omni mode constants
238
console.log(Enumerations.CHANNEL_MODE_MESSAGES.omnimodeoff); // 124
239
console.log(Enumerations.CHANNEL_MODE_MESSAGES.omnimodeon); // 125
240
241
// Mono/poly mode constants
242
console.log(Enumerations.CHANNEL_MODE_MESSAGES.monomodeon); // 126
243
console.log(Enumerations.CHANNEL_MODE_MESSAGES.polymodeon); // 127
244
245
// Use in emergency stop function
246
function panicStop(output) {
247
const allSoundOff = Enumerations.CHANNEL_MODE_MESSAGES.allsoundoff;
248
const allNotesOff = Enumerations.CHANNEL_MODE_MESSAGES.allnotesoff;
249
250
// Send to all channels
251
for (let channel = 1; channel <= 16; channel++) {
252
output.sendControlChange(allSoundOff, 0, { channels: channel });
253
output.sendControlChange(allNotesOff, 0, { channels: channel });
254
}
255
}
256
```
257
258
### Registered Parameter Numbers
259
260
Registered Parameter Number (RPN) constants for standard parameters.
261
262
```javascript { .api }
263
/**
264
* Registered parameter constants
265
*/
266
static readonly REGISTERED_PARAMETERS: {
267
pitchbendrange: number[];
268
channelfinetuning: number[];
269
channelcoarsetuning: number[];
270
tuningprogram: number[];
271
tuningbank: number[];
272
modulationrange: number[];
273
azimuthangle: number[];
274
elevationangle: number[];
275
gain: number[];
276
distanceratio: number[];
277
maximumdistance: number[];
278
gainincrease: number[];
279
referenceazimuthangle: number[];
280
referenceelvationangle: number[];
281
referencegain: number[];
282
referencedistanceratio: number[];
283
};
284
285
/**
286
* MIDI registered parameter constants
287
*/
288
static readonly MIDI_REGISTERED_PARAMETERS: object;
289
```
290
291
**Usage Examples:**
292
293
```javascript
294
// RPN constants
295
console.log(Enumerations.REGISTERED_PARAMETERS.pitchbendrange); // [0, 0]
296
console.log(Enumerations.REGISTERED_PARAMETERS.channelfinetuning); // [0, 1]
297
console.log(Enumerations.REGISTERED_PARAMETERS.channelcoarsetuning); // [0, 2]
298
console.log(Enumerations.REGISTERED_PARAMETERS.tuningprogram); // [0, 3]
299
300
// Use with RPN messages
301
function setPitchBendRange(output, channel, semitones, cents = 0) {
302
const rpn = Enumerations.REGISTERED_PARAMETERS.pitchbendrange;
303
output.sendRpnValue(rpn, [semitones, cents], { channels: channel });
304
}
305
306
function setFineTuning(output, channel, cents) {
307
const rpn = Enumerations.REGISTERED_PARAMETERS.channelfinetuning;
308
const msbLsb = Utilities.fromFloatToMsbLsb((cents + 100) / 200); // -100 to +100 cents
309
output.sendRpnValue(rpn, [msbLsb.msb, msbLsb.lsb], { channels: channel });
310
}
311
```
312
313
### System Messages
314
315
System message constants for real-time and common messages.
316
317
```javascript { .api }
318
/**
319
* System message constants
320
*/
321
static readonly SYSTEM_MESSAGES: {
322
sysex: number;
323
timecode: number;
324
songposition: number;
325
songselect: number;
326
tunerequest: number;
327
sysexend: number;
328
clock: number;
329
start: number;
330
continue: number;
331
stop: number;
332
activesensing: number;
333
reset: number;
334
};
335
336
/**
337
* MIDI system message constants
338
*/
339
static readonly MIDI_SYSTEM_MESSAGES: object;
340
```
341
342
**Usage Examples:**
343
344
```javascript
345
// System message constants
346
console.log(Enumerations.SYSTEM_MESSAGES.sysex); // 240 (0xF0)
347
console.log(Enumerations.SYSTEM_MESSAGES.clock); // 248 (0xF8)
348
console.log(Enumerations.SYSTEM_MESSAGES.start); // 250 (0xFA)
349
console.log(Enumerations.SYSTEM_MESSAGES.stop); // 252 (0xFC)
350
console.log(Enumerations.SYSTEM_MESSAGES.reset); // 255 (0xFF)
351
352
// System common messages
353
console.log(Enumerations.SYSTEM_MESSAGES.timecode); // 241 (0xF1)
354
console.log(Enumerations.SYSTEM_MESSAGES.songposition); // 242 (0xF2)
355
console.log(Enumerations.SYSTEM_MESSAGES.songselect); // 243 (0xF3)
356
console.log(Enumerations.SYSTEM_MESSAGES.tunerequest); // 246 (0xF6)
357
358
// Use for message filtering
359
function isClockMessage(message) {
360
return message.statusByte === Enumerations.SYSTEM_MESSAGES.clock;
361
}
362
363
function isTransportMessage(message) {
364
const transportMessages = [
365
Enumerations.SYSTEM_MESSAGES.start,
366
Enumerations.SYSTEM_MESSAGES.continue,
367
Enumerations.SYSTEM_MESSAGES.stop
368
];
369
return transportMessages.includes(message.statusByte);
370
}
371
```
372
373
### Channel Events
374
375
Array of channel event type names.
376
377
```javascript { .api }
378
/**
379
* Channel event type names
380
*/
381
static readonly CHANNEL_EVENTS: string[];
382
```
383
384
**Usage Examples:**
385
386
```javascript
387
// Channel event names
388
console.log(Enumerations.CHANNEL_EVENTS);
389
// ["noteoff", "noteon", "keyaftertouch", "controlchange",
390
// "programchange", "channelaftertouch", "pitchbend"]
391
392
// Use for event handling
393
function setupChannelListeners(input) {
394
Enumerations.CHANNEL_EVENTS.forEach(eventType => {
395
input.addListener(eventType, (e) => {
396
console.log(`Received ${eventType} on channel ${e.channel}`);
397
});
398
});
399
}
400
401
// Check if event is a channel event
402
function isChannelEvent(eventType) {
403
return Enumerations.CHANNEL_EVENTS.includes(eventType);
404
}
405
```
406
407
## Practical Usage Examples
408
409
### Message Type Detection
410
411
```javascript
412
import { Enumerations, Message } from "webmidi";
413
414
function analyzeMessage(message) {
415
const statusByte = message.statusByte;
416
417
// Check channel messages
418
if (message.isChannelMessage) {
419
const command = message.command;
420
421
if (command === Enumerations.CHANNEL_MESSAGES.noteon) {
422
return "Note On";
423
} else if (command === Enumerations.CHANNEL_MESSAGES.controlchange) {
424
const ccNumber = message.dataBytes[0];
425
426
// Check for channel mode messages
427
if (ccNumber >= 120) {
428
for (const [name, value] of Object.entries(Enumerations.CHANNEL_MODE_MESSAGES)) {
429
if (value === ccNumber) {
430
return `Channel Mode: ${name}`;
431
}
432
}
433
}
434
435
// Regular control change
436
return `Control Change: CC${ccNumber}`;
437
}
438
}
439
440
// Check system messages
441
for (const [name, value] of Object.entries(Enumerations.SYSTEM_MESSAGES)) {
442
if (value === statusByte) {
443
return `System: ${name}`;
444
}
445
}
446
447
return "Unknown";
448
}
449
```
450
451
### Control Change Name Resolution
452
453
```javascript
454
function getControllerName(ccNumber) {
455
// Find name in control change messages
456
for (const [name, value] of Object.entries(Enumerations.CONTROL_CHANGE_MESSAGES)) {
457
if (value === ccNumber) {
458
return name;
459
}
460
}
461
462
return `CC${ccNumber}`;
463
}
464
465
function getControllerNumber(ccName) {
466
const normalizedName = ccName.toLowerCase().replace(/[^a-z0-9]/g, '');
467
468
for (const [name, value] of Object.entries(Enumerations.CONTROL_CHANGE_MESSAGES)) {
469
if (name === normalizedName) {
470
return value;
471
}
472
}
473
474
return undefined;
475
}
476
477
// Usage
478
console.log(getControllerName(64)); // "sustain"
479
console.log(getControllerName(91)); // "effects1depth" (reverb)
480
console.log(getControllerNumber("volume")); // undefined (need "volumecoarse")
481
console.log(getControllerNumber("volumecoarse")); // 7
482
```
483
484
### Standard MIDI Implementation
485
486
```javascript
487
// Create a standard MIDI implementation using constants
488
class StandardMidiDevice {
489
constructor(output) {
490
this.output = output;
491
}
492
493
// Standard program change
494
selectProgram(channel, program) {
495
this.output.sendProgramChange(program, { channels: channel });
496
}
497
498
// Volume control
499
setVolume(channel, volume) {
500
const cc = Enumerations.CONTROL_CHANGE_MESSAGES.volumecoarse;
501
this.output.sendControlChange(cc, volume, { channels: channel });
502
}
503
504
// Pan control
505
setPan(channel, pan) {
506
const cc = Enumerations.CONTROL_CHANGE_MESSAGES.pancoarse;
507
this.output.sendControlChange(cc, pan, { channels: channel });
508
}
509
510
// Sustain pedal
511
setSustain(channel, enabled) {
512
const cc = Enumerations.CONTROL_CHANGE_MESSAGES.sustain;
513
const value = enabled ? 127 : 0;
514
this.output.sendControlChange(cc, value, { channels: channel });
515
}
516
517
// Emergency stop
518
panic() {
519
const allSoundOff = Enumerations.CHANNEL_MODE_MESSAGES.allsoundoff;
520
const allNotesOff = Enumerations.CHANNEL_MODE_MESSAGES.allnotesoff;
521
522
Enumerations.CHANNEL_NUMBERS.forEach(channel => {
523
this.output.sendControlChange(allSoundOff, 0, { channels: channel });
524
this.output.sendControlChange(allNotesOff, 0, { channels: channel });
525
});
526
}
527
528
// Reset all controllers
529
resetControllers(channel = "all") {
530
const reset = Enumerations.CHANNEL_MODE_MESSAGES.resetallcontrollers;
531
this.output.sendControlChange(reset, 0, { channels: channel });
532
}
533
}
534
```
535
536
## Types
537
538
```javascript { .api }
539
type ChannelMessageType = "noteoff" | "noteon" | "keyaftertouch" | "controlchange" | "programchange" | "channelaftertouch" | "pitchbend";
540
541
type SystemMessageType = "sysex" | "timecode" | "songposition" | "songselect" | "tunerequest" | "clock" | "start" | "continue" | "stop" | "activesensing" | "reset";
542
543
type ChannelModeMessageType = "allsoundoff" | "resetallcontrollers" | "localcontrol" | "allnotesoff" | "omnimodeoff" | "omnimodeon" | "monomodeon" | "polymodeon";
544
545
interface ControlChangeMessages {
546
[key: string]: number;
547
}
548
549
interface RegisteredParameters {
550
[key: string]: number[];
551
}
552
```