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
```