156 lines
3.4 KiB
TypeScript
156 lines
3.4 KiB
TypeScript
|
|
/**
|
||
|
|
* Edit commands for audio buffer operations
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { BaseCommand } from '../command';
|
||
|
|
import type { Selection } from '@/types/selection';
|
||
|
|
import {
|
||
|
|
extractBufferSegment,
|
||
|
|
deleteBufferSegment,
|
||
|
|
insertBufferSegment,
|
||
|
|
trimBuffer,
|
||
|
|
} from '@/lib/audio/buffer-utils';
|
||
|
|
|
||
|
|
export type EditCommandType = 'cut' | 'delete' | 'paste' | 'trim';
|
||
|
|
|
||
|
|
export interface EditCommandParams {
|
||
|
|
type: EditCommandType;
|
||
|
|
beforeBuffer: AudioBuffer;
|
||
|
|
afterBuffer: AudioBuffer;
|
||
|
|
selection?: Selection;
|
||
|
|
clipboardData?: AudioBuffer;
|
||
|
|
pastePosition?: number;
|
||
|
|
onApply: (buffer: AudioBuffer) => void;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Command for edit operations (cut, delete, paste, trim)
|
||
|
|
*/
|
||
|
|
export class EditCommand extends BaseCommand {
|
||
|
|
private type: EditCommandType;
|
||
|
|
private beforeBuffer: AudioBuffer;
|
||
|
|
private afterBuffer: AudioBuffer;
|
||
|
|
private selection?: Selection;
|
||
|
|
private clipboardData?: AudioBuffer;
|
||
|
|
private pastePosition?: number;
|
||
|
|
private onApply: (buffer: AudioBuffer) => void;
|
||
|
|
|
||
|
|
constructor(params: EditCommandParams) {
|
||
|
|
super();
|
||
|
|
this.type = params.type;
|
||
|
|
this.beforeBuffer = params.beforeBuffer;
|
||
|
|
this.afterBuffer = params.afterBuffer;
|
||
|
|
this.selection = params.selection;
|
||
|
|
this.clipboardData = params.clipboardData;
|
||
|
|
this.pastePosition = params.pastePosition;
|
||
|
|
this.onApply = params.onApply;
|
||
|
|
}
|
||
|
|
|
||
|
|
execute(): void {
|
||
|
|
this.onApply(this.afterBuffer);
|
||
|
|
}
|
||
|
|
|
||
|
|
undo(): void {
|
||
|
|
this.onApply(this.beforeBuffer);
|
||
|
|
}
|
||
|
|
|
||
|
|
getDescription(): string {
|
||
|
|
switch (this.type) {
|
||
|
|
case 'cut':
|
||
|
|
return 'Cut';
|
||
|
|
case 'delete':
|
||
|
|
return 'Delete';
|
||
|
|
case 'paste':
|
||
|
|
return 'Paste';
|
||
|
|
case 'trim':
|
||
|
|
return 'Trim';
|
||
|
|
default:
|
||
|
|
return 'Edit';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the type of edit operation
|
||
|
|
*/
|
||
|
|
getType(): EditCommandType {
|
||
|
|
return this.type;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the selection that was affected
|
||
|
|
*/
|
||
|
|
getSelection(): Selection | undefined {
|
||
|
|
return this.selection;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Factory functions to create edit commands
|
||
|
|
*/
|
||
|
|
|
||
|
|
export function createCutCommand(
|
||
|
|
buffer: AudioBuffer,
|
||
|
|
selection: Selection,
|
||
|
|
onApply: (buffer: AudioBuffer) => void
|
||
|
|
): EditCommand {
|
||
|
|
const afterBuffer = deleteBufferSegment(buffer, selection.start, selection.end);
|
||
|
|
|
||
|
|
return new EditCommand({
|
||
|
|
type: 'cut',
|
||
|
|
beforeBuffer: buffer,
|
||
|
|
afterBuffer,
|
||
|
|
selection,
|
||
|
|
onApply,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function createDeleteCommand(
|
||
|
|
buffer: AudioBuffer,
|
||
|
|
selection: Selection,
|
||
|
|
onApply: (buffer: AudioBuffer) => void
|
||
|
|
): EditCommand {
|
||
|
|
const afterBuffer = deleteBufferSegment(buffer, selection.start, selection.end);
|
||
|
|
|
||
|
|
return new EditCommand({
|
||
|
|
type: 'delete',
|
||
|
|
beforeBuffer: buffer,
|
||
|
|
afterBuffer,
|
||
|
|
selection,
|
||
|
|
onApply,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function createPasteCommand(
|
||
|
|
buffer: AudioBuffer,
|
||
|
|
clipboardData: AudioBuffer,
|
||
|
|
pastePosition: number,
|
||
|
|
onApply: (buffer: AudioBuffer) => void
|
||
|
|
): EditCommand {
|
||
|
|
const afterBuffer = insertBufferSegment(buffer, clipboardData, pastePosition);
|
||
|
|
|
||
|
|
return new EditCommand({
|
||
|
|
type: 'paste',
|
||
|
|
beforeBuffer: buffer,
|
||
|
|
afterBuffer,
|
||
|
|
clipboardData,
|
||
|
|
pastePosition,
|
||
|
|
onApply,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function createTrimCommand(
|
||
|
|
buffer: AudioBuffer,
|
||
|
|
selection: Selection,
|
||
|
|
onApply: (buffer: AudioBuffer) => void
|
||
|
|
): EditCommand {
|
||
|
|
const afterBuffer = trimBuffer(buffer, selection.start, selection.end);
|
||
|
|
|
||
|
|
return new EditCommand({
|
||
|
|
type: 'trim',
|
||
|
|
beforeBuffer: buffer,
|
||
|
|
afterBuffer,
|
||
|
|
selection,
|
||
|
|
onApply,
|
||
|
|
});
|
||
|
|
}
|