@dawcore/components 0.0.14 → 0.0.16

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/README.md CHANGED
@@ -13,6 +13,7 @@ Framework-agnostic Web Components for multi-track audio editing. Drop `<daw-edit
13
13
  - **File drop** — Drag audio files onto the editor to add tracks
14
14
  - **Recording** — Live mic recording with waveform preview, pause/resume, cancelable clip creation
15
15
  - **Pre-computed peaks** — Instant waveform rendering from `.dat` files before audio decodes
16
+ - **MIDI tracks** — Programmatic MIDI clips render as piano-roll via `<daw-piano-roll>`. Playback via Tone.js adapter (native MIDI synth deferred). See [MIDI Tracks](#midi-tracks).
16
17
  - **Track controls** — Volume, pan, mute, solo per track via `<daw-track-controls>`
17
18
  - **Transport access** — Tempo, metronome, count-in, meter, effects via `@dawcore/transport`
18
19
  - **CSS theming** — Dark mode by default, fully customizable via CSS custom properties
@@ -92,7 +93,7 @@ adapter.transport.setCountIn(true);
92
93
 
93
94
  ### Tone.js (effects, MIDI synths)
94
95
 
95
- Uses Tone.js for audio processing. Single tempo/meter only.
96
+ Uses Tone.js for audio processing. Single tempo/meter only. **Required for MIDI playback** — the native adapter has no MIDI synth yet, so MIDI clips render as piano-roll but are silent.
96
97
 
97
98
  ```bash
98
99
  npm install @waveform-playlist/playout tone
@@ -125,6 +126,50 @@ For multiple clips per track with independent positioning:
125
126
  </daw-editor>
126
127
  ```
127
128
 
129
+ ## MIDI Tracks
130
+
131
+ Programmatic MIDI clips render as piano-roll. Playback requires the Tone.js adapter (the native adapter has no MIDI synth yet). Use the `editor.addTrack({ midi })` sugar for the simplest path:
132
+
133
+ ```javascript
134
+ import { createToneAdapter } from '@waveform-playlist/playout';
135
+
136
+ const editor = document.querySelector('daw-editor');
137
+ editor.adapter = createToneAdapter({ ppqn: 960 });
138
+
139
+ await editor.addTrack({
140
+ name: 'Lead',
141
+ midi: {
142
+ notes: [
143
+ { midi: 60, name: 'C4', time: 0.0, duration: 0.5, velocity: 0.8 },
144
+ { midi: 64, name: 'E4', time: 0.5, duration: 0.5, velocity: 0.7 },
145
+ { midi: 67, name: 'G4', time: 1.0, duration: 0.5, velocity: 0.8 },
146
+ ],
147
+ channel: 0, // optional — 9 = GM percussion
148
+ program: 24, // optional — GM instrument 0-127 (used by SoundFontToneTrack)
149
+ },
150
+ });
151
+ ```
152
+
153
+ This expands to a `<daw-track render-mode="piano-roll">` containing a `<daw-clip>` whose `midiNotes` JS property is set to the notes array. Equivalent declarative form:
154
+
155
+ ```html
156
+ <daw-track render-mode="piano-roll" name="Lead">
157
+ <daw-clip midi-channel="0" midi-program="24"></daw-clip>
158
+ </daw-track>
159
+ <script>
160
+ document.querySelector('daw-clip').midiNotes = [
161
+ { midi: 60, name: 'C4', time: 0.0, duration: 0.5, velocity: 0.8 },
162
+ // ...
163
+ ];
164
+ </script>
165
+ ```
166
+
167
+ A clip is treated as MIDI iff `clip.midiNotes != null`. MIDI clips skip audio fetch + decode + peak generation. Trim handles and split-at-playhead are inert on MIDI clips for now (note slicing is a follow-up). Move drag works.
168
+
169
+ **Theming:** the piano-roll honors `--daw-piano-roll-note-color` (default `#2a7070`), `--daw-piano-roll-selected-note-color` (default `#3d9e9e`), and `--daw-piano-roll-background` (default `#1a1a2e`).
170
+
171
+ See `examples/dawcore-tone/midi.html` for a runnable demo (C major scale, PolySynth playback).
172
+
128
173
  ## Pre-Computed Peaks
129
174
 
130
175
  For instant waveform rendering before audio finishes decoding:
@@ -233,6 +278,9 @@ daw-editor {
233
278
  --daw-clip-header-text: #e0d4c8;
234
279
  --daw-controls-width: 180px;
235
280
  --daw-min-height: 200px;
281
+ --daw-piano-roll-note-color: #2a7070;
282
+ --daw-piano-roll-selected-note-color: #3d9e9e;
283
+ --daw-piano-roll-background: #1a1a2e;
236
284
  }
237
285
  ```
238
286
 
@@ -259,11 +307,15 @@ Methods: `loadFiles(fileList)`, `splitAtPlayhead()`.
259
307
 
260
308
  ### `<daw-track>`
261
309
 
262
- Declarative track data. Attributes: `src`, `name`, `volume`, `pan`, `muted`, `soloed`, `mono`.
310
+ Declarative track data. Attributes: `src`, `name`, `volume`, `pan`, `muted`, `soloed`, `mono`, `render-mode` (`'waveform' | 'piano-roll'`, default `'waveform'`).
263
311
 
264
312
  ### `<daw-clip>`
265
313
 
266
- Declarative clip data. Attributes: `src`, `peaks-src`, `start`, `duration`, `offset`, `gain`.
314
+ Declarative clip data. Attributes: `src`, `peaks-src`, `start`, `duration`, `offset`, `gain`, `midi-channel`, `midi-program`. JS-only property: `midiNotes: MidiNoteData[] | null` (note arrays are too large for attributes).
315
+
316
+ ### `<daw-piano-roll>`
317
+
318
+ Visual element for MIDI note rendering. Mounted automatically when the parent track has `render-mode="piano-roll"` — you don't usually instantiate it directly. See [MIDI Tracks](#midi-tracks).
267
319
 
268
320
  ### `<daw-transport for="editor-id">`
269
321
 
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as lit from 'lit';
2
2
  import { LitElement, PropertyValues, ReactiveController, ReactiveControllerHost } from 'lit';
3
- import { Peaks, Bits, FadeType, PeakData, MeterEntry, SnapTo, ClipTrack, KeyboardShortcut } from '@waveform-playlist/core';
3
+ import { MidiNoteData, FadeType, Peaks, Bits, PeakData, MeterEntry, SnapTo, ClipTrack, KeyboardShortcut } from '@waveform-playlist/core';
4
4
  import WaveformData from 'waveform-data';
5
5
  import { PlayoutAdapter, PlaylistEngine } from '@waveform-playlist/engine';
6
6
 
@@ -16,6 +16,16 @@ declare class DawClipElement extends LitElement {
16
16
  fadeIn: number;
17
17
  fadeOut: number;
18
18
  fadeType: string;
19
+ /** MIDI notes — JS property only, not reflected (note arrays are too large for attributes). */
20
+ midiNotes: MidiNoteData[] | null;
21
+ /** MIDI channel (0-indexed). Channel 9 = GM percussion. */
22
+ get midiChannel(): number | null;
23
+ set midiChannel(value: number | null);
24
+ private _midiChannel;
25
+ /** MIDI program (GM instrument 0-127). Used by SoundFontToneTrack. */
26
+ get midiProgram(): number | null;
27
+ set midiProgram(value: number | null);
28
+ private _midiProgram;
19
29
  readonly clipId: `${string}-${string}-${string}-${string}-${string}`;
20
30
  createRenderRoot(): this;
21
31
  connectedCallback(): void;
@@ -28,6 +38,111 @@ declare global {
28
38
  }
29
39
  }
30
40
 
41
+ type TrackRenderMode = 'waveform' | 'piano-roll';
42
+ interface TrackDescriptor {
43
+ name: string;
44
+ src: string;
45
+ volume: number;
46
+ pan: number;
47
+ muted: boolean;
48
+ soloed: boolean;
49
+ renderMode: TrackRenderMode;
50
+ clips: ClipDescriptor[];
51
+ }
52
+ /**
53
+ * Common fields shared by all clip descriptors regardless of source.
54
+ */
55
+ interface BaseClipDescriptor {
56
+ src: string;
57
+ peaksSrc: string;
58
+ start: number;
59
+ duration: number;
60
+ offset: number;
61
+ gain: number;
62
+ name: string;
63
+ fadeIn: number;
64
+ fadeOut: number;
65
+ fadeType: FadeType;
66
+ midiNotes: MidiNoteData[] | null;
67
+ midiChannel: number | null;
68
+ midiProgram: number | null;
69
+ }
70
+ /**
71
+ * A clip descriptor sourced from a `<daw-clip>` DOM element. `clipId` is
72
+ * always set — `<daw-clip>.clipId` is a `crypto.randomUUID()` generated at
73
+ * construction. Engine `clip.id` is aligned with this id in `_loadTrack`
74
+ * and `_loadAndAppendClip` so DOM and engine reference the same clip.
75
+ */
76
+ interface DomClipDescriptor extends BaseClipDescriptor {
77
+ kind: 'dom';
78
+ clipId: string;
79
+ }
80
+ /**
81
+ * A clip descriptor synthesized from a non-DOM source — file drops, the
82
+ * `<daw-track src>` shorthand fallback, or recording-clip insertion. No
83
+ * `clipId` because there's no DOM element to align with; the engine
84
+ * generates its own id at clip-creation time.
85
+ */
86
+ interface DropClipDescriptor extends BaseClipDescriptor {
87
+ kind: 'drop';
88
+ }
89
+ type ClipDescriptor = DomClipDescriptor | DropClipDescriptor;
90
+ /**
91
+ * Type predicate for the `'dom'` discriminator. Use to narrow a
92
+ * `ClipDescriptor` to `DomClipDescriptor` (which has `clipId`) without
93
+ * inline `c.kind === 'dom'` repetition.
94
+ */
95
+ declare function isDomClip(desc: ClipDescriptor): desc is DomClipDescriptor;
96
+ /**
97
+ * Public input shape for `editor.addTrack(config)`. All fields optional —
98
+ * defaults match the declarative `<daw-track>` defaults.
99
+ */
100
+ interface TrackConfig {
101
+ name?: string;
102
+ volume?: number;
103
+ pan?: number;
104
+ muted?: boolean;
105
+ soloed?: boolean;
106
+ renderMode?: TrackRenderMode;
107
+ clips?: ClipConfig[];
108
+ /**
109
+ * Convenience: creates a single piano-roll `<daw-clip>` child with these
110
+ * notes and sets `render-mode="piano-roll"` on the track. Equivalent to
111
+ * passing `{ renderMode: 'piano-roll', clips: [{ midiNotes, midiChannel, midiProgram }] }`.
112
+ * An explicit `renderMode` takes precedence over the inferred `'piano-roll'`.
113
+ *
114
+ * Creation-only — ignored by `updateTrack`. To modify notes after the
115
+ * track is built, use `editor.updateClip(trackId, clipId, { midiNotes })` or
116
+ * mutate the `<daw-clip>` element's `midiNotes` property directly.
117
+ */
118
+ midi?: {
119
+ notes: MidiNoteData[];
120
+ channel?: number;
121
+ program?: number;
122
+ };
123
+ }
124
+ /**
125
+ * Public input shape for clips passed via `TrackConfig.clips` or
126
+ * `editor.addClip(trackId, config)`. `src` is optional to support MIDI clips
127
+ * with no audio source. Other fields default to the matching `<daw-clip>`
128
+ * attribute defaults.
129
+ */
130
+ interface ClipConfig {
131
+ src?: string;
132
+ peaksSrc?: string;
133
+ start?: number;
134
+ duration?: number;
135
+ offset?: number;
136
+ gain?: number;
137
+ name?: string;
138
+ fadeIn?: number;
139
+ fadeOut?: number;
140
+ fadeType?: FadeType;
141
+ midiNotes?: MidiNoteData[];
142
+ midiChannel?: number;
143
+ midiProgram?: number;
144
+ }
145
+
31
146
  declare class DawTrackElement extends LitElement {
32
147
  src: string;
33
148
  name: string;
@@ -35,6 +150,7 @@ declare class DawTrackElement extends LitElement {
35
150
  pan: number;
36
151
  muted: boolean;
37
152
  soloed: boolean;
153
+ renderMode: TrackRenderMode;
38
154
  readonly trackId: `${string}-${string}-${string}-${string}-${string}`;
39
155
  createRenderRoot(): this;
40
156
  connectedCallback(): void;
@@ -112,6 +228,42 @@ declare global {
112
228
  }
113
229
  }
114
230
 
231
+ declare class DawPianoRollElement extends LitElement {
232
+ midiNotes: MidiNoteData[];
233
+ length: number;
234
+ waveHeight: number;
235
+ get samplesPerPixel(): number;
236
+ set samplesPerPixel(value: number);
237
+ private _samplesPerPixel;
238
+ get sampleRate(): number;
239
+ set sampleRate(value: number);
240
+ private _sampleRate;
241
+ clipOffsetSeconds: number;
242
+ /** Visible viewport start in pixels (relative to timeline origin). */
243
+ visibleStart: number;
244
+ /** Visible viewport end in pixels (relative to timeline origin). */
245
+ visibleEnd: number;
246
+ /** This element's left offset on the timeline (for viewport intersection). */
247
+ originX: number;
248
+ selected: boolean;
249
+ static styles: lit.CSSResult;
250
+ private _rafHandle;
251
+ private _scheduleDraw;
252
+ willUpdate(_changed: PropertyValues): void;
253
+ updated(changedProperties: Map<string, unknown>): void;
254
+ private _getPitchRange;
255
+ private _getNoteColor;
256
+ private _draw;
257
+ connectedCallback(): void;
258
+ disconnectedCallback(): void;
259
+ render(): lit.TemplateResult<1>;
260
+ }
261
+ declare global {
262
+ interface HTMLElementTagNameMap {
263
+ 'daw-piano-roll': DawPianoRollElement;
264
+ }
265
+ }
266
+
115
267
  declare class DawPlayheadElement extends LitElement {
116
268
  private _animation;
117
269
  private _line;
@@ -173,6 +325,8 @@ declare class DawPauseButtonElement extends DawTransportButton {
173
325
  private _targetRef;
174
326
  private _onRecStart;
175
327
  private _onRecEnd;
328
+ private _onRecPause;
329
+ private _onRecResume;
176
330
  static styles: lit.CSSResultGroup[];
177
331
  connectedCallback(): void;
178
332
  disconnectedCallback(): void;
@@ -195,87 +349,6 @@ declare global {
195
349
  }
196
350
  }
197
351
 
198
- interface TrackDescriptor {
199
- name: string;
200
- src: string;
201
- volume: number;
202
- pan: number;
203
- muted: boolean;
204
- soloed: boolean;
205
- clips: ClipDescriptor[];
206
- }
207
- /**
208
- * Common fields shared by all clip descriptors regardless of source.
209
- */
210
- interface BaseClipDescriptor {
211
- src: string;
212
- peaksSrc: string;
213
- start: number;
214
- duration: number;
215
- offset: number;
216
- gain: number;
217
- name: string;
218
- fadeIn: number;
219
- fadeOut: number;
220
- fadeType: FadeType;
221
- }
222
- /**
223
- * A clip descriptor sourced from a `<daw-clip>` DOM element. `clipId` is
224
- * always set — `<daw-clip>.clipId` is a `crypto.randomUUID()` generated at
225
- * construction. Engine `clip.id` is aligned with this id in `_loadTrack`
226
- * and `_loadAndAppendClip` so DOM and engine reference the same clip.
227
- */
228
- interface DomClipDescriptor extends BaseClipDescriptor {
229
- kind: 'dom';
230
- clipId: string;
231
- }
232
- /**
233
- * A clip descriptor synthesized from a non-DOM source — file drops, the
234
- * `<daw-track src>` shorthand fallback, or recording-clip insertion. No
235
- * `clipId` because there's no DOM element to align with; the engine
236
- * generates its own id at clip-creation time.
237
- */
238
- interface DropClipDescriptor extends BaseClipDescriptor {
239
- kind: 'drop';
240
- }
241
- type ClipDescriptor = DomClipDescriptor | DropClipDescriptor;
242
- /**
243
- * Type predicate for the `'dom'` discriminator. Use to narrow a
244
- * `ClipDescriptor` to `DomClipDescriptor` (which has `clipId`) without
245
- * inline `c.kind === 'dom'` repetition.
246
- */
247
- declare function isDomClip(desc: ClipDescriptor): desc is DomClipDescriptor;
248
- /**
249
- * Public input shape for `editor.addTrack(config)`. All fields optional —
250
- * defaults match the declarative `<daw-track>` defaults.
251
- */
252
- interface TrackConfig {
253
- name?: string;
254
- volume?: number;
255
- pan?: number;
256
- muted?: boolean;
257
- soloed?: boolean;
258
- clips?: ClipConfig[];
259
- }
260
- /**
261
- * Public input shape for clips passed via `TrackConfig.clips` or
262
- * `editor.addClip(trackId, config)`. `src` is required — every clip needs
263
- * an audio source to load. Other fields default to the matching
264
- * `<daw-clip>` attribute defaults.
265
- */
266
- interface ClipConfig {
267
- src: string;
268
- peaksSrc?: string;
269
- start?: number;
270
- duration?: number;
271
- offset?: number;
272
- gain?: number;
273
- name?: string;
274
- fadeIn?: number;
275
- fadeOut?: number;
276
- fadeType?: FadeType;
277
- }
278
-
279
352
  /**
280
353
  * Peak generation pipeline: AudioBuffer → web worker → WaveformData → PeakData.
281
354
  *
@@ -434,6 +507,12 @@ interface RecordingSession {
434
507
  /** Stored so it can be removed on stop/cleanup — not just when stream ends. */
435
508
  readonly _onTrackEnded: (() => void) | null;
436
509
  readonly _audioTrack: MediaStreamTrack | null;
510
+ /** Set during stopRecording, cleared by the done message from the worklet. */
511
+ stopAckResolve: (() => void) | null;
512
+ /** True from the start of stopRecording until the session is deleted.
513
+ * Guards pauseRecording / resumeRecording so a mid-drain pause toggle
514
+ * can't dispatch events for a session that's already terminating. */
515
+ stopping: boolean;
437
516
  }
438
517
  /** Readonly view of a recording session for external consumers. */
439
518
  type ReadonlyRecordingSession = Readonly<Omit<RecordingSession, 'chunks' | 'peaks' | '_onTrackEnded' | '_audioTrack' | 'latencySamples'>> & {
@@ -475,16 +554,21 @@ declare class RecordingController implements ReactiveController {
475
554
  private _host;
476
555
  private _sessions;
477
556
  private _workletLoadedCtx;
557
+ /** Tracks worklet pause state explicitly so external consumers (editor,
558
+ * pause button, spacebar) can share one source of truth. */
559
+ private _isPaused;
478
560
  constructor(host: RecordingHost & HTMLElement);
479
561
  hostConnected(): void;
480
562
  hostDisconnected(): void;
481
563
  get isRecording(): boolean;
564
+ get isPaused(): boolean;
482
565
  getSession(trackId: string): ReadonlyRecordingSession | undefined;
483
566
  startRecording(stream: MediaStream, options?: RecordingOptions): Promise<void>;
484
567
  pauseRecording(trackId?: string): void;
485
568
  resumeRecording(trackId?: string): void;
486
- stopRecording(trackId?: string): void;
569
+ stopRecording(trackId?: string): Promise<void>;
487
570
  private _onWorkletMessage;
571
+ private _processWorkletSamples;
488
572
  private _createClipFromRecording;
489
573
  private _removeTrackEndedListener;
490
574
  private _cleanupSession;
@@ -538,6 +622,11 @@ interface ClipPointerHost {
538
622
  dispatchEvent(event: Event): boolean;
539
623
  /** Re-extract peaks for a clip at new offset/duration from cached WaveformData. */
540
624
  reextractClipPeaks(clipId: string, offsetSamples: number, durationSamples: number): ClipPeakSlice | null;
625
+ /**
626
+ * Returns true if the clip is a MIDI clip (has midiNotes).
627
+ * Trim handles are inert for MIDI clips — note slicing is not yet implemented.
628
+ */
629
+ isMidiClip(trackId: string, clipId: string): boolean;
541
630
  }
542
631
  /**
543
632
  * Handles pointer interactions for clip move and trim drag operations.
@@ -646,6 +735,12 @@ interface DawRecordingErrorDetail {
646
735
  trackId: string;
647
736
  error: unknown;
648
737
  }
738
+ interface DawRecordingPauseDetail {
739
+ trackId: string;
740
+ }
741
+ interface DawRecordingResumeDetail {
742
+ trackId: string;
743
+ }
649
744
  interface DawClipConnectedDetail {
650
745
  clipId: string;
651
746
  element: DawClipElement;
@@ -702,6 +797,8 @@ interface DawEventMap {
702
797
  'daw-recording-start': CustomEvent<DawRecordingStartDetail>;
703
798
  'daw-recording-complete': CustomEvent<DawRecordingCompleteDetail>;
704
799
  'daw-recording-error': CustomEvent<DawRecordingErrorDetail>;
800
+ 'daw-recording-pause': CustomEvent<DawRecordingPauseDetail>;
801
+ 'daw-recording-resume': CustomEvent<DawRecordingResumeDetail>;
705
802
  'daw-clip-connected': CustomEvent<DawClipConnectedDetail>;
706
803
  'daw-clip-update': CustomEvent<DawClipUpdateDetail>;
707
804
  'daw-clip-ready': CustomEvent<DawClipIdDetail>;
@@ -801,6 +898,12 @@ declare class DawEditorElement extends LitElement {
801
898
  get renderSamplesPerPixel(): number;
802
899
  /** Re-extract peaks for a clip at new offset/duration from cached WaveformData. */
803
900
  reextractClipPeaks(clipId: string, offsetSamples: number, durationSamples: number): PeakData | null;
901
+ /**
902
+ * Returns true if the clip is a MIDI clip (has midiNotes).
903
+ * Used by ClipPointerHandler to make trim handles inert for MIDI clips.
904
+ * Returns false for unknown track/clip IDs (defensive).
905
+ */
906
+ isMidiClip(trackId: string, clipId: string): boolean;
804
907
  private _pointer;
805
908
  private _viewport;
806
909
  static styles: lit.CSSResult[];
@@ -859,6 +962,27 @@ declare class DawEditorElement extends LitElement {
859
962
  * uses sync `extractPeaks` and inserts a preview track BEFORE audio decode.
860
963
  */
861
964
  private _finalizeAudioClip;
965
+ /**
966
+ * Filter MIDI notes to only those with finite, in-range fields. Logs a
967
+ * warning for each dropped note. Used by _buildMidiClip and the
968
+ * _applyClipUpdate MIDI branch to prevent NaN propagation through the
969
+ * timeline.
970
+ */
971
+ private _validMidiNotes;
972
+ /**
973
+ * A clip descriptor is treated as MIDI when it has no audio src.
974
+ * Includes placeholder MIDI clips (no notes, no duration yet — registered
975
+ * with a 1s default span; notes upgrade via _applyClipUpdate). Warns when
976
+ * a clip ambiguously has both src and midiNotes — the audio path runs
977
+ * and notes would be silently ignored.
978
+ */
979
+ private _isMidiDescriptor;
980
+ /**
981
+ * Build an engine clip from a MIDI clip descriptor. Always returns a clip
982
+ * — empty notes / no declared duration get a 1-second placeholder span so
983
+ * the clip is reachable via `engine.updateTrack` once notes arrive.
984
+ */
985
+ private _buildMidiClip;
862
986
  /** Remove a single clip from all per-clip caches. Used by error rollbacks. */
863
987
  private _purgeClipCaches;
864
988
  /**
@@ -963,9 +1087,20 @@ declare class DawEditorElement extends LitElement {
963
1087
  recordingStream: MediaStream | null;
964
1088
  get currentTime(): number;
965
1089
  get isRecording(): boolean;
1090
+ get isRecordingPaused(): boolean;
966
1091
  pauseRecording(): void;
967
1092
  resumeRecording(): void;
968
- stopRecording(): void;
1093
+ /**
1094
+ * Audacity-style pause toggle for active recordings: pauses both the
1095
+ * worklet capture and (if running) the playback Transport. On resume,
1096
+ * Transport restarts only if it was running before — non-overdub
1097
+ * recordings stay silent on resume.
1098
+ */
1099
+ togglePauseRecording(): void;
1100
+ /** Set in togglePauseRecording when Transport is paused alongside the
1101
+ * worklet, so resume can restart it. Cleared on resume and on stop. */
1102
+ private _wasPlayingDuringRecording;
1103
+ stopRecording(): Promise<void>;
969
1104
  _addRecordedClip(trackId: string, buf: AudioBuffer, startSample: number, durSamples: number, offsetSamples?: number): void;
970
1105
  addWorkletModule(url: string): Promise<void>;
971
1106
  createAudioWorkletNode(name: string, options?: AudioWorkletNodeOptions): AudioWorkletNode;
@@ -1149,4 +1284,4 @@ interface SplitHost {
1149
1284
  */
1150
1285
  declare function splitAtPlayhead(host: SplitHost): boolean;
1151
1286
 
1152
- export { AudioResumeController, type ClipConfig, type ClipDescriptor, type ClipEngineContract, ClipPointerHandler, type ClipPointerHost, type DawClipConnectedDetail, DawClipElement, type DawClipErrorDetail, type DawClipIdDetail, type DawClipMoveDetail, type DawClipSplitDetail, type DawClipTrimDetail, type DawClipUpdateDetail, DawEditorElement, type DawErrorDetail, type DawEvent, type DawEventMap, type DawFilesLoadErrorDetail, DawGridElement, DawKeyboardShortcutsElement, DawPauseButtonElement, DawPlayButtonElement, DawPlayheadElement, DawRecordButtonElement, type DawRecordingCompleteDetail, type DawRecordingErrorDetail, type DawRecordingStartDetail, DawRulerElement, type DawSeekDetail, type DawSelectionDetail, DawSelectionElement, DawStopButtonElement, type DawTrackConnectedDetail, type DawTrackControlDetail, DawTrackControlsElement, DawTrackElement, type DawTrackErrorDetail, type DawTrackIdDetail, type DawTrackRemoveDetail, type DawTrackSelectDetail, DawTransportButton, DawTransportElement, DawWaveformElement, type DomClipDescriptor, type DropClipDescriptor, type KeyBinding, type LoadFilesResult, type PlaybackShortcutMap, type PointerEngineContract, RecordingController, type RecordingOptions, type RecordingSession, type SplitEngineContract, type SplitHost, type SplittingShortcutMap, type TrackConfig, type TrackDescriptor, type UndoShortcutMap, type WaveformSegment, isDomClip, splitAtPlayhead };
1287
+ export { AudioResumeController, type ClipConfig, type ClipDescriptor, type ClipEngineContract, ClipPointerHandler, type ClipPointerHost, type DawClipConnectedDetail, DawClipElement, type DawClipErrorDetail, type DawClipIdDetail, type DawClipMoveDetail, type DawClipSplitDetail, type DawClipTrimDetail, type DawClipUpdateDetail, DawEditorElement, type DawErrorDetail, type DawEvent, type DawEventMap, type DawFilesLoadErrorDetail, DawGridElement, DawKeyboardShortcutsElement, DawPauseButtonElement, DawPianoRollElement, DawPlayButtonElement, DawPlayheadElement, DawRecordButtonElement, type DawRecordingCompleteDetail, type DawRecordingErrorDetail, type DawRecordingStartDetail, DawRulerElement, type DawSeekDetail, type DawSelectionDetail, DawSelectionElement, DawStopButtonElement, type DawTrackConnectedDetail, type DawTrackControlDetail, DawTrackControlsElement, DawTrackElement, type DawTrackErrorDetail, type DawTrackIdDetail, type DawTrackRemoveDetail, type DawTrackSelectDetail, DawTransportButton, DawTransportElement, DawWaveformElement, type DomClipDescriptor, type DropClipDescriptor, type KeyBinding, type LoadFilesResult, type PlaybackShortcutMap, type PointerEngineContract, RecordingController, type RecordingOptions, type RecordingSession, type SplitEngineContract, type SplitHost, type SplittingShortcutMap, type TrackConfig, type TrackDescriptor, type TrackRenderMode, type UndoShortcutMap, type WaveformSegment, isDomClip, splitAtPlayhead };