雨音を自分で作る:ノイズをフィルターで雨にする
遊びをつくる執筆にClaudeを使用しています。

ブラウザゲームに雨の場面を入れたいとき、雨音の音声ファイルを探して組み込むのが定番の方法です。ただ、コードだけで雨音を作れるなら、ファイルを持たずに済みます。容量が軽くなり、強さや雰囲気を実行中に滑らかに変えることもできます。 そこで問いです。何の特徴もない「ザーッ」というだけのノイズは、周波数の操作だけでどこまで雨に近づくでしょうか。この記事は、その答えを読者が自分の耳で出すための実験の設計書です。結果は書きません。手元で鳴らし、条件を一つずつ動かして、自分の基準で判断してください。 使うのはWeb Audio APIというブラウザ標準の音の仕組みだけです。外部ライブラリもサーバーも要りません。乱数で作ったノイズに、特定の周波数帯だけを通すフィルターをかけ、そこに「粒」の音を重ねます。この3段階で、何が雨らしさを決めるのかを切り分けます。
何を確かめるか:三つの変数と仮説
雨音を分解すると、少なくとも三つの要素があります。まず、屋根や地面に当たる無数の雨粒が重なった「ザーッ」という背景です。次に、その背景がどの周波数帯に偏っているか。最後に、背景の上に聞こえる個々の雫の音です。実験ではこれを次の変数に置き換えます。
- 背景のノイズ:乱数から作ったホワイトノイズです。ホワイトノイズは全周波数に均等にエネルギーが散らばった音で、人の耳には高域が強く聞こえやすい性質があります。
- 帯域の偏り:バンドパスフィルターの中心周波数と、通す幅(Q値)です。Qが小さいほど幅が広く、大きいほど狭くなります。
- 粒:短く高い音を、ランダムな間隔で重ねたものです。
実験を始める前に、自分の仮説を紙に書いておいてください。たとえば「中心周波数が低すぎると風や換気扇に聞こえ、高すぎると砂嵐に聞こえるはずで、雨らしい範囲はその間にある」「粒がゼロだと雨ではなく単なる雑音に聞こえる」といった形です。仮説と結果のずれが、この実験でいちばん面白い部分になります。
準備するもの
- モダンブラウザ(Web Audio APIに対応したもの)と、テキストエディタ
- 有線かBluetoothを問わず同じヘッドホン(スピーカーでも構いませんが、実験中は変えないでください)
- 記録用の紙か表計算ソフト
- 可能なら、条件を伏せて聞き比べてくれる協力者を1人
音量には注意してください。ノイズは意外に耳に刺さります。最初は端末の音量を低めにして、少しずつ上げてください。
次のコードを rain.html として保存し、ブラウザで開きます。音は、ボタンを押した後でないと鳴りません。ブラウザは利用者の操作前の自動再生を制限しているためです。
<!doctype html>
<meta charset="utf-8">
<button id="go">雨を鳴らす</button>
<label>中心周波数 <input id="f" type="range" min="400" max="8000" value="3000"></label>
<label>Q <input id="q" type="range" min="0.2" max="4" step="0.1" value="0.7"></label>
<label>粒の量 <input id="d" type="range" min="0" max="30" value="8"></label>
<script>
let ctx, band;
const $ = id => document.getElementById(id);
function update() {
if (!band) return;
band.frequency.value = +$("f").value;
band.Q.value = +$("q").value;
}
$("f").oninput = $("q").oninput = update;
function drop() {
const n = +$("d").value;
if (n > 0) {
const o = ctx.createOscillator(), g = ctx.createGain(), t = ctx.currentTime;
o.frequency.value = 1500 + Math.random() * 2500;
g.gain.setValueAtTime(0.04, t);
g.gain.exponentialRampToValueAtTime(0.0001, t + 0.05);
o.connect(g).connect(ctx.destination);
o.start(t); o.stop(t + 0.06);
}
const rate = Math.max(n, 1);
setTimeout(drop, -Math.log(Math.random()) * 1000 / rate);
}
$("go").onclick = () => {
if (ctx) return;
ctx = new AudioContext();
const len = ctx.sampleRate * 2;
const buf = ctx.createBuffer(1, len, ctx.sampleRate);
const data = buf.getChannelData(0);
for (let i = 0; i < len; i++) data[i] = Math.random() * 2 - 1;
const src = ctx.createBufferSource();
src.buffer = buf; src.loop = true;
const hp = ctx.createBiquadFilter();
hp.type = "highpass"; hp.frequency.value = 500;
band = ctx.createBiquadFilter(); band.type = "bandpass";
const gain = ctx.createGain(); gain.gain.value = 0.25;
src.connect(hp).connect(band).connect(gain).connect(ctx.destination);
src.start();
update(); drop();
};
</script>コードの流れは次のとおりです。
- 2秒分のバッファに、-1から1までの乱数を詰めます。これがホワイトノイズです。
- バッファをループ再生し、ハイパスフィルターで500Hz未満の低音を削ります。
- バンドパスフィルターで、中心周波数の付近だけを通します。
- 粒は、1.5kHzから4kHzのランダムな高さの短い音を、指数分布の間隔で鳴らします。指数分布にすると、雨粒のように「不規則だが平均すると一定の頻度」という並びになります。粒はフィルターを通さず、直接出力に流しています。
手順:条件を一つずつ動かす
実験の原則は、1回に動かす変数を一つだけにすることです。三つを同時に触ると、何が効いたのか分からなくなります。
手順1:まず基準を決める
- 中心周波数3000、Q 0.7、粒の量8の初期状態で、ボタンを押して30秒聞きます。
- この音を「基準」と呼び、雨らしさを1(全く雨に聞こえない)から5(雨に聞こえる)で採点します。
- 続けて、「何に聞こえるか」を一言で書きます。風、換気扇、砂嵐、シャワー、屋根の雨など、思いついた言葉で構いません。
手順2:中心周波数だけを動かす
Qは0.7、粒の量は8のまま、中心周波数を800、2000、3000、5000、7000の順に変えます。一つの条件につき30秒以上聞いてください。各条件で、採点と一言を記録します。
手順3:Qだけを動かす
中心周波数を手順2で最も雨らしかった値に固定します。Qを0.3、0.7、2、4と変えて、同じ記録を取ります。
手順4:粒の量だけを動かす
中心周波数とQを手順2・3の最良値に固定し、粒の量を0、8、20に変えます。粒の量を上げた直後は、次の粒が鳴るまで少し間があくことがあります。数秒聞いてから判断してください。
手順5:協力者に伏せて聞いてもらう
自分の耳は、条件を知っていると判断が偏ります。可能なら、協力者に画面を見せず、あなたが条件を切り替えた音を聞いてもらい、同じ採点をしてもらってください。条件を出す順番はサイコロやくじなどでランダムにします。
記録の取り方
記録は、条件ごとに1行の表にします。
- 1、周波数:3000、Q:0.7、粒:8、雨らしさ(1〜5):、一言:、聞いた人:自分
- 2、周波数:800、Q:0.7、粒:8、雨らしさ(1〜5):、一言:、聞いた人:自分
同じ条件を2回、別の日や時間を置いて採点してください。同じ条件でも点が大きくぶれるなら、その差は条件の効果ではなく、聞き手の状態や環境の影響が混ざっている可能性があります。
採点より、「一言」の欄を大切にしてください。「3だった」より「換気扇っぽい」のほうが、次にどこを直すかの手がかりになります。
結果の読み方:こうなればこう判断する
結果は、次のように読みます。傾向の説明は、音響の一般的な性質に基づく目安です。実際にどう聞こえるかは、ヘッドホンやスピーカーの特性、聞き手の耳によって変わります。
- 周波数を動かして採点がほとんど変わらない場合:帯域の偏りより、ほかの要素(粒、揺らぎ)が雨らしさを左右している可能性があります。次はQと粒を重点的に見てください。
- 周波数の両端で「風」や「砂嵐」といった言葉が出る場合:雨らしい範囲が中間にあるという最初の仮説が支持されます。その範囲の中央をメモしてください。
- Qを上げたときに笛のような、音程のある音に聞こえる場合:帯域が狭いほど、特定の音の高さが目立ちやすくなります。雨の「面」の広がりが失われたと判断できます。
- 粒を入れると採点が上がる場合:雨の印象は、背景の帯域だけでなく、個々の雫の存在にも支えられていると読めます。逆に粒が邪魔に感じる場合は、音の高さや音量が合っていない可能性があります。コードの 1500 + Math.random() * 2500 や 0.04 を変えて、同じ実験をやり直してください。
- 自分と協力者の採点が大きく食い違う場合:個人差の影響が大きい条件です。ゲームに入れるなら、意見が一致した範囲を選ぶほうが安全です。
起こりやすい誤り
- 条件を複数同時に変えてしまう。原因が分からなくなります。必ず一つずつ動かします。
- 聞く時間が短い。ループ再生のノイズは、数秒では判断しにくい場合があります。30秒以上聞いてください。
- 2秒のループの継ぎ目が気になる。短いバッファを繰り返しているため、同じパターンが規則的に聞こえることがあります。長めのバッファにするか、ほかの工夫が必要です。この点は、拡張実験として確かめられます。
- 音量を揃えない。大きい音は迫力があり、雨らしく感じやすい傾向があります。条件ごとに音量を変えないでください。
- スピーカーとヘッドホンを混ぜる。再生機器の特性が結果に混ざります。
- ブラウザ操作の前に音を出そうとする。ボタンを押す前は鳴らない仕様です。故障ではありません。
次の行動
まず、基準の30秒を聞いて、採点と一言を書いてみてください。そこから周波数、Q、粒の順に動かせば、あなたの耳に合う雨の設定が表にまとまります。その数値は、そのままゲームの環境音に使えます。
ファイルが1つのHTMLなので、アソバースへの投稿にも向いています。アップロードは20MiB以内で、直下の index.html が入口になります。雨音の聞き比べには、「雨音のピアノ」の雨音つき自由演奏も使えます。ただし、あの雨音の作り方は確認できていません。同じ作り方だと思い込まず、耳で比べるだけにしてください。
参考資料
- MDN Web Docs「Web Audio API」
- MDN Web Docs「BiquadFilterNode」
- MDN Web Docs「Autoplay guide for media and Web Audio APIs」



