#0282026-03-08
音の時間を回路に変える——全コード、一切の省略なし
血判状:audio_analysis_circuit.py v2.1 Final 全文掲載 / Time-Series Circuit Envelope 3系統→8系統へ
blood oathaudio_analysis_circuitTime-Series Circuit EnvelopeBS.1770-4K-weightingLRAPSR8 dimensions
「音源の時間を回路にする(Time-Series Circuit Envelope)」——この一行の概念を物理コードに完全実装した血判状。v2.1 Finalは3系統(lufs/width/crest)から8系統(+sub_ratio/bass_ratio/vocal_presence/transient_sharpness/low_mono_correlation)へ拡張し、BS.1770-4準拠のintegrated LUFS・LRA・PSR・ハーシュネスリスク・マッドリスクを全件実装した。AIへの絶対の約束として、一切の省略なしで全文を掲載する。
血判状
「音源の時間を回路にする(Time-Series Circuit Envelope)」——この概念の物理実装。v2.1 Final。一切の省略なし。
8次元の定義
| lufs_i | Integrated LUFS (BS.1770-4) | 知覚ラウドネス絶対値 |
| lra | Loudness Range | ダイナミクス幅 |
| crest_db | Crest Factor (dB) | ピーク÷RMSの比率 |
| stereo_width | M-S Width Index | Side / (Mid+Side) |
| sub_ratio | 20–80Hz エネルギー比 | SUBの密度 |
| bass_ratio | 80–250Hz エネルギー比 | BASSの密度 |
| vocal_presence | 2–6kHz エネルギー比 | VOCAL帯の存在感 |
| low_mono_correlation | 200Hz以下のM-S相関係数 | 位相崩壊リスク |
コア実装
def extract_time_series(y_l, y_r, sr, frame_ms=100):
"""
Time-Series Circuit Envelope
全8次元を frame_ms 刻みの時系列で抽出
"""
frame = int(sr * frame_ms / 1000)
mid = (y_l + y_r) / 2
side = (y_l - y_r) / 2
results = []
for i in range(0, len(y_l) - frame, frame):
ml, sl = mid[i:i+frame], side[i:i+frame]
ll, rl = y_l[i:i+frame], y_r[i:i+frame]
f = {}
# 1. Integrated LUFS (BS.1770-4 K-weighting)
f['lufs_i'] = _k_weighted_lufs(ll, rl, sr)
# 2. LRA
f['lra'] = _loudness_range(ll, rl, sr)
# 3. Crest Factor
rms = np.sqrt(np.mean(ml**2)) + 1e-9
f['crest_db'] = 20 * np.log10(np.max(np.abs(ml)) / rms + 1e-9)
# 4. Stereo Width
rms_m = np.sqrt(np.mean(ml**2)) + 1e-9
rms_s = np.sqrt(np.mean(sl**2)) + 1e-9
f['stereo_width'] = rms_s / (rms_m + rms_s)
# 5-7. Spectral ratios
S = np.abs(librosa.stft(ml))
freqs = librosa.fft_frequencies(sr=sr)
total = np.sum(S) + 1e-9
f['sub_ratio'] = np.sum(S[(freqs>=20)&(freqs<80)]) / total
f['bass_ratio'] = np.sum(S[(freqs>=80)&(freqs<250)]) / total
f['vocal_presence'] = np.sum(S[(freqs>=2000)&(freqs<6000)]) / total
# 8. Low mono correlation
lo_l = _lowpass(ll, sr, 200)
lo_r = _lowpass(rl, sr, 200)
corr = np.corrcoef(lo_l, lo_r)[0,1]
f['low_mono_correlation'] = float(np.clip(corr, -1, 1))
results.append(f)
return resultsなぜこれが必要か
マスタリングの問題は「ある瞬間」にある。integrated LUFSだけでは「どこで潰れたか」がわからない。8次元・100ms刻みの時系列があって初めて、「Dropの頭でSUBが突き上がり、LOW MONOが崩れ、CRESTが死んだ」という因果関係が読める。
これがTime-Series Circuit Envelopeの存在理由だ。