Меня всегда интересовало, существуют ли какие-то критерии правильной нормализации громкости аудиодорожек. Ну, что обычно подразумевается под нормализацией, так сказать, в быту? Простой пересчёт пиков до отметки в 0 дБ. Однако, результат чаще всего неудовлетворителен — динамический диапазон, т. е., разница между самым громким и самым тихим звуками вроде бы сохраняется (хотя ещё вопрос, так ли это в действительности при простом пересчёте), но сама по себе общая громкость может не повыситься совсем или повыситься незначительно из-за того, что самые громкие звуки, которых может быть один-два на всю запись, уже нормализованы и их повышать уже некуда, а остальной материал так и остался где-то снизу, и слышно его всё так же плохо.
Понятно, что простая линейная нормализация не подходит и нужна какая-то динамическая (в сочетании с компрессией), причём желательно основанная на каких-то объективных критериях. Последнее время я увлёкся изучением возможностей совершенно прекрасного консольного медиаконвертера ffmpeg, где я обнаружил аудиоплагин loudnorm, как раз занимающийся нормализацией аудиосигнала по стандарту Европейского вещательного союза EBU R128.
Какими основными критериями оперирует loudnorm?
- Общая громкость (Integrated loudness), измеряемая в единицах абсолютного значения громкости (Loudness units relative to full scale, LUFS). Общая громкость вычисляется на основании анализа звуковых частот и уровня сигнала, применимое к чувствительности человеческого слуха к ним.
- Точный пик сигнала (True peak), измеряемый в децибелах (dB). Это одномоментное наивысшее значение пика сигнала во всём звуковом материале, то есть, грубо говоря, самый громкий звук. По этому критерию как раз и делается линейная нормализация, описанная мной в начале статьи.
- Диапазон громкости (Loudness Range, LRA), измеряемый в единицах громкости (Loudness units, LU). Разница между самым громким и самым тихим звуками.
- Порог (Threshold). Я до конца не понял, что это за критерий, но вероятно, ниже этого порога сигнал не обрабатывается.
Чтобы повысить качество обработки аудиодорожки, loudnorm предусматривает обработку в два прохода. Первый — сбор данных, второй — непосредственно обработка с параметрами, полученными во время первого прохода. В интернете есть статья автора loudnorm, где он показывает на примере, как это работает. За основу там взят документ американского Сообщества аудиоинженеров AES TD1004.1.15-10 Recommendation for Loudness of Audio Streaming and Network File Playback, где в рекомендациях сказано, что общая громкость (Integrated loudness) не должна быть выше -16 LUFS и ниже -20 LUFS, а максимальный пик (True peak) не должен превышать -1.0 dB.
Что касается диапазона громкости (Loudness Range, LRA), то здесь нужно действовать по ситуации. Я нашёл на сайте AudioKinetic рекомендации по максимальному уровню LRA, там даны примерные значения для разных условий:
- Домашний кинотеатр — 20 единиц
- Гостиная — 18 единиц
- Кухня — 15 единиц
- Гостиная (поздний вечер) — 9 единиц
- Общественный транспорт, мобильное устройство — 6 единиц
Чем шумнее вокруг, тем меньший динамический диапазон нужно выставлять, чтобы расслышать все звуки в записи. Чем больше и громче динамики, тем больший LRA возможен. В общем, однозначного критерия здесь быть не может, хотя некоторые значения мы выяснили.
Перейдём, наконец, к практике. Имеется DVD-Video с полукустарно записанным концертом классической музыки, имеющий стандартные проблемы: громкие аплодисменты, тихая музыка и речь ведущей концерта. Графически аудиодорожка выглядит так:
Делаем первый проход для сбора данных. Берём среднее значение из рекомендуемых для общей громкости -18 LUFS и рекомендуемый максимальный пик -1.0 dB. Диапазон громкости и порог, как значения неизвестные или приблизительные, пусть высчитываются автоматически.
ffmpeg -i in.wav -af loudnorm=I=-18:TP=-1:print_format=json -f null -
После окончания анализа получаем следующие данные:
[Parsed_loudnorm_0 @ 000000eef2eeea80]
{
"input_i" : "-22.27",
"input_tp" : "0.03",
"input_lra" : "20.10",
"input_thresh" : "-33.99",
"output_i" : "-19.39",
"output_tp" : "-1.00",
"output_lra" : "13.20",
"output_thresh" : "-30.08",
"normalization_type" : "dynamic",
"target_offset" : "1.39"
}
Запускаем второй проход в соответствии с полученными данными. Параметр -ar 48k
нужен для сохранения результата в файл с частотой сэмплирования 48000 Гц. Если этого не сделать, то на выходе будет файл с нечеловеческими 192000 Гц. Это преобразование связано с наиболее точным поиском точного пика сигнала (True peak), но полагаю, что в данном случае этим можно пренебречь.
ffmpeg -i in.wav `
-af loudnorm=I=-16:TP=-1:measured_I=-22.27:measured_TP=0.03:measured_LRA=20.10:measured_thresh=-33.99:offset=1.39:print_format=summary `
-ar 48k out.wav
После окончания обработки получаем следующую картину:
[Parsed_loudnorm_0 @ 0000003e678ee8c0]
Input Integrated: -22.3 LUFS
Input True Peak: +0.0 dBTP
Input LRA: 20.1 LU
Input Threshold: -34.0 LUFS
Output Integrated: -16.2 LUFS
Output True Peak: -1.0 dBTP
Output LRA: 13.0 LU
Output Threshold: -26.8 LUFS
Normalization Type: Dynamic
Target Offset: +0.2 LU
Видно, что общая громкость стала на 6,1 выше, несмотря на то, что максимальный пик снизился на единицу, в соответствии с рекомендованным значением. Динамический диапазон стал уже на 7,1 — это привело к более ровному звучанию без резких перепадов громкости, но и сохранило динамику.
Результат обработки в графическом виде:
Субъективно могу сказать, что стало гораздо лучше. Приведу отрывки из записи, где есть большой перепад громкости.
Upd: Всё же, нужно задавать динамический диапазон вручную, чтобы автомат не зажимал его слишком сильно. В итоге, более-менее универсальные параметры получились следующие: -af loudnorm=I=-16:TP=-1:LRA=18
. Если LRA уже узкий, то он обратно не разжимается, насколько я успел заметить.