マガジン

一つの音を加工して効果音を10種類作れるか:高さ・速さ・逆再生の実験設計

遊びをつくる

執筆にClaudeを使用しています。

つなぎ目のない銅色のリボンとテープリールで、自然なBGMループを表した写真風イメージ。
記事のテーマをもとに制作したAI生成イラスト。

ゲームの効果音を一つずつ探して集めると、ファイルが増え、音の雰囲気もばらつきます。では、短い音を一つだけ用意して、再生の仕方を変えるだけで10種類の効果音を作ったらどうなるでしょうか。決定音、キャンセル音、取得音、失敗音、残り時間の警告音まで、一つの素材から用途ごとに「別の音」として聞き分けられるかを確かめます。 使う加工は三つだけです。高さを変える、速さを変える、逆から再生する。この記事は、その10種類を自分の手で作り、聞き分けられるかを記録して判断するための実験の設計書です。結果は書いていません。何が聞き分けやすく、何が似てしまうかは、実際に鳴らして初めてわかります。 あらかじめ一つだけ押さえておきます。ブラウザの再生速度(Web Audio APIのplaybackRate)を変えると、高さと長さが同時に変わります。速くすれば高く短くなり、遅くすれば低く長くなります。「高さだけ」「速さだけ」を独立に動かすには別の手法が要ります。この実験では扱いません。連動する前提で、どこまで音の種類を増やせるかを試します。

この記事の目次
  1. 実験で確かめる問い
  2. 準備するもの
  3. 手順:10種類のレシピを鳴らす
  4. 記録の取り方
  5. 結果の読み方
  6. 起こりやすい誤り
  7. 次の行動
  8. 参考資料

実験で確かめる問い

問いは次の一文です。「一つの原音から作った10種類の音を、用途の違う効果音として聞き分けられるか。」

これを三つの観察に分けて考えます。

  • 近い加工同士(例:原音と「少し高く」)が、同じ音として混同されないか
  • 逆再生や高さの変化が、決定・失敗・取得といった用途の印象と結びつくか
  • 10種類を続けて聞いても、同じ素材から出た音だと気づかれて飽きないか

一つ目は聞き分けの問題、二つ目は用途への割り当ての問題、三つ目はゲームの中で使ったときの問題です。いずれも自分一人の耳だけでは判断を誤りやすいので、後で述べるように他の人にも聞いてもらう形にします。

準備するもの

  • ブラウザ(音を鳴らせるもの)と、テキストエディタ
  • ヘッドホンとスピーカーの両方(再生環境で印象が変わるため)
  • 原音。次のコードのように、短い音をその場で合成します。自分の声や手拍子を録音したファイルで差し替えてもかまいません
  • 記録用の紙か表計算ソフト
  • 聞き分けを確かめるための、できれば2人以上の協力者

原音は長さ0.2〜0.5秒ほどで、音の立ち上がりがはっきりしたものを選びます。立ち上がりが曖昧な音は、逆再生すると「だんだん大きくなって突然切れる」音になり、通常の再生との違いが強く出ます。逆に、音が一定の大きさで続くだけの素材は、逆再生しても元と区別がつきません。素材選びが、この実験の結果を大きく左右します。

手順:10種類のレシピを鳴らす

次のコードを index.html として保存し、ブラウザで開きます。外部ライブラリは使いません。ボタンを押すと、一つの原音から作った音が鳴ります。

html
<!doctype html><meta charset="utf-8">
<script>
const ctx = new AudioContext();
const sr = ctx.sampleRate;
// 原音:0.3秒の下降する「ぽん」
const base = ctx.createBuffer(1, sr * 0.3, sr);
const d = base.getChannelData(0);
for (let i = 0; i < d.length; i++) {
  const t = i / sr;
  d[i] = Math.sin(2 * Math.PI * (600 - 800 * t) * t) * Math.exp(-t * 12);
}
// 逆再生用:同じ波形を後ろから並べ直す
const rev = ctx.createBuffer(1, base.length, sr);
rev.getChannelData(0).set(d.slice().reverse());

function play(buf, r0, r1 = r0, at = 0) {
  const s = ctx.createBufferSource();
  s.buffer = buf;
  const t = ctx.currentTime + at;
  s.playbackRate.setValueAtTime(r0, t);
  s.playbackRate.linearRampToValueAtTime(r1, t + buf.duration);
  const g = ctx.createGain();
  g.gain.value = 0.5;
  s.connect(g).connect(ctx.destination);
  s.start(t);
}
const recipes = {
  "1 原音": () => play(base, 1),
  "2 高く": () => play(base, 2),
  "3 低く": () => play(base, 0.5),
  "4 逆再生": () => play(rev, 1),
  "5 逆・高く": () => play(rev, 2),
  "6 逆・低く": () => play(rev, 0.5),
  "7 上昇": () => play(base, 0.5, 2),
  "8 下降": () => play(base, 2, 0.5),
  "9 逆・上昇": () => play(rev, 0.5, 2),
  "10 連打": () => [1, 1.25, 1.5].forEach((r, i) => play(base, r, r, i * 0.08)),
};
for (const [name, fn] of Object.entries(recipes)) {
  const b = document.createElement("button");
  b.textContent = name;
  b.onclick = () => { ctx.resume(); fn(); };
  document.body.append(b);
}
</script>

10個のレシピは、加工の軸で次のように整理できます。

  • 1、加工:原音、軸:基準
  • 2・3、加工:2倍・0.5倍の速度、軸:高さ(長さも連動)
  • 4、加工:逆再生、軸:向き
  • 5・6、加工:逆再生に2倍・0.5倍、軸:向き+高さ
  • 7・8、加工:再生中に速度を0.5→2、2→0.5へ動かす、軸:高さの変化
  • 9、加工:逆再生で0.5→2、軸:向き+高さの変化
  • 10、加工:速度1・1.25・1.5で80ms間隔に3回、軸:繰り返し+高さ

7〜9は再生の途中で速度を連続的に変えるため、音程が滑るように動きます。数値(2倍、0.5倍、80msなど)は出発点にすぎません。聞き分けにくければ、数値を動かして調整してください。

記録の取り方

実験は、自分で聞く段階と、他の人に聞いてもらう段階の二段構えにします。

自分で聞く段階

10個を1回ずつ、番号順に鳴らします。その後、順番をばらして、もう1セット鳴らします。1音ごとに次の三点を記録します。

  • 用途のラベル:決定、キャンセル、取得、失敗、警告など、最初に浮かんだ言葉を一つ
  • 原音との距離:「ほぼ同じ」「違う」「別の音に聞こえる」の3段階
  • 不快さ:繰り返し聞いて耳が疲れるかを、1〜5で

順番をばらした2セット目でラベルが1セット目と変わった音は、印象が安定していない音です。ラベルが変わらない音は、用途を割り当てる候補になります。

他の人に聞いてもらう段階

自分は加工の中身を知っているため、聞こえ方に先入観が入ります。協力者には番号の対応を伏せ、次の手順で聞いてもらいます。

  1. 10音をランダムな順番で1回ずつ鳴らす(番号は見せない)
  2. 聞くたびに、ゲームの中のどんな場面の音に聞こえるかを一言で書いてもらう
  3. 最後に、原音と同じに聞こえた音があれば、その順番を挙げてもらう

人数は多いほど判断は安定しますが、まずは2〜3人でもかまいません。ここでの目的は統計的な結論を出すことではなく、自分の耳の偏りに気づくことです。

記録表は次のような形にします。

番号 / 自分のラベル(1回目) / 自分のラベル(2回目) / 協力者Aのラベル / 協力者Bのラベル / 原音と同じと言われた回数

結果の読み方

表が埋まったら、次の基準で読みます。

  • ラベルが一致している音は採用候補です。 自分の2回と協力者のラベルが近い言葉(例:どちらも「取った」系)なら、その用途に割り当ててよい音です。
  • 原音と同じと言われた音は、差が小さすぎます。 数値を動かして距離を広げるか、どちらか一方を捨てます。2倍と1.25倍のように近い速度は、特に混同されやすい組です。
  • ラベルがばらばらな音は、場面を限定しない音です。 用途を決めず、環境音や演出に回すという判断もあります。
  • 不快さが高い音は、頻度の低い場面に回します。 低く長い音や、逆再生の急に切れる音は繰り返すと耳に残りやすいため、何度も鳴る場面には向きません。
  • 「同じ素材だ」と言われた場合は、使う場面を分けます。 同じ画面で続けて鳴る音同士は、加工の軸を変えて差をつけます。

たとえば「高くした音」と「低くした音」が、ともに「決定」とラベルされたなら、高さの差は用途の差になっていません。その場合は、高さを変えるより、逆再生や上昇・下降といった動きを加えるほうが用途の差を作れるかもしれません。これは仮説であり、実際に自分の素材で確かめる必要があります。

起こりやすい誤り

  • 音量差を見落とします。 速度を変えると、聞こえる大きさも変わって聞こえます。音量が違うだけで印象が決まっていないかを、音量をそろえた状態でも聞いて確かめます。
  • 一度に全部を聞いて判断します。 続けて聞くと比較になり、単独で鳴ったときの印象とずれます。ゲーム内では単独で鳴る場面が多いので、1音だけを鳴らして印象を書き留めます。
  • 自分の耳だけで決めます。 作った本人は加工の違いに敏感すぎます。違いが大きく聞こえても、他の人には同じに聞こえることがあります。
  • 再生環境を一つに限ります。 スマートフォンの小さなスピーカーでは、低くした音が弱く聞こえることがあります。遊ぶ人の環境に近い機器でも確認してください。
  • 高さと速さを別々に動かせたと思い込みます。 この方法では連動しています。「高いのに長い音」は作れません。

次の行動

まずコードを保存して、10個のボタンを自分で鳴らしてください。そのうえで協力者に番号を伏せて聞いてもらい、記録表から採用できる音を3つ選んでみてください。選んだ音は、ゲームの中で実際の操作に結びつけて鳴らし、違和感がないかを確かめます。

なお、アソバースに投稿するゲームは、アップロード全体で20MiB以内などの容量の条件があります。一つの原音から作る方法は、音声ファイルを増やさずに済む選択肢の一つです。投稿前に、現在の案内で条件を確認してください。

参考資料

  • MDN Web Docs「Web Audio API」「AudioBufferSourceNode」「AudioParam」