generating-sounds-with-ai について
generating-sounds-with-ai は、Web Audio API の音声合成コードをレビューするスキルです。効果音を実装・確認する開発者向けに、ファイル位置付きのルール違反と集計、パラメーター調整の指針を示します。
主な機能
- 01AudioContext の再利用と再開を確認
- 02オーディオノードの後処理を確認
- 03エンベロープの減衰設定をレビュー
- 04ノイズ、オシレーター、フィルターの使い方を確認
- 05ファイルと行番号、ルール別件数を報告
- 06音の印象をパラメーター変更に対応付け
活用シーン
- 01Web のクリック音実装をレビュー
- 02後処理されていないオーディオノードを発見
- 03ゲインエンベロープの不具合を確認
- 04聴感に応じてフィルターやゲインを調整
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ raphaelsalaja/ skill --skill generating-sounds-with-aiインストール後、Claude Code で/generating-sounds-with-aiを入力して読み込まれたか確認します。
詳細
AI によるサウンド生成
サウンド合成のベストプラクティスに照らして、Web Audio API のコードをレビューします。
動作の仕組み
- 指定されたファイルを読み取ります(または、ファイル/パターンをユーザーに尋ねます)
- 以下のすべてのルールに照らして確認します
file:line形式で指摘事項を出力します
ルールのカテゴリ
| 優先度 | カテゴリ | プレフィックス |
|---|---|---|
| 1 | コンテキスト管理 | context- |
| 2 | 減衰とエンベロープ | envelope- |
| 3 | サウンドデザイン | design- |
| 4 | パラメーター | param- |
ルール
コンテキスト管理のルール
context-reuse-single
単一の AudioContext インスタンスを再利用し、サウンドごとに新しいインスタンスを作成しないでください。
失敗例:
function playSound() {
const ctx = new AudioContext();
// Creates new context every call
}
成功例:
let audioContext: AudioContext | null = null;
function getAudioContext(): AudioContext {
if (!audioContext) {
audioContext = new AudioContext();
}
return audioContext;
}
context-resume-suspended
再生する前に、AudioContext が停止状態かどうかを確認し、停止している場合は再開してください。
失敗例:
function playSound() {
const ctx = getAudioContext();
// Plays immediately without checking state
}
成功例:
function playSound() {
const ctx = getAudioContext();
if (ctx.state === "suspended") {
ctx.resume();
}
}
context-cleanup-nodes
再生後にオーディオノードを切断し、クリーンアップしてください。
失敗例:
source.start();
// Nodes remain connected after sound ends
成功例:
source.start();
source.onended = () => {
source.disconnect();
gain.disconnect();
};
エンベロープのルール
envelope-exponential-decay
自然な減衰には、線形ではなく指数ランプを使用してください。
失敗例:
gain.gain.linearRampToValueAtTime(0, t + 0.05);
成功例:
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
envelope-no-zero-target
指数ランプの目標値に 0 は指定できません。0.001 などの小さな値を使用してください。
失敗例:
gain.gain.exponentialRampToValueAtTime(0, t + 0.05);
成功例:
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
envelope-set-initial-value
グリッチを防ぐため、ランプを開始する前に初期値を設定してください。
失敗例:
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
// No setValueAtTime before ramp
成功例:
gain.gain.setValueAtTime(0.3, t);
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
サウンドデザインのルール
design-noise-for-percussion
クリック音やタップ音には、オシレーターではなくフィルターを適用したノイズを使用してください。
失敗例:
// Click sound using sine oscillator
const osc = ctx.createOscillator();
osc.type = "sine";
// Results in tonal "beep" not "click"
成功例:
// Click sound using noise burst
const buffer = ctx.createBuffer(1, ctx.sampleRate * 0.008, ctx.sampleRate);
const data = buffer.getChannelData(0);
for (let i = 0; i < data.length; i++) {
data[i] = (Math.random() * 2 - 1) * Math.exp(-i / 50);
}
design-oscillator-for-tonal
音程感のあるサウンド(ポップ音、確認音)には、ピッチを変化させるオシレーターを使用してください。
失敗例:
// Confirmation sound using static frequency
osc.frequency.value = 400;
成功例:
// Confirmation sound with pitch sweep
osc.frequency.setValueAtTime(400, t);
osc.frequency.exponentialRampToValueAtTime(600, t + 0.04);
design-filter-for-character
打撃音の音色を整えるため、バンドパスフィルターを適用してください。
失敗例:
// Raw noise without filtering
source.connect(gain).connect(ctx.destination);
成功例:
const filter = ctx.createBiquadFilter();
filter.type = "bandpass";
filter.frequency.value = 4000;
filter.Q.value = 3;
source.connect(filter).connect(gain).connect(ctx.destination);
パラメーターのルール
param-click-duration
クリック音やタップ音の長さは 5~15ms にしてください。
失敗例:
const buffer = ctx.createBuffer(1, ctx.sampleRate * 0.1, ctx.sampleRate);
// 100ms is too long for a click
成功例:
const buffer = ctx.createBuffer(1, ctx.sampleRate * 0.008, ctx.sampleRate);
// 8ms is appropriate for a click
param-filter-frequency-range
クリック音用のバンドパスフィルターは 3000~6000Hz にしてください。
失敗例:
filter.frequency.value = 500; // Too low, sounds muffled
成功例:
filter.frequency.value = 4000; // Crisp, present
param-reasonable-gain
クリッピングを防ぐため、ゲイン値は 1.0 を超えないようにしてください。
失敗例:
gain.gain.setValueAtTime(1.5, t);
成功例:
gain.gain.setValueAtTime(0.3, t);
param-q-value-range
クリック音用のフィルター Q は 2~5 にし、輪郭を保ちつつ耳障りにならないサウンドにしてください。
失敗例:
filter.Q.value = 15; // Too resonant, harsh
成功例:
filter.Q.value = 3; // Focused but natural
出力形式
ファイルをレビューするときは、指摘事項を次の形式で出力してください。
file:line - [rule-id] description of issue
Example:
lib/sounds.ts:23 - [envelope-exponential-decay] Using linearRampToValueAtTime instead of exponential
lib/sounds.ts:45 - [context-reuse-single] Creating new AudioContext on each call
まとめの表
指摘事項の後に、次のまとめを出力してください。
| ルール | 件数 | 重大度 |
|---|---|---|
context-reuse-single | 1 | HIGH |
envelope-exponential-decay | 3 | MEDIUM |
param-click-duration | 1 | LOW |
パラメーター変換表
ユーザーが問題を説明した場合は、次のようにパラメーター変更へ置き換えてください。
| ユーザーの表現 | パラメーターの変更 |
|---|---|
| "耳障りすぎる" | フィルター周波数を下げ、Q を小さくする |
| "こもりすぎる" | フィルター周波数を上げる |
| "長すぎる" | 長さを短くし、減衰を速くする |
| "急に途切れる" | 指数減衰を使用する |
| "より機械的に" | Q を大きくし、減衰を速くする |
| "より柔らかく" | ゲインを下げ、三角波を使用する |