Hauptdemo
CDN v3.0.0

Füge diese Tags zu deiner Seite hinzu — vor </body> oder in <head> :

Synth-Engine
<script src="https://cdn.chiptune-synth.8binami.com/3.0.0/chiptune-synth.min.js"></script>
Sound Font (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()

Erstellens a new synthesizer instance with 4 Spuren (Lead, Bass, 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.

Abspielenback Methods

synth.playNote(frequency, trackIndex, duration, startTime) → noteId

Abspielens 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=Bass, 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.playNoteByName(note, octave, trackIndex, duration) → noteId

Abspielens a note by its musical name.

ParameterTypeDefaultDescription
notestringNote name: C, C#, D, D#, E, F, F#, G, G#, A, A#, B (also Db, Eb, Gb, Ab, Bb)
octavenumber4Oktave (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.stopNote(noteId)

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

synth.stopAllNotes()

Immediately stops all active notes across all tracks.

Presets & Instrumente

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 beamSchießening, beams
coinRising bright dingCollecting items
jumpQuick ascending sweepSprunging, bouncing
explosionRauschen burst decayDestruction, death
powerupRising sweep fanfarePower-ups, upgrades
hitSharp impact noiseDamage, collision
blipShort UI clickMenu selection, UI
bassDeep triangle thumpBass 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 Instrumente (12)

NameTypeDescription
pianotriangleBright percussive tone with quick decay
violinsawtoothWarm bowed string with vibrato
cellosawtoothDeep bowed string, low register
flutesineSoft breathy tone with vibrato
organsquareSustained pipe organ tone
brasssawtoothBold horn/trumpet sound
harmonicasquareReedy PWM tone with tremolo
synthLeadsquareClassic chiptune lead
synthPadsawtoothWide unison pad with filter
synthBasssawtoothPunchy 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'Wellenform: '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)
octaveOffsetnumber0Oktave shift (±)
semitoneOffsetnumber0Halbtontone shift (±)
pitchEnvnumber0Tonhöhe 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-1Lautstärke level while note is held (0 = off after decay)
releasenumber0-10sFade-out time after note stops

Default Envelopes

TrackAnschlagAbfallSustainAusklingen
0 - Lead0.010.100.70.20
1 - Bass0.010.200.80.15
2 - Drums0.0010.100.00.05
3 - FX0.0050.300.00.20

Vibrato

synth.updateVibrato(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)
depthnumber0Tonhöhe deviation in cents (0 = off)

Filter

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
filterAktivierendbooleanfalseAktivieren/disable filter
filterTypestring'lowpass''lowpass', 'highpass', 'bandpass', 'notch'
filterGrenzfrequenznumber20000Grenzfrequenz frequency in Hz
filterQnumber0.1Resonanz / Q factor
filterKeyTracknumber0Key tracking 0-100 (cutoff follows pitch)
filterEnvBetragnumber0Filter envelope depth (semitones)
filterEnvAnschlagnumber0.01Filter envelope attack (seconds)
filterEnvAusklingennumber0.2Filter envelope release (seconds)

Unison & Verstimmung

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
unisonStimmennumber1Number of oscillators (1-16)
unisonVerstimmungnumber0Verstimmung spread in cents
unisonBreitenumber0Stereo panning spread (0-100%)

LFOs (Tremolo & Filter Modulation)

Tremolo (Amplitude LFO)

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

Filter 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
tremoloRatenumberTremolo speed in Hz (0 = off)
tremoloTiefenumberTremolo amount (0-100)
lfoFilterRatenumberFilter LFO speed in Hz (0 = off)
lfoFilterTiefenumberFilter LFO range in Hz
ChiptuneSynth has 3 independent LFOs per track: Vibrato (pitch), Tremolo (volume), and Filter modulation.

MIDI Support

synth.enableMIDI(options) async→ inputNames[]

Aktivierens 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
onNoteOnfunctionCalled on note on (note, velocity, channel)
onNoteOfffunctionCalled on note off (note, channel)
onCCfunctionCalled on control change (cc, value, channel)

Supported MIDI CC

CCNameEffect
1Mod WheelControls vibrato depth
7LautstärkeControls track volume
64Sustain PedalSustains held notes
120All Sound OffStops all notes
123All Notes 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.isMIDIAktivierend() → boolean

Returns whether MIDI is currently active.

Visualizer Data

synth.getWellenformData() → 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.setMasterLautstärke(value)

Sets the master output volume (0-1).

synth.getMasterLautstärke() → 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.getInstrumente() 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 Instrumente

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

Grundlagen 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 entdecken — 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. Lernen more

Default Values

Track Defaults

TrackIndexWellenformLautstärke
Lead0square0.30
Bass1triangle0.40
Drums2noise0.50
FX3sawtooth0.25

Architecture Note

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.