/** * Convenience wrapper over DynamicZeroCrossing.snap for callers that prefer a * plain function. * @param {Float32Array} audioData * @param {number} startSample * @param {number} endSample * @param {number} [searchWindow=441] * @returns {[number, number]} [snappedStart, snappedEnd] */ export function snapToZeroCrossings(audioData: Float32Array, startSample: number, endSample: number, searchWindow?: number): [number, number]; export { calculateBeatAlignment } from "../scripts/musical-timing.js"; /** * Dynamic Zero Crossing with Micro Crossfades. * Maintains musical accuracy while ensuring clean audio boundaries. * All-static API: use `DynamicZeroCrossing.snap(...)` / `.optimizeLoopBoundaries(...)`. */ export class DynamicZeroCrossing { /** * Find optimal loop boundaries with zero crossing alignment * @param {Float32Array} audioData - Raw audio samples * @param {Object} musicalLoop - { start: 0-1, end: 0-1 } musical loop points * @param {number} sampleRate - Audio sample rate * @returns {Object} - Optimized loop with crossfade data */ static optimizeLoopBoundaries(audioData: Float32Array, musicalLoop: any, sampleRate: number): any; /** * Find nearest zero crossing within search window * @param {Float32Array} audioData - Audio samples * @param {number} centerSample - Target sample position * @param {number} searchWindow - Samples to search around center * @returns {Object} - { sample: number, confidence: number, distanceFromMusical: number } */ static findNearestZeroCrossing(audioData: Float32Array, centerSample: number, searchWindow: number): any; /** * Generate crossfade data for smooth loop transitions * @param {Object} crossfadeInfo - Crossfade configuration ({ crossfadeDuration }) * @returns {{ fadeIn: Float32Array, fadeOut: Float32Array, length: number }} */ static generateMicroCrossfade(crossfadeInfo: any): { fadeIn: Float32Array; fadeOut: Float32Array; length: number; }; /** * Snap raw start/end sample indices to the nearest zero-crossing within * ±searchWindow samples. * * @param {Float32Array} audioData * @param {number} startSample initial start index (samples) * @param {number} endSample initial end index (samples) * @param {number} [searchWindow=441] - window half-width in samples (≈10 ms @ 44.1 kHz) * @returns {[number, number]} [snappedStart, snappedEnd] sample indices */ static snap(audioData: Float32Array, startSample: number, endSample: number, searchWindow?: number): [number, number]; } /** * Pleco-XA Loop Controller — dynamic loop manipulation with configurable * constraints. Pure state, environment-agnostic, result-object API. * Positions are normalized 0..1 over the buffer duration. */ export class LoopController { constructor(options?: {}); minLoopDuration: any; audioBuffer: AudioBuffer; currentLoop: { start: number; end: number; }; /** * Set minimum loop duration * @param {number} durationSeconds - Minimum loop duration in seconds (e.g. 0.001 for 1ms) */ setMinLoopDuration(durationSeconds: number): void; /** * Set audio buffer for loop calculations * @param {AudioBuffer} audioBuffer - Web Audio API AudioBuffer */ setAudioBuffer(audioBuffer: AudioBuffer): void; /** * Halve the current loop duration * @returns {Object} - { success: boolean, loop: Object, reason?: string } */ halfLoop(): any; /** * Double the current loop duration (symmetric to halfLoop). * The end is clamped to the buffer end (1.0); if the loop is already at the * maximum extent, the call fails with a reason. * @returns {Object} - { success: boolean, loop: Object, reason?: string, clamped?: boolean } */ doubleLoop(): any; /** * Move loop forward by its current duration * @returns {Object} - { success: boolean, loop: Object, reason?: string } */ moveLoopForward(): any; /** * Reset loop to full audio duration * @returns {Object} - { success: boolean, loop: Object } */ resetLoop(): any; /** * Get current loop boundaries * @returns {Object} - { start: number, end: number } */ getCurrentLoop(): any; /** * Set custom loop boundaries * @param {number} start - Start position (0-1) * @param {number} end - End position (0-1) * @returns {Object} - { success: boolean, loop: Object, reason?: string } */ setLoop(start: number, end: number): any; }