UNPKG

ez-web-audio

Version:

Making the Web Audio API super EZ since 2024.

230 lines 8.26 kB
import { TimeObject } from './utils/create-time-object'; import { ControlType, RampType } from './controllers/base-param-controller'; import { OscillatorController } from './controllers/oscillator-controller'; import { BaseSoundOptions, BaseSound } from './base-sound'; import { EnvelopeOptions } from './envelope'; /** * Filter configuration for oscillator frequency shaping. */ export interface OscillatorOptsFilterValues { /** Filter cutoff frequency in Hz. */ frequency?: number; /** Filter Q factor (resonance). Higher values create more pronounced peaks. */ q?: number; } /** * Configuration options for creating an Oscillator. * * @example * ```typescript * const opts: OscillatorOpts = { * frequency: 440, // A4 * type: 'sawtooth', // Rich harmonic content * gain: 0.5, // Half volume * lowpass: { // Filter out harsh highs * frequency: 2000, * q: 1 * }, * envelope: { // ADSR for note shaping * attack: 0.01, * decay: 0.2, * sustain: 0.5, * release: 0.3 * } * } * ``` */ export interface OscillatorOpts extends BaseSoundOptions { /** Starting offset in seconds (rarely used for oscillators). */ startOffset?: number; /** Base frequency in Hz (default: 440). */ frequency?: number; /** Detune in cents (100 cents = 1 semitone). */ detune?: number; /** Initial gain/volume (0-1). */ gain?: number; /** Waveform type: 'sine', 'square', 'sawtooth', or 'triangle'. */ type?: OscillatorType; /** Highpass filter - removes frequencies below cutoff. */ highpass?: OscillatorOptsFilterValues; /** Bandpass filter - allows frequencies near cutoff, attenuates others. */ bandpass?: OscillatorOptsFilterValues; /** Lowpass filter - removes frequencies above cutoff. */ lowpass?: OscillatorOptsFilterValues; /** Lowshelf filter - boosts/cuts frequencies below cutoff. */ lowshelf?: OscillatorOptsFilterValues; /** Highshelf filter - boosts/cuts frequencies above cutoff. */ highshelf?: OscillatorOptsFilterValues; /** Peaking filter - boosts/cuts frequencies around cutoff. */ peaking?: OscillatorOptsFilterValues; /** Notch filter - attenuates frequencies at cutoff. */ notch?: OscillatorOptsFilterValues; /** Allpass filter - shifts phase without changing amplitude. */ allpass?: OscillatorOptsFilterValues; /** ADSR envelope for amplitude shaping. */ envelope?: EnvelopeOptions; } /** * Synthesizer that generates audio from oscillator waveforms. * * Oscillator creates sound from scratch using sine, square, sawtooth, or triangle * waves. Supports ADSR envelopes for professional-quality synthesis, filters for * tone shaping, and all the gain/pan controls from {@link BaseSound}. * * Unlike {@link Sound} which plays pre-recorded audio, Oscillator generates audio * in real-time. Oscillators have infinite duration and must be explicitly stopped. * * @example * ```typescript * import { createOscillator } from 'ez-web-audio' * * // Simple sine wave at 440Hz (A4) * const synth = await createOscillator({ frequency: 440, type: 'sine' }) * synth.play() * setTimeout(() => synth.stop(), 500) * * // With ADSR envelope for piano-like decay * const piano = await createOscillator({ * frequency: 440, * type: 'triangle', * envelope: { attack: 0.01, decay: 0.1, sustain: 0.7, release: 0.3 } * }) * piano.play() * setTimeout(() => piano.stop(), 500) // Release phase plays after stop * * // With lowpass filter * const muted = await createOscillator({ * frequency: 440, * type: 'sawtooth', * lowpass: { frequency: 800, q: 1 } * }) * muted.play() * ``` */ export declare class Oscillator extends BaseSound { /** The underlying OscillatorNode that generates the audio signal. */ audioSourceNode: OscillatorNode; /** Array of BiquadFilterNodes for frequency filtering. */ private filters; /** Oscillator waveform type (sine, square, sawtooth, triangle). */ private type; /** Base frequency in Hz. */ protected freq: number; /** Controller for managing gain, pan, frequency, and detune parameters. */ protected controller: OscillatorController; /** Optional ADSR envelope for amplitude shaping. */ private envelope?; /** * Create an Oscillator instance. * * Note: Use {@link createOscillator} factory function instead of calling this directly. * * @param audioContext - The AudioContext to use for audio operations * @param options - Oscillator configuration (frequency, type, filters, envelope) */ constructor(audioContext: AudioContext, options?: OscillatorOpts); /** * Schedule a parameter value to be set when play() is called. * * Oscillator supports additional parameters beyond Sound: * - 'gain': Volume level (0-1) * - 'pan': Stereo position (-1 to 1) * - 'frequency': Oscillator frequency in Hz * - 'detune': Detune in cents * * @param type - The parameter to control * @returns Fluent builder for setting value and timing * * @example * ```typescript * // Start at frequency 220, glide up to 440 over 0.5 seconds * osc.onPlaySet('frequency').to(220).at(0) * osc.onPlaySet('frequency').to(440).endingAt(0.5, 'linear') * osc.play() * ``` */ onPlaySet(type: ControlType): { to: (value: number) => { at: (time: number) => void; endingAt: (time: number, rampType?: RampType) => void; }; }; /** * Schedule a parameter ramp when play() is called. * * @param type - The parameter to ramp ('gain', 'pan', 'frequency', 'detune') * @param rampType - Type of ramp curve ('linear' or 'exponential') * @returns Fluent builder for setting start value, end value, and duration * * @example * ```typescript * // Vibrato effect: ramp frequency up and down * osc.onPlayRamp('frequency', 'linear').from(440).to(450).in(0.1) * osc.play() * ``` */ onPlayRamp(type: ControlType, rampType?: RampType): { from: (startValue: number) => { to: (endValue: number) => { in: (endTime: number) => void; }; }; }; /** * Set up a fresh OscillatorNode for playback. * Called automatically before each play() since OscillatorNode is single-use. * @protected */ protected setup(): void; /** * Wire oscillator through filters and connections to effect chain. * @protected */ protected wireConnections(): void; /** * Get the duration of the oscillator. * * Oscillators have no inherent duration - they play indefinitely until stopped. * Returns Infinity to indicate continuous playback, distinguishing from finite * Sound/Track durations. * * @example * ```typescript * const osc = await createOscillator({ frequency: 440 }) * console.log(osc.duration.raw) // Infinity * * // Oscillators must be explicitly stopped * osc.play() * setTimeout(() => osc.stop(), 1000) * ``` */ get duration(): TimeObject; /** * Stop the oscillator. * * If an ADSR envelope is configured, triggers the release phase and schedules * the actual stop after the release completes. This ensures the release tail * plays fully rather than being cut off abruptly. * * Note: stopAt() and stopIn() bypass the envelope release phase. For scheduled * stops with proper release, use the regular stop() method. * * @example * ```typescript * // Without envelope - stops immediately * const simple = await createOscillator({ frequency: 440 }) * simple.play() * await simple.stop() // Immediate stop * * // With envelope - release phase plays * const piano = await createOscillator({ * frequency: 440, * envelope: { attack: 0.01, decay: 0.1, sustain: 0.7, release: 0.5 } * }) * piano.play() * await piano.stop() // Fades out over 0.5 seconds * ``` */ stop(): Promise<void>; } //# sourceMappingURL=oscillator.d.ts.map