118 lines
3.8 KiB
JavaScript
118 lines
3.8 KiB
JavaScript
// js/audio/audio_clipboard.js
|
|
import { appState } from '../state.js';
|
|
import { removeAudioClip, loadAudioForClip } from './audio_state.js';
|
|
import { renderAudioEditor } from './audio_ui.js';
|
|
import { getMainGainNode } from '../audio.js';
|
|
|
|
/**
|
|
* Copia o clipe selecionado para a área de transferência global.
|
|
*/
|
|
export function copyAudioClip() {
|
|
const clipId = appState.global.selectedClipId;
|
|
if (!clipId) return;
|
|
|
|
const clip = appState.audio.clips.find(c => c.id == clipId);
|
|
if (!clip) return;
|
|
|
|
// Remove a marca de "recortado" se houver
|
|
if (appState.global.clipboard?.cutSourceId) {
|
|
appState.global.clipboard.cutSourceId = null;
|
|
}
|
|
|
|
// Cria uma cópia limpa dos dados do clipe
|
|
const clipData = { ...clip };
|
|
// Remove referências a nós de áudio, que devem ser únicos
|
|
delete clipData.gainNode;
|
|
delete clipData.pannerNode;
|
|
delete clipData.player;
|
|
|
|
appState.global.clipboard = {
|
|
type: 'audio',
|
|
clip: clipData,
|
|
cutSourceId: null
|
|
};
|
|
|
|
console.log("Clipe copiado:", appState.global.clipboard.clip.name);
|
|
renderAudioEditor(); // Re-renderiza para remover o visual "cut"
|
|
}
|
|
|
|
/**
|
|
* Recorta o clipe selecionado para a área de transferência global.
|
|
*/
|
|
export function cutAudioClip() {
|
|
const clipId = appState.global.selectedClipId;
|
|
if (!clipId) return;
|
|
|
|
// Limpa o "cut" anterior
|
|
if (appState.global.clipboard?.cutSourceId) {
|
|
appState.global.clipboard.cutSourceId = null;
|
|
}
|
|
|
|
const clip = appState.audio.clips.find(c => c.id == clipId);
|
|
if (!clip) return;
|
|
|
|
// Cria uma cópia limpa dos dados do clipe
|
|
const clipData = { ...clip };
|
|
delete clipData.gainNode;
|
|
delete clipData.pannerNode;
|
|
delete clipData.player;
|
|
|
|
appState.global.clipboard = {
|
|
type: 'audio',
|
|
clip: clipData,
|
|
cutSourceId: clipId // Marca o ID original para exclusão
|
|
};
|
|
|
|
console.log("Clipe recortado:", appState.global.clipboard.clip.name);
|
|
renderAudioEditor(); // Re-renderiza para adicionar o visual "cut"
|
|
}
|
|
|
|
/**
|
|
* Cola o clipe da área de transferência na timeline.
|
|
* @param {number} targetTrackId - O ID da pista onde colar.
|
|
* @param {number} targetTimeInSeconds - O tempo (em segundos) onde colar.
|
|
*/
|
|
export function pasteAudioClip(targetTrackId, targetTimeInSeconds) {
|
|
const clipboard = appState.global.clipboard;
|
|
if (!clipboard || clipboard.type !== 'audio' || !clipboard.clip) {
|
|
console.warn("Área de transferência vazia ou inválida para colar áudio.");
|
|
return;
|
|
}
|
|
|
|
const clipToPaste = clipboard.clip;
|
|
|
|
// Se for um "recorte", primeiro remove o clipe original
|
|
if (clipboard.cutSourceId) {
|
|
removeAudioClip(clipboard.cutSourceId); //
|
|
clipboard.cutSourceId = null; // Limpa para que não remova de novo
|
|
}
|
|
|
|
// Cria um novo clipe a partir dos dados copiados
|
|
const newClip = {
|
|
...clipToPaste,
|
|
id: Date.now() + Math.random(), // ID novo e único
|
|
trackId: targetTrackId,
|
|
startTimeInSeconds: targetTimeInSeconds,
|
|
|
|
// Cria novos nós de áudio
|
|
gainNode: new Tone.Gain(Tone.gainToDb(clipToPaste.volume || 1.0)),
|
|
pannerNode: new Tone.Panner(clipToPaste.pan || 0),
|
|
|
|
player: null,
|
|
// O buffer será copiado/referenciado
|
|
};
|
|
|
|
newClip.gainNode.connect(newClip.pannerNode);
|
|
newClip.pannerNode.connect(getMainGainNode()); //
|
|
|
|
appState.audio.clips.push(newClip);
|
|
|
|
// Como o buffer já deve existir no clipe original,
|
|
// não precisamos de 'loadAudioForClip', mas chamamos
|
|
// para garantir (caso a fonte seja um 'sourcePath').
|
|
// A função 'loadAudioForClip' precisa ser inteligente
|
|
// para não recarregar se o buffer já existir.
|
|
loadAudioForClip(newClip).then(() => { //
|
|
renderAudioEditor();
|
|
});
|
|
} |