Как автоматически настроить громкость в соответствии со звуком вокруг меня?

8

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

Моя система - Debian Buster, хотя я, вероятно, смогу получить общее решение для работы. Если нет доступных пакетов, которые делают это, команда для извлечения громкости из микрофона по умолчанию уже была бы полезна для сценария этого.

Люк
источник
1
Вы можете использовать soxдля расчета средней громкости (IIRC, есть другой вопрос на стеке об этом), а также pacmdдля изменения громкости для Pulseaudio.
dirkt
1
@dirkt Спасибо за указатели! Я нашел этот вопрос, я постараюсь реализовать его завтра и доложить (возможно, я смогу ответить на свой вопрос): superuser.com/questions/306701/…
Люк,

Ответы:

2

Я сделал скрипт Python, чтобы сделать работу. Остающаяся проблема заключается в том, что микрофон моего ноутбука, конечно же, также поднимет свои динамики. Я думаю, что «эхоподавление» может быть тем, что я ищу, но я не знаю, как реализовать это сам. Использование внешнего микрофона может работать, хотя.

Это Python 2 из-за python-alsaaudioзависимости, к сожалению.

#!/usr/bin/env python

''' For noise cancellation:
$ pactl load-module module-echo-cancel
$ PULSE_PROP="filter.want=echo-cancel" ./this-script.py
'''

''' SETTINGS (you might want to keep presets for music and speech) '''
smoothing = 15 # Over how many samples should we compute?
step_size = 1 # maximum volume adjustment in percent points
# scale_xxx = (n, level) # At mic level n, scale to level% audio volume
scale_min = (4, 39)
scale_max = (19, 53)

''' CREDITS
https://stackoverflow.com/a/1937058
How get sound input from microphone in python, and process it on the fly?
Answer by jbochi

https://stackoverflow.com/a/10739764
How to programmatically change volume in Ubuntu
Answer by mata
'''

import alsaaudio, audioop, sys, os

bucket = [None for i in range(smoothing)]

inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE)

inp.setchannels(1)
inp.setrate(8000)
inp.setformat(alsaaudio.PCM_FORMAT_S16_LE)

inp.setperiodsize(200)

print('Setting volume to minimum ({}%)'.format(scale_min[1]))
os.system('pactl set-sink-volume 0 {}%'.format(scale_min[1]))

i = 1
last_volume = scale_min[1]
while True:
    l, data = inp.read()
    if l:
        val = audioop.max(data, 2)
        bucket[i % smoothing] = val

        if i % smoothing == 0:
            m = min(bucket)
            miclvl = float(m) / 50.0

            if miclvl < scale_min[0]:
                scale = scale_min[1]
            elif miclvl > scale_max[0]:
                scale = scale_max[1]
            else:
                miclvl_range = scale_max[0] - scale_min[0]
                level_range = scale_max[1] - scale_min[1]
                scale = (miclvl - scale_min[0]) / miclvl_range * level_range + scale_min[1]

            scale = int(round(scale))
            step = max(min(scale - last_volume, step_size), -step_size)

            if step != 0:
                last_volume += step
                step = '+' + str(step) if step > 0 else str(step)
                os.system('pactl set-sink-volume 0 {}%'.format(step))

            miclvl = round(miclvl, 1)
            miclvlpacing = ' ' * (4 - len(str(miclvl)))
            stepspacing = ' ' * (2 - len(str(step)))
            sys.stdout.write('mic lvl {}{}  ideal scale {}%  adjust {}{}  now {}  '.format(
                miclvl, miclvlpacing, str(scale), step, stepspacing, last_volume))
            print(int(round(last_volume - scale_min[1])) * 'x')

        i += 1
Люк
источник
1
Pulseaudio может до некоторой степени выполнять эхоподавление, см., Например, здесь и здесь , Google для получения дополнительной информации. Если вы хотите сделать это самостоятельно, вы должны вычесть выходной сигнал из входного сигнала с задержкой по времени и с правильной амплитудой. Нахождение этих двух параметров автоматически является забавной частью. :-) (Google "корреляция")
dirkt
@dirkt Еще раз спасибо! Пульсаудио, похоже, не очень хорошо работает; особенно при более высоких уровнях громкости (> 50%) он просто ломается, обнаруживает себя и продолжает расти. Мне просто нужно пойти и взять микрофон, это не так, как они дорогие в любом случае :)
Люк