diff --git a/assets/js/creations/audio.js b/assets/js/creations/audio.js index 46edd0d..8e2377a 100644 --- a/assets/js/creations/audio.js +++ b/assets/js/creations/audio.js @@ -63,7 +63,7 @@ export function playMetronomeSound(isDownbeat) { audioContext.currentTime + 0.05 ); oscillator.connect(gainNode); - gainNode.connect(audioContext.destination); + gainNode.connect(mainGainNode); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + 0.05); } @@ -75,7 +75,6 @@ export function playSample(filePath, trackId) { const track = trackId ? appState.tracks.find((t) => t.id == trackId) : null; if (!track || !track.audioBuffer) { - // Se não houver buffer (ex: preview do sample browser), toca como um áudio simples const audio = new Audio(filePath); audio.play(); return; @@ -95,12 +94,12 @@ export function playSample(filePath, trackId) { function tick() { const totalSteps = getTotalSteps(); - if (totalSteps === 0) { + if (totalSteps === 0 || !appState.isPlaying) { stopPlayback(); return; } - const lastStepIndex = - appState.currentStep === 0 ? totalSteps - 1 : appState.currentStep - 1; + + const lastStepIndex = appState.currentStep === 0 ? totalSteps - 1 : appState.currentStep - 1; highlightStep(lastStepIndex, false); const bpm = parseInt(document.getElementById("bpm-input").value, 10) || 120; @@ -111,28 +110,23 @@ function tick() { } if (appState.metronomeEnabled) { - const noteValue = - parseInt(document.getElementById("compasso-b-input").value, 10) || 4; + const noteValue = parseInt(document.getElementById("compasso-b-input").value, 10) || 4; const stepsPerBeat = 16 / noteValue; if (appState.currentStep % stepsPerBeat === 0) { - playMetronomeSound(appState.currentStep === 0); + playMetronomeSound(appState.currentStep % (stepsPerBeat * 4) === 0); } } - // --- INÍCIO DA CORREÇÃO --- appState.tracks.forEach((track) => { - // 1. Verifica se a faixa tem patterns if (!track.patterns || track.patterns.length === 0) return; - // 2. Pega o pattern que está ativo para esta faixa - const activePattern = track.patterns[track.activePatternIndex]; + // Usa o índice GLOBAL para saber qual pattern tocar, sincronizando com a UI. + const activePattern = track.patterns[appState.activePatternIndex]; - // 3. Verifica se o pattern existe e se o step atual está ativo NELE if (activePattern && activePattern.steps[appState.currentStep] && track.samplePath) { playSample(track.samplePath, track.id); } }); - // --- FIM DA CORREÇÃO --- highlightStep(appState.currentStep, true); appState.currentStep = (appState.currentStep + 1) % totalSteps; @@ -141,6 +135,11 @@ function tick() { export function startPlayback() { if (appState.isPlaying || appState.tracks.length === 0) return; initializeAudioContext(); + + if (appState.currentStep === 0) { + rewindPlayback(); + } + const bpm = parseInt(document.getElementById("bpm-input").value, 10) || 120; const stepInterval = (60 * 1000) / (bpm * 4); @@ -160,8 +159,9 @@ export function stopPlayback() { } appState.playbackIntervalId = null; appState.isPlaying = false; - highlightStep(appState.currentStep - 1, false); - highlightStep(appState.currentStep, false); // Garante que o último step "playing" seja limpo + + document.querySelectorAll('.step.playing').forEach(s => s.classList.remove('playing')); + appState.currentStep = 0; if (timerDisplay) timerDisplay.textContent = '00:00:00'; @@ -174,25 +174,20 @@ export function stopPlayback() { } export function rewindPlayback() { - const previousStep = appState.currentStep; + const lastStep = appState.currentStep > 0 ? appState.currentStep - 1 : getTotalSteps() - 1; appState.currentStep = 0; if (!appState.isPlaying) { if (timerDisplay) timerDisplay.textContent = '00:00:00'; - highlightStep(previousStep - 1, false); - highlightStep(previousStep, false); + highlightStep(lastStep, false); } } export function togglePlayback() { - initializeAudioContext(); // Garante que o contexto de áudio foi iniciado por um gesto do usuário + initializeAudioContext(); if (appState.isPlaying) { - // Pausa a reprodução, mas não reseta - clearInterval(appState.playbackIntervalId); - appState.playbackIntervalId = null; - appState.isPlaying = false; - document.getElementById("play-btn").classList.remove("fa-pause"); - document.getElementById("play-btn").classList.add("fa-play"); + stopPlayback(); } else { + appState.currentStep = 0; startPlayback(); } } \ No newline at end of file