mmpSearch/src/manual.md

6.3 KiB

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.

// 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.

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.

// 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.

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.

.step.active {
  background-color: var(--accent-green);
  border: 1px solid #fff;
  box-shadow: 0 0 8px var(--accent-green);
}