sync mode on
This commit is contained in:
1 parent
1818932244
commit
1174b328e5
415 files changed
+44294
-1182
No files matched your search
@@ -0,0 +1,118 @@
|
||||
// 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();
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user