import type { BungeePitchShiftConfig, PitchShiftParams, BungeeInfo, EventListener, IBungeePitchShift } from './types'; /** * BungeePitchShift - High-quality pitch shifting and time stretching for Web Audio API * * Provides professional-grade pitch shifting and time stretching using the Bungee * phase vocoder algorithm compiled to WebAssembly. Runs in an AudioWorklet for * low-latency, glitch-free processing in the audio thread. * * ## Features * - Independent pitch shifting (±2 octaves) and time stretching (0.25x-4x) * - Low latency (~40ms algorithmic delay) * - High audio quality using phase vocoder technology * - Real-time parameter updates without audio discontinuities * - Efficient WebAssembly implementation * - Built-in dry/wet mixing * * ## Usage Pattern * 1. Create instance with {@link BungeePitchShift.create} * 2. Connect to Web Audio graph via {@link node} property * 3. Control parameters with {@link setPitch}, {@link setSpeed}, {@link setMix} * 4. Clean up with {@link dispose} when done * * @example * Basic usage: * ```typescript * const audioContext = new AudioContext(); * const pitchShift = await BungeePitchShift.create(audioContext, { * workletPath: '/bungee-processor.js' * }); * * // Connect to audio graph * sourceNode.connect(pitchShift.node); * pitchShift.connect(audioContext.destination); * * // Control parameters * pitchShift.setPitch(5); // +5 semitones (perfect fourth up) * pitchShift.setSpeed(1.2); // 20% faster * pitchShift.setMix(0.8); // 80% wet, 20% dry * * // Cleanup when done * pitchShift.dispose(); * ``` * * @example * Listening to events: * ```typescript * pitchShift.addEventListener((event) => { * if (event.type === 'initialized') { * console.log(`Bungee v${event.info.version} ready`); * console.log(`Latency: ${event.info.latency} samples`); * } else if (event.type === 'error') { * console.error('Pitch shift error:', event.message); * } * }); * ``` */ export declare class BungeePitchShift implements IBungeePitchShift { private _node; private _audioContext; private _initialized; private _params; private _info; private _eventListeners; private _config; /** * Private constructor - use BungeePitchShift.create() instead */ private constructor(); /** * Create and initialize a new BungeePitchShift instance * * This is the main entry point for creating a pitch shifter. The method is * asynchronous because it loads the AudioWorklet processor and WASM module. * * @param audioContext - Web Audio API AudioContext (must be in 'running' state) * @param config - Configuration options for paths and initial parameters * @returns Promise that resolves to initialized BungeePitchShift instance * * @throws {Error} If AudioWorklet module fails to load (check workletPath) * @throws {Error} If WASM module fails to load (check wasmPath/wasmBinaryPath) * @throws {DOMException} If AudioContext is in 'closed' state * * @example * Basic creation with defaults: * ```typescript * const audioContext = new AudioContext(); * await audioContext.resume(); // Ensure context is running * * const pitchShift = await BungeePitchShift.create(audioContext); * ``` * * @example * Custom configuration: * ```typescript * const pitchShift = await BungeePitchShift.create(audioContext, { * workletPath: '/audio-worklets/bungee-processor.js', * wasmPath: 'https://cdn.example.com/bungee-wasm.js', * initialPitch: 2, // Start with +2 semitones * initialSpeed: 1.0, // Normal speed * initialMix: 0.7 // 70% wet * }); * ``` * * @example * Error handling: * ```typescript * try { * const pitchShift = await BungeePitchShift.create(audioContext); * } catch (error) { * console.error('Failed to initialize pitch shifter:', error); * // Handle error - maybe show user a message or fall back to no processing * } * ``` */ static create(audioContext: AudioContext, config?: BungeePitchShiftConfig): Promise; /** * Initialize the AudioWorklet */ private _initialize; /** * Handle messages from the AudioWorklet processor */ private _handleWorkletMessage; /** * Send a message to the AudioWorklet processor */ private _sendMessage; /** * Emit an event to all listeners */ private _emitEvent; /** * Get the AudioWorkletNode for connecting to the audio graph * * This node can be connected like any other Web Audio API node. * Connect audio sources to this node's input, and connect this node's * output to your destination or other effects. * * @returns The underlying AudioWorkletNode * * @throws {Error} If accessed before initialization completes * * @example * ```typescript * const pitchShift = await BungeePitchShift.create(audioContext); * * // Connect source -> pitch shifter -> destination * sourceNode.connect(pitchShift.node); * pitchShift.node.connect(audioContext.destination); * * // Or use the convenience method: * sourceNode.connect(pitchShift.node); * pitchShift.connect(audioContext.destination); * ``` */ get node(): AudioWorkletNode; /** * Check if the pitch shifter is initialized */ get initialized(): boolean; /** * Get current parameters */ get params(): Readonly; /** * Get Bungee library information */ get info(): Readonly; /** * Set pitch shift in semitones * * @param semitones - Pitch shift (-12 to +12 typical range) * * @example * ```typescript * pitchShift.setPitch(5); // +5 semitones (perfect fourth up) * pitchShift.setPitch(-12); // -12 semitones (one octave down) * ``` */ setPitch(semitones: number): void; /** * Set playback speed * * @param speed - Playback speed (0.5 to 2.0 typical range) * * @example * ```typescript * pitchShift.setSpeed(1.5); // 50% faster * pitchShift.setSpeed(0.75); // 25% slower * ``` */ setSpeed(speed: number): void; /** * Set wet/dry mix * * @param mix - Mix amount (0 = dry, 1 = wet) * * @example * ```typescript * pitchShift.setMix(1.0); // 100% wet (fully processed) * pitchShift.setMix(0.5); // 50/50 mix * pitchShift.setMix(0.0); // 100% dry (bypass) * ``` */ setMix(mix: number): void; /** * Reset the internal state (useful for seeking in audio playback) * * @example * ```typescript * // When seeking to a new position: * pitchShift.reset(); * ``` */ reset(): void; /** * Connect the pitch shifter to another audio node * * @param destination - Audio node to connect to * * @example * ```typescript * pitchShift.connect(audioContext.destination); * pitchShift.connect(reverbNode); * ``` */ connect(destination: AudioNode): void; /** * Disconnect from all connected nodes, or from a specific node * * @param destination - Optional specific node to disconnect from */ disconnect(destination?: AudioNode): void; /** * Add an event listener * * @param listener - Callback function to handle events * * @example * ```typescript * pitchShift.addEventListener((event) => { * if (event.type === 'initialized') { * console.log('Bungee version:', event.info.version); * } * }); * ``` */ addEventListener(listener: EventListener): void; /** * Remove an event listener * * @param listener - Callback function to remove */ removeEventListener(listener: EventListener): void; /** * Dispose and clean up resources * * Call this when you're done using the pitch shifter. * * @example * ```typescript * pitchShift.dispose(); * ``` */ dispose(): void; } //# sourceMappingURL=BungeePitchShift.d.ts.map