0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

dBは足し算できない。騒音レベルの合成・距離減衰・A特性補正をJavaScriptで実装

0
Posted at

「隣の部屋で掃除機かけてるだけなのに、うちのテレビの音が全然聞こえない…」
そんな経験、ありませんか?

実はこれ、音のエネルギーは足し算できるのに、デシベル(dB)という単位が対数スケールだから、単純な足し算が通用しないという“落とし穴”があるからなんです。

例えば、80dBの音源が2つあったら、合計は「80+80=160dB」にはなりません。正解は83dB。これ、直感とズレてませんか?

今回は、そんな「音の正体」を数式とコードで徹底的に解剖しながら、点音源/線音源の違い、距離減衰、大気吸収、A特性補正まで一気に理解できるシミュレーターを題材に、実装レベルまで踏み込みます。


ざっくり本質:音は「球」か「円柱」で広がる

「音の広がり方は、音源の形で決まる。点音源は球状、線音源は円柱状。距離が2倍になると、点は−6dB、線は−3dB減衰する。」

まずは直感でイメージしてください。

  • 点音源(ポンプの排気口、スピーカー):音が1点から球状に広がる。表面積は距離の2乗で増える → エネルギー密度は1/r²で減る → dBにすると −6dB/距離2倍。
  • 線音源(道路、長い配管):音が線から円柱状に広がる。表面積は距離の1乗で増える → エネルギー密度は1/rで減る → dBにすると −3dB/距離2倍。

これ、実は物理の「逆2乗則」そのもの。直感ができたら、次は数式で確かめましょう。


数式で理解する

騒音レベル計算の根幹は、以下の合成式です。

合成SPL(Sound Pressure Level)

L_{total} = 10 \log_{10} \left( \sum_{i=1}^{n} 10^{L_i / 10} \right) \quad [dB]

ここで $L_i$ は各音源の寄与レベル。これが「エネルギー加算」の正体です。デシベル同士を足すのではなく、一旦エネルギー(10^{L/10})に戻して足し、またdBに戻す。

各音源の距離減衰+大気吸収

各音源 $i$ の、評価点(距離 $r$ [m])におけるレベルは:

L_i = L_{0i} - \text{減衰項} - \text{大気吸収項} \quad [dB]
  • 点音源:減衰項 = $20 \log_{10}(r / r_0)$
    ただし $r_0$ は基準距離(通常1m)。 $r_0=1$mなら $20\log_{10}(r)$。
  • 線音源:減衰項 = $10 \log_{10}(r / r_0)$
  • 大気吸収項: $\alpha \cdot r / 100$
    $\alpha$ [dB/100m] は大気吸収係数。周波数・温度・湿度に依存。

さらに、A特性補正を適用する場合は、各周波数帯域に補正値を加えてから合成します。人間の耳は中音域(1〜4kHz)に敏感で、低音・高音を感じにくいため、環境アセスメントではdBAが標準です。


コードで実装する ★最重要★

核心の計算を、ブラウザでも動くJavaScriptで書きます。実際にコピペして動かせます。

/**
 * 騒音レベル計算コアエンジン
 * @param {Array} sources - 音源リスト [{type: 'point'|'line', L0: number, r0: number, freq: number}, ...]
 * @param {number} r - 評価点までの距離 [m]
 * @param {number} alpha - 大気吸収係数 [dB/100m]
 * @param {number[]} aWeight - A特性補正値 [dB](各周波数帯ごと)
 * @returns {{ total: number, contributions: number[] }}
 */
function calcNoiseLevel(sources, r, alpha, aWeight = []) {
  // 各音源の寄与をエネルギーで計算
  const energies = sources.map(src => {
    // 1. 距離減衰項
    let atten;
    if (src.type === 'point') {
      atten = 20 * Math.log10(r / src.r0);  // 点音源: -6dB/距離2倍
    } else { // line
      atten = 10 * Math.log10(r / src.r0);  // 線音源: -3dB/距離2倍
    }
    
    // 2. 大気吸収項
    const airAbsorption = alpha * r / 100;
    
    // 3. A特性補正(簡易:単一周波数と仮定、実際は帯域ごと)
    let aCorr = 0;
    if (aWeight.length > 0) {
      // 音源の周波数に最も近いA特性値を適用(実用では帯域分割)
      const idx = Math.min(Math.floor(src.freq / 1000), aWeight.length - 1);
      aCorr = aWeight[idx] || 0;
    }
    
    // 4. 最終レベル
    const L = src.L0 - atten - airAbsorption + aCorr;
    
    // エネルギー(10^(L/10))を返す
    return Math.pow(10, L / 10);
  });
  
  // 5. エネルギー総和 → dBに戻す
  const totalEnergy = energies.reduce((sum, e) => sum + e, 0);
  const total = 10 * Math.log10(totalEnergy);
  
  // 各音源の寄与(エネルギー比率をdBで表示)
  const contributions = energies.map(e => {
    return 10 * Math.log10(e); // 単独のdB値
  });
  
  return { total: Math.round(total * 100) / 100, contributions };
}

// 使用例:点音源2つ、距離10m
const sources = [
  { type: 'point', L0: 80, r0: 1, freq: 1000 },  // 80dB @1m
  { type: 'point', L0: 80, r0: 1, freq: 2000 }   // 80dB @1m
];
const result = calcNoiseLevel(sources, 10, 0.5, [0, -1.3, -3.2]); // 簡易A特性
console.log(`合成騒音レベル: ${result.total} dB`);
// → 83.01 dB(80dB+80dBの合成、理論値83.01と一致)

ポイント:

  • Math.log10 はES6以降で使用可能
  • エネルギー加算の前に Math.pow(10, L/10) でリニアスケールに戻す
  • A特性は本来1/3オクターブ帯域ごとに定義されるが、ここでは簡易的に周波数に応じて補正

数値例で確かめる

実際に、現実的な条件で計算してみましょう。

条件:

  • 音源A:点音源、L₀=85dB @1m、周波数1000Hz
  • 音源B:線音源、L₀=75dB @1m、周波数500Hz
  • 評価距離:r=50m
  • 大気吸収α:0.5 dB/100m(標準的な値)
  • A特性補正:1000Hz→0dB、500Hz→−3.2dB

手計算(途中式):

  1. 音源A(点音源):

    • 距離減衰:$20\log_{10}(50/1) = 20 \times 1.699 = 33.98$ dB
    • 大気吸収:$0.5 \times 50 / 100 = 0.25$ dB
    • A特性補正:0 dB
    • 最終レベル:$85 - 33.98 - 0.25 + 0 = 50.77$ dB
  2. 音源B(線音源):

    • 距離減衰:$10\log_{10}(50/1) = 10 \times 1.699 = 16.99$ dB
    • 大気吸収:$0.5 \times 50 / 100 = 0.25$ dB
    • A特性補正:−3.2 dB
    • 最終レベル:$75 - 16.99 - 0.25 - 3.2 = 54.56$ dB
  3. 合成:

    • エネルギーA:$10^{50.77/10} = 10^{5.077} \approx 119,400$
    • エネルギーB:$10^{54.56/10} = 10^{5.456} \approx 285,800$
    • 総エネルギー:$119,400 + 285,800 = 405,200$
    • 合成レベル:$10\log_{10}(405,200) = 10 \times 5.608 = 56.08$ dB

コードで確認:

const src = [
  { type: 'point', L0: 85, r0: 1, freq: 1000 },
  { type: 'line',  L0: 75, r0: 1, freq: 500 }
];
const r = calcNoiseLevel(src, 50, 0.5, [0, -3.2, -1.3]);
console.log(r.total); // → 56.08 dB

見事に一致。線音源のほうが減衰が緩やかなので、遠方では線音源の寄与が支配的になることがわかります。


シミュレーターで遊ぶ(実験3連発)

実際に 騒音レベル計算ツール を開いて、以下の実験を試してみてください。

実験1:点音源 vs 線音源、同じ距離でどれだけ差が出る?

  • 音源1:点音源、L₀=80dB
  • 音源2:線音源、L₀=80dB
  • 距離を10m→20m→50mと変えてみる。

結果:

  • 10m:点=74dB、線=77dB(差3dB)
  • 20m:点=68dB、線=74dB(差6dB)
  • 50m:点=60dB、線=68dB(差8dB)

なぜ? 点音源は距離2倍で−6dB、線音源は−3dB。差が開くのは、減衰の傾きが違うから。遠方ほど「線音源のほうがうるさい」という直感が得られます。

実験2:大気吸収の影響を体感

  • 音源:点音源、L₀=90dB、ピーク周波数=8000Hz(高音)
  • 距離=200m
  • αを0.1→1.0→3.0と変える。

結果:

  • α=0.1:90 − 20log₁₀(200) − 0.2 = 90 − 46.0 − 0.2 = 43.8dB
  • α=1.0:90 − 46.0 − 2.0 = 42.0dB
  • α=3.0:90 − 46.0 − 6.0 = 38.0dB

気づき:α=3.0は高周波・乾燥空気に相当。遠距離では5dB以上変わる。逆に低周波(500Hz以下)ならαは0.1程度でほとんど効かない。

実験3:音源を増やすとどうなる?(エネルギー加算の実感)

  • 80dBの点音源を1つ→2つ→4つと追加。
  • 距離10m、α=0.5

結果:

  • 1台:80 − 20log₁₀(10) − 0.5 = 80 − 20 − 0.5 = 59.5dB
  • 2台:10log₁₀(2×10⁵.⁹⁵) = 59.5 + 3.01 = 62.5dB
  • 4台:59.5 + 6.02 = 65.5dB

ポイント:音源が2倍で+3dB、4倍で+6dB。つまり「音源を半分に減らしても、騒音は3dBしか下がらない」。防音対策では、最大寄与音源を特定して集中的に減らすのが効率的だとわかります。


現場でハマるポイント(落とし穴3選)

1. 「点音源」でモデリングしがちな落とし穴

「長さ5mのファン」を点音源でモデル化してませんか?
評価距離が10mなら、音源サイズ(5m)は距離の半分。点音源モデルは「音源サイズ≪距離」が前提なので、距離減衰を過大評価し、実際より低い騒音レベルを出します。

目安:音源の最大寸法が評価距離の1/5以上なら、線音源または面音源を検討すべき。

2. 「基準距離の音圧 L₀」の解釈ミス

カタログに「音源表面から1mで85dB」と書いてあっても、それが音源中心から1mなのか筐体表面から1mなのかで、実測値が数dB変わります。大型機械ではこの差が致命傷に。

対策:測定条件のメタデータ(距離の定義、無響室かどうか)を必ず確認。

3. 大気吸収係数αを「固定値」で決めつける

ツールのスライダーは便利ですが、実際のαは気温・湿度・周波数に強く依存します。夏の湿度80%と冬の乾燥空気では、高周波の減衰が全く違う。

正しい使い方:「α=0.5(標準)」だけで計算せず、α=0.1(低吸収)とα=2.0(高吸収)の2ケースを比較する。これで結果の幅を把握できる。


まとめ

  • 音の合成はエネルギー加算:dB同士を足さず、一旦リニアに戻してから足す。2倍で+3dB。
  • 点音源 vs 線音源:距離2倍で点は−6dB、線は−3dB。遠方ほど差が開く。
  • 大気吸収は高周波・遠距離で効く:αは気温・湿度で変わるから、複数ケースを比較しよう。
  • A特性補正で人間の聴感に近づける:環境アセスメントではdBAが標準。

そして何より、このシミュレーターはブラウザで即動くので、理論を「手を動かして」体感できます。

▶ 騒音レベル計算ツール — 登録不要、すぐ試せる

NovaSolverでは1,600以上の工学シミュレーターを無料公開中 👉 一覧はこちら

「音の正体」を数式とコードで理解すれば、防音設計も騒音予測も、もう怖くない。ぜひ一度、パラメータを動かして“音の広がり”を実感してみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?