or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

constants.mdindex.mdmessage-forwarding.mdmessage-processing.mdmidi-input.mdmidi-output.mdnote-processing.mdutilities.mdwebmidi-interface.md

constants.mddocs/

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

```