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つのトラック(Lead、Bass、Drums、FX)、デフォルトのエンベロープ、および空のビブラート設定を持つ新しいシンセサイザーインスタンスを作成します。

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数値周波数(Hz)(例:A4の場合は440)
trackIndex番号0トラックインデックス:0=リード、1=ベース、2=ドラム、3=FX
duration番号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

音名でノートを再生します。

パラメータデフォルト説明
note文字列音名: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)

1回の呼び出しで、組み込みのSFXプリセットを読み込んで再生します。ゲームのサウンドエフェクトに最適です。

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

利用可能なSFXプリセット (10)

名前説明使用例
laser下降するザップビーム射撃、ビーム
コイン上昇する明るい音アイテム収集
ジャンプ素早い上昇スイープジャンプ、バウンド
爆発ノイズバーストの減衰破壊、死
パワーアップ上昇するスイープファンファーレパワーアップ、アップグレード
ヒット鋭い衝撃音ダメージ、衝突
ビープ音UIの短めのクリックメニュー選択、UI
低音深い三角形のドスンという音低音のドロップ、衝撃
撃つ素早い放電ショット連射武器
1UP上昇ファンファーレ追加ライフ、ボーナス

synth.loadPreset(name)

プリセットの設定(波形、エンベロープ、エフェクト)を、再生せずにトラックに読み込みます。手動でノートをトリガーする前にトラックを設定するのに便利です。

synth.loadInstrument(name, trackIndex) → boolean

指定されたトラックに完全なインストゥルメント・プリセットを読み込み、波形、エンベロープ、ビブラート、モジュレーションを設定します。

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

利用可能なインストゥルメント (12)

名前タイプ説明
pianoトライアングル明るい打楽器のような音色で、余韻が短い
ヴァイオリンノコギリ波ビブラートのかかった温かみのある弓奏
チェロノコギリ波低音域の深い弓奏
フルート正弦波ビブラートを伴う柔らかく息の通った音色
オルガンスクエアサステインのあるパイプオルガンの音色
brass鋸歯波力強いホルン/トランペットの音
ハーモニカスクエアトレモロ付き葦のようなPWM音色
シンセリードスクエアクラシック・チップチューン・リード
シンセパッドソーフィルター付きワイドユニゾン・パッド
シンセベースソー歯波パンチのあるシンセベース
マリンバサイン波パーカッシブなマレット音色
エレクトリックギタースクエアオーバードライブ・ギター・エミュレーション

トラック設定

synth.updateTrack(trackIndex, settings)

トラックの1つ以上のプロパティを更新します。変更は、現在再生中のノートにリアルタイムで反映されます。

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

トラックのプロパティ

プロパティデフォルト説明
タイプ文字列'square'波形: 'square', 'triangle', 'sawtooth', 'sine', 'noise'
音量数値0.3トラック音量 (0-1)
デューティサイクル数値0.5矩形波のパルス幅 (0-1)
デチューン数値0セント単位の微調整 (1200 = 1 オクターブ)
オクターブオフセット数値0オクターブシフト (±)
semitoneOffset数値0半音シフト (±)
ピッチエンベロープ数値0半音単位でのピッチエンベロープの深さ
glide数値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
});
プロパティ範囲説明
attack0~5秒最大音量に達するまでの時間
減衰数値0~5秒ピークからサスティンレベルまで低下する時間
サスティン数値0-1ノートを保持している間の音量レベル(0 = 減衰後にオフ)
release数値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
});
プロパティデフォルト説明
rate数値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文字列'lowpass''lowpass', 'highpass', 'bandpass', 'notch'
filterCutoff数値20000カットオフ周波数(Hz)
filterQ数値0.1共振 / Q値
filterKeyTrack数値0キートラッキング 0-100 (カットオフはピッチに追従)
filterEnvAmount数値0フィルターエンベロープの深さ(半音)
filterEnvAttack数値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 %
プロパティタイプデフォルト説明
ユニゾンボイス1オシレーター数 (1-16)
unisonDetune数値0デチューンの広がり(セント単位)
ユニゾンスプレッド数値0ステレオ・パンニング・スプレッド (0-100%)

LFO(トレモロ&フィルターモジュレーション)

トレモロ (振幅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 = すべて)
onConnectonConnectMIDIデバイスが接続されたときに呼び出される
onDisconnect関数MIDIデバイスが切断されたときに呼び出されます
onNoteOn関数note on 時に呼び出される (note, velocity, channel)
onNoteOff関数ノートオフ時に呼び出される (note, channel)
onCC関数コントロールチェンジ時に呼び出される (cc, value, channel)

サポートされているMIDI CC

CC名前エフェクト
1モジュレーション・ホイールビブラートの強さを調整します
7Volumeトラックの音量を調整します
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() → number

現在のマスター音量を返します。

synth.resetToDefaults()

すべてのトラック、エンベロープ、ビブラートをデフォルト値にリセットします。

静的メソッド

ChiptuneSynth.noteToFrequency(note, octave) static→ number

音名とオクターブを Hz 単位の周波数に変換します。

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

ChiptuneSynth.noteToFrequency(note, octave) 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);

カスタムSFX(プリセットスタイル)

プリセットのパターンを再現します。トラックを設定し、ノートを演奏すれば、あとはエンベロープが処理してくれます:

// 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/コンプレッサー付きフルミキサー、トラックごとのLFO 3つ、50種類以上の内蔵楽器を備えています。詳細はこちら

デフォルト値

トラックのデフォルト設定

トラックインデックス波形音量
リード0正方形0.30
低音1トライアングル0.40
ドラム2ノイズ0.50
エフェクト3ノコギリ波0.25

アーキテクチャに関する注記

ノートごとのgainNodeは、ADSRエンベロープ(正規化0→1→サスティン)のみを処理します。トラックの音量は、別の_trackGains[]ノードによって制御されます。このアーキテクチャにより、演奏中のノートのADSRスケジュールを中断することなく、リアルタイムでパラメータを変更することが可能です。