入门指南

逐步学习 ChiptuneSynth — 点击“运行”即可实时试听每个示例

1

你好,Chiptune!

创建一个合成器,初始化它,并播放你的第一个音效——仅需 3 行代码。

const synth = new ChiptuneSynth();
await synth.init();
synth.playPreset('coin');  // ding!
AudioContext 需要用户操作(点击)才能启动——这就是我们使用按钮的原因。
2

按名称播放音符

在主音轨(轨道 0)上播放中音 C 半秒钟。

synth.playNoteByName('C', 4, 0, 0.5);
// note, octave, track, duration (seconds)
3

演奏旋律

安排多个音符的时长,以创作一段简单的旋律。

const melody = [
  { note:'C', oct:4, time:0 },
  { note:'E', oct:4, time:0.25 },
  { note:'G', oct:4, time:0.5 },
  { note:'C', oct:5, time:0.75 }
];
melody.forEach(n =>
  setTimeout(() =>
    synth.playNoteByName(n.note, n.oct, 0, 0.3),
    n.time * 1000
  )
);
4

加载乐器

将默认的方波切换为小提琴,然后弹奏一个音符。

synth.loadInstrument('violin', 0);
synth.playNoteByName('A', 4, 0, 1.5);
// Available: piano, violin, cello, flute, organ,
// brass, harmonica, synthLead, synthPad, synthBass,
// marimba, electricGuitar
5

多轨叠加

在不同的音轨上同时演奏不同的乐器。

synth.loadInstrument('synthPad', 0);  // Lead
synth.loadInstrument('synthBass', 1); // Bass

// Play a chord on the pad
synth.playNoteByName('C', 4, 0, 2);
synth.playNoteByName('E', 4, 0, 2);
synth.playNoteByName('G', 4, 0, 2);

// Bass note underneath
synth.playNoteByName('C', 2, 1, 2);
6

调整音色

自定义包络、颤音和波形,塑造您的音色。

// Slow attack pad
synth.updateEnvelope(0, {
  attack: 0.5, decay: 0.3,
  sustain: 0.6, release: 1.0
});

// Add vibrato
synth.updateVibrato(0, {
  rate: 5, depth: 8
});

// Change waveform to sawtooth
synth.updateTrack(0, { type: 'sawtooth' });

synth.playNoteByName('D', 4, 0, 2.5);
7

游戏音效组合

将多个音效串联成游戏场景——收集金币、升级、射击!

synth.playPreset('coin');
setTimeout(() => synth.playPreset('powerup'), 400);
setTimeout(() => synth.playPreset('laser'), 1200);
setTimeout(() => synth.playPreset('explosion'), 1500);
setTimeout(() => synth.playPreset('1up'), 2200);
8

波形可视化

在画布上绘制实时音频波形——非常适合游戏界面!

function draw() {
  const data = synth.getWaveformData();
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.strokeStyle = '#00f0ff';
  ctx.beginPath();
  data.forEach((v, i) => {
    const x = (i / data.length) * canvas.width;
    const y = (v / 255) * canvas.height;
    i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
  });
  ctx.stroke();
  requestAnimationFrame(draw);
}
draw();