129 lines
6.3 KiB
Markdown
129 lines
6.3 KiB
Markdown
# Visão Geral do Código
|
|
Este é o código de um sequenciador de música para a web, similar a um "DAW" (Digital Audio Workstation) simplificado, focado em criar batidas e melodias. Ele permite carregar e salvar projetos no formato .mmp (LMMS), manipular trilhas de instrumentos, programar notas em um sequenciador e controlar aspectos como volume e pan.
|
|
|
|
# main.js - O Ponto de Partida
|
|
Este arquivo inicializa a aplicação. Ele conecta os botões da interface (como "Play", "Salvar", "Adicionar Trilha") às suas funções correspondentes, que estão em outros arquivos. Pense nele como o cérebro que delega as tarefas.
|
|
|
|
# Função Principal
|
|
- Configura todos os "ouvintes de eventos" (event listeners).
|
|
|
|
Exemplo: Quando o usuário clica no botão com o ID play-btn, a função togglePlayback do arquivo audio.js é chamada para iniciar ou parar a música.
|
|
|
|
```JavaScript
|
|
|
|
// Exemplo de como um botão é conectado a uma função
|
|
playBtn.addEventListener("click", togglePlayback);
|
|
addInstrumentBtn.addEventListener("click", addTrackToState);
|
|
saveMmpBtn.addEventListener("click", generateMmpFile);
|
|
```
|
|
# state.js - O Coração da Aplicação
|
|
|
|
Aqui fica guardado todo o estado atual do projeto. Isso inclui as trilhas, as notas, o volume de cada instrumento, se a música está tocando ou não, etc. Quando algo muda (por exemplo, o usuário adiciona uma nota), este estado é atualizado, e a interface visual reflete essa mudança.
|
|
|
|
|
|
# Função Principal
|
|
- Manter um objeto central (appState) com todas as informações do projeto.
|
|
|
|
Exemplo: O objeto appState contém uma lista (tracks) onde cada item representa um instrumento com seus padrões de notas, volume e nome do sample.
|
|
|
|
```JavaScript
|
|
|
|
export let appState = {
|
|
tracks: [], // Lista de instrumentos
|
|
isPlaying: false, // A música está tocando?
|
|
currentStep: 0, // Qual passo da batida está sendo tocado
|
|
masterVolume: 0.8, // Volume geral
|
|
};
|
|
```
|
|
|
|
# ui.js - A Interface Gráfica
|
|
|
|
Este arquivo é responsável por desenhar tudo o que o usuário vê e com o que interage na tela: as trilhas, os "knobs" de volume, a grade do sequenciador e o navegador de arquivos de áudio. Ele lê os dados do state.js para saber o que mostrar.
|
|
|
|
# Função Principal
|
|
- Gerar e atualizar os elementos HTML da página.
|
|
|
|
Exemplo: A função renderApp cria uma "div" para cada trilha existente no appState, e redrawSequencer desenha os quadradinhos de notas, colorindo os que estão ativos.
|
|
|
|
```JavaScript
|
|
|
|
// Exemplo da lógica para desenhar os passos da batida
|
|
for (let i = 0; i < totalGridSteps; i++) {
|
|
const stepElement = document.createElement("div");
|
|
// Se a nota 'i' estiver marcada como ativa no estado, adiciona a classe 'active'
|
|
if (patternSteps[i] === true) {
|
|
stepElement.classList.add("active");
|
|
}
|
|
sequencerContainer.appendChild(stepElement);
|
|
}
|
|
```
|
|
|
|
# audio.js - O Módulo de Som
|
|
|
|
Este é o motor de áudio. Ele usa a API de Áudio do navegador para carregar os samples (os sons dos instrumentos), controlar a reprodução, gerenciar o tempo (BPM), tocar o metrônomo e garantir que as notas toquem na hora certa.
|
|
|
|
# Função Principal
|
|
- Controlar a reprodução de áudio e o tempo da música.
|
|
|
|
Exemplo: A função tick é chamada repetidamente em um intervalo de tempo preciso (calculado a partir do BPM). A cada chamada, ela verifica quais notas devem ser tocadas no passo atual e dispara os sons correspondentes.
|
|
|
|
```JavaScript
|
|
|
|
function tick() {
|
|
// Para cada trilha...
|
|
appState.tracks.forEach((track) => {
|
|
// Se a nota no passo atual estiver ativa...
|
|
if (activePattern.steps[appState.currentStep]) {
|
|
// Toca o som daquela trilha
|
|
playSample(track.samplePath, track.id);
|
|
}
|
|
});
|
|
// Avança para o próximo passo
|
|
appState.currentStep = (appState.currentStep + 1) % totalSteps;
|
|
}
|
|
```
|
|
|
|
# file.js - O Gerenciador de Arquivos
|
|
|
|
Responsável por ler, interpretar e salvar arquivos de projeto. Ele sabe como decodificar o formato .mmp (baseado em XML) e traduzi-lo para a estrutura de dados que a aplicação entende (appState). Também faz o caminho inverso, convertendo o estado atual do projeto em um arquivo .mmp que pode ser salvo.
|
|
|
|
# Função Principal
|
|
- Ler e escrever projetos no formato .mmp.
|
|
|
|
Exemplo: Ao carregar um arquivo, a função parseMmpContent usa o DOMParser do navegador para ler o XML, extrair informações como BPM e as notas de cada trilha, e popular o appState.
|
|
|
|
# Utilitários
|
|
- config.js e utils.js
|
|
|
|
# config.js
|
|
- Guarda valores constantes e configurações padrão, como o volume inicial ou o pan. Isso facilita a manutenção, mantendo números "mágicos" em um só lugar.
|
|
|
|
# utils.js
|
|
- Contém pequenas funções de ajuda usadas em várias partes do código. Por exemplo, a função getTotalSteps calcula quantos "passos" a música terá com base no número de compassos e na fórmula de compasso definidos pelo usuário.
|
|
|
|
# upload_server.py - O Servidor de Suporte
|
|
|
|
Este é um pequeno servidor web escrito em Python que roda nos bastidores. Sua principal tarefa é permitir o upload de novos samples de áudio. Quando um novo arquivo é enviado, ele o salva na pasta correta e, crucialmente, atualiza os arquivos de "manifesto" (.json). Esses manifestos são listas que a interface web consulta para saber quais samples e projetos estão disponíveis para serem carregados.
|
|
|
|
# Função Principal
|
|
- Receber uploads de arquivos e manter os manifestos de samples e projetos atualizados.
|
|
|
|
Exemplo: Um usuário faz o upload do arquivo kick_drum.wav. O servidor salva este arquivo e automaticamente adiciona uma entrada para kick_drum.wav no arquivo samples-manifest.json. Da próxima vez que o usuário abrir o navegador de samples, o novo bumbo aparecerá na lista.
|
|
|
|
# style.css - A Aparência
|
|
|
|
Este é o arquivo de estilização. Ele define todas as cores, tamanhos, fontes e o layout da aplicação. É o que dá ao sequenciador sua aparência de "software de música", com temas escuros e elementos visuais que lembram equipamentos de estúdio.
|
|
|
|
# Função Principal
|
|
- Definir o estilo visual de todos os componentes.
|
|
|
|
Exemplo: O estilo para um passo ativo no sequenciador é definido aqui, fazendo-o brilhar em verde.
|
|
|
|
```CSS
|
|
|
|
.step.active {
|
|
background-color: var(--accent-green);
|
|
border: 1px solid #fff;
|
|
box-shadow: 0 0 8px var(--accent-green);
|
|
}
|
|
``` |