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

note-processing.mddocs/

0

# Note Processing

1

2

Note processing provides comprehensive functionality for representing musical notes and converting between different note formats. The Note class handles note creation, properties, and transformations for MIDI applications.

3

4

## Capabilities

5

6

### Note Construction

7

8

Create Note objects from various input formats.

9

10

```javascript { .api }

11

class Note {

12

/**

13

* Create a Note object from various input formats

14

* @param value - Note input (string, number, or Note object)

15

* @param options - Note creation options

16

* @param options.duration - Note duration in milliseconds

17

* @param options.attack - Attack velocity (0-1, default: 0.5)

18

* @param options.release - Release velocity (0-1, default: 0.5)

19

* @param options.octaveOffset - Octave offset to apply

20

*/

21

constructor(value: string | number | Note, options?: {

22

duration?: number;

23

attack?: number;

24

release?: number;

25

octaveOffset?: number;

26

});

27

}

28

```

29

30

**Usage Examples:**

31

32

```javascript

33

import { Note } from "webmidi";

34

35

// Create from note name

36

const c4 = new Note("C4");

37

const fSharp3 = new Note("F#3");

38

const bFlat5 = new Note("Bb5");

39

40

// Create from MIDI number

41

const middleC = new Note(60); // C4

42

const highA = new Note(81); // A5

43

44

// Create with options

45

const note = new Note("G4", {

46

duration: 2000, // 2 seconds

47

attack: 0.8, // Strong attack

48

release: 0.3, // Soft release

49

octaveOffset: -1 // One octave lower

50

});

51

52

// Create from existing Note

53

const noteCopy = new Note(c4);

54

```

55

56

### Note Properties

57

58

Access note properties and characteristics.

59

60

```javascript { .api }

61

/**

62

* Full note identifier (e.g., "C4", "F#3", "Bb5")

63

*/

64

readonly identifier: string;

65

66

/**

67

* Note name without octave (e.g., "C", "F#", "Bb")

68

*/

69

readonly name: string;

70

71

/**

72

* Accidental symbol (sharp/flat) or undefined for natural notes

73

*/

74

readonly accidental?: string;

75

76

/**

77

* Octave number (-2 to 8)

78

*/

79

readonly octave: number;

80

81

/**

82

* MIDI note number (0-127)

83

*/

84

readonly number: number;

85

86

/**

87

* Note duration in milliseconds (if specified)

88

*/

89

readonly duration?: number;

90

91

/**

92

* Attack velocity as float (0-1)

93

*/

94

readonly attack: number;

95

96

/**

97

* Release velocity as float (0-1)

98

*/

99

readonly release: number;

100

101

/**

102

* Raw attack velocity (0-127)

103

*/

104

readonly rawAttack: number;

105

106

/**

107

* Raw release velocity (0-127)

108

*/

109

readonly rawRelease: number;

110

```

111

112

**Usage Examples:**

113

114

```javascript

115

const note = new Note("F#4", { attack: 0.8, release: 0.6, duration: 1500 });

116

117

console.log(note.identifier); // "F#4"

118

console.log(note.name); // "F#"

119

console.log(note.accidental); // "#"

120

console.log(note.octave); // 4

121

console.log(note.number); // 66

122

console.log(note.attack); // 0.8

123

console.log(note.rawAttack); // 101 (0.8 * 127)

124

console.log(note.duration); // 1500

125

```

126

127

### Note Transformations

128

129

Transform notes with offsets and modifications.

130

131

```javascript { .api }

132

/**

133

* Get MIDI note number with applied offsets

134

* @param octaveOffset - Octave offset to apply (default: 0)

135

* @param semitoneOffset - Semitone offset to apply (default: 0)

136

* @returns Modified MIDI note number (0-127)

137

*/

138

getOffsetNumber(octaveOffset?: number, semitoneOffset?: number): number;

139

```

140

141

**Usage Examples:**

142

143

```javascript

144

const c4 = new Note("C4"); // MIDI number 60

145

146

// Apply offsets

147

console.log(c4.getOffsetNumber()); // 60 (no offset)

148

console.log(c4.getOffsetNumber(1)); // 72 (C5)

149

console.log(c4.getOffsetNumber(-1)); // 48 (C3)

150

console.log(c4.getOffsetNumber(0, 7)); // 67 (G4)

151

console.log(c4.getOffsetNumber(1, -5)); // 67 (G5)

152

```

153

154

## Note Name Formats

155

156

### Supported Input Formats

157

158

WebMidi.js supports various note name formats:

159

160

```javascript

161

// Basic note names

162

new Note("C4"); // C in 4th octave

163

new Note("A0"); // Lowest A

164

new Note("G8"); // Highest G

165

166

// Sharp notes

167

new Note("C#4"); // C-sharp

168

new Note("F#3"); // F-sharp

169

170

// Flat notes

171

new Note("Bb4"); // B-flat

172

new Note("Db2"); // D-flat

173

174

// Alternative flat notation

175

new Note("B♭4"); // B-flat (Unicode)

176

new Note("D♭2"); // D-flat (Unicode)

177

178

// Alternative sharp notation

179

new Note("C♯4"); // C-sharp (Unicode)

180

new Note("F♯3"); // F-sharp (Unicode)

181

182

// MIDI numbers

183

new Note(60); // Middle C (C4)

184

new Note(69); // A4 (440 Hz)

185

new Note(127); // Highest MIDI note

186

```

187

188

### Octave Numbering

189

190

WebMidi.js uses scientific pitch notation:

191

192

- C3 = Middle C (MIDI note 60)

193

- A4 = 440 Hz (MIDI note 69)

194

- Octaves range from -2 to 8

195

- Each octave starts at C and ends at B

196

197

```javascript

198

// Octave examples

199

new Note("C-2"); // MIDI 0 (lowest)

200

new Note("C-1"); // MIDI 12

201

new Note("C0"); // MIDI 24

202

new Note("C1"); // MIDI 36

203

new Note("C2"); // MIDI 48

204

new Note("C3"); // MIDI 60

205

new Note("C4"); // MIDI 72

206

new Note("C5"); // MIDI 84

207

new Note("C6"); // MIDI 96

208

new Note("C7"); // MIDI 108

209

new Note("C8"); // MIDI 120

210

new Note("G8"); // MIDI 127 (highest)

211

```

212

213

## Working with Note Arrays

214

215

### Creating Note Arrays

216

217

```javascript

218

// From string array

219

const notes = ["C4", "E4", "G4"].map(n => new Note(n));

220

221

// From mixed inputs

222

const chord = [

223

new Note("C4"),

224

new Note(64), // E4

225

new Note("G4", { attack: 0.7 })

226

];

227

228

// With consistent options

229

const melody = ["C4", "D4", "E4", "F4"].map(note =>

230

new Note(note, { duration: 500, attack: 0.6 })

231

);

232

```

233

234

### Note Array Operations

235

236

```javascript

237

// Find notes by property

238

const sharps = notes.filter(note => note.accidental === "#");

239

const highNotes = notes.filter(note => note.octave >= 5);

240

241

// Transform notes

242

const transposed = notes.map(note =>

243

new Note(note.getOffsetNumber(1)) // Up one octave

244

);

245

246

// Sort notes by pitch

247

notes.sort((a, b) => a.number - b.number);

248

```

249

250

## Integration with MIDI Messages

251

252

### Playing Notes

253

254

```javascript

255

import { WebMidi, Note } from "webmidi";

256

257

await WebMidi.enable();

258

const output = WebMidi.outputs[0];

259

260

// Play individual notes

261

const c4 = new Note("C4", { attack: 0.8, duration: 1000 });

262

output.channels[0].playNote(c4);

263

264

// Play chord with consistent timing

265

const chord = ["C4", "E4", "G4"].map(n =>

266

new Note(n, { attack: 0.7, duration: 2000 })

267

);

268

output.channels[0].playNote(chord);

269

```

270

271

### Note Event Handling

272

273

```javascript

274

const input = WebMidi.inputs[0];

275

276

input.addListener("noteon", (e) => {

277

const playedNote = e.note;

278

console.log(`Played: ${playedNote.identifier}`);

279

console.log(`MIDI: ${playedNote.number}`);

280

console.log(`Octave: ${playedNote.octave}`);

281

console.log(`Velocity: ${playedNote.attack}`);

282

});

283

```

284

285

## Common Note Operations

286

287

### Interval Calculations

288

289

```javascript

290

function getInterval(note1, note2) {

291

return Math.abs(note1.number - note2.number);

292

}

293

294

const c4 = new Note("C4");

295

const g4 = new Note("G4");

296

const perfectFifth = getInterval(c4, g4); // 7 semitones

297

```

298

299

### Scale and Chord Generation

300

301

```javascript

302

function generateMajorScale(root) {

303

const intervals = [0, 2, 4, 5, 7, 9, 11]; // Major scale intervals

304

const rootNote = new Note(root);

305

306

return intervals.map(interval =>

307

new Note(rootNote.getOffsetNumber(0, interval))

308

);

309

}

310

311

function generateMajorTriad(root) {

312

const rootNote = new Note(root);

313

return [

314

rootNote, // Root

315

new Note(rootNote.getOffsetNumber(0, 4)), // Major third

316

new Note(rootNote.getOffsetNumber(0, 7)) // Perfect fifth

317

];

318

}

319

320

// Usage

321

const cMajorScale = generateMajorScale("C4");

322

const fMajorChord = generateMajorTriad("F4");

323

```

324

325

### Note Range Validation

326

327

```javascript

328

function isValidMidiNote(note) {

329

const noteObj = new Note(note);

330

return noteObj.number >= 0 && noteObj.number <= 127;

331

}

332

333

function transposeWithinRange(note, semitones) {

334

const originalNote = new Note(note);

335

const transposed = originalNote.getOffsetNumber(0, semitones);

336

337

if (transposed < 0 || transposed > 127) {

338

throw new Error("Transposition out of MIDI range");

339

}

340

341

return new Note(transposed);

342

}

343

```

344

345

## Types

346

347

```javascript { .api }

348

interface NoteOptions {

349

duration?: number;

350

attack?: number;

351

release?: number;

352

octaveOffset?: number;

353

}

354

355

type NoteInput = string | number | Note;

356

type NoteArray = Array<string | number | Note>;

357

```