API 文档

ChiptuneSynth 完整参考指南 — 基于 Web Audio API 的 4 轨芯片音乐合成器

快速入门

// 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);
AudioContext 需要用户手势(点击/轻触)才能启动。请务必在点击处理程序内部或用户交互之后调用 `init()`。

构造函数与初始化

new ChiptuneSynth()

创建一个包含 4 个音轨(主音、低音、鼓、效果音)、默认包络以及空的颤音设置的新合成器实例。

const synth = new ChiptuneSynth();

synth.init() async

初始化 Web Audio API 上下文,创建主增益、分析器、各音轨增益节点以及噪声缓冲区。必须在任何播放操作之前调用一次。

await synth.init();

synth.dispose()

停止所有音符并关闭 AudioContext。当不再使用该合成器时调用此方法。

播放方法

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

在指定音轨上播放频率为 (Hz) 的音符。

参数类型默认值描述
frequency数字频率(单位:赫兹)(例如:A4 为 440)
trackIndex数字0音轨索引:0=主音,1=贝斯,2=鼓,3=效果
时长数字10时长(单位:秒)。值≥10将生成持续音
startTime数字现在AudioContext 开始时间(用于调度)
const noteId = synth.playNote(440, 0, 0.5);  // A4, Lead, 0.5s
若需通过 `stopNote()` 手动控制延音音符,请使用 `duration = 10` 或更高版本。键盘和 MIDI 即是通过此方式工作的。

synth.playNoteByName(note, octave, trackIndex, duration) → noteId

根据音名播放音符。

参数类型默认描述
音符字符串音符名称:C、C#、D、D#、E、F、F#、G、G#、A、A#、B(也包括 Db、Eb、Gb、Ab、Bb)
八度数字4八度 (1-7)
轨道索引编号0目标曲目
时长编号10时长(秒)
synth.playNoteByName('C', 4, 0, 0.5);  // Middle C on Lead
synth.playNoteByName('Eb', 3, 1, 1.0); // Eb3 on Bass

synth.stopNote(noteId)

停止特定音符及其释放包络。请使用playNote()playNoteByName()返回的noteId。

synth.stopAllNotes()

立即停止所有音轨中所有正在播放的音符。

预设与乐器

synth.playPreset(name)

通过一次调用加载并播放内置的 SFX 预设。非常适合游戏音效。

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

可用 SFX 预设 (10)

名称描述使用场景
激光向下射出的电击光束射击、光束
硬币上升的明亮叮声收集物品
跳跃快速上升扫射跳跃、弹跳
爆炸噪音爆发衰减毁灭、死亡
能量提升上升扫荡号角强化道具、升级
击中尖锐的撞击声伤害、碰撞
短促的UI点击声菜单选择、UI
低音深沉的三角铁重击低音下沉、冲击
射击快速电击射击连发武器
1UP升腾的号角额外生命、奖励

synth.loadPreset(name)

将预设的配置(波形、包络、效果)加载到音轨上,但不播放。适用于在手动触发音符之前设置音轨。

synth.loadInstrument(name, trackIndex) → boolean

将完整的乐器预设加载到指定音轨,配置波形、包络、颤音和调制。

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

可用乐器 (12)

名称类型描述
钢琴三角铁明亮的打击乐音色,衰减迅速
小提琴锯齿波温暖的弓弦音色,带有颤音
大提琴锯齿波低音区深沉的弓弦声
长笛正弦波柔和的、带有颤音的呼吸音色
管风琴方波长音管风琴音色
铜管锯齿波粗犷的号角/小号音色
口琴方波带颤音的簧片PWM音色
合成器主音方波经典芯片音乐主音
合成器垫音锯齿波宽广的齐奏垫音(带滤波器)
合成贝斯锯齿波强劲的合成贝斯
马林巴琴正弦波打击乐槌击音色
电吉他方波过载吉他模拟

音轨配置

synth.updateTrack(trackIndex, settings)

更新音轨的一个或多个属性。更改将实时应用于当前正在播放的音符。

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

音轨属性

属性类型默认值描述
type字符串'方波'波形:'方波'、'三角波'、'锯齿波'、'正弦波'、'噪声'
音量数字0.3音量 (0-1)
占空比数值0.5方波脉冲宽度 (0-1)
失谐数值0以分音为单位的微调(1200 = 1 个八度)
八度偏移数字0八度偏移 (±)
半音偏移数字0半音偏移 (±)
音高包络数字0音高包络深度(半音)
滑音数值0滑音时间(秒)

您还可以直接设置轨道对象的属性:

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

包络(ADSR)

synth.updateEnvelope(trackIndex, settings)

设置音轨的幅度包络。控制音符的渐入、保持和渐出效果。

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
});
属性类型范围描述
attack数值0-5秒达到最大音量所需时间
衰减数值0-5秒从峰值降至持续音量所需的时间
sustain数值0-1音符保持期间的音量级别(0 = 衰减后关闭)
释放数值0-10 秒音符停止后的淡出时间

默认包络

音轨起音衰减延音释放
0 - 主音0.010.100.70.20
1 - 低音0.010.200.80.15
2 - 鼓0.0010.100.00.05
3 - 音效0.0050.300.00.20

颤音

synth.updateVibrato(trackIndex, settings)

配置音轨的音高调制(颤音)。

synth.updateVibrato(0, {
  rate:  5,   // Speed in Hz
  depth: 12   // Amount in cents
});
属性类型默认值描述
速率数字0LFO 速度(单位:Hz)(0 = 关闭)
深度数值0音高偏移(以分表示)(0 = 关闭)

滤波器

每条音轨都配有一个可选滤波器,用于塑造声音的频率成分。

synth.tracks[0].filterEnabled = true;
synth.tracks[0].filterType = 'lowpass';
synth.tracks[0].filterCutoff = 2000;
synth.tracks[0].filterQ = 5;
synth.updateLiveNotes(0);
属性类型默认描述
filterEnabled布尔值false启用/禁用过滤器
filterType字符串'低通''低通', '高通', '带通', '陷波'
滤波器截止频率数字20000截止频率(单位:Hz)
filterQ数字0.1共振 / Q 因子
滤波器键轨数字0键跟踪 0-100(截止频率随音高变化)
滤波器包络量数字0滤波器包络深度(半音)
滤波器包络起音数字0.01滤波器包络攻击时间(秒)
filterEnvRelease数值0.2滤波器包络释放(秒)

齐奏与失谐

叠加多个失谐振荡器,营造厚实、宽广的声音。对于垫音和主奏音色至关重要。

synth.tracks[0].unisonVoices = 8;
synth.tracks[0].unisonDetune = 25;  // cents between voices
synth.tracks[0].unisonSpread = 80;  // stereo spread %
属性类型默认描述
unisonVoices数字1振荡器数量 (1-16)
unisonDetune数字0音高偏移范围(以分音为单位)
齐奏音程数字0立体声声像范围(0-100%)

低频振荡器(颤音与滤波器调制)

颤音(振幅 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
属性类型描述
tremoloRate数字颤音速度(单位:Hz)(0 = 关闭)
tremoloDepth数字颤音量(0-100)
lfoFilterRate数字滤波器 LFO 速度(单位:Hz)(0 = 关闭)
lfoFilterDepth数字滤波器 LFO 范围(单位:Hz)
ChiptuneSynth 每条音轨拥有 3 个独立的 LFO:颤音(音高)、颤音(音量)和滤波器调制。

MIDI 支持

synth.enableMIDI(options) async→ inputNames[]

启用来自连接控制器的 MIDI 输入。返回一个检测到的 MIDI 输入设备名称数组。

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

选项

属性类型默认描述
track编号0MIDI 音符的目标音轨
通道编号0MIDI 通道过滤器(1-16,0 = 全部)
onConnectonConnect当 MIDI 设备连接时调用
onDisconnectonDisconnect当 MIDI 设备断开连接时调用
onNoteOn函数在音符开启时调用 (note, velocity, channel)
onNoteOff函数在音符关闭时调用 (note, channel)
onCConNoteOff在控制变化时调用 (cc, value, channel)

支持的 MIDI CC

CC名称效果
1调制轮控制颤音深度
7音量控制音轨音量
64延音踏板延音踏板
120全部静音停止所有音符
123关闭所有音符停止所有音符

synth.disableMIDI()

禁用 MIDI 输入并停止所有正在发声的 MIDI 音符。

synth.setMIDITrack(trackIndex)

更改接收 MIDI 输入的轨道。

synth.setMIDIChannel(ch)

设置 MIDI 通道过滤器(0 表示所有通道)。

synth.isMIDIEnabled() → boolean

返回当前 MIDI 是否处于活动状态。

可视化数据

synth.getWaveformData() → Uint8Array

返回用于绘制示波器样式可视化的时域波形数据。值范围为 0-255(128 = 中心)。

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

返回用于频谱可视化的时域(FFT)数据。数值范围为 0-255。

synth.setMasterVolume(value)

设置主输出音量(0-1)。

synth.getMasterVolume() → 数字

返回当前主音量。

synth.resetToDefaults()

将所有音轨、包络和颤音重置为默认值。

静态方法

ChiptuneSynth.noteToFrequency(note, octave) static→ number

将音符名称和八度音转换为以赫兹为单位的频率。

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

ChiptuneSynth.midiToFrequency(midi) static→ number

将 MIDI 音符编号(0-127)转换为频率(单位:Hz)。

ChiptuneSynth.frequencyToMidi(freq) static→ number

将频率转换为最接近的 MIDI 音符编号。

ChiptuneSynth.getPresetNames() static→ string[]

返回一个包含所有可用 SFX 预设名称的数组。

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

ChiptuneSynth.getInstrumentNames() static→ string[]

返回一个包含所有可用乐器预设名称的数组。

ChiptuneSynth.getInstruments() static→ object

返回一个以乐器名称为键的对象,每个值包含完整的定义(音轨设置、包络、颤音、滤波器等)。

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'

创建自定义乐器

您可以通过组合音轨设置、包络、颤音和滤波器来制作自己的乐器。以下是从零开始构建声音的方法。

基础自定义音色

手动配置音轨,然后在其上演奏音符:

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

带效果的丰富乐器

结合多种功能,打造富有表现力的乐器:

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

多轨分层音效

叠加多条音轨以生成复杂音色:

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

可复用乐器对象模式

将自定义乐器组织为配置对象:

// 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);
可复用乐器对象模式是管理游戏或应用中自定义乐器的推荐方法。它能让您的音效设计保持简洁,并便于调整。
探索 8BitForge —— 这款基于 ChiptuneSynth 构建的创意应用,配备可视化乐器编辑器、8 条音轨、带 EQ/压缩器的全功能混音台、每条音轨 3 个 LFO,以及 50 多种内置乐器。了解更多

默认值

音轨默认设置

音轨索引波形音量
主音0方形0.30
低音1三角铁0.40
2噪音0.50
音效3锯齿波0.25

架构说明

每个音符的gainNode仅处理ADSR包络(归一化0→1→保持)。音轨音量由独立的_trackGains[]节点控制。这种架构允许实时更改参数,同时不干扰正在播放音符的ADSR进程。