@kidlib/web-audio 0.1.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/dist/io.d.ts ADDED
@@ -0,0 +1,239 @@
1
+ declare type AudioInputDevice = DeviceInfo & {
2
+ kind: 'audioinput';
3
+ };
4
+
5
+ declare type AudioOutputDevice = DeviceInfo & {
6
+ kind: 'audiooutput';
7
+ };
8
+
9
+ export declare const chromaticKeymap: KeyMap;
10
+
11
+ export declare type ControlCallback = (value: number, event: ControlChangeEvent) => void;
12
+
13
+ export declare type ControlChangeEvent = {
14
+ type: 'controlchange';
15
+ controller: number;
16
+ normalizedValue: number;
17
+ midiValue: number;
18
+ channel: number;
19
+ raw: any;
20
+ };
21
+
22
+ declare type ControlChangeHandler = (event: ControlChangeEvent) => void;
23
+
24
+ export declare type ControlTarget = SimpleControlTarget | KnobControlTarget | DetailedControlTarget | ControlCallback;
25
+
26
+ export declare const DEFAULT_KEYMAP_KEY: KeymapKey;
27
+
28
+ /**
29
+ * Default keyboard-to-MIDI note mapping for audio input.
30
+ * Provides a piano-like layout across the QWERTY keyboard.
31
+ * Used by KeyboardInputManager to translate keyboard events to MIDI notes.
32
+ */
33
+ export declare const defaultKeymap: KeyMap;
34
+
35
+ export declare type DetailedControlTarget = {
36
+ onControlChange: (value: number, event: ControlChangeEvent) => void;
37
+ };
38
+
39
+ declare type DeviceInfo = {
40
+ deviceId: string;
41
+ label: string;
42
+ kind: MediaDeviceKind;
43
+ };
44
+
45
+ /**
46
+ * Generate a keymap from a base note and scale intervals.
47
+ * Each QWERTY row is mapped one octave above the previous (bottom row lowest).
48
+ */
49
+ export declare function generateKeymap(config: {
50
+ baseNote: number;
51
+ scale: number[];
52
+ }): KeyMap;
53
+
54
+ export declare function getAudioInputDevices(): Promise<AudioInputDevice[]>;
55
+
56
+ export declare function getAudioOutputDevices(): Promise<AudioOutputDevice[]>;
57
+
58
+ export declare function getCamera(constraints?: MediaTrackConstraints): Promise<MediaStream>;
59
+
60
+ export declare function getDevices(): Promise<DeviceInfo[]>;
61
+
62
+ export declare function getMicrophone(constraints?: MediaTrackConstraints, deviceId?: string): Promise<MediaStream>;
63
+
64
+ export declare function getMIDIAccess(): Promise<MIDIAccess>;
65
+
66
+ /**
67
+ * Get browser-specific MIDI support information
68
+ */
69
+ export declare function getMidiSupportInfo(): {
70
+ supported: boolean;
71
+ browserName: string;
72
+ message: string;
73
+ };
74
+
75
+ export declare function getVideoInputDevices(): Promise<VideoInputDevice[]>;
76
+
77
+ export declare class InputController {
78
+ #private;
79
+ init(): Promise<boolean>;
80
+ onNoteOn(handler: NoteHandler): () => void;
81
+ onNoteOff(handler: NoteHandler): () => void;
82
+ onControlChange(handler: ControlChangeHandler): () => void;
83
+ onSustainPedal(handler: SustainPedalHandler): () => void;
84
+ registerNoteTarget(target: NoteTarget, channel?: number | 'all'): () => void;
85
+ /**
86
+ * Register one or more control targets to respond to MIDI CC messages.
87
+ *
88
+ * By default, passes normalized values (0-1) to targets. Use transformValue for custom behavior.
89
+ *
90
+ * Supports multiple target types for maximum flexibility:
91
+ *
92
+ * @example
93
+ * // Knobs - automatically calls setValueNormalized if available
94
+ * inputController.registerControlTarget(knobElement, { controller: 15 });
95
+ *
96
+ * @example
97
+ * // Simple callback function - cleanest for custom logic
98
+ * inputController.registerControlTarget(
99
+ * (value, event) => console.log(`CC${event.controller}: ${value}`),
100
+ * { controller: 15 }
101
+ * );
102
+ *
103
+ * @example
104
+ * // Multiple targets controlled by same CC
105
+ * inputController.registerControlTarget([knob1, knob2], { controller: 15 });
106
+ *
107
+ * @example
108
+ * // Raw MIDI values (0-127) instead of normalized (0-1)
109
+ * inputController.registerControlTarget(knobElement, {
110
+ * controller: 15,
111
+ * transformValue: (event) => event.midiValue
112
+ * });
113
+ *
114
+ * @example
115
+ * // Object with setValue method (sliders, etc.)
116
+ * inputController.registerControlTarget({ setValue: (v) => slider.value = v }, { controller: 15 });
117
+ */
118
+ registerControlTarget(target: ControlTarget | ControlTarget[], options: RegisterControlOptions): () => void;
119
+ registerSustainPedalTarget(target: SustainPedalTarget, channel?: number | 'all'): () => void;
120
+ get initialized(): boolean;
121
+ get midiSupported(): boolean;
122
+ get supportInfo(): {
123
+ supported: boolean;
124
+ browserName: string;
125
+ message: string;
126
+ };
127
+ }
128
+
129
+ export declare const inputController: InputController;
130
+
131
+ export declare interface InputHandler {
132
+ onNoteOn: (midiNote: number, velocity: number, modifiers?: PressedModifiers) => void;
133
+ onNoteOff: (midiNote: number, modifiers: PressedModifiers) => void;
134
+ onBlur: () => void;
135
+ onModifierChange?: (modifiers: PressedModifiers) => void;
136
+ }
137
+
138
+ /**
139
+ * Check if Web MIDI API is supported in the current browser
140
+ */
141
+ export declare function isMidiSupported(): boolean;
142
+
143
+ export declare type KeyMap = Record<string, number>;
144
+
145
+ export declare type KeymapKey = 'piano' | 'major' | 'minor' | 'pentatonic' | 'chromatic';
146
+
147
+ export declare const keymaps: Record<KeymapKey, KeyMap>;
148
+
149
+ export declare type KnobControlTarget = {
150
+ setValueNormalized?: (value: number) => void;
151
+ setValue?: (value: number) => void;
152
+ };
153
+
154
+ export declare const majorKeymap: KeyMap;
155
+
156
+ export declare const minorKeymap: KeyMap;
157
+
158
+ export declare type ModifierKey = 'space' | 'caps' | 'meta' | 'shift' | 'ctrl' | 'alt';
159
+
160
+ /**
161
+ * MIDI Input Controller - Clean, Flexible API
162
+ *
163
+ * Supports multiple target types for maximum convenience:
164
+ * - Knob elements (auto-detects setValueNormalized/setValue methods)
165
+ * - Simple callback functions
166
+ * - Objects with setValue method
167
+ * - Objects with onControlChange method
168
+ *
169
+ * ControlChangeEvent provides both value formats:
170
+ * - event.normalizedValue: 0-1 range (default, most common)
171
+ * - event.midiValue: 0-127 range (raw MIDI spec)
172
+ *
173
+ * @example
174
+ * // Knobs - automatically calls the right method
175
+ * inputController.registerControlTarget(knobElement, { controller: 15 });
176
+ *
177
+ * @example
178
+ * // Simple callback - cleanest for custom logic
179
+ * inputController.registerControlTarget(
180
+ * (value, event) => console.log(`CC${event.controller}: ${value}`),
181
+ * { controller: 15 }
182
+ * );
183
+ *
184
+ * @example
185
+ * // Raw MIDI values instead of normalized
186
+ * inputController.registerControlTarget(knob, {
187
+ * controller: 15,
188
+ * transformValue: (event) => event.midiValue
189
+ * });
190
+ */
191
+ export declare type NoteEvent = {
192
+ type: 'noteon' | 'noteoff';
193
+ note: number;
194
+ velocity: number;
195
+ channel: number;
196
+ raw: any;
197
+ };
198
+
199
+ declare type NoteHandler = (event: NoteEvent) => void;
200
+
201
+ export declare type NoteTarget = {
202
+ play: (note: number, velocity?: number) => void;
203
+ release: (note: number) => void;
204
+ };
205
+
206
+ export declare function onDeviceChange(callback: () => void): () => void;
207
+
208
+ export declare const pentatonicKeymap: KeyMap;
209
+
210
+ export declare type PressedModifiers = Partial<Record<ModifierKey, boolean>>;
211
+
212
+ declare type RegisterControlOptions = {
213
+ controller: number | number[];
214
+ channel?: number | 'all';
215
+ transformValue?: (event: ControlChangeEvent) => number;
216
+ };
217
+
218
+ export declare type SimpleControlTarget = {
219
+ setValue: (value: number) => void;
220
+ };
221
+
222
+ export declare type SustainPedalEvent = {
223
+ type: 'sustainpedal';
224
+ pressed: boolean;
225
+ channel: number;
226
+ raw: any;
227
+ };
228
+
229
+ declare type SustainPedalHandler = (event: SustainPedalEvent) => void;
230
+
231
+ export declare type SustainPedalTarget = {
232
+ setSustainPedal: (pressed: boolean) => void;
233
+ };
234
+
235
+ declare type VideoInputDevice = DeviceInfo & {
236
+ kind: 'videoinput';
237
+ };
238
+
239
+ export { }
package/dist/io.js ADDED
@@ -0,0 +1,193 @@
1
+ var M = (t) => {
2
+ throw TypeError(t);
3
+ };
4
+ var w = (t, e, r) => e.has(t) || M("Cannot " + r);
5
+ var s = (t, e, r) => (w(t, e, "read from private field"), r ? r.call(t) : e.get(t)), d = (t, e, r) => e.has(t) ? M("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, r), S = (t, e, r, a) => (w(t, e, "write to private field"), a ? a.call(t, r) : e.set(t, r), r), f = (t, e, r) => (w(t, e, "access private method"), r);
6
+ import { D as F, c as T, d as H, a as L, b as j, e as Y, f as _, h as $, i as q, g as B, j as G, k as R, m as J, l as Q, o as X, p as Z } from "./keymap-3lZMR1Ak.js";
7
+ import { WebMidi as V } from "webmidi";
8
+ function A() {
9
+ return typeof navigator < "u" && typeof navigator.requestMIDIAccess == "function";
10
+ }
11
+ function O() {
12
+ const t = navigator.userAgent, e = /Chrome/.test(t) && /Google Inc/.test(navigator.vendor || ""), r = /Edg/.test(t), a = /OPR/.test(t), n = /Safari/.test(t) && !/Chrome/.test(t), o = /Firefox/.test(t);
13
+ let u = "Unknown";
14
+ e ? u = "Chrome" : r ? u = "Edge" : a ? u = "Opera" : n ? u = "Safari" : o && (u = "Firefox");
15
+ const m = A();
16
+ let l = "";
17
+ return m || (n ? l = "Safari doesn't support Web MIDI API. Use Chrome, Edge, or Opera for MIDI functionality." : o ? l = "Firefox has limited Web MIDI API support. Use Chrome, Edge, or Opera for full MIDI functionality." : l = "Web MIDI API not supported in this browser."), { supported: m, browserName: u, message: l };
18
+ }
19
+ var y, b, I, h, p, i, E, D, P, z, C;
20
+ class N {
21
+ constructor() {
22
+ d(this, i);
23
+ d(this, y, !1);
24
+ d(this, b, /* @__PURE__ */ new Set());
25
+ d(this, I, /* @__PURE__ */ new Set());
26
+ d(this, h, /* @__PURE__ */ new Set());
27
+ d(this, p, /* @__PURE__ */ new Set());
28
+ }
29
+ async init() {
30
+ if (s(this, y)) return !0;
31
+ if (!A()) {
32
+ const { browserName: e, message: r } = O();
33
+ return console.warn(`InputController: ${r} (Browser: ${e})`), !1;
34
+ }
35
+ try {
36
+ await V.enable();
37
+ } catch (e) {
38
+ return console.warn("InputController: WebMIDI enable failed", e), !1;
39
+ }
40
+ return V.enabled ? (S(this, y, !0), f(this, i, E).call(this), !0) : (console.warn("InputController: WebMIDI not enabled"), !1);
41
+ }
42
+ onNoteOn(e) {
43
+ return s(this, b).add(e), () => s(this, b).delete(e);
44
+ }
45
+ onNoteOff(e) {
46
+ return s(this, I).add(e), () => s(this, I).delete(e);
47
+ }
48
+ onControlChange(e) {
49
+ return s(this, h).add(e), () => s(this, h).delete(e);
50
+ }
51
+ onSustainPedal(e) {
52
+ return s(this, p).add(e), () => s(this, p).delete(e);
53
+ }
54
+ registerNoteTarget(e, r = "all") {
55
+ const a = this.onNoteOn((o) => {
56
+ f(this, i, C).call(this, r, o.channel) && e.play(o.note, o.velocity ?? 0);
57
+ }), n = this.onNoteOff((o) => {
58
+ f(this, i, C).call(this, r, o.channel) && e.release(o.note);
59
+ });
60
+ return () => {
61
+ a(), n();
62
+ };
63
+ }
64
+ /**
65
+ * Register one or more control targets to respond to MIDI CC messages.
66
+ *
67
+ * By default, passes normalized values (0-1) to targets. Use transformValue for custom behavior.
68
+ *
69
+ * Supports multiple target types for maximum flexibility:
70
+ *
71
+ * @example
72
+ * // Knobs - automatically calls setValueNormalized if available
73
+ * inputController.registerControlTarget(knobElement, { controller: 15 });
74
+ *
75
+ * @example
76
+ * // Simple callback function - cleanest for custom logic
77
+ * inputController.registerControlTarget(
78
+ * (value, event) => console.log(`CC${event.controller}: ${value}`),
79
+ * { controller: 15 }
80
+ * );
81
+ *
82
+ * @example
83
+ * // Multiple targets controlled by same CC
84
+ * inputController.registerControlTarget([knob1, knob2], { controller: 15 });
85
+ *
86
+ * @example
87
+ * // Raw MIDI values (0-127) instead of normalized (0-1)
88
+ * inputController.registerControlTarget(knobElement, {
89
+ * controller: 15,
90
+ * transformValue: (event) => event.midiValue
91
+ * });
92
+ *
93
+ * @example
94
+ * // Object with setValue method (sliders, etc.)
95
+ * inputController.registerControlTarget({ setValue: (v) => slider.value = v }, { controller: 15 });
96
+ */
97
+ registerControlTarget(e, r) {
98
+ const a = Array.isArray(e) ? e : [e], n = Array.isArray(r.controller) ? r.controller : [r.controller], o = r.channel ?? "all", u = r.transformValue ?? ((l) => l.normalizedValue);
99
+ return this.onControlChange((l) => {
100
+ if (!n.includes(l.controller) || !f(this, i, C).call(this, o, l.channel)) return;
101
+ const g = u(l);
102
+ a.forEach((c) => {
103
+ typeof c == "function" ? c(g, l) : "onControlChange" in c ? c.onControlChange(g, l) : "setValueNormalized" in c && c.setValueNormalized ? c.setValueNormalized(g) : "setValue" in c && c.setValue && c.setValue(g);
104
+ });
105
+ });
106
+ }
107
+ registerSustainPedalTarget(e, r = "all") {
108
+ return this.onSustainPedal((n) => {
109
+ f(this, i, C).call(this, r, n.channel) && e.setSustainPedal(n.pressed);
110
+ });
111
+ }
112
+ get initialized() {
113
+ return s(this, y);
114
+ }
115
+ get midiSupported() {
116
+ return A();
117
+ }
118
+ get supportInfo() {
119
+ return O();
120
+ }
121
+ }
122
+ y = new WeakMap(), b = new WeakMap(), I = new WeakMap(), h = new WeakMap(), p = new WeakMap(), i = new WeakSet(), E = function() {
123
+ V.inputs.forEach((e) => {
124
+ e && (e.addListener("noteon", (r) => {
125
+ f(this, i, D).call(this, s(this, b), r, "noteon");
126
+ }), e.addListener("noteoff", (r) => {
127
+ f(this, i, D).call(this, s(this, I), r, "noteoff");
128
+ }), e.addListener("controlchange", (r) => {
129
+ var n, o;
130
+ (((n = r.controller) == null ? void 0 : n.number) ?? ((o = r.controller) == null ? void 0 : o.value) ?? 0) === 64 ? f(this, i, z).call(this, r) : f(this, i, P).call(this, r);
131
+ }));
132
+ });
133
+ }, D = function(e, r, a) {
134
+ var o, u, m, l;
135
+ if (!e.size) return;
136
+ const n = {
137
+ type: a,
138
+ note: ((o = r.note) == null ? void 0 : o.number) ?? 0,
139
+ velocity: ((u = r.note) == null ? void 0 : u.rawAttack) ?? (typeof r.velocity == "number" ? r.velocity : ((m = r.note) == null ? void 0 : m.attack) ?? 0),
140
+ channel: ((l = r.message) == null ? void 0 : l.channel) ?? 1,
141
+ raw: r
142
+ };
143
+ e.forEach((g) => g(n));
144
+ }, P = function(e) {
145
+ var a, n, o;
146
+ if (!s(this, h).size) return;
147
+ const r = {
148
+ type: "controlchange",
149
+ controller: ((a = e.controller) == null ? void 0 : a.number) ?? ((n = e.controller) == null ? void 0 : n.value) ?? (typeof e.controller == "number" ? e.controller : 0),
150
+ // Provide both values explicitly
151
+ normalizedValue: typeof e.value == "number" ? e.value : typeof e.rawValue == "number" ? e.rawValue / 127 : 0,
152
+ midiValue: typeof e.rawValue == "number" ? e.rawValue : typeof e.value == "number" ? Math.round(e.value * 127) : 0,
153
+ channel: ((o = e.message) == null ? void 0 : o.channel) ?? 1,
154
+ raw: e
155
+ };
156
+ s(this, h).forEach((u) => u(r));
157
+ }, z = function(e) {
158
+ var n;
159
+ if (!s(this, p).size) return;
160
+ const a = {
161
+ type: "sustainpedal",
162
+ pressed: (typeof e.rawValue == "number" ? e.rawValue : typeof e.value == "number" ? Math.round(e.value * 127) : 0) >= 64,
163
+ // MIDI standard: >= 64 is "on"
164
+ channel: ((n = e.message) == null ? void 0 : n.channel) ?? 1,
165
+ raw: e
166
+ };
167
+ s(this, p).forEach((o) => o(a));
168
+ }, C = function(e, r) {
169
+ return e === "all" ? !0 : typeof r != "number" ? !1 : e === r;
170
+ };
171
+ const U = new N();
172
+ export {
173
+ F as DEFAULT_KEYMAP_KEY,
174
+ N as InputController,
175
+ T as chromaticKeymap,
176
+ H as defaultKeymap,
177
+ L as generateKeymap,
178
+ j as getAudioInputDevices,
179
+ Y as getAudioOutputDevices,
180
+ _ as getCamera,
181
+ $ as getDevices,
182
+ q as getMIDIAccess,
183
+ B as getMicrophone,
184
+ O as getMidiSupportInfo,
185
+ G as getVideoInputDevices,
186
+ U as inputController,
187
+ A as isMidiSupported,
188
+ R as keymaps,
189
+ J as majorKeymap,
190
+ Q as minorKeymap,
191
+ X as onDeviceChange,
192
+ Z as pentatonicKeymap
193
+ };
@@ -0,0 +1,167 @@
1
+ async function u() {
2
+ try {
3
+ return await navigator.mediaDevices.getUserMedia({ audio: !0, video: !0 }), (await navigator.mediaDevices.enumerateDevices()).map((a) => ({
4
+ deviceId: a.deviceId,
5
+ label: a.label,
6
+ kind: a.kind
7
+ }));
8
+ } catch (e) {
9
+ return console.error("Failed to enumerate devices:", e), [];
10
+ }
11
+ }
12
+ async function f() {
13
+ if (!navigator.requestMIDIAccess)
14
+ throw new Error("MIDI access not supported in this browser");
15
+ return navigator.requestMIDIAccess();
16
+ }
17
+ async function N(e = {
18
+ echoCancellation: !1,
19
+ noiseSuppression: !0,
20
+ // ?
21
+ autoGainControl: !0
22
+ // ?
23
+ }, a = "") {
24
+ try {
25
+ return await navigator.mediaDevices.getUserMedia({
26
+ audio: a ? {
27
+ ...e,
28
+ deviceId: { exact: a }
29
+ } : e
30
+ });
31
+ } catch (t) {
32
+ if (a && t.name === "OverconstrainedError")
33
+ return console.warn(
34
+ "Requested audio input device unavailable, falling back to default"
35
+ ), navigator.mediaDevices.getUserMedia({ audio: e });
36
+ throw t;
37
+ }
38
+ }
39
+ async function w(e = {
40
+ width: 1280,
41
+ height: 720,
42
+ facingMode: "user"
43
+ }) {
44
+ return navigator.mediaDevices.getUserMedia({
45
+ video: e
46
+ });
47
+ }
48
+ async function M() {
49
+ return (await u()).filter((a) => a.kind === "audioinput");
50
+ }
51
+ async function E() {
52
+ return (await u()).filter((a) => a.kind === "audiooutput");
53
+ }
54
+ async function I() {
55
+ return (await u()).filter((a) => a.kind === "videoinput");
56
+ }
57
+ function k(e) {
58
+ return navigator.mediaDevices.addEventListener("devicechange", e), () => navigator.mediaDevices.removeEventListener("devicechange", e);
59
+ }
60
+ const g = {
61
+ KeyZ: 48,
62
+ KeyS: 49,
63
+ KeyX: 50,
64
+ KeyD: 51,
65
+ KeyC: 52,
66
+ KeyV: 53,
67
+ KeyG: 54,
68
+ KeyB: 55,
69
+ KeyH: 56,
70
+ KeyN: 57,
71
+ KeyJ: 58,
72
+ KeyM: 59,
73
+ Comma: 60,
74
+ KeyL: 61,
75
+ Period: 62,
76
+ Semicolon: 63,
77
+ Slash: 64,
78
+ KeyQ: 60,
79
+ Digit2: 61,
80
+ KeyW: 62,
81
+ Digit3: 63,
82
+ KeyE: 64,
83
+ KeyR: 65,
84
+ Digit5: 66,
85
+ KeyT: 67,
86
+ Digit6: 68,
87
+ KeyY: 69,
88
+ Digit7: 70,
89
+ KeyU: 71,
90
+ KeyI: 72,
91
+ Digit9: 73,
92
+ KeyO: 74,
93
+ Digit0: 75,
94
+ KeyP: 76,
95
+ BracketLeft: 77,
96
+ Equal: 78,
97
+ BracketRight: 79,
98
+ // Numpad
99
+ Numpad1: 60,
100
+ Numpad2: 62,
101
+ Numpad3: 64,
102
+ Numpad4: 65,
103
+ Numpad5: 67,
104
+ Numpad6: 69,
105
+ Numpad7: 71,
106
+ Numpad8: 72,
107
+ Numpad9: 74
108
+ };
109
+ function n(e) {
110
+ const { baseNote: a, scale: t } = e;
111
+ if (t.length === 0)
112
+ throw new RangeError("scale must contain at least one interval");
113
+ const y = [
114
+ ["KeyZ", "KeyX", "KeyC", "KeyV", "KeyB", "KeyN", "KeyM", "Comma", "Period", "Slash"],
115
+ ["KeyA", "KeyS", "KeyD", "KeyF", "KeyG", "KeyH", "KeyJ", "KeyK", "KeyL", "Semicolon", "Quote", "Backslash"],
116
+ ["KeyQ", "KeyW", "KeyE", "KeyR", "KeyT", "KeyY", "KeyU", "KeyI", "KeyO", "KeyP", "BracketLeft", "BracketRight"],
117
+ ["Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9", "Digit0", "Minus", "Equal"]
118
+ ], o = {};
119
+ return y.forEach((s, i) => {
120
+ const c = a + i * 12;
121
+ s.forEach((r, d) => {
122
+ const K = d % t.length, m = Math.floor(d / t.length);
123
+ o[r] = c + m * 12 + t[K];
124
+ });
125
+ }), ["Numpad1", "Numpad2", "Numpad3", "Numpad4", "Numpad5", "Numpad6", "Numpad7", "Numpad8", "Numpad9"].forEach((s, i) => {
126
+ const c = i % t.length, r = Math.floor(i / t.length);
127
+ o[s] = a + 36 + r * 12 + t[c];
128
+ }), o;
129
+ }
130
+ const p = n({
131
+ baseNote: 36,
132
+ scale: [0, 2, 4, 5, 7, 9, 11]
133
+ }), v = n({
134
+ baseNote: 36,
135
+ scale: [0, 2, 3, 5, 7, 8, 10]
136
+ }), l = n({
137
+ baseNote: 36,
138
+ scale: [0, 2, 4, 7, 9]
139
+ // Major pentatonic
140
+ }), D = n({
141
+ baseNote: 48,
142
+ scale: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
143
+ }), b = "major", A = {
144
+ piano: g,
145
+ major: p,
146
+ minor: v,
147
+ pentatonic: l,
148
+ chromatic: D
149
+ };
150
+ export {
151
+ b as D,
152
+ n as a,
153
+ M as b,
154
+ D as c,
155
+ g as d,
156
+ E as e,
157
+ w as f,
158
+ N as g,
159
+ u as h,
160
+ f as i,
161
+ I as j,
162
+ A as k,
163
+ v as l,
164
+ p as m,
165
+ k as o,
166
+ l as p
167
+ };