[Astro] #181 ブラウザだけで動く音量そろえツール — 曲の音量を、まとめて同じにする
はじめに
前回は、音声ファイルを切ってつなぐ、Audio Cutter を作りました。
[Astro] #180 ブラウザだけで動く音声カッター — 曲を切ってつないで、MP3・M4A・FLAC で書き出す
ブラウザの中だけで動く、音声ファイルのカット・結合ツールを作りました。
lain-lab.com今回は、音量をそろえるツールです。Audio 系のツールを作ってきて、最後に欲しかったのが、これでした。
曲を集めると、ファイルごとに、音の大きさがばらばらです。1 曲ごとに、再生しながら音量を直すのは、手間がかかります。そこで、複数のファイルを、まとめてドロップして、全部を同じ大きさにそろえて書き出すツールを、作りました。名前は Audio Gain です。
ファイルは、サーバーに送られません。
画面
全体
左がファイルの一覧、右が設定です。ファイルを入れると、すぐに音量を測ります。「現在の音量」「ピーク」「調整」「変換後」が、1 行に並びます。
ノイズ対策
右の設定は、上から「音量」「ノイズ対策」「書き出し」「保存の方法」です。ふだんは、目標の音量を決めて、「変換して保存」を押すだけです。
F1 ヘルプ
F1 キーで、「やりたいこと → やり方」を検索できます。Audio Cutter と同じ作りです。
作ったもの
- 複数のファイルや、フォルダごとドロップして、自動で音量を測ります
- 目標の音量(初期値は −14 LUFS)を決めると、ファイルごとに、上げ下げする量を計算します。すぐに、全部同じ大きさにそろいます
- 音が割れないように、音量の上限(初期値 −1 dBTP)を守るリミッターを入れています
- 読み込みは、MP3、M4A(AAC)、WAV、OGG、FLAC、Opus と、動画ファイルの音声です
- 書き出しは、元の形式のまま、MP3、M4A、Opus、FLAC、WAV(16bit・24bit)。保存は、ZIP でまとめて、フォルダに保存、1 つずつダウンロード
- 低音の雑音カットと、電源ハムの除去
- タグ・ジャケット画像の引き継ぎ、試聴、F1 ヘルプ
作り方
「聴こえる大きさ」を測る
音量をそろえるとき、波形の一番高い所(ピーク)をそろえても、聴いた感じはそろいません。ピークが同じでも、音がずっと鳴っている曲と、たまに鳴る曲では、聴こえる大きさが違うからです。
そこで、人の耳に近づけた音量の単位、LUFS(ラウドネス)を使います。規格は、ITU-R BS.1770-4(放送の基準で、EBU R128 の元になったもの)です。
測り方は、次のとおりです。
- 音に、2 段のフィルタ(K 特性)をかけます。高い音を少し持ち上げて、低い音を削って、耳の感じ方に近づけます
- 400 ミリ秒の窓を、100 ミリ秒ずつずらして、窓ごとの大きさを出します
- −70 LUFS より小さい窓を捨てます(ほぼ無音の所)
- 残りの平均から、10 LU 以上小さい窓を、もう一度捨てて(ゲート)、その平均を、全体の音量にします
フィルタの係数は、サンプルレートごとに、計算し直しています。44.1kHz、48kHz、22.05kHz などで、同じ結果になります。
確かめるために、ffmpeg の ebur128 と、同じ音を比べました。6 種類の音(正弦波、ノイズ、混ぜた音、サンプルレートの違い)で、差は 0.05 dB 以内でした(ffmpeg の表示が 0.1 単位なので、それ以上は比べられません)。
上げすぎて、割れないように
音量を上げると、波形の一番高い所が、0 dB を超えます。超えた部分は、潰れて、音が割れます。
しかも、デジタルの音は、サンプルの点と点の間で、実際の波形が、点よりも高くなることがあります。それも含めた、本当のピークが、True Peak です。4 倍に細かくして調べています。
最初は、補間の窓関数に Blackman-Harris(16 タップ)を使いました。ところが、測ると、15kHz の信号のピークを、0.3 dB 以上、低く見積もっていました。窓が狭くて、高い音を、正しく補間できていなかったためです。Kaiser 窓(β=4)の 24 タップに、直しました。
上限を超える所には、リミッターをかけます。作りは、こうです。
- 上限を超えそうな所を、2 ミリ秒先読みして、必要な下げ量を出します
- 前後 2 ミリ秒の最小値を取って、移動平均で、滑らかにします。これで、音量が急に変わらず、下げ始めの「ブチッ」というノイズを避けられます
- 戻るときは、80 ミリ秒かけて、ゆっくり戻します
- 書き出した結果は、元と同じ長さです(最後に、残りを出し切ります)
3 種類の音を、0 / +6 / +12 dB 上げて通したところ、どれも、書き出したあとの True Peak が、上限の −1.000 dBTP を超えませんでした。
書き出し
読み込みと書き出しは、Audio Cutter と同じ、Mediabunny(1.61.6)です。MP3 と FLAC の WASM エンコーダも、Audio Cutter のものを、そのまま使っています。
16bit の WAV にするときだけ、丸める前に、ごく小さなノイズ(TPDF ディザ)を足して、小さい音の歪みを防いでいます。
目標との差が、0.05 dB 未満のファイルは、再エンコードしないで、そのままコピーします。音質が変わらないためです。ほぼ無音のファイルは、測れないので、変えません。上げる量は、最大 +24 dB までです。それ以上は、背景のノイズが、大きくなりすぎます。
ノイズ対策(段階 1)
音量を上げると、もともと入っていた背景のノイズも、同じだけ大きくなります。そこで、ノイズ対策も、入れることにしました。ただし、一度に全部は作らないで、軽い所から、1 つずつです。
今回は、いちばん軽い、2 種類だけです。
- 低音の雑音をカット: 40Hz より下を削ります。風の音、マイクを触った振動、床の揺れなどが、対象です
- ハム除去: 電源由来の「ブーン」という音(50Hz か 60Hz と、その倍の高さ)を、細いフィルタで削ります
どちらも、2 次のフィルタ(Biquad)を、つないだものです。低音カットは、4 次の Butterworth(2 段)で、20Hz で −24 dB、60Hz でも −0.2 dB なので、ふつうの低音は、ほとんど変わりません。ハム除去は、基本波と、2 倍、3 倍の、3 本のノッチです。
順番が大事です。ノイズ対策を先にかけて、そのあとで、音量を測って、ゲインをかけます。 逆だと、ノイズを含んだ音量で、そろえてしまうためです。ノイズ対策を選ぶと、全部のファイルを、測り直します。
確認として、50Hz・100Hz・150Hz のハムと、18Hz のゴロゴロを混ぜた、合成の音楽で、変換してみました。ハムは、−24〜−34 dB から、約 −100 dB に下がりました。18Hz は、26 dB 下がりました。ほかの音(220Hz、440Hz)は、変わっていません。
ただし、これは、合成の音です。本物のハムは、周波数が、少しずれます。50Hz から 0.2Hz ずれると、効きは −12 dB ほどに、落ちます。そして、「サーッ」というノイズ(ヒスノイズ)や、声の背景ノイズは、この機能では、消えません。
初期値は、「なし」です。ふつうの音楽にかけると、50Hz や 60Hz のベースの音が、少し細くなるためです。
詰まったこと
AAC の書き出しで、エラー
実機(Windows の Chrome)で、ネットで見つけた AAC のサンプルを入れたところ、読み込みと再生はできたのに、変換でエラーになりました。
This specific encoder configuration (mp4a.40.2, 256000 bps, 2 channels, 44100 Hz) is not supported
原因は、音質(ビットレート)でした。元のファイルが高いビットレートだったので、「元に近い値」として、256 kbps を選んでいました。ところが、Windows の AAC エンコーダは、ステレオで 96〜192 kbps までしか、受け付けません。
確かめずに、選んでいたのが、間違いでした。ヘッドレスのブラウザ(画面なしのテスト環境)には、AAC がなく、試せていませんでした。
直しは、変換の前に、canEncodeAudio を、ビットレートつきで確かめて、使えない値は、近い値に下げる、というものです。256 は 192 になります。それでも失敗したときは、英語のエラーを、日本語の説明にします。直したあとで、同じファイルが、変換できました。−17.8 LUFS が −14.0 LUFS になり、ビットレートは 192 kbps でした。
圧縮すると、音量が少しずれる
測った値は、圧縮する前の音量です。MP3 や AAC にすると、エンコーダの癖で、書き出した結果の音量が、±0.5 dB ほど、ずれます。128 kbps の MP3 では、−14.0 が −14.5 LUFS になりました(ffmpeg の LAME でも同じでした)。
これは、仕様です。ずれが気になる場合は、WAV や FLAC に書き出すか、ビットレートを上げてください。ヘルプにも、書いています。
目標まで、上がらないファイル
音が尖っているファイル(ドラムや、ピアノのアタックが強い曲)は、目標まで上げると、一番高い所が、上限を超えます。リミッターで抑えると、全体の音量は、上がりきりません。テストの音では、−14 を目指して、−17.7 になりました。
画面には、リミッターの下げ量の最大値を、出しています。強くかかったファイルは、そこで分かります。
実機で確認できたこと
Windows 11 の Chrome で、確認しました。
- 音量の違う MP3 を、複数入れて、一括で変換しました。再生して、音がそろっていました
- 「フォルダに保存」は、問題なく動きました
- AAC は、読み込み、再生、変換ができました。M4A の 256 kbps を選んでも、通りました(ビットレートは、192 kbps に下がります)
- ノイズ対策を選んで変換しても、問題なく動きました。ただし、実際のノイズが入ったファイルは、手元になく、効き目は、確かめていません
ヘッドレスのブラウザと、ffmpeg では、次のことを確認しました。
- LUFS の測定は、ffmpeg と一致(上のとおり)
- リミッターは、どの条件でも、上限を超えない
- MP3、WAV、FLAC、OGG、Opus を一括で変換して、ZIP にまとめ、測り直して、目標の −14.0 LUFS(WAV・FLAC・Opus)
- ZIP の中身の整合性
未確認のこと・制限
- 聴いた感じの良し悪し: リミッターで音が潰れて聴こえないか、80 ミリ秒の戻りが音楽に合うかは、聴いて決める部分です。強くかけたファイルは、特に、聴いて確かめてください
- ノイズの入った実際の録音: ノイズ対策の効き目は、合成の音でしか、確かめていません
- フォルダごとのドロップの動作、数百 MB のファイルや、数十本のバッチでの、時間とメモリ。ZIP でまとめる場合は、変換結果を、全部メモリに持ちます
- Safari と Firefox
- 3ch 以上の音声は、先頭の 2ch だけを使います
- 試聴は、簡易です。リミッターは、ブラウザの簡易なもので、代わりにしています。ノイズ対策は、試聴にはかかりません
おわりに
「音量をそろえる」だけに見えて、測り方の規格、割れない上限の考え方、圧縮したときのずれと、考えることが、思ったより、ありました。
ノイズ対策は、軽い 2 種類だけ入れました。「サーッ」というノイズを、周波数ごとに引く方法(スペクトルゲート)や、声に強い AI の方法(RNNoise)は、あとで、ひとつずつ、足していくつもりです。
今は、v1.0 です。