audio_analysis_circuit.py v2.3
コードに刻まれた12の伝承
詠み人知らず——誰が最初に言ったか分からない。
だが現場を通過した者だけが知っている、周波数のハック法。
これは audio_analysis_circuit.py v2.3 のコードの背景にある思想の記録だ。 K-Weighting・True Peak・LRA・Spectral Centroid——国際規格と現場の経験則が数値とアルゴリズムに変換されている。 数式の前に、なぜその数値なのかを知らなければ、コードを読んでも意味がない。 この12本の伝承がその答えだ。
K-Weightingは人間の耳の嘘を暴く
f0 = 1500.0 gain = 4.0 Q = 0.7071
人間の聴覚は全帯域を均等に聴いていない。1.5kHz〜6kHz付近を過剰に敏感に感じ、低域は実際より小さく聴こえる。BS.1770-4のK-Weightingフィルタは、この人間の嘘を数値に焼き込む。High-shelfで1.5kHz以上を+4dB持ち上げ、38Hz以下をハイパスで切る。この2段構成が「人間が感じるラウドネス」を物理量に変換する唯一の国際規格準拠の方法。
伝承の核心
ラウドネスをRMSで測る者は素人。K-Weightedで測らなければ、人間が聴く音量と計測値が乖離する。このコードがv1のrms_dbを捨ててK-Weighted LUFSに移行したのは、この伝承に従ったから。
120Hz以下のステレオは犯罪
sos_low_pass = butter(4, 120.0, btype='lowpass', fs=sample_rate, output='sos')
120Hz以下でL/Rの位相がずれていると、クラブのサブウーファーで音が消える。モノラルサミングされた瞬間にキックとベースが相殺し、フロアから低音が消失する。vinyl盤のカッティングでも、低域のステレオ成分は針を溝から飛ばす物理的な破壊因子になる。
伝承の核心
120Hz以下のモノラル相関係数が0.7を下回ったら赤信号。このコードがlow_mono_correlationを8次元エンベロープの1つに入れ、さらにdetected_problemsでphase_cancellation_lowsとして検出するのは、クラブとvinylの現場から伝わった絶対則。
200〜500Hzは泥(Mud)の巣窟
mud_risk = np.clip((ratios.get("low_mid_ratio", 0.0) - 0.15) / 0.15, 0.0, 1.0)200〜500Hzは楽器の基音が密集する帯域であり、何も考えずにミックスすると必ず「もわっ」とした濁りが溜まる。この帯域のエネルギー比が全体の15%を超えたら泥が始まり、30%を超えたら致命的。
伝承の核心
マスタリングエンジニアが最初にやることはローミッドの掃除。この帯域に手を入れないマスタリングは存在しない。閾値0.15(15%)は、長年の現場で「ここから上は問題がある」と経験的に確立された境界線。
2〜6kHzのハーシュネスは耳を殺す
harshness_mask = (spectrum.freqs >= 2000) & (spectrum.freqs < 6000) harshness_risk = np.clip((np.sum(spectrum.mono_power[harshness_mask]) / total_energy) * 3.0, 0.0, 1.0)
人間の外耳道の共鳴周波数は約2.5〜4kHz。この帯域にエネルギーが集中すると、物理的に鼓膜への圧力が増幅され、「痛い」「キンキンする」と感じる。リスナーは無意識にボリュームを下げる。つまりラウドネス戦争に勝っても、ハーシュネスで聴取時間を失う。
伝承の核心
ラウドネスを上げることとハーシュネスを制御することは別の技術。係数3.0の増幅はこの帯域が全体の33%を占めた時点でリスク最大(1.0)になる設計であり、「3分の1を超えたら耳が逃げる」という現場の経験則。
クレストファクターは音楽の呼吸
crest_envelope = 20.0 * np.log10(np.maximum(peak_values, LOG_FLOOR)) - 20.0 * np.log10(rms_values)
ピーク値とRMS値の差がクレストファクター。これが6dBを下回ると「過剰圧縮された素材」として検出される。音楽のダイナミクスは呼吸であり、吸う(静かな瞬間)と吐く(ピーク)の差がなくなると、音楽は窒息する。
伝承の核心
クレストファクター6dBは「ラウドネス戦争の限界線」。これを切ったマスターは波形が四角い。四角い波形は振幅の変化がないので、人間の聴覚の順応により数十秒で「小さく」感じ始める。ラウドネスを稼いだつもりが逆効果になる現象の物理的証拠がこの数値。
LRAのダブルゲーティングは沈黙を無視する技術
absolute_threshold = -70.0 relative_threshold = ... - 20.0
LRA(Loudness Range)を正しく測るには2段のゲートが必要。まず-70 LUFS以下の完全な無音を除外(絶対ゲート)。次に、残った信号の平均ラウドネスから-20 LUを引いた値を相対ゲートとして適用。これにより、曲中の極端に静かなパッセージ(残響の尾、フェードアウト)がLRAを不当に拡大するのを防ぐ。
伝承の核心
ゲートなしのLRAは嘘をつく。無音区間がある曲は実際より広いLRAを示し、「ダイナミクスが豊か」と誤判定される。放送規格(EBU R128)でダブルゲーティングが義務化された理由がこれ。
Spectral Centroid(重心周波数)はトランジェントの刃
weighted_frequencies = np.sum(power_chunks * frequencies, axis=1) hfc_envelope = weighted_frequencies / total_energy_per_chunk / (chunk_size // 2)
周波数スペクトルの重心(全周波数をパワーで重み付けした平均)が高いほど、その瞬間の音は「鋭い」。スネアのアタック、ハイハットのオープン、シンセのプラックは重心周波数が跳ね上がる。重心が低い区間はパッド、サブベース、リバーブの余韻。
伝承の核心
トランジェントの「鋭さ」を時間軸で追えば、曲のどこに打撃感があるかが分かる。マスタリングでリミッターがトランジェントを潰すと、この値が時間軸上で平坦化する。フラット化回避(仕様書の重要度98/100)を数値で監視できる唯一の指標。
4xオーバーサンプリングでなければTrue Peakは見えない
left_oversampled = resample_poly(left_chunk, 4, 1)
デジタル音声のサンプル間には、サンプル値より大きい瞬間的ピークが存在する。44.1kHzで記録されたサンプル点の間に、実際にはサンプル値を超えるアナログ波形のピークが隠れている。これをInter-Sample Peakと呼ぶ。4倍にオーバーサンプリングして初めてこのピークが可視化される。
伝承の核心
サンプルピークが-1.0 dBFSでも、Inter-Sample Peakが0 dBTPを超えていることがある。DACがこのピークを再生した瞬間にクリッピングが発生する。True Peakを-1.0 dBTP以下に抑えるのは配信プラットフォーム(Spotify, Apple Music)の必須要件であり、オーバーサンプリングなしのピーク測定は規格違反。
Side信号のRMSがステレオの広さ
width_envelope = np.clip(side_rms_values / rms_values, 0.0, 1.0)
Mid = (L+R)/2、Side = (L-R)/2。Side成分のRMSをMid成分のRMSで割った値がステレオ幅の物理的定義。Side/Midが0ならモノラル、1に近づくほどLとRの差が大きい。
伝承の核心
ステレオ幅を「広い」「狭い」と感覚で語る時代は終わった。Side/Mid比で数値化すれば、セクションごとの空間変化を時系列エンベロープとして追える。dropでwidthを広げ、buildで狭めるのはEDMマスタリングの定石であり、この数値がその定石の物理的裏付け。
1〜5kHzはボーカルの王座
vocal_energy = np.sum(power_chunks[:, (frequencies >= 1000) & (frequencies < 5000)], axis=1)
人間の声の基本周波数は80〜400Hz程度だが、声の「存在感」を決めるのは倍音構造であり、1〜5kHzに集中する。この帯域のエネルギー比が高いセクションにはボーカルまたはボーカルに類する主旋律が存在する可能性が高い。
伝承の核心
ボーカルが入っている区間とインストゥルメンタルの区間では、マスタリングの制約が根本的に異なる。ボーカル区間でリミッターを深くかけると声の明瞭度が真っ先に犠牲になる。vocal_presenceエンベロープは、Control Layerが「この区間ではリミッターを緩める」という判断をするための物理的根拠。
帯域は6つに分けろ、4つでは足りない
BAND_EDGES = {
"sub": (20, 60),
"bass": (60, 200),
"low_mid": (200, 500),
"mid": (500, 2000),
"high": (2000, 8000),
"air": (8000, None)
}伝統的な3バンド(Low/Mid/High)や4バンド分割では、問題の所在が特定できない。subとbassを分けなければキックとベースの棲み分けが見えない。midとhighの間にhighを置かなければ、ハーシュネスの居場所が分からない。8kHz以上のairは「空気感」であり、ここを潰すと音が死ぬ。
伝承の核心
sub/bass/low_mid/mid/high/airの6帯域分割は、マスタリングスタジオのマルチバンドコンプレッサーのクロスオーバー設定に由来する。各帯域には固有の問題と固有の制御法がある。このコードがBAND_EDGESを6分割にしているのは、4バンドの仕様書評価が44/100だった理由そのもの。
チャンクサイズ5秒はOOMとの和平条約
chunk_size = 44100 * 5 # 5 seconds
4xオーバーサンプリングはメモリ消費が4倍になる。10分の楽曲を一括処理すると、44100 × 600秒 × 4倍 × 8バイト × 2ch = 約17GBのメモリが必要になり、REST APIのコンテナが即死する。5秒チャンクに分割し、ピークが全体の50%以上のチャンクだけをオーバーサンプリングすることで、必要なメモリを数百MBに抑える。
伝承の核心
精度と生存の両立。全サンプルをオーバーサンプリングする純粋主義は本番環境で人を殺す。ピークの50%閾値は「ここより下にTrue Peakの最大値が隠れている可能性は極めて低い」という統計的判断。
これが audio_analysis_circuit.py v2.3に刻まれた12の伝承だ。 誰が最初に言ったかは分からない。だが現場を通過した者だけが知っている周波数のハック法であり、 このコードはそれを数値とアルゴリズムに変換して永続化した。 詠み人知らずの思想はコードの中に生きている。