Может ли pydub установить максимальную/минимальную громкость?

В качестве заголовка, могу ли я установить значение максимальной/минимальной громкости, то есть в выходном аудиофайле не будет слишком громко или слишком тихо? (Не нормализовать, я просто хочу настроить конкретную громкость на нормальную, как на фото ниже.)

введите здесь описание изображения


person Leo Hsieh    schedule 15.11.2015    source источник


Ответы (2)


Громкость немного сложна. Простое решение состоит в измерении одним из более простых методов, таких как dBFS и установите усиление для всего вашего аудио, чтобы оно соответствовало.

sounds = [audio_segment1, audio_segment2, audio_segment3, audio_segment4]

def set_loudness(sound, target_dBFS):
    loudness_difference = target_dBFS - sound.dBFS
    return sound.apply_gain(loudness_difference)

# -20dBFS is relatively quiet, but very likely to be enough headroom    
same_loudness_sounds = [
    set_loudness(sound, target_dBFS=-20)
    for sound in sounds
]

Одним из усложняющих факторов является то, что некоторые из ваших звуков могут иметь продолжительные части тишины или даже просто очень тихие части. Это понизит среднее значение, и вам, возможно, придется написать более сложное измерение громкости. Опять же, простой способ: вы можете разрезать звук на более короткие фрагменты и просто использовать самый громкий, предполагая, что весь ваш звук длится 15 минут, мы можем взять фрагменты по 1 минуте:

from pydub.utils import make_chunks

def get_loudness(sound, slice_size=60*1000):
    return max(chunk.dBFS for chunk in make_chunks(sound, slice_size))


# ...and replace set_loudness() in above example with…
def set_loudness(sound, target_dBFS):
    loudness_difference = target_dBFS - get_loudness(sound)
    return sound.apply_gain(loudness_difference)
person Jiaaro    schedule 15.11.2015
comment
@Jiarro этот метод, кажется, приводит к слишком громкому или слишком тихому, если максимальное / минимальное значение далеко от среднего, поскольку вы выбираете экстремальное значение в качестве критерия регулировки. (Это также увеличит другую часть, которая не слишком тихая, или уменьшит другую часть, которая не слишком громкая) - person Leo Hsieh; 16.11.2015
comment
@LeoHsieh, как я уже сказал, громкость - сложная вещь для измерения - я просто даю вам несколько стратегий, которые нужно использовать. Во втором примере показан способ использования самого громкого 1-минутного фрагмента, чтобы избежать усреднения в тишине (вы можете поиграть с этим значением, возможно, 15-секундные фрагменты будут работать лучше). Другая проблема, не упомянутая выше, заключается в том, что не все частоты звучат одинаково громко при одинаковой мощности (см. кривые Флетчера-Мансона). Вы также можете рассмотреть возможность использования средней громкости фрагментов вместо максимальной с более короткими длинами фрагментов. - person Jiaaro; 16.11.2015
comment
@Jiarro Хорошо, понятно. Я постараюсь использовать более короткие фрагменты для достижения своей цели, хотя это может занять много времени... Спасибо за вашу помощь. - person Leo Hsieh; 17.11.2015

Это то, что я делаю, и это хорошо работает для меня. Недостатком является плохая производительность, если sample_rate слишком мал.

from pydub import AudioSegment
from pydub.utils import make_chunks

def match_target_amplitude(sound, target_dBFS):
    change_in_dBFS = target_dBFS - sound.dBFS
    return sound.apply_gain(change_in_dBFS)

def sound_slice_normalize(sound, sample_rate, target_dBFS):
    def max_min_volume(min, max):
        for chunk in make_chunks(sound, sample_rate):
            if chunk.dBFS < min:
                yield match_target_amplitude(chunk, min)
            elif chunk.dBFS > max:
                yield match_target_amplitude(chunk, max)
            else:
                yield chunk

    return reduce(lambda x, y: x + y, max_min_volume(target_dBFS[0], target_dBFS[1]))

sound = AudioSegment.from_mp3("vanilla_sky.mp3")
normalized_db = min_normalized_db, max_normalized_db = [-32.0, -18.0]
sample_rate = 1000
normalized_sound = sound_slice_normalize(sound, sample_rate, normalized_db)
person Leo Hsieh    schedule 17.11.2015
comment
Попробуйте использовать интегрированный алгоритм громкости стандарта ITU-R BS.1770-4, который вычисляет громкость, разбивая аудиосигнал на 0,4-секундные сегменты с перекрытием 75%. Вот реализация Python github.com/BrechtDeMan/loudness.py - person droptop; 11.02.2021