@waveform-playlist/browser 13.1.2 → 14.0.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/index.d.ts CHANGED
@@ -1,12 +1,9 @@
1
- import { Analyser, ToneAudioNode, InputNode } from 'tone';
2
- import * as tone from 'tone';
3
- export { tone as Tone };
4
- import { EffectsFunction, SoundFontCache, TrackEffectsFunction as TrackEffectsFunction$1 } from '@waveform-playlist/playout';
1
+ import { EffectsFunction, SoundFontCache, TrackEffectsFunction } from '@waveform-playlist/playout';
5
2
  export { EffectsFunction, TrackEffectsFunction } from '@waveform-playlist/playout';
6
3
  import * as React$1 from 'react';
7
4
  import React__default, { ReactNode, RefObject } from 'react';
8
- import { PlaylistEngine, EngineState } from '@waveform-playlist/engine';
9
- import { PeakData, Fade, MidiNoteData, ClipTrack, AnnotationData, AnnotationAction, WaveformDataObject, TrackEffectsFunction as TrackEffectsFunction$2, RenderMode, SpectrogramConfig, ColorMapValue, KeyboardShortcut, AnnotationActionOptions, RenderAnnotationItemProps, TrackSpectrogramOverrides } from '@waveform-playlist/core';
5
+ import { PlayoutAdapter, PlaylistEngine, EngineState } from '@waveform-playlist/engine';
6
+ import { PeakData, Fade, MidiNoteData, ClipTrack, AnnotationData, AnnotationAction, WaveformDataObject, KeyboardShortcut, AnnotationActionOptions, RenderAnnotationItemProps, TrackSpectrogramOverrides, SpectrogramConfig, ColorMapValue, RenderMode } from '@waveform-playlist/core';
10
7
  export { AnnotationData, AudioClip, ClipTrack, Fade, getShortcutLabel } from '@waveform-playlist/core';
11
8
  import { WaveformPlaylistTheme, TimeFormat, RenderPlayheadFunction, TrackMenuItem, SnapTo } from '@waveform-playlist/ui-components';
12
9
  export { TimeFormat } from '@waveform-playlist/ui-components';
@@ -32,9 +29,9 @@ type TrackClipPeaks = ClipPeaks[];
32
29
  interface WaveformTrack {
33
30
  src: string | AudioBuffer;
34
31
  name?: string;
35
- effects?: TrackEffectsFunction$1;
32
+ effects?: TrackEffectsFunction;
36
33
  }
37
- interface TrackState$1 {
34
+ interface TrackState {
38
35
  name: string;
39
36
  muted: boolean;
40
37
  soloed: boolean;
@@ -66,12 +63,19 @@ interface PlaybackAnimationContextValue {
66
63
  audioStartPositionRef: React__default.RefObject<number>;
67
64
  /** Returns raw playback time from engine (auto-wraps at loop boundaries). */
68
65
  getPlaybackTime: () => number;
66
+ /** Current time of the adapter's AudioContext, in seconds. */
67
+ getAudioContextTime: () => number;
69
68
  /**
70
69
  * Returns the current adapter scheduler lookahead (Tone ~0.1s, native 0).
71
70
  * Use this for any audible-latency calculation that must match the playhead
72
71
  * (e.g., recording live-preview peak slicing).
73
72
  */
74
73
  getLookAhead: () => number;
74
+ /**
75
+ * Returns the adapter AudioContext's output latency in seconds.
76
+ * Use this for audible-latency calculations (e.g., recording live-preview peak slicing).
77
+ */
78
+ getOutputLatency: () => number;
75
79
  /** Register a per-frame callback driven by the single animation loop. */
76
80
  registerFrameCallback: (id: string, cb: (data: FrameData) => void) => void;
77
81
  /** Unregister a per-frame callback. */
@@ -133,7 +137,7 @@ interface PlaylistDataContextValue {
133
137
  duration: number;
134
138
  audioBuffers: AudioBuffer[];
135
139
  peaksDataArray: TrackClipPeaks[];
136
- trackStates: TrackState$1[];
140
+ trackStates: TrackState[];
137
141
  tracks: ClipTrack[];
138
142
  sampleRate: number;
139
143
  waveHeight: number;
@@ -184,6 +188,10 @@ interface WaveformPlaylistProviderProps {
184
188
  };
185
189
  effects?: EffectsFunction;
186
190
  onReady?: () => void;
191
+ /** Called when audio/engine initialization fails (e.g. a missing optional peer,
192
+ * a throwing `createAdapter`, or an invalid `zoomLevels`/`samplesPerPixel`). The
193
+ * provider already logs the error; use this to surface it in your UI. */
194
+ onError?: (err: Error) => void;
187
195
  /** @deprecated Use onAnnotationsChange instead */
188
196
  onAnnotationUpdate?: (annotations: AnnotationData[]) => void;
189
197
  /** Callback when annotations are changed (drag, edit, etc.) */
@@ -217,6 +225,13 @@ interface WaveformPlaylistProviderProps {
217
225
  * this rate via standardized-audio-context. Pre-computed peaks (.dat files)
218
226
  * render instantly when they match. On mismatch, falls back to worker. */
219
227
  sampleRate?: number;
228
+ /** Factory for a custom PlayoutAdapter. When omitted, the Tone.js engine
229
+ * (@waveform-playlist/playout) is dynamically imported — so a custom adapter
230
+ * lets a consumer use neither @waveform-playlist/playout nor tone. Called once
231
+ * per engine rebuild; the provider owns and disposes the returned instance.
232
+ * Pass a stable reference (module-level or useCallback) — it is read directly
233
+ * inside the curated `loadAudio` effect, not via its dependency array. */
234
+ createAdapter?: () => PlayoutAdapter;
220
235
  children: ReactNode;
221
236
  }
222
237
  declare const WaveformPlaylistProvider: React__default.FC<WaveformPlaylistProviderProps>;
@@ -224,6 +239,13 @@ declare const usePlaybackAnimation: () => PlaybackAnimationContextValue;
224
239
  declare const usePlaylistState: () => PlaylistStateContextValue;
225
240
  declare const usePlaylistControls: () => PlaylistControlsContextValue;
226
241
  declare const usePlaylistData: () => PlaylistDataContextValue;
242
+ /**
243
+ * Like {@link usePlaylistData} but returns `null` instead of throwing when there
244
+ * is no WaveformPlaylistProvider ancestor. Use this in hooks/components that may
245
+ * also run in the MediaElement path (MediaElementPlaylistProvider), where the
246
+ * WebAudio playlist context is absent.
247
+ */
248
+ declare const usePlaylistDataOptional: () => PlaylistDataContextValue | null;
227
249
 
228
250
  interface MediaElementTrackConfig {
229
251
  /** Audio source URL or Blob URL */
@@ -328,6 +350,13 @@ interface MediaElementPlaylistProviderProps {
328
350
  audioContext?: AudioContext;
329
351
  /** Callback when audio is ready */
330
352
  onReady?: () => void;
353
+ /** Called when playout initialization fails (e.g. a missing optional peer,
354
+ * a throwing `createPlayout`, or an `addTrack` error). The provider already
355
+ * logs the error; use this to surface it in your UI. */
356
+ onError?: (err: Error) => void;
357
+ /** Factory for a custom MediaElement playout. When omitted, the bundled engine
358
+ * (@waveform-playlist/media-element-playout) is dynamically imported. */
359
+ createPlayout?: () => MediaElementPlayout;
331
360
  children: ReactNode;
332
361
  }
333
362
  /**
@@ -422,122 +451,6 @@ declare function useMasterVolume({ engineRef, initialVolume, }: UseMasterVolumeP
422
451
  onEngineState: (state: EngineState) => void;
423
452
  };
424
453
 
425
- /**
426
- * Hook for master effects with frequency analyzer
427
- * Returns the analyser ref and the effects function to pass to WaveformPlaylistProvider
428
- *
429
- * For more advanced effects (reverb, delay, filters, etc.), use useDynamicEffects instead.
430
- */
431
- declare const useMasterAnalyser: (fftSize?: number) => {
432
- analyserRef: React$1.MutableRefObject<Analyser | null>;
433
- masterEffects: EffectsFunction;
434
- };
435
-
436
- /**
437
- * Configuration for a single audio track to load
438
- *
439
- * Audio can be provided in three ways:
440
- * 1. `src` - URL to fetch and decode (standard loading)
441
- * 2. `audioBuffer` - Pre-loaded AudioBuffer (skip fetch/decode)
442
- * 3. `waveformData` only - Peaks-first rendering (audio loads later)
443
- *
444
- * For peaks-first rendering, just provide `waveformData` - the sample rate
445
- * and duration are derived from the waveform data automatically.
446
- */
447
- interface AudioTrackConfig {
448
- /** URL to audio file - used if audioBuffer not provided */
449
- src?: string;
450
- /** Pre-loaded AudioBuffer - skips fetch/decode if provided */
451
- audioBuffer?: AudioBuffer;
452
- name?: string;
453
- muted?: boolean;
454
- soloed?: boolean;
455
- volume?: number;
456
- pan?: number;
457
- color?: string;
458
- effects?: TrackEffectsFunction$2;
459
- startTime?: number;
460
- duration?: number;
461
- offset?: number;
462
- fadeIn?: Fade;
463
- fadeOut?: Fade;
464
- waveformData?: WaveformDataObject;
465
- /** Visualization render mode: 'waveform' | 'spectrogram' | 'both'. Default: 'waveform' */
466
- renderMode?: RenderMode;
467
- /** Spectrogram configuration (FFT size, window, frequency scale, etc.) */
468
- spectrogramConfig?: SpectrogramConfig;
469
- /** Spectrogram color map name or custom color array */
470
- spectrogramColorMap?: ColorMapValue;
471
- }
472
- /**
473
- * Options for useAudioTracks hook
474
- */
475
- interface UseAudioTracksOptions {
476
- /**
477
- * When true, all tracks render immediately as placeholders with clip geometry
478
- * from the config. Audio fills in progressively as files decode, and peaks
479
- * render as each buffer becomes available. Use with `deferEngineRebuild={loading}`
480
- * on the provider for a single engine build when all tracks are ready.
481
- *
482
- * Requires `duration` or `waveformData` in each config so clip dimensions are known upfront.
483
- * Default: false
484
- */
485
- immediate?: boolean;
486
- /** @deprecated Use `immediate` instead. */
487
- progressive?: boolean;
488
- }
489
- /**
490
- * Hook to load audio from URLs and convert to ClipTrack format
491
- *
492
- * This hook fetches audio files, decodes them, and creates ClipTrack objects
493
- * with a single clip per track. Supports custom positioning for multi-clip arrangements.
494
- *
495
- * @param configs - Array of audio track configurations
496
- * @param options - Optional configuration for loading behavior
497
- * @returns Object with tracks array, loading state, and progress info
498
- *
499
- * @example
500
- * ```typescript
501
- * // Basic usage (clips positioned at start)
502
- * const { tracks, loading, error } = useAudioTracks([
503
- * { src: 'audio/vocals.mp3', name: 'Vocals' },
504
- * { src: 'audio/drums.mp3', name: 'Drums' },
505
- * ]);
506
- *
507
- * // Immediate rendering with deferred engine build (recommended for multi-track)
508
- * const { tracks, loading } = useAudioTracks(
509
- * [
510
- * { src: 'audio/vocals.mp3', name: 'Vocals', duration: 30 },
511
- * { src: 'audio/drums.mp3', name: 'Drums', duration: 30 },
512
- * ],
513
- * { immediate: true }
514
- * );
515
- * // All tracks render instantly as placeholders, peaks fill in as files load
516
- * return (
517
- * <WaveformPlaylistProvider tracks={tracks} deferEngineRebuild={loading}>
518
- * ...
519
- * </WaveformPlaylistProvider>
520
- * );
521
- *
522
- * // Pre-loaded AudioBuffer (skip fetch/decode)
523
- * const { tracks } = useAudioTracks([
524
- * { audioBuffer: myPreloadedBuffer, name: 'Pre-loaded' },
525
- * ]);
526
- *
527
- * // Peaks-first rendering (instant visual, audio loads later)
528
- * const { tracks } = useAudioTracks([
529
- * { waveformData: preloadedPeaks, name: 'Peaks Only' }, // Renders immediately
530
- * ]);
531
- * ```
532
- */
533
- declare function useAudioTracks(configs: AudioTrackConfig[], options?: UseAudioTracksOptions): {
534
- tracks: ClipTrack[];
535
- loading: boolean;
536
- error: string | null;
537
- loadedCount: number;
538
- totalCount: number;
539
- };
540
-
541
454
  interface UseClipDragHandlersOptions {
542
455
  tracks: ClipTrack[];
543
456
  onTracksChange: (tracks: ClipTrack[]) => void;
@@ -598,7 +511,8 @@ interface UseAnnotationDragHandlersOptions {
598
511
  annotations: AnnotationData[];
599
512
  onAnnotationsChange: (annotations: AnnotationData[]) => void;
600
513
  samplesPerPixel: number;
601
- /** Sample rate for pixel-to-time conversion. Defaults to AudioContext.sampleRate. */
514
+ /** Sample rate for pixel-to-time conversion. Providers pass the real rate from
515
+ * context; defaults to 48000 (the engine default) for out-of-provider usage. */
602
516
  sampleRate?: number;
603
517
  duration: number;
604
518
  linkEndpoints: boolean;
@@ -824,6 +738,14 @@ interface UseAnnotationKeyboardControlsOptions {
824
738
  scrollContainerRef?: React.RefObject<HTMLDivElement | null>;
825
739
  /** Optional: callback to start playback at a time with optional duration */
826
740
  onPlay?: (startTime: number, duration?: number) => void;
741
+ /**
742
+ * Pixels-per-sample for auto-scroll positioning. Falls back to the
743
+ * WaveformPlaylistProvider context when omitted (WebAudio path). Pass
744
+ * explicitly when used outside that provider (e.g. the MediaElement path).
745
+ */
746
+ samplesPerPixel?: number;
747
+ /** Sample rate for auto-scroll positioning. Falls back to context. */
748
+ sampleRate?: number;
827
749
  }
828
750
  /**
829
751
  * Hook for keyboard-based annotation navigation and boundary editing
@@ -856,7 +778,7 @@ interface UseAnnotationKeyboardControlsOptions {
856
778
  * });
857
779
  * ```
858
780
  */
859
- declare function useAnnotationKeyboardControls({ annotations, activeAnnotationId, onAnnotationsChange, onActiveAnnotationChange, duration, linkEndpoints, continuousPlay, enabled, scrollContainerRef, onPlay, }: UseAnnotationKeyboardControlsOptions): {
781
+ declare function useAnnotationKeyboardControls({ annotations, activeAnnotationId, onAnnotationsChange, onActiveAnnotationChange, duration, linkEndpoints, continuousPlay, enabled, scrollContainerRef, onPlay, samplesPerPixel: samplesPerPixelProp, sampleRate: sampleRateProp, }: UseAnnotationKeyboardControlsOptions): {
860
782
  moveStartBoundary: (delta: number) => void;
861
783
  moveEndBoundary: (delta: number) => void;
862
784
  selectPrevious: () => void;
@@ -868,280 +790,6 @@ declare function useAnnotationKeyboardControls({ annotations, activeAnnotationId
868
790
  playActiveAnnotation: () => void;
869
791
  };
870
792
 
871
- /**
872
- * Effect definitions for all available Tone.js effects
873
- * Each effect has parameters with min/max/default values for UI controls
874
- */
875
- type ParameterType = 'number' | 'select' | 'boolean';
876
- interface EffectParameter {
877
- name: string;
878
- label: string;
879
- type: ParameterType;
880
- min?: number;
881
- max?: number;
882
- step?: number;
883
- default: number | string | boolean;
884
- unit?: string;
885
- options?: {
886
- value: string | number;
887
- label: string;
888
- }[];
889
- }
890
- interface EffectDefinition {
891
- id: string;
892
- name: string;
893
- category: 'delay' | 'reverb' | 'modulation' | 'distortion' | 'filter' | 'dynamics' | 'spatial';
894
- description: string;
895
- parameters: EffectParameter[];
896
- }
897
- declare const effectDefinitions: EffectDefinition[];
898
- declare const getEffectDefinition: (id: string) => EffectDefinition | undefined;
899
- declare const getEffectsByCategory: (category: EffectDefinition["category"]) => EffectDefinition[];
900
- declare const effectCategories: {
901
- id: EffectDefinition['category'];
902
- name: string;
903
- }[];
904
-
905
- interface ActiveEffect {
906
- instanceId: string;
907
- effectId: string;
908
- definition: EffectDefinition;
909
- params: Record<string, number | string | boolean>;
910
- bypassed: boolean;
911
- }
912
- interface UseDynamicEffectsReturn {
913
- activeEffects: ActiveEffect[];
914
- availableEffects: EffectDefinition[];
915
- addEffect: (effectId: string) => void;
916
- removeEffect: (instanceId: string) => void;
917
- updateParameter: (instanceId: string, paramName: string, value: number | string | boolean) => void;
918
- toggleBypass: (instanceId: string) => void;
919
- reorderEffects: (fromIndex: number, toIndex: number) => void;
920
- clearAllEffects: () => void;
921
- masterEffects: EffectsFunction;
922
- /**
923
- * Creates a fresh effects function for offline rendering.
924
- * This creates new effect instances that work in the offline AudioContext.
925
- */
926
- createOfflineEffectsFunction: () => EffectsFunction | undefined;
927
- analyserRef: React.RefObject<Analyser | null>;
928
- }
929
- /**
930
- * Hook for managing a dynamic chain of audio effects with real-time parameter updates
931
- */
932
- declare function useDynamicEffects(fftSize?: number): UseDynamicEffectsReturn;
933
-
934
- interface TrackActiveEffect {
935
- instanceId: string;
936
- effectId: string;
937
- definition: EffectDefinition;
938
- params: Record<string, number | string | boolean>;
939
- bypassed: boolean;
940
- }
941
- interface TrackEffectsState {
942
- trackId: string;
943
- activeEffects: TrackActiveEffect[];
944
- }
945
- interface UseTrackDynamicEffectsReturn {
946
- trackEffectsState: Map<string, TrackActiveEffect[]>;
947
- addEffectToTrack: (trackId: string, effectId: string) => void;
948
- removeEffectFromTrack: (trackId: string, instanceId: string) => void;
949
- updateTrackEffectParameter: (trackId: string, instanceId: string, paramName: string, value: number | string | boolean) => void;
950
- toggleBypass: (trackId: string, instanceId: string) => void;
951
- clearTrackEffects: (trackId: string) => void;
952
- getTrackEffectsFunction: (trackId: string) => TrackEffectsFunction$1 | undefined;
953
- /**
954
- * Creates a fresh effects function for a track for offline rendering.
955
- * This creates new effect instances that work in the offline AudioContext.
956
- */
957
- createOfflineTrackEffectsFunction: (trackId: string) => TrackEffectsFunction$1 | undefined;
958
- availableEffects: EffectDefinition[];
959
- }
960
- /**
961
- * Hook for managing dynamic effects per track with real-time parameter updates
962
- */
963
- declare function useTrackDynamicEffects(): UseTrackDynamicEffectsReturn;
964
-
965
- /**
966
- * WAV file encoder
967
- * Converts AudioBuffer to WAV format Blob
968
- */
969
- interface WavEncoderOptions {
970
- /** Bit depth: 16 or 32. Default: 16 */
971
- bitDepth?: 16 | 32;
972
- }
973
-
974
- /** Function type for per-track effects (same as in @waveform-playlist/core) */
975
- type TrackEffectsFunction = (graphEnd: unknown, destination: unknown, isOffline: boolean) => void | (() => void);
976
- interface ExportOptions extends WavEncoderOptions {
977
- /** Filename for download (without extension) */
978
- filename?: string;
979
- /** Export mode: 'master' for full mixdown, 'individual' for single track */
980
- mode?: 'master' | 'individual';
981
- /** Track index for individual export (only used when mode is 'individual') */
982
- trackIndex?: number;
983
- /** Whether to trigger automatic download */
984
- autoDownload?: boolean;
985
- /** Whether to apply effects (fades, etc.) - defaults to true */
986
- applyEffects?: boolean;
987
- /**
988
- * Optional Tone.js effects function for master effects. When provided, export renders
989
- * through the effects chain. The function receives isOffline=true.
990
- */
991
- effectsFunction?: EffectsFunction;
992
- /**
993
- * Optional function to create offline track effects.
994
- * Takes a trackId and returns a TrackEffectsFunction for offline rendering.
995
- * This is used instead of track.effects to avoid AudioContext mismatch issues.
996
- */
997
- createOfflineTrackEffects?: (trackId: string) => TrackEffectsFunction | undefined;
998
- /** Progress callback (0-1) */
999
- onProgress?: (progress: number) => void;
1000
- }
1001
- interface ExportResult {
1002
- /** The rendered audio buffer */
1003
- audioBuffer: AudioBuffer;
1004
- /** The WAV file as a Blob */
1005
- blob: Blob;
1006
- /** Duration in seconds */
1007
- duration: number;
1008
- }
1009
- interface UseExportWavReturn {
1010
- /** Export the playlist to WAV */
1011
- exportWav: (tracks: ClipTrack[], trackStates: TrackState[], options?: ExportOptions) => Promise<ExportResult>;
1012
- /** Whether export is in progress */
1013
- isExporting: boolean;
1014
- /** Export progress (0-1) */
1015
- progress: number;
1016
- /** Error message if export failed */
1017
- error: string | null;
1018
- }
1019
- interface TrackState {
1020
- muted: boolean;
1021
- soloed: boolean;
1022
- volume: number;
1023
- pan: number;
1024
- }
1025
- /**
1026
- * Hook for exporting the waveform playlist to WAV format.
1027
- * Uses Tone.Offline for non-real-time rendering, mirroring the live playback graph.
1028
- */
1029
- declare function useExportWav(): UseExportWavReturn;
1030
-
1031
- /**
1032
- * useDynamicTracks — imperative hook for runtime track additions.
1033
- *
1034
- * Complements `useAudioTracks` (declarative, configs-driven) with an
1035
- * imperative `addTracks()` API for dynamic loading (drag-and-drop, file pickers).
1036
- *
1037
- * Placeholder tracks appear instantly while audio decodes in parallel.
1038
- */
1039
-
1040
- /** A source that can be decoded into a track. */
1041
- type TrackSource = File | Blob | string | {
1042
- src: string;
1043
- name?: string;
1044
- };
1045
- /** Info about a track that failed to load. */
1046
- interface TrackLoadError {
1047
- /** Display name of the source that failed. */
1048
- name: string;
1049
- /** The underlying error. */
1050
- error: Error;
1051
- }
1052
- interface UseDynamicTracksReturn {
1053
- /**
1054
- * Current tracks array (placeholders + loaded). Pass to WaveformPlaylistProvider.
1055
- * Placeholder tracks have `clips: []` and names ending with " (loading...)".
1056
- */
1057
- tracks: ClipTrack[];
1058
- /** Add one or more sources — creates placeholder tracks immediately. */
1059
- addTracks: (sources: TrackSource[]) => void;
1060
- /** Remove a track by its id. Aborts in-flight fetch/decode if still loading. */
1061
- removeTrack: (trackId: string) => void;
1062
- /** Number of sources currently decoding. */
1063
- loadingCount: number;
1064
- /** True when any source is still decoding. */
1065
- isLoading: boolean;
1066
- /** Tracks that failed to load (removed from `tracks` automatically). */
1067
- errors: TrackLoadError[];
1068
- }
1069
- declare function useDynamicTracks(): UseDynamicTracksReturn;
1070
-
1071
- /**
1072
- * Hook for monitoring master output levels
1073
- *
1074
- * Connects an AudioWorklet meter processor to the Destination node for
1075
- * real-time output level monitoring. Computes sample-accurate peak and
1076
- * RMS via the meter worklet — no transient is missed.
1077
- *
1078
- * IMPORTANT: Uses getGlobalContext() from playout to ensure the meter
1079
- * is created on the same AudioContext as the audio engine. Tone.js's
1080
- * getContext()/getDestination() return the DEFAULT context, which is
1081
- * replaced when getGlobalContext() calls setContext() on first audio init.
1082
- */
1083
- interface UseOutputMeterOptions {
1084
- /**
1085
- * Number of channels to meter.
1086
- * Default: 2 (stereo output)
1087
- */
1088
- channelCount?: number;
1089
- /**
1090
- * How often to update the levels (in Hz).
1091
- * Default: 60 (60fps)
1092
- */
1093
- updateRate?: number;
1094
- /**
1095
- * Whether audio is currently playing. When this transitions to false,
1096
- * all levels (current, peak, RMS) and smoothed state are reset to zero.
1097
- * Without this, the browser's tail-time optimization stops calling the
1098
- * worklet's process() when no audio flows, leaving the last non-zero
1099
- * levels frozen in state.
1100
- * Default: false
1101
- */
1102
- isPlaying?: boolean;
1103
- }
1104
- interface UseOutputMeterReturn {
1105
- /** Per-channel peak output levels (0-1) */
1106
- levels: number[];
1107
- /** Per-channel held peak levels (0-1) */
1108
- peakLevels: number[];
1109
- /** Per-channel RMS output levels (0-1) */
1110
- rmsLevels: number[];
1111
- /** Reset all held peak levels to 0 */
1112
- resetPeak: () => void;
1113
- /** Error from meter setup (worklet load failure, context issues, etc.) */
1114
- error: Error | null;
1115
- }
1116
- declare function useOutputMeter(options?: UseOutputMeterOptions): UseOutputMeterReturn;
1117
-
1118
- /**
1119
- * Factory for creating Tone.js effect instances from effect definitions
1120
- */
1121
-
1122
- interface EffectInstance {
1123
- effect: ToneAudioNode;
1124
- id: string;
1125
- instanceId: string;
1126
- dispose: () => void;
1127
- setParameter: (name: string, value: number | string | boolean) => void;
1128
- getParameter: (name: string) => number | string | boolean | undefined;
1129
- connect: (destination: InputNode) => void;
1130
- disconnect: () => void;
1131
- }
1132
- /**
1133
- * Create an effect instance from a definition with initial parameter values
1134
- */
1135
- declare function createEffectInstance(definition: EffectDefinition, initialParams?: Record<string, number | string | boolean>): EffectInstance;
1136
- /**
1137
- * Create a chain of effects connected in series
1138
- */
1139
- declare function createEffectChain(effects: EffectInstance[]): {
1140
- input: ToneAudioNode;
1141
- output: ToneAudioNode;
1142
- dispose: () => void;
1143
- };
1144
-
1145
793
  declare const PlayButton: React__default.FC<{
1146
794
  className?: string;
1147
795
  }>;
@@ -1251,38 +899,6 @@ declare const DownloadAnnotationsButton: React__default.FC<{
1251
899
  className?: string;
1252
900
  }>;
1253
901
 
1254
- interface ExportWavButtonProps {
1255
- /** Button label */
1256
- label?: string;
1257
- /** Filename for the downloaded file (without extension) */
1258
- filename?: string;
1259
- /** Export mode: 'master' for stereo mix, 'individual' for single track */
1260
- mode?: 'master' | 'individual';
1261
- /** Track index for individual export */
1262
- trackIndex?: number;
1263
- /** Bit depth: 16 or 32 */
1264
- bitDepth?: 16 | 32;
1265
- /** Whether to apply effects (fades, etc.) - defaults to true */
1266
- applyEffects?: boolean;
1267
- /**
1268
- * Optional Tone.js effects function for master effects. When provided, export will use Tone.Offline
1269
- * to render through the effects chain. The function receives isOffline=true.
1270
- */
1271
- effectsFunction?: EffectsFunction;
1272
- /**
1273
- * Optional function to create offline track effects.
1274
- * Takes a trackId and returns a TrackEffectsFunction for offline rendering.
1275
- */
1276
- createOfflineTrackEffects?: (trackId: string) => TrackEffectsFunction | undefined;
1277
- /** CSS class name */
1278
- className?: string;
1279
- /** Callback when export completes */
1280
- onExportComplete?: (blob: Blob) => void;
1281
- /** Callback when export fails */
1282
- onExportError?: (error: Error) => void;
1283
- }
1284
- declare const ExportWavButton: React__default.FC<ExportWavButtonProps>;
1285
-
1286
902
  /**
1287
903
  * Shared annotation types used across Waveform components
1288
904
  */
@@ -1850,4 +1466,4 @@ declare function getWaveformDataMetadata(src: string): Promise<{
1850
1466
  bits: 8 | 16;
1851
1467
  }>;
1852
1468
 
1853
- export { type ActiveEffect, type AnnotationIntegration, AnnotationIntegrationProvider, AudioPosition, type AudioTrackConfig, AutomaticScrollCheckbox, ClearAllButton, type ClearAllButtonProps, ClipCollisionModifier, ClipInteractionProvider, type ClipInteractionProviderProps, ContinuousPlayCheckbox, DownloadAnnotationsButton, EditableCheckbox, type EffectDefinition, type EffectInstance, type EffectParameter, type ExportOptions, type ExportResult, ExportWavButton, type ExportWavButtonProps, FastForwardButton, type FrameData, type GetAnnotationBoxLabelFn, KeyboardShortcuts, type KeyboardShortcutsProps, LinkEndpointsCheckbox, LoopButton, MasterVolumeControl, type MasterVolumeControls, type MediaElementAnimationContextValue, MediaElementAnnotationList, type MediaElementAnnotationListProps, type MediaElementControlsContextValue, type MediaElementDataContextValue, MediaElementPlaylist, type MediaElementPlaylistProps, MediaElementPlaylistProvider, type MediaElementStateContextValue, type MediaElementTrackConfig, MediaElementWaveform, type MediaElementWaveformProps, type OnAnnotationUpdateFn, type ParameterType, PauseButton, PlayButton, PlaylistAnnotationList, type PlaylistAnnotationListProps, PlaylistVisualization, type PlaylistVisualizationProps, RewindButton, SelectionTimeInputs, SetLoopRegionButton, SkipBackwardButton, SkipForwardButton, SnapToGridModifier, type SpectrogramCanvasRegistration, type SpectrogramIntegration, SpectrogramIntegrationProvider, StopButton, type TimeFormatControls, TimeFormatSelect, type TrackActiveEffect, type TrackEffectsState, type TrackLoadError, type TrackSource, type TrackState$1 as TrackState, type UseDynamicEffectsReturn, type UseDynamicTracksReturn, type UseExportWavReturn, type UseOutputMeterOptions, type UseOutputMeterReturn, type UsePlaybackShortcutsOptions, type UsePlaybackShortcutsReturn, type UseTrackDynamicEffectsReturn, Waveform, WaveformPlaylistProvider, type WaveformProps, type WaveformTrack, type ZoomControls, ZoomInButton, ZoomOutButton, createEffectChain, createEffectInstance, effectCategories, effectDefinitions, getEffectDefinition, getEffectsByCategory, getWaveformDataMetadata, loadPeaksFromWaveformData, loadWaveformData, noDropAnimationPlugins, useAnnotationDragHandlers, useAnnotationIntegration, useAnnotationKeyboardControls, useAudioTracks, useClipDragHandlers, useClipInteractionEnabled, useClipSplitting, useDragSensors, useDynamicEffects, useDynamicTracks, useExportWav, useKeyboardShortcuts, useMasterAnalyser, useMasterVolume, useMediaElementAnimation, useMediaElementControls, useMediaElementData, useMediaElementState, useOutputMeter, usePlaybackAnimation, usePlaybackShortcuts, usePlaylistControls, usePlaylistData, usePlaylistState, useSpectrogramIntegration, useTimeFormat, useTrackDynamicEffects, useZoomControls, waveformDataToPeaks };
1469
+ export { type AnnotationIntegration, AnnotationIntegrationProvider, AudioPosition, AutomaticScrollCheckbox, ClearAllButton, type ClearAllButtonProps, ClipCollisionModifier, ClipInteractionProvider, type ClipInteractionProviderProps, ContinuousPlayCheckbox, DownloadAnnotationsButton, EditableCheckbox, FastForwardButton, type FrameData, type GetAnnotationBoxLabelFn, KeyboardShortcuts, type KeyboardShortcutsProps, LinkEndpointsCheckbox, LoopButton, MasterVolumeControl, type MasterVolumeControls, type MediaElementAnimationContextValue, MediaElementAnnotationList, type MediaElementAnnotationListProps, type MediaElementControlsContextValue, type MediaElementDataContextValue, MediaElementPlaylist, type MediaElementPlaylistProps, MediaElementPlaylistProvider, type MediaElementStateContextValue, type MediaElementTrackConfig, MediaElementWaveform, type MediaElementWaveformProps, type OnAnnotationUpdateFn, PauseButton, PlayButton, PlaylistAnnotationList, type PlaylistAnnotationListProps, PlaylistVisualization, type PlaylistVisualizationProps, RewindButton, SelectionTimeInputs, SetLoopRegionButton, SkipBackwardButton, SkipForwardButton, SnapToGridModifier, type SpectrogramCanvasRegistration, type SpectrogramIntegration, SpectrogramIntegrationProvider, StopButton, type TimeFormatControls, TimeFormatSelect, type TrackState, type UsePlaybackShortcutsOptions, type UsePlaybackShortcutsReturn, Waveform, WaveformPlaylistProvider, type WaveformProps, type WaveformTrack, type ZoomControls, ZoomInButton, ZoomOutButton, getWaveformDataMetadata, loadPeaksFromWaveformData, loadWaveformData, noDropAnimationPlugins, useAnnotationDragHandlers, useAnnotationIntegration, useAnnotationKeyboardControls, useClipDragHandlers, useClipInteractionEnabled, useClipSplitting, useDragSensors, useKeyboardShortcuts, useMasterVolume, useMediaElementAnimation, useMediaElementControls, useMediaElementData, useMediaElementState, usePlaybackAnimation, usePlaybackShortcuts, usePlaylistControls, usePlaylistData, usePlaylistDataOptional, usePlaylistState, useSpectrogramIntegration, useTimeFormat, useZoomControls, waveformDataToPeaks };