/** * Effect commands for undo/redo system */ import { BaseCommand } from '../command'; export class EffectCommand extends BaseCommand { private originalBuffer: AudioBuffer; private modifiedBuffer: AudioBuffer; private applyCallback: (buffer: AudioBuffer) => void; private description: string; constructor( originalBuffer: AudioBuffer, modifiedBuffer: AudioBuffer, applyCallback: (buffer: AudioBuffer) => void, description: string ) { super(); this.originalBuffer = originalBuffer; this.modifiedBuffer = modifiedBuffer; this.applyCallback = applyCallback; this.description = description; } getDescription(): string { return this.description; } execute(): void { this.applyCallback(this.modifiedBuffer); } undo(): void { this.applyCallback(this.originalBuffer); } redo(): void { this.execute(); } } /** * Factory function to create effect commands */ export function createEffectCommand( originalBuffer: AudioBuffer, effectFunction: (buffer: AudioBuffer) => AudioBuffer | Promise, applyCallback: (buffer: AudioBuffer) => void, description: string ): EffectCommand { const result = effectFunction(originalBuffer); const modifiedBuffer = result instanceof Promise ? originalBuffer : result; return new EffectCommand(originalBuffer, modifiedBuffer, applyCallback, description); } /** * Factory function to create async effect commands */ export async function createAsyncEffectCommand( originalBuffer: AudioBuffer, effectFunction: (buffer: AudioBuffer) => Promise, applyCallback: (buffer: AudioBuffer) => void, description: string ): Promise { const modifiedBuffer = await effectFunction(originalBuffer); return new EffectCommand(originalBuffer, modifiedBuffer, applyCallback, description); } /** * Factory for gain effect command */ export function createGainCommand( buffer: AudioBuffer, gainValue: number, applyCallback: (buffer: AudioBuffer) => void ): EffectCommand { return createEffectCommand( buffer, (buf) => { // Import will happen at runtime const { applyGain } = require('@/lib/audio/effects/gain'); return applyGain(buf, gainValue); }, applyCallback, `Apply Gain (${gainValue.toFixed(2)}x)` ); } /** * Factory for normalize peak command */ export function createNormalizePeakCommand( buffer: AudioBuffer, targetPeak: number, applyCallback: (buffer: AudioBuffer) => void ): EffectCommand { return createEffectCommand( buffer, (buf) => { const { normalizePeak } = require('@/lib/audio/effects/normalize'); return normalizePeak(buf, targetPeak); }, applyCallback, `Normalize to Peak (${targetPeak.toFixed(2)})` ); } /** * Factory for normalize RMS command */ export function createNormalizeRMSCommand( buffer: AudioBuffer, targetRMS: number, applyCallback: (buffer: AudioBuffer) => void ): EffectCommand { return createEffectCommand( buffer, (buf) => { const { normalizeRMS } = require('@/lib/audio/effects/normalize'); return normalizeRMS(buf, targetRMS); }, applyCallback, `Normalize to RMS (${targetRMS.toFixed(2)})` ); } /** * Factory for fade in command */ export function createFadeInCommand( buffer: AudioBuffer, duration: number, applyCallback: (buffer: AudioBuffer) => void ): EffectCommand { return createEffectCommand( buffer, (buf) => { const { applyFadeIn } = require('@/lib/audio/effects/fade'); return applyFadeIn(buf, duration); }, applyCallback, `Fade In (${duration.toFixed(2)}s)` ); } /** * Factory for fade out command */ export function createFadeOutCommand( buffer: AudioBuffer, duration: number, applyCallback: (buffer: AudioBuffer) => void ): EffectCommand { return createEffectCommand( buffer, (buf) => { const { applyFadeOut } = require('@/lib/audio/effects/fade'); return applyFadeOut(buf, duration); }, applyCallback, `Fade Out (${duration.toFixed(2)}s)` ); } /** * Factory for reverse command */ export function createReverseCommand( buffer: AudioBuffer, applyCallback: (buffer: AudioBuffer) => void ): EffectCommand { return createEffectCommand( buffer, (buf) => { const { reverseAudio } = require('@/lib/audio/effects/reverse'); return reverseAudio(buf); }, applyCallback, 'Reverse Audio' ); } /** * Factory for low-pass filter command */ export async function createLowPassFilterCommand( buffer: AudioBuffer, frequency: number, Q: number, applyCallback: (buffer: AudioBuffer) => void ): Promise { return createAsyncEffectCommand( buffer, async (buf) => { const { applyLowPassFilter } = require('@/lib/audio/effects/filters'); return await applyLowPassFilter(buf, frequency, Q); }, applyCallback, `Low-Pass Filter (${frequency}Hz)` ); } /** * Factory for high-pass filter command */ export async function createHighPassFilterCommand( buffer: AudioBuffer, frequency: number, Q: number, applyCallback: (buffer: AudioBuffer) => void ): Promise { return createAsyncEffectCommand( buffer, async (buf) => { const { applyHighPassFilter } = require('@/lib/audio/effects/filters'); return await applyHighPassFilter(buf, frequency, Q); }, applyCallback, `High-Pass Filter (${frequency}Hz)` ); } /** * Factory for band-pass filter command */ export async function createBandPassFilterCommand( buffer: AudioBuffer, frequency: number, Q: number, applyCallback: (buffer: AudioBuffer) => void ): Promise { return createAsyncEffectCommand( buffer, async (buf) => { const { applyBandPassFilter } = require('@/lib/audio/effects/filters'); return await applyBandPassFilter(buf, frequency, Q); }, applyCallback, `Band-Pass Filter (${frequency}Hz)` ); }