메인 데모
CDN v3.0.0

페이지에 이 두 태그를 추가하세요 — </body> 또는 <head> :

신스 엔진
<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.