Главное демо
CDN v3.0.0

Добавьте эти теги на страницу — перед </body> или в <head> :

Synth-движок
<script src="https://cdn.chiptune-synth.8binami.com/3.0.0/chiptune-synth.min.js"></script>
Банк звуков (170+ instruments)
<script src="https://cdn.chiptune-synth.8binami.com/3.0.0/chiptune-sound-font.min.js"></script>

API Documentation

Complete reference for ChiptuneSynth — 4-track chiptune synthesizer for the Web Audio API

Table of Contents

Quick Start

// 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);
The AudioContext requires a user gesture (click/tap) to start. Always call init() inside a click handler or after user interaction.

Constructor & Initialization

new ChiptuneSynth()

Создатьs a new synthesizer instance with 4 дорожки (Lead, Бас, Drums, FX), default envelopes, and empty vibrato settings.

const synth = new ChiptuneSynth();

synth.init() async

Initializes the Web Audio API context, creates master gain, analyser, per-track gain nodes, and noise buffer. Must be called once before any playback.

await synth.init();

synth.dispose()

Stops all notes and closes the AudioContext. Call when you're done with the synth.

Воспроизвестиback Methods

synth.playНота(frequency, trackIndex, duration, startTime) → noteId

Воспроизвестиs a note at the given frequency (Hz) on the specified track.

ParameterTypeDefaultDescription
frequencynumberFrequency in Hz (e.g. 440 for A4)
trackIndexnumber0Track index: 0=Lead, 1=Бас, 2=Drums, 3=FX
durationnumber10Duration in seconds. Values ≥10 create sustained notes
startTimenumbernowAudioContext time to start (for scheduling)
const noteId = synth.playNote(440, 0, 0.5);  // A4, Lead, 0.5s
Use duration = 10 or higher for sustained notes that you control manually with stopNote(). This is how the keyboard and MIDI work.

synth.playНотаByName(note, octave, trackIndex, duration) → noteId

Воспроизвестиs a note by its musical name.

ParameterTypeDefaultDescription
notestringНота name: C, C#, D, D#, E, F, F#, G, G#, A, A#, B (also Db, Eb, Gb, Ab, Bb)
octavenumber4Октава (1-7)
trackIndexnumber0Target track
durationnumber10Duration in seconds
synth.playNoteByName('C', 4, 0, 0.5);  // Middle C on Lead
synth.playNoteByName('Eb', 3, 1, 1.0); // Eb3 on Bass

synth.stopНота(noteId)

Stops a specific note with its release envelope. Use the noteId returned by playNote() or playNoteByName().

synth.stopAllНотаs()

Immediately stops all active notes across all tracks.

Presets & Инструменты

synth.playPreset(name)

Loads and plays a built-in SFX preset in one call. Perfect for game sound effects.

synth.playPreset('coin');
synth.playPreset('explosion');
synth.playPreset('jump');

Available SFX Presets (10)

NameDescriptionUse Case
laserDescending zap beamВыстрелing, beams
coinRising bright dingCollecting items
jumpQuick ascending sweepПрыжокing, bouncing
explosionШум burst decayDestruction, death
powerupRising sweep fanfarePower-ups, upgrades
hitSharp impact noiseDamage, collision
blipShort UI clickMenu selection, UI
bassDeep triangle thumpБас drops, impacts
shootQuick zap shotRapid fire weapons
1upAscending fanfareExtra lives, bonuses

synth.loadPreset(name)

Loads a preset's configuration (waveform, envelope, effects) onto a track without playing it. Useful for setting up a track before triggering notes manually.

synth.loadInstrument(name, trackIndex) → boolean

Loads a full instrument preset onto the specified track, configuring waveform, envelope, vibrato, and modulation.

synth.loadInstrument('violin', 0);
synth.playNoteByName('A', 4, 0, 2.0);

Available Инструменты (12)

NameTypeDescription
pianotriangleBright percussive tone with quick decay
violinsawtoothWarm bowed string with vibrato
cellosawtoothDeep bowed string, low register
flutesineSoft breathy tone with vibrato
organsquareСустейнed pipe organ tone
brasssawtoothBold horn/trumpet sound
harmonicasquareReedy PWM tone with tremolo
synthLeadsquareClassic chiptune lead
synthPadsawtoothWide unison pad with filter
synthБасsawtoothPunchy synth bass
marimbasinePercussive mallet tone
electricGuitarsquareOverdriven guitar emulation

Track Configuration

synth.updateTrack(trackIndex, settings)

Updates one or more properties of a track. Changes apply in real-time to currently playing notes.

synth.updateTrack(0, {
  type: 'sawtooth',
  volume: 0.4,
  unisonVoices: 4,
  unisonDetune: 20
});

Track Properties

PropertyTypeDefaultDescription
typestring'square'Форма сигнала: 'square', 'triangle', 'sawtooth', 'sine', 'noise'
volumenumber0.3Track volume (0-1)
dutyCyclenumber0.5Pulse width for square waves (0-1)
detunenumber0Fine tuning in cents (1200 = 1 octave)
octaveOffsetnumber0Октава shift (±)
semitoneOffsetnumber0Полутонtone shift (±)
pitchEnvnumber0Высота envelope depth in semitones
glidenumber0Portamento time in seconds

You can also directly set properties on the track objects:

synth.tracks[0].type = 'sawtooth';
synth.tracks[0].volume = 0.4;
synth.updateLiveNotes(0); // Apply to active notes

Envelopes (ADSR)

synth.updateEnvelope(trackIndex, settings)

Sets the amplitude envelope for a track. Controls how notes fade in, sustain, and fade out.

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
});
PropertyTypeRangeDescription
attacknumber0-5sTime to reach full volume
decaynumber0-5sTime to fall from peak to sustain level
sustainnumber0-1Громкость level while note is held (0 = off after decay)
releasenumber0-10sFade-out time after note stops

Default Envelopes

TrackАтакаСпадСустейнЗатухание
0 - Lead0.010.100.70.20
1 - Бас0.010.200.80.15
2 - Drums0.0010.100.00.05
3 - FX0.0050.300.00.20

Вибрато

synth.updateВибрато(trackIndex, settings)

Configures pitch modulation (vibrato) for a track.

synth.updateVibrato(0, {
  rate:  5,   // Speed in Hz
  depth: 12   // Amount in cents
});
PropertyTypeDefaultDescription
ratenumber0LFO speed in Hz (0 = off)
depthnumber0Высота deviation in cents (0 = off)

Фильтр

Each track has an optional filter for shaping the frequency content of the sound.

synth.tracks[0].filterEnabled = true;
synth.tracks[0].filterType = 'lowpass';
synth.tracks[0].filterCutoff = 2000;
synth.tracks[0].filterQ = 5;
synth.updateLiveNotes(0);
PropertyTypeDefaultDescription
filterВкл.dbooleanfalseВкл./disable filter
filterTypestring'lowpass''lowpass', 'highpass', 'bandpass', 'notch'
filterСрезnumber20000Срез frequency in Hz
filterQnumber0.1Резонанс / Q factor
filterKeyTracknumber0Key tracking 0-100 (cutoff follows pitch)
filterEnvКоличествоnumber0Фильтр envelope depth (semitones)
filterEnvАтакаnumber0.01Фильтр envelope attack (seconds)
filterEnvЗатуханиеnumber0.2Фильтр envelope release (seconds)

Унисон & Расстройка

Stack multiple detuned oscillators for a thick, wide sound. Essential for pads and leads.

synth.tracks[0].unisonVoices = 8;
synth.tracks[0].unisonDetune = 25;  // cents between voices
synth.tracks[0].unisonSpread = 80;  // stereo spread %
PropertyTypeDefaultDescription
unisonГолосаnumber1Number of oscillators (1-16)
unisonРасстройкаnumber0Расстройка spread in cents
unisonШиринаnumber0Stereo panning spread (0-100%)

LFOs (Тремоло & Фильтр Модulation)

Тремоло (Amplitude LFO)

synth.tracks[0].tremoloRate = 6;    // Hz
synth.tracks[0].tremoloDepth = 50;   // 0-100

Фильтр LFO

synth.tracks[0].filterEnabled = true;
synth.tracks[0].filterCutoff = 1000;
synth.tracks[0].lfoFilterRate = 3;     // Hz
synth.tracks[0].lfoFilterDepth = 2000;  // Hz range
PropertyTypeDescription
tremoloСкоростьnumberТремоло speed in Hz (0 = off)
tremoloГлубинаnumberТремоло amount (0-100)
lfoФильтрСкоростьnumberФильтр LFO speed in Hz (0 = off)
lfoФильтрГлубинаnumberФильтр LFO range in Hz
ChiptuneSynth has 3 independent LFOs per track: Вибрато (pitch), Тремоло (volume), and Фильтр modulation.

MIDI Support

synth.enableMIDI(options) async→ inputNames[]

Вкл.s MIDI input from connected controllers. Returns an array of detected MIDI input device names.

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 */ }
});

Options

PropertyTypeDefaultDescription
tracknumber0Target track for MIDI notes
channelnumber0MIDI channel filter (1-16, 0 = all)
onConnectfunctionCalled when a MIDI device connects
onDisconnectfunctionCalled when a MIDI device disconnects
onНотаOnfunctionCalled on note on (note, velocity, channel)
onНотаOfffunctionCalled on note off (note, channel)
onCCfunctionCalled on control change (cc, value, channel)

Supported MIDI CC

CCNameEffect
1Мод WheelControls vibrato depth
7ГромкостьControls track volume
64Сустейн PedalСустейнs held notes
120All Sound OffStops all notes
123All Нотаs OffStops all notes

synth.disableMIDI()

Disables MIDI input and stops all held MIDI notes.

synth.setMIDITrack(trackIndex)

Changes which track receives MIDI input.

synth.setMIDIChannel(ch)

Sets the MIDI channel filter (0 = all channels).

synth.isMIDIВкл.d() → boolean

Returns whether MIDI is currently active.

Visualizer Data

synth.getФорма сигналаData() → Uint8Array

Returns time-domain waveform data for drawing oscilloscope-style visualizations. Values range from 0-255 (128 = center).

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);
}

synth.getFrequencyData() → Uint8Array

Returns frequency-domain (FFT) data for spectrum visualizations. Values range from 0-255.

synth.setМастерГромкость(value)

Sets the master output volume (0-1).

synth.getМастерГромкость() → number

Returns the current master volume.

synth.resetToDefaults()

Resets all tracks, envelopes, and vibrato to their default values.

Static Methods

ChiptuneSynth.noteToFrequency(note, octave) static→ number

Converts a note name and octave to frequency in Hz.

ChiptuneSynth.noteToFrequency('A', 4);  // → 440
ChiptuneSynth.noteToFrequency('C', 4);  // → 261.63

ChiptuneSynth.midiToFrequency(midi) static→ number

Converts a MIDI note number (0-127) to frequency in Hz.

ChiptuneSynth.frequencyToMidi(freq) static→ number

Converts a frequency to the nearest MIDI note number.

ChiptuneSynth.getPresetNames() static→ string[]

Returns an array of all available SFX preset names.

ChiptuneSynth.getPresetNames();
// → ['laser','coin','jump','explosion','powerup','hit','blip','bass','shoot','1up']

ChiptuneSynth.getInstrumentNames() static→ string[]

Returns an array of all available instrument preset names.

ChiptuneSynth.getИнструменты() static→ object

Returns an object keyed by instrument name, each value containing the full definition (track settings, envelope, vibrato, filter, 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'

Creating Custom Инструменты

You can craft your own instruments by combining track settings, envelopes, vibrato, and filters. Here's how to build sounds from scratch.

Основы Custom Sound

Configure a track manually, then play notes on it:

// 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);

Custom SFX (Preset-Style)

Replicate the preset pattern — configure a track, play a note, and let the envelope handle the rest:

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

Rich Instrument with Effects

Combine multiple features for expressive instruments:

// 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);

Multi-Track Layered Sound

Layer multiple tracks for complex sounds:

// 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);
}

Reusable Instrument Object Pattern

Organize your custom instruments as config objects:

// 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);
The Reusable Instrument Object pattern is the recommended approach for managing custom instruments in your game or app. It keeps your sound design clean and easy to tweak.
Открыть 8BitForge — a creative app built with ChiptuneSynth featuring a visual instrument editor, 8 tracks, full mixer with EQ/compressor, 3 LFOs per track, and 50+ built-in instruments. Учиться more

Default Values

Track Defaults

TrackIndexФорма сигналаГромкость
Lead0square0.30
Бас1triangle0.40
Drums2noise0.50
FX3sawtooth0.25

Architecture Нота

Per-note gainNode handles only the ADSR envelope (normalized 0→1→sustain). Track volume is controlled by a separate _trackGains[] node. This architecture allows real-time parameter changes without interrupting the ADSR schedule of playing notes.