import { TrackEffectsFunction, Fade, WaveformDataObject, RenderMode, SpectrogramConfig, ColorMapValue, ClipTrack } from '@waveform-playlist/core'; import * as React$1 from 'react'; import React__default from 'react'; import { EffectsFunction, TrackEffectsFunction as TrackEffectsFunction$1 } from '@waveform-playlist/playout'; import { Analyser, Volume, ToneAudioNode, Gain, InputNode } from 'tone'; import * as _dawcore_wam from '@dawcore/wam'; import { WamPluginInstance } from '@dawcore/wam'; /** * Configuration for a single audio track to load * * Audio can be provided in three ways: * 1. `src` - URL to fetch and decode (standard loading) * 2. `audioBuffer` - Pre-loaded AudioBuffer (skip fetch/decode) * 3. `waveformData` only - Peaks-first rendering (audio loads later) * * For peaks-first rendering, just provide `waveformData` - the sample rate * and duration are derived from the waveform data automatically. */ interface AudioTrackConfig { /** URL to audio file - used if audioBuffer not provided */ src?: string; /** Pre-loaded AudioBuffer - skips fetch/decode if provided */ audioBuffer?: AudioBuffer; name?: string; muted?: boolean; soloed?: boolean; volume?: number; pan?: number; color?: string; effects?: TrackEffectsFunction; startTime?: number; duration?: number; offset?: number; fadeIn?: Fade; fadeOut?: Fade; waveformData?: WaveformDataObject; /** Visualization render mode: 'waveform' | 'spectrogram' | 'both'. Default: 'waveform' */ renderMode?: RenderMode; /** Spectrogram configuration (FFT size, window, frequency scale, etc.) */ spectrogramConfig?: SpectrogramConfig; /** Spectrogram color map name or custom color array */ spectrogramColorMap?: ColorMapValue; } /** * Options for useAudioTracks hook */ interface UseAudioTracksOptions { /** * When true, all tracks render immediately as placeholders with clip geometry * from the config. Audio fills in progressively as files decode, and peaks * render as each buffer becomes available. Use with `deferEngineRebuild={loading}` * on the provider for a single engine build when all tracks are ready. * * Requires `duration` or `waveformData` in each config so clip dimensions are known upfront. * Default: false */ immediate?: boolean; /** @deprecated Use `immediate` instead. */ progressive?: boolean; } /** * Hook to load audio from URLs and convert to ClipTrack format * * This hook fetches audio files, decodes them, and creates ClipTrack objects * with a single clip per track. Supports custom positioning for multi-clip arrangements. * * @param configs - Array of audio track configurations * @param options - Optional configuration for loading behavior * @returns Object with tracks array, loading state, and progress info * * @example * ```typescript * // Basic usage (clips positioned at start) * const { tracks, loading, error } = useAudioTracks([ * { src: 'audio/vocals.mp3', name: 'Vocals' }, * { src: 'audio/drums.mp3', name: 'Drums' }, * ]); * * // Immediate rendering with deferred engine build (recommended for multi-track) * const { tracks, loading } = useAudioTracks( * [ * { src: 'audio/vocals.mp3', name: 'Vocals', duration: 30 }, * { src: 'audio/drums.mp3', name: 'Drums', duration: 30 }, * ], * { immediate: true } * ); * // All tracks render instantly as placeholders, peaks fill in as files load * return ( * * ... * * ); * * // Pre-loaded AudioBuffer (skip fetch/decode) * const { tracks } = useAudioTracks([ * { audioBuffer: myPreloadedBuffer, name: 'Pre-loaded' }, * ]); * * // Peaks-first rendering (instant visual, audio loads later) * const { tracks } = useAudioTracks([ * { waveformData: preloadedPeaks, name: 'Peaks Only' }, // Renders immediately * ]); * ``` */ declare function useAudioTracks(configs: AudioTrackConfig[], options?: UseAudioTracksOptions): { tracks: ClipTrack[]; loading: boolean; error: string | null; loadedCount: number; totalCount: number; }; /** * Hook for master effects with frequency analyzer * Returns the analyser ref and the effects function to pass to WaveformPlaylistProvider * * For more advanced effects (reverb, delay, filters, etc.), use useDynamicEffects instead. */ declare const useMasterAnalyser: (fftSize?: number) => { analyserRef: React$1.MutableRefObject; masterEffects: EffectsFunction; }; /** * Effect definitions for all available Tone.js effects * Each effect has parameters with min/max/default values for UI controls */ type ParameterType = 'number' | 'select' | 'boolean'; interface EffectParameter { name: string; label: string; type: ParameterType; min?: number; max?: number; step?: number; default: number | string | boolean; unit?: string; options?: { value: string | number; label: string; }[]; } interface EffectDefinition { id: string; name: string; category: 'delay' | 'reverb' | 'modulation' | 'distortion' | 'filter' | 'dynamics' | 'spatial' | 'wam'; description: string; parameters: EffectParameter[]; } declare const effectDefinitions: EffectDefinition[]; declare const getEffectDefinition: (id: string) => EffectDefinition | undefined; declare const getEffectsByCategory: (category: EffectDefinition["category"]) => EffectDefinition[]; declare const effectCategories: { id: EffectDefinition['category']; name: string; }[]; /** * WAV file encoder * Converts AudioBuffer to WAV format Blob */ interface WavEncoderOptions { /** Bit depth: 16 or 32. Default: 16 */ bitDepth?: 16 | 32; } /** Cleanup returned by an offline effects function (disposes offline instances / WAM clones). */ type OfflineEffectsCleanup = void | (() => void); /** * Master-chain effects function for offline rendering. May return a Promise — * WAM entries are re-instantiated asynchronously on the offline context. * Every live EffectsFunction is assignable to this type. */ type OfflineEffectsFunction = (masterVolume: Volume, destination: ToneAudioNode, isOffline: boolean) => OfflineEffectsCleanup | Promise; /** Per-track variant of OfflineEffectsFunction. */ type OfflineTrackEffectsFunction = (graphEnd: Gain, masterGainNode: ToneAudioNode, isOffline: boolean) => OfflineEffectsCleanup | Promise; interface ExportOptions extends WavEncoderOptions { /** Filename for download (without extension) */ filename?: string; /** Export mode: 'master' for full mixdown, 'individual' for single track */ mode?: 'master' | 'individual'; /** Track index for individual export (only used when mode is 'individual') */ trackIndex?: number; /** Whether to trigger automatic download */ autoDownload?: boolean; /** Whether to apply effects (fades, etc.) - defaults to true */ applyEffects?: boolean; /** * Optional effects function for master effects. When provided, export renders * through the effects chain (WAM entries included — re-instantiated on the * offline context). The function receives isOffline=true and may be async. */ effectsFunction?: OfflineEffectsFunction; /** * Optional function to create offline track effects. * Takes a trackId and returns an offline effects function for that track. * This is used instead of track.effects to avoid AudioContext mismatch issues. */ createOfflineTrackEffects?: (trackId: string) => OfflineTrackEffectsFunction | undefined; /** Progress callback (0-1) */ onProgress?: (progress: number) => void; } interface ExportResult { /** The rendered audio buffer */ audioBuffer: AudioBuffer; /** The WAV file as a Blob */ blob: Blob; /** Duration in seconds */ duration: number; } interface UseExportWavReturn { /** Export the playlist to WAV */ exportWav: (tracks: ClipTrack[], trackStates: TrackState[], options?: ExportOptions) => Promise; /** Whether export is in progress */ isExporting: boolean; /** Export progress (0-1) */ progress: number; /** Error message if export failed */ error: string | null; } interface TrackState { muted: boolean; soloed: boolean; volume: number; pan: number; } /** * Hook for exporting the waveform playlist to WAV format. * Uses a Tone offline render (native OfflineAudioContext in native-context mode), * mirroring the live playback graph. */ declare function useExportWav(): UseExportWavReturn; interface ActiveEffect { instanceId: string; effectId: string; /** 'native' = built-in Tone effect; 'wam' = hosted WAM plugin. */ kind: 'native' | 'wam'; /** Module URL for wam entries. */ url?: string; definition: EffectDefinition; params: Record; bypassed: boolean; } interface UseDynamicEffectsReturn { activeEffects: ActiveEffect[]; availableEffects: EffectDefinition[]; addEffect: (effectId: string) => void; /** * Hosts a WAM plugin from a module URL and appends it to the master chain. * Requires native-context mode — call configureGlobalContext({ nativeAudioContext: true }) * from @waveform-playlist/playout before any audio initialization. * WAM entries render in offline WAV export (re-instantiated on the offline context). * Resolves with the new entry's instanceId. */ addWamEffect: (url: string, initialState?: unknown) => Promise; /** Live plugin handle for a hosted WAM entry (for GUI mounting via WamEffectGui). */ getWamPlugin: (instanceId: string) => WamPluginInstance | undefined; removeEffect: (instanceId: string) => void; updateParameter: (instanceId: string, paramName: string, value: number | string | boolean) => void; toggleBypass: (instanceId: string) => void; reorderEffects: (fromIndex: number, toIndex: number) => void; clearAllEffects: () => void; masterEffects: EffectsFunction; /** * Creates a fresh effects function for offline rendering. Native effects are * re-created on the offline context; WAM entries are re-instantiated from * their URL-cached factories with the live instance's state transferred. * The returned function may be async and may reject — a WAV export never * silently renders without an effect the live chain has. */ createOfflineEffectsFunction: () => OfflineEffectsFunction | undefined; analyserRef: React.RefObject; } /** * Hook for managing a dynamic chain of audio effects with real-time parameter updates */ declare function useDynamicEffects(fftSize?: number): UseDynamicEffectsReturn; interface TrackActiveEffect { instanceId: string; effectId: string; /** 'native' = built-in Tone effect; 'wam' = hosted WAM plugin. */ kind: 'native' | 'wam'; /** Module URL for wam entries. */ url?: string; definition: EffectDefinition; params: Record; bypassed: boolean; } interface TrackEffectsState { trackId: string; activeEffects: TrackActiveEffect[]; } interface UseTrackDynamicEffectsReturn { trackEffectsState: Map; addEffectToTrack: (trackId: string, effectId: string) => void; /** * Hosts a WAM plugin from a module URL and appends it to a track's effect chain. * Requires native-context mode — call configureGlobalContext({ nativeAudioContext: true }) * from @waveform-playlist/playout before any audio initialization. * WAM entries render in offline WAV export (re-instantiated on the offline context). * Resolves with the new entry's instanceId. */ addWamEffectToTrack: (trackId: string, url: string, initialState?: unknown) => Promise; /** Live plugin handle for a hosted WAM entry on a track (for GUI mounting via WamEffectGui). */ getTrackWamPlugin: (trackId: string, instanceId: string) => WamPluginInstance | undefined; removeEffectFromTrack: (trackId: string, instanceId: string) => void; updateTrackEffectParameter: (trackId: string, instanceId: string, paramName: string, value: number | string | boolean) => void; toggleBypass: (trackId: string, instanceId: string) => void; clearTrackEffects: (trackId: string) => void; getTrackEffectsFunction: (trackId: string) => TrackEffectsFunction$1 | undefined; /** * Creates a fresh effects function for a track for offline rendering. * Native effects are re-created on the offline context; WAM entries are * re-instantiated with the live instance's state transferred. May reject — * a WAV export never silently renders without an effect the live chain has. */ createOfflineTrackEffectsFunction: (trackId: string) => OfflineTrackEffectsFunction | undefined; availableEffects: EffectDefinition[]; } /** * Hook for managing dynamic effects per track with real-time parameter updates */ declare function useTrackDynamicEffects(): UseTrackDynamicEffectsReturn; /** * useDynamicTracks — imperative hook for runtime track additions. * * Complements `useAudioTracks` (declarative, configs-driven) with an * imperative `addTracks()` API for dynamic loading (drag-and-drop, file pickers). * * Placeholder tracks appear instantly while audio decodes in parallel. */ /** A source that can be decoded into a track. */ type TrackSource = File | Blob | string | { src: string; name?: string; }; /** Info about a track that failed to load. */ interface TrackLoadError { /** Display name of the source that failed. */ name: string; /** The underlying error. */ error: Error; } interface UseDynamicTracksReturn { /** * Current tracks array (placeholders + loaded). Pass to WaveformPlaylistProvider. * Placeholder tracks have `clips: []` and names ending with " (loading...)". */ tracks: ClipTrack[]; /** Add one or more sources — creates placeholder tracks immediately. */ addTracks: (sources: TrackSource[]) => void; /** Remove a track by its id. Aborts in-flight fetch/decode if still loading. */ removeTrack: (trackId: string) => void; /** Number of sources currently decoding. */ loadingCount: number; /** True when any source is still decoding. */ isLoading: boolean; /** Tracks that failed to load (removed from `tracks` automatically). */ errors: TrackLoadError[]; } declare function useDynamicTracks(): UseDynamicTracksReturn; /** * Hook for monitoring master output levels * * Connects an AudioWorklet meter processor to the Destination node for * real-time output level monitoring. Computes sample-accurate peak and * RMS via the meter worklet — no transient is missed. * * IMPORTANT: Uses getGlobalContext() from playout to ensure the meter * is created on the same AudioContext as the audio engine. Tone.js's * getContext()/getDestination() return the DEFAULT context, which is * replaced when getGlobalContext() calls setContext() on first audio init. */ interface UseOutputMeterOptions { /** * Number of channels to meter. * Default: 2 (stereo output) */ channelCount?: number; /** * How often to update the levels (in Hz). * Default: 60 (60fps) */ updateRate?: number; /** * Whether audio is currently playing. When this transitions to false, * all levels (current, peak, RMS) and smoothed state are reset to zero. * Without this, the browser's tail-time optimization stops calling the * worklet's process() when no audio flows, leaving the last non-zero * levels frozen in state. * Default: false */ isPlaying?: boolean; } interface UseOutputMeterReturn { /** Per-channel peak output levels (0-1) */ levels: number[]; /** Per-channel held peak levels (0-1) */ peakLevels: number[]; /** Per-channel RMS output levels (0-1) */ rmsLevels: number[]; /** Reset all held peak levels to 0 */ resetPeak: () => void; /** Error from meter setup (worklet load failure, context issues, etc.) */ error: Error | null; } declare function useOutputMeter(options?: UseOutputMeterOptions): UseOutputMeterReturn; /** * Factory for creating Tone.js effect instances from effect definitions */ interface EffectInstance { effect: ToneAudioNode | AudioNode; id: string; instanceId: string; dispose: () => void; setParameter: (name: string, value: number | string | boolean) => void; getParameter: (name: string) => number | string | boolean | undefined; connect: (destination: InputNode) => void; disconnect: () => void; } /** * Create an effect instance from a definition with initial parameter values */ declare function createEffectInstance(definition: EffectDefinition, initialParams?: Record): EffectInstance; /** * Create a chain of effects connected in series */ declare function createEffectChain(effects: EffectInstance[]): { input: ToneAudioNode | AudioNode; output: ToneAudioNode | AudioNode; dispose: () => void; }; interface ExportWavButtonProps { /** Button label */ label?: string; /** Filename for the downloaded file (without extension) */ filename?: string; /** Export mode: 'master' for stereo mix, 'individual' for single track */ mode?: 'master' | 'individual'; /** Track index for individual export */ trackIndex?: number; /** Bit depth: 16 or 32 */ bitDepth?: 16 | 32; /** Whether to apply effects (fades, etc.) - defaults to true */ applyEffects?: boolean; /** * Optional effects function for master effects. When provided, export renders * through the effects chain (WAM entries included). May be async. */ effectsFunction?: OfflineEffectsFunction; /** * Optional function to create offline track effects. * Takes a trackId and returns an offline effects function for that track. */ createOfflineTrackEffects?: (trackId: string) => OfflineTrackEffectsFunction | undefined; /** CSS class name */ className?: string; /** Callback when export completes */ onExportComplete?: (blob: Blob) => void; /** Callback when export fails */ onExportError?: (error: Error) => void; } declare const ExportWavButton: React__default.FC; interface WamEffectGuiProps { /** Live plugin handle from getWamPlugin/getTrackWamPlugin. */ plugin: WamPluginInstance | undefined; className?: string; } /** * Mounts a WAM plugin's own GUI (plugin.createGui), falling back to the * generic parameter panel from @dawcore/wam for headless plugins. The GUI is * destroyed on unmount — GUI and audio lifecycles are independent, so this * never interrupts sound. */ declare const WamEffectGui: React__default.FC; /** * Dynamic loader for the optional '@dawcore/wam' peer (the @dawcore/midi * loadMidiImpl pattern). Keeps WAM hosting out of the bundle for consumers * that never use it; `import type` from '@dawcore/wam' elsewhere is fine * (erased at runtime). */ type WamModule = typeof _dawcore_wam; declare function loadWamModule(): Promise; interface WamEffectInstance extends EffectInstance { kind: 'wam'; plugin: WamPluginInstance; url?: string; } declare function createWamEffectInstance(plugin: WamPluginInstance): WamEffectInstance; export { type ActiveEffect, type AudioTrackConfig, type EffectDefinition, type EffectInstance, type EffectParameter, type ExportOptions, type ExportResult, ExportWavButton, type ExportWavButtonProps, type OfflineEffectsCleanup, type OfflineEffectsFunction, type OfflineTrackEffectsFunction, type ParameterType, type TrackActiveEffect, type TrackEffectsState, type TrackLoadError, type TrackSource, type UseDynamicEffectsReturn, type UseDynamicTracksReturn, type UseExportWavReturn, type UseOutputMeterOptions, type UseOutputMeterReturn, type UseTrackDynamicEffectsReturn, WamEffectGui, type WamEffectGuiProps, type WamEffectInstance, createEffectChain, createEffectInstance, createWamEffectInstance, effectCategories, effectDefinitions, getEffectDefinition, getEffectsByCategory, loadWamModule, useAudioTracks, useDynamicEffects, useDynamicTracks, useExportWav, useMasterAnalyser, useOutputMeter, useTrackDynamicEffects };