Referência completa para o ChiptuneSynth — sintetizador chiptune de 4 faixas para a Web Audio API
// 1. Include the library
<script src="chiptune-synth.js"></script>
// 2. Create and initialize
const synth = new ChiptuneSynth();
await synth.init();
// 3. Play a note
synth.playNoteByName('C', 4, 0, 0.5);
// 4. Or play a sound effect
synth.playPreset('coin');
// 5. Load an instrument
synth.loadInstrument('violin', 0);
synth.playNoteByName('A', 4, 0, 1.0); init()` dentro de um manipulador de clique ou após a interação do usuário.Cria uma nova instância do sintetizador com 4 faixas (Lead, Bass, Drums, FX), envelopes padrão e configurações de vibrato vazias.
const synth = new ChiptuneSynth(); Inicializa o contexto da API Web Audio, cria o ganho mestre, o analisador, os nós de ganho por faixa e o buffer de ruído. Deve ser chamado uma vez antes de qualquer reprodução.
await synth.init(); Interrompe todas as notas e fecha o AudioContext. Chame quando terminar de usar o sintetizador.
Reproduz uma nota na frequência fornecida (Hz) na faixa especificada.
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| frequência | número | — | Frequência em Hz (por exemplo, 440 para A4) |
| índice da faixa | número | 0 | Índice da faixa: 0=Melodia, 1=Baixo, 2=Bateria, 3=Efeitos |
| duração | número | 10 | Duração em segundos. Valores ≥10 criam notas sustentadas |
| horaInicial | número | agora | AudioContext hora de início (para agendamento) |
const noteId = synth.playNote(440, 0, 0.5); // A4, Lead, 0.5s duration = 10` ou superior para notas sustentadas que você controla manualmente com `stopNote()`. É assim que o teclado e o MIDI funcionam.Reproduz uma nota pelo seu nome musical.
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| nota | string | — | Nome da nota: C, C#, D, D#, E, F, F#, G, G#, A, A#, B (também Db, Eb, Gb, Ab, Bb) |
| oitava | número | 4 | Oitava (1-7) |
| índice da faixa | número | 0 | Faixa de destino |
| duração | número | 10 | Duração em segundos |
synth.playNoteByName('C', 4, 0, 0.5); // Middle C on Lead
synth.playNoteByName('Eb', 3, 1, 1.0); // Eb3 on Bass Interrompe uma nota específica com seu envelope de liberação. Use o noteId retornado por playNote() ou playNoteByName().
Interrompe imediatamente todas as notas ativas em todas as faixas.
Carrega e reproduz uma predefinição de SFX integrada em uma única chamada. Perfeito para efeitos sonoros de jogos.
synth.playPreset('coin');
synth.playPreset('explosion');
synth.playPreset('jump'); | Nome | Descrição | Caso de uso |
|---|---|---|
| laser | Feixe descendente | Tiro, feixes |
| moeda | Ding brilhante ascendente | Coletar itens |
| salto | Varredura ascendente rápida | Pular, quicar |
| Explosão | Decaimento da explosão sonora | Destruição, morte |
| potencialização | Fanfarra crescente | Power-ups, melhorias |
| golpe | Ruído de impacto agudo | Dano, colisão |
| bip | Clique curto na interface | Seleção de menu, interface do usuário |
| baixo | Batida profunda em forma de triângulo | Baixos, impactos |
| tiro | Tiro rápido | Armas de disparo rápido |
| 1up | Fanfarra ascendente | Vidas extras, bônus |
Carrega a configuração de uma predefinição (forma de onda, envelope, efeitos) em uma faixa sem reproduzi-la. Útil para configurar uma faixa antes de acionar notas manualmente.
Carrega uma predefinição completa de instrumento na faixa especificada, configurando forma de onda, envelope, vibrato e modulação.
synth.loadInstrument('violin', 0);
synth.playNoteByName('A', 4, 0, 2.0); | Nome | Tipo | Descrição |
|---|---|---|
| piano | triângulo | Tom percussivo brilhante com decaimento rápido |
| violino | dente de serra | Cordas quentes tocadas com arco e vibrato |
| violoncelo | dente de serra | Cordas tocadas com arco, som grave |
| flauta | senoidal | Tom suave e soproso com vibrato |
| órgão | quadrado | Tom sustentado de órgão de tubos |
| metais | dente de serra | Som forte de trompa/trompete |
| gaita | quadrado | Tom PWM com vibração |
| sintetizadorLead | quadrado | Lead clássico de chiptune |
| synthPad | dente de serra | Pad de uníssono amplo com filtro |
| synthBass | dente de serra | Baixo sintético impactante |
| marimba | senoidal | Tom percussivo de baqueta |
| guitarra elétrica | quadrado | Emulação de guitarra com overdrive |
Atualiza uma ou mais propriedades de uma faixa. As alterações são aplicadas em tempo real às notas que estão sendo reproduzidas no momento.
synth.updateTrack(0, {
type: 'sawtooth',
volume: 0.4,
unisonVoices: 4,
unisonDetune: 20
}); | Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
| tipo | string | 'quadrada' | Forma de onda: 'quadrada', 'triangular', 'dente de serra', 'senoidal', 'ruído' |
| volume | número | 0,3 | Volume da faixa (0-1) |
| ciclo de trabalho | número | 0,5 | Largura de pulso para ondas quadradas (0-1) |
| desafinação | número | 0 | Afinação fina em centésimos (1200 = 1 oitava) |
| desvio de oitava | número | 0 | Desvio de oitava (±) |
| desvio de semitom | número | 0 | Desvio de semitom (±) |
| Envelope de altura | número | 0 | Profundidade do envelope de afinação em semitons |
| glide | número | 0 | Tempo de portamento em segundos |
Você também pode definir propriedades diretamente nos objetos da faixa:
synth.tracks[0].type = 'sawtooth';
synth.tracks[0].volume = 0.4;
synth.updateLiveNotes(0); // Apply to active notes Define o envelope de amplitude para uma faixa. Controla como as notas entram, se mantêm e saem.
synth.updateEnvelope(0, {
attack: 0.1, // Fade-in time (seconds)
decay: 0.2, // Decay to sustain level
sustain: 0.6, // Held level (0-1)
release: 0.5 // Fade-out after note stops
}); | Propriedade | Tipo | Intervalo | Descrição |
|---|---|---|---|
| ataque | número | 0-5 s | Tempo para atingir o volume máximo |
| decaimento | número | 0-5 s | Tempo para cair do pico até o nível de sustain |
| sustentação | número | 0-1 | Nível de volume enquanto a nota é mantida (0 = desligado após o decaimento) |
| soltar | número | 0-10s | Tempo de fade-out após a nota parar |
| Faixa | Ataque | Decaimento | Sustentação | Liberação |
|---|---|---|---|---|
| 0 - Lead | 0,01 | 0,10 | 0,7 | 0,20 |
| 1 - Baixo | 0,01 | 0,20 | 0,8 | 0,15 |
| 2 - Bateria | 0,001 | 0,10 | 0,0 | 0,05 |
| 3 - Efeitos | 0,005 | 0,30 | 0,0 | 0,20 |
Configura a modulação de tom (vibrato) para uma faixa.
synth.updateVibrato(0, {
rate: 5, // Speed in Hz
depth: 12 // Amount in cents
}); | Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
| taxa | número | 0 | Velocidade do LFO em Hz (0 = desligado) |
| profundidade | número | 0 | Desvio de afinação em cents (0 = desativado) |
Cada faixa possui um filtro opcional para moldar o conteúdo de frequência do som.
synth.tracks[0].filterEnabled = true;
synth.tracks[0].filterType = 'lowpass';
synth.tracks[0].filterCutoff = 2000;
synth.tracks[0].filterQ = 5;
synth.updateLiveNotes(0); | Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
| filterEnabled | booleano | false | Ativar/desativar filtro |
| filterType | string | 'lowpass' | 'lowpass', 'highpass', 'bandpass', 'notch' |
| corte do filtro | número | 20000 | Frequência de corte em Hz |
| Q do filtro | número | 0,1 | Ressonância / Fator Q |
| faixa principal do filtro | número | 0 | Rastreamento de tecla 0-100 (cutoff acompanha o tom) |
| filterEnvAmount | número | 0 | Profundidade do envelope do filtro (semitons) |
| filterEnvAttack | número | 0,01 | Ataque do envelope do filtro (segundos) |
| filterEnvRelease | número | 0,2 | Liberação do envelope do filtro (segundos) |
Empilhe vários osciladores desafinados para obter um som denso e amplo. Essencial para pads e leads.
synth.tracks[0].unisonVoices = 8;
synth.tracks[0].unisonDetune = 25; // cents between voices
synth.tracks[0].unisonSpread = 80; // stereo spread % | Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
| unisonVoices | número | 1 | Número de osciladores (1-16) |
| desafinação em uníssono | número | 0 | Diferencial de afinação em centésimos |
| unisonSpread | número | 0 | Dispersão do panning estéreo (0-100%) |
synth.tracks[0].tremoloRate = 6; // Hz
synth.tracks[0].tremoloDepth = 50; // 0-100 synth.tracks[0].filterEnabled = true;
synth.tracks[0].filterCutoff = 1000;
synth.tracks[0].lfoFilterRate = 3; // Hz
synth.tracks[0].lfoFilterDepth = 2000; // Hz range | Propriedade | Tipo | Descrição |
|---|---|---|
| tremoloRate | número | Velocidade do tremolo em Hz (0 = desativado) |
| tremoloDepth | número | Intensidade do tremolo (0-100) |
| lfoFilterRate | número | Velocidade do LFO do filtro em Hz (0 = desativado) |
| lfoFilterDepth | número | Intervalo do LFO do filtro em Hz |
Habilita a entrada MIDI de controladores conectados. Retorna uma matriz com os nomes dos dispositivos de entrada MIDI detectados.
const inputs = await synth.enableMIDI({
track: 0,
channel: 0, // 0 = all channels
onConnect: (name) => console.log('Connected:', name),
onDisconnect: (name) => console.log('Disconnected:', name),
onNoteOn: (note, vel, ch) => { /* MIDI note 0-127 */ },
onNoteOff: (note, ch) => { /* ... */ },
onCC: (cc, value, ch) => { /* CC 0-127 */ }
}); | Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
| faixa | número | 0 | Faixa de destino para notas MIDI |
| canal | número | 0 | Filtro de canal MIDI (1-16, 0 = todos) |
| onConnect | função | — | Chamada quando um dispositivo MIDI se conecta |
| onDisconnect | função | — | Chamada quando um dispositivo MIDI se desconecta |
| onNoteOn | função | — | Chamada ao início da nota (nota, velocidade, canal) |
| onNoteOff | função | — | Chamada ao desligar a nota (nota, canal) |
| onCC | função | — | Chamada ao ocorrer uma mudança de controle (cc, valor, canal) |
| CC | Nome | Efeito |
|---|---|---|
| 1 | Roda de modulação | Controla a profundidade do vibrato |
| 7 | Volume | Controla o volume da faixa |
| 64 | Pedal de sustain | Sustenta as notas mantidas |
| 120 | Desligar todos os sons | Interrompe todas as notas |
| 123 | Desligar todas as notas | Interrompe todas as notas |
Desativa a entrada MIDI e interrompe todas as notas MIDI mantidas.
Altera a faixa que recebe a entrada MIDI.
Define o filtro de canal MIDI (0 = todos os canais).
Retorna se o MIDI está ativo no momento.
Retorna dados de forma de onda no domínio do tempo para desenhar visualizações no estilo osciloscópio. Os valores variam de 0 a 255 (128 = centro).
function draw() {
const data = synth.getWaveformData();
// Draw on canvas...
ctx.beginPath();
data.forEach((v, i) => {
const x = (i / data.length) * width;
const y = (v / 255) * height;
i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
});
ctx.stroke();
requestAnimationFrame(draw);
} Retorna dados no domínio da frequência (FFT) para visualizações de espectro. Os valores variam de 0 a 255.
Define o volume de saída principal (0-1).
Retorna o volume principal atual.
Redefine todas as faixas, envelopes e vibrato para seus valores padrão.
Converte um nome de nota e uma oitava em frequência em Hz.
ChiptuneSynth.noteToFrequency('A', 4); // → 440
ChiptuneSynth.noteToFrequency('C', 4); // → 261.63 Converte um número de nota MIDI (0-127) em frequência em Hz.
Converte uma frequência no número de nota MIDI mais próximo.
Retorna uma matriz com todos os nomes de predefinições de efeitos sonoros disponíveis.
ChiptuneSynth.getPresetNames();
// → ['laser','coin','jump','explosion','powerup','hit','blip','bass','shoot','1up'] Retorna uma matriz com todos os nomes de predefinições de instrumentos disponíveis.
Retorna um objeto indexado pelo nome do instrumento, cada valor contendo a definição completa (configurações de faixa, envelope, vibrato, filtro, etc.).
const instruments = ChiptuneSynth.getInstruments();
// { piano: { name, label, icon, type, volume, ... }, violin: { ... }, ... }
// Access a specific instrument definition
const piano = instruments.piano;
console.log(piano.type); // 'triangle'
console.log(piano.label); // 'Piano' Você pode criar seus próprios instrumentos combinando configurações de faixa, envelopes, vibrato e filtros. Veja como construir sons do zero.
Configure uma faixa manualmente e, em seguida, toque notas nela:
// Create a retro pluck bass
synth.updateTrack(1, {
type: 'sawtooth',
volume: 0.5,
octaveOffset: -1
});
synth.updateEnvelope(1, {
attack: 0.005,
decay: 0.3,
sustain: 0.0,
release: 0.1
});
synth.playNoteByName('E', 2, 1, 0.4); Reproduza o padrão predefinido — configure uma faixa, toque uma nota e deixe o envelope cuidar do resto:
// Custom "warp" SFX on FX track (3)
function playWarp() {
synth.updateTrack(3, {
type: 'square',
volume: 0.3,
dutyCycle: 0.25,
pitchEnv: -24 // pitch drops 2 octaves
});
synth.updateEnvelope(3, {
attack: 0.01,
decay: 0.4,
sustain: 0.0,
release: 0.1
});
synth.playNote(880, 3, 0.5);
}
// Now call playWarp() anytime! Combine vários recursos para criar instrumentos expressivos:
// Dreamy synth pad with filter sweep
function setupDreamPad(track) {
synth.updateTrack(track, {
type: 'square',
volume: 0.25,
dutyCycle: 0.3,
unisonVoices: 6,
unisonDetune: 18,
unisonSpread: 70
});
synth.updateEnvelope(track, {
attack: 0.8,
decay: 0.5,
sustain: 0.6,
release: 2.0
});
synth.updateVibrato(track, {
rate: 4,
depth: 8
});
// Add filter with LFO modulation
synth.tracks[track].filterEnabled = true;
synth.tracks[track].filterType = 'lowpass';
synth.tracks[track].filterCutoff = 1200;
synth.tracks[track].filterQ = 3;
synth.tracks[track].lfoFilterRate = 0.3;
synth.tracks[track].lfoFilterDepth = 800;
}
setupDreamPad(0);
synth.playNoteByName('C', 4, 0, 3.0); Sobreponha várias faixas para sons complexos:
// Layered "epic hit" — noise + bass + lead
function playEpicHit() {
// Layer 1: noise crash
synth.updateTrack(2, { type: 'noise', volume: 0.4 });
synth.updateEnvelope(2, { attack:0.001, decay:0.3, sustain:0, release:0.1 });
synth.playNote(200, 2, 0.4);
// Layer 2: sub bass thump
synth.updateTrack(1, { type: 'sine', volume: 0.6, pitchEnv: 12 });
synth.updateEnvelope(1, { attack:0.001, decay:0.25, sustain:0, release:0.1 });
synth.playNote(60, 1, 0.3);
// Layer 3: bright accent
synth.updateTrack(0, { type: 'square', volume: 0.2 });
synth.updateEnvelope(0, { attack:0.001, decay:0.1, sustain:0, release:0.2 });
synth.playNote(440, 0, 0.15);
} Organize seus instrumentos personalizados como objetos de configuração:
// Define instrument configs
const myInstruments = {
retroLead: {
track: { type: 'square', dutyCycle: 0.25, volume: 0.3 },
env: { attack: 0.02, decay: 0.15, sustain: 0.5, release: 0.3 },
vib: { rate: 5.5, depth: 10 }
},
fatBass: {
track: { type: 'sawtooth', volume: 0.5, unisonVoices: 3, unisonDetune: 10 },
env: { attack: 0.01, decay: 0.2, sustain: 0.7, release: 0.1 },
vib: { rate: 0, depth: 0 }
}
};
// Apply an instrument to a track
function applyInstrument(name, trackIndex) {
const inst = myInstruments[name];
synth.updateTrack(trackIndex, inst.track);
synth.updateEnvelope(trackIndex, inst.env);
synth.updateVibrato(trackIndex, inst.vib);
}
applyInstrument('retroLead', 0);
synth.playNoteByName('C', 5, 0, 0.5); | Faixa | Índice | Forma de onda | Volume |
|---|---|---|---|
| Canal principal | 0 | quadrado | 0,30 |
| Baixo | 1 | triângulo | 0,40 |
| Bateria | 2 | ruído | 0,50 |
| Efeitos | 3 | dente de serra | 0,25 |
O "gainNode" por nota lida apenas com o envelope ADSR (normalizado 0→1→sustentação). O volume da faixa é controlado por um nó "_trackGains[]" separado. Essa arquitetura permite alterações de parâmetros em tempo real sem interromper a sequência ADSR das notas tocadas.