나는 큰 길 옆에 산다. 밤에 창문을 열어두니 정말 시원했고, 가끔 소음이 많이 들렸습니다. 내장 마이크 입력에 따라 볼륨을 자동으로 조정하는 방법은 무엇입니까? 자동차가 지나갈 때 영화 속 대사가 들리도록 볼륨을 설정하면 때로는 시끄러워서 주변 사람들(외부 및 이웃)에게 거슬릴 수 있습니다.
내 시스템은 Debian Buster이지만 일반적인 솔루션을 얻을 수도 있습니다. 이 작업을 수행할 수 있는 패키지가 없는 경우 기본 마이크에서 음량을 추출하는 명령이 이 스크립트를 작성하는 데 도움이 됩니다.
답변1
이를 위해 Python 스크립트를 작성했습니다. 남은 문제는 물론 내 노트북의 마이크도 자체 스피커를 포착한다는 것입니다. "에코 취소"가 제가 찾고 있는 것일 수도 있지만 직접 구현하는 방법을 모르겠습니다. 그러나 외부 마이크를 사용하면 작동할 수 있습니다.
불행히도 python-alsaaudio
종속성으로 인해 Python 2입니다.
#!/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