import { Beat } from './beat';
import { Connectable } from './interfaces/connectable';
import { Playable } from './interfaces/playable';
import { SamplerOptions, Sampler } from './sampler';
import { BeatTrackEventMap } from './events/event-types';
export interface BeatTrackOptions extends SamplerOptions {
    numBeats?: number;
    duration?: number;
    /**
     * @method wrapWith
     * wrapWith allows you to run a function on each beat as it is created
     * This function must accept a beat and return a beat. An example use-case
     * appears in the docs site in the "Multisampled Drum Machine" example where
     * this method is used to wrap each beat in an nx-js observable proxy.
     *
     * @param beat
     * @returns
     */
    wrapWith?: (beat: Beat) => Beat;
}
/**
 * Drum machine lane with rhythmic beat patterns.
 *
 * BeatTrack manages an array of Beat instances for creating drum patterns.
 * It extends Sampler for round-robin sample variation and adds tempo-synced
 * playback with beat events for visual synchronization.
 *
 * @example
 * ```typescript
 * import { createBeatTrack } from 'ez-web-audio'
 *
 * const kick = await createBeatTrack(['kick.mp3'], { numBeats: 8 })
 *
 * // Set a basic 4-on-the-floor pattern
 * kick.beats[0].active = true  // beat 1
 * kick.beats[2].active = true  // beat 3
 * kick.beats[4].active = true  // beat 5
 * kick.beats[6].active = true  // beat 7
 *
 * kick.playBeats(120, 1/4) // Play quarter notes at 120 BPM
 *
 * // Listen for beat events
 * kick.on('beat', (e) => {
 *   console.log(`Beat ${e.detail.beatIndex}`)
 * })
 * ```
 */
export declare class BeatTrack extends Sampler {
    private audioContext;
    private eventTarget;
    private scheduleAheadTime;
    private schedulerInterval;
    private nextBeatTime;
    private currentBeatIndex;
    private timerID;
    private currentTempo;
    private noteType;
    private pausedBeatIndex;
    private pausedBeatTime;
    constructor(audioContext: AudioContext, sounds: (Playable & Connectable)[], opts?: BeatTrackOptions);
    /**
     * Optional function to wrap each beat as it's created (e.g., with observables).
     * @internal
     */
    private wrapWith?;
    /**
     * Number of beats in this track.
     * @default 4
     */
    numBeats: number;
    /**
     * How long (in milliseconds) the `isPlaying` flag stays true after a beat plays.
     * Useful for visual feedback in the UI.
     * @default 100
     */
    duration: number;
    /**
     * Array of Beat instances in this track.
     *
     * The array length always matches `numBeats`. Beats are reused when the
     * count changes, preserving their `active` state.
     *
     * @example
     * ```typescript
     * // Toggle individual beats
     * track.beats[0].active = true
     * track.beats[1].active = false
     *
     * // Check all beat states
     * track.beats.forEach((beat, i) => {
     *   console.log(`Beat ${i}: ${beat.active ? 'on' : 'off'}`)
     * })
     * ```
     */
    get beats(): Beat[];
    /**
     * Start playing all beats in the pattern continuously.
     *
     * Starts a lookahead scheduler that triggers beats at precise audio times.
     * Emits 'beat' events for UI synchronization.
     *
     * @param bpm - Tempo in beats per minute
     * @param noteType - Rhythmic length of each beat (e.g., 1/4 for quarter notes, 1/8 for eighths)
     *
     * @example
     * ```typescript
     * track.playBeats(120, 1/4)  // 120 BPM, quarter notes
     * track.playBeats(140, 1/8)  // 140 BPM, eighth notes
     * ```
     */
    playBeats(bpm: number, noteType: number): void;
    /**
     * Start playing only active beats in the pattern continuously.
     *
     * Same as playBeats(), but only plays beats where `active === true`.
     * Inactive beats become rests (silence), maintaining timing.
     *
     * @param bpm - Tempo in beats per minute
     * @param noteType - Rhythmic length of each beat/rest
     *
     * @example
     * ```typescript
     * // Set up a pattern with rests
     * track.beats[0].active = true
     * track.beats[2].active = true
     * track.playActiveBeats(120, 1/4)  // Only beats 0 and 2 play
     * ```
     */
    playActiveBeats(bpm: number, noteType: number): void;
    /**
     * Stop playback and reset to the beginning.
     *
     * Emits a 'stop' event. Use pause() instead if you want to resume later.
     *
     * @example
     * ```typescript
     * track.stop()
     * track.on('stop', () => console.log('Stopped'))
     * ```
     */
    stop(): void;
    /**
     * Pause playback at the current position.
     *
     * Emits a 'pause' event with the current beat index.
     * Use resume() to continue from where you left off.
     *
     * @example
     * ```typescript
     * track.pause()
     * // later...
     * track.resume()
     * ```
     */
    pause(): void;
    /**
     * Resume playback from where it was paused.
     *
     * Emits a 'resume' event with the beat index where playback resumes.
     * Has no effect if not paused.
     *
     * @example
     * ```typescript
     * track.pause()
     * // ...user clicks play button...
     * track.resume() // continues from paused position
     * ```
     */
    resume(): void;
    /**
     * Change the tempo while playing.
     *
     * The new tempo takes effect on the next scheduled beat.
     *
     * @param bpm - New tempo in beats per minute
     *
     * @example
     * ```typescript
     * track.playBeats(120, 1/4)
     * // later, speed up...
     * track.setTempo(140)
     * ```
     */
    setTempo(bpm: number): void;
    /**
     * Lookahead scheduler that schedules beats 100ms ahead.
     * @internal
     */
    private scheduler;
    /**
     * Schedule a single beat and emit the beat event.
     * @internal
     */
    private scheduleBeat;
    /**
     * Advance to the next beat in the pattern using current tempo.
     * @internal
     */
    private advanceToNextBeat;
    /**
     * The underlying method for playing beats at calculated intervals.
     * @internal
     */
    protected callPlayMethodOnBeats(method: 'ifActivePlayIn' | 'playIn', bpm: number, noteType?: number): void;
    /**
     * Emit a typed event with the given detail.
     * @internal
     */
    protected emit<K extends keyof BeatTrackEventMap>(type: K, detail: BeatTrackEventMap[K]['detail']): void;
    /**
     * Add a typed event listener for BeatTrack lifecycle events.
     *
     * @param type - Event type: 'beat', 'stop', 'pause', 'resume'
     * @param listener - Handler function
     * @param options - Standard addEventListener options
     */
    addEventListener<K extends keyof BeatTrackEventMap>(type: K, listener: (event: BeatTrackEventMap[K]) => void, options?: boolean | AddEventListenerOptions): void;
    /**
     * Remove a typed event listener.
     *
     * @param type - Event type to unsubscribe from
     * @param listener - Handler function to remove
     * @param options - Standard removeEventListener options
     */
    removeEventListener<K extends keyof BeatTrackEventMap>(type: K, listener: (event: BeatTrackEventMap[K]) => void, options?: boolean | EventListenerOptions): void;
    /**
     * Subscribe to an event. Supports chaining.
     *
     * @param type - Event type: 'beat', 'stop', 'pause', 'resume'
     * @param listener - Handler function
     * @returns this for chaining
     *
     * @example
     * ```typescript
     * track.on('beat', (e) => {
     *   console.log(`Beat ${e.detail.beatIndex}`)
     *   highlightBeat(e.detail.beatIndex)
     * }).on('stop', () => {
     *   console.log('Stopped')
     * })
     * ```
     */
    on<K extends keyof BeatTrackEventMap>(type: K, listener: (event: BeatTrackEventMap[K]) => void): this;
    /**
     * Unsubscribe from an event. Supports chaining.
     *
     * @param type - Event type to unsubscribe from
     * @param listener - Handler function to remove
     * @returns this for chaining
     */
    off<K extends keyof BeatTrackEventMap>(type: K, listener: (event: BeatTrackEventMap[K]) => void): this;
    /**
     * Subscribe to an event once. Handler is removed after first invocation.
     *
     * @param type - Event type to listen for
     * @param listener - Handler function (called only once)
     * @returns this for chaining
     *
     * @example
     * ```typescript
     * track.once('stop', () => {
     *   console.log('Track stopped for the first time')
     * })
     * ```
     */
    once<K extends keyof BeatTrackEventMap>(type: K, listener: (event: BeatTrackEventMap[K]) => void): this;
}
//# sourceMappingURL=beat-track.d.ts.map