Bagaimana cara saya mengatur volume secara otomatis sesuai dengan suara di sekitar saya?


8

Saya tinggal di sebelah jalan besar. Memiliki jendela terbuka di malam hari sangat dingin dan, sebentar-sebentar, sangat keras. Bagaimana saya bisa mengatur volume secara otomatis, berdasarkan input mikrofon bawaan? Jika saya mengatur volume sehingga saya bisa mendengar pidato di film saat mobil lewat, itu akan sangat keras di waktu lain, dan rasanya sangat menjengkelkan terhadap orang-orang terdekat (di luar dan tetangga).

Sistem saya adalah Debian Buster, meskipun saya mungkin bisa mendapatkan solusi umum untuk bekerja. Jika tidak ada paket yang tersedia yang melakukan ini, perintah untuk mengekstrak kenyaringan dari mikrofon default sudah akan membantu untuk skrip ini.


1
Anda dapat menggunakan soxuntuk menghitung kenyaringan rata-rata (IIRC ada pertanyaan lain tentang stackexchange tentang ini), dan pacmduntuk mengubah volume untuk Pulseaudio.
dirkt

1
@ sangat berterima kasih atas petunjuknya! Saya menemukan pertanyaan ini, saya akan mencoba mengimplementasikannya besok dan melaporkan kembali (mungkin saya dapat menjawab pertanyaan saya sendiri): superuser.com/questions/306701/…
Luc

Jawaban:


2

Saya telah membuat skrip Python untuk melakukan pekerjaan itu. Masalah yang tersisa adalah bahwa mikrofon laptop saya akan, tentu saja, juga mengambil speaker sendiri. Saya pikir 'pembatalan gema' mungkin yang saya cari, tapi saya tidak tahu bagaimana menerapkannya sendiri. Menggunakan mikrofon eksternal mungkin berfungsi.

Sayangnya, ini adalah python 2 karena python-alsaaudioketergantungan.

#!/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 dapat melakukan pembatalan gema sampai tingkat tertentu, lihat misalnya di sini dan di sini , google untuk lebih lanjut. Jika Anda ingin melakukannya sendiri, Anda harus mengurangi sinyal output dari sinyal input, waktu-tertunda dan dengan amplitudo yang tepat. Menemukan kedua parameter itu secara otomatis adalah bagian yang menyenangkan. :-) (Google "korelasi")
dirkt

@ membingungkan Terima kasih lagi! Pulseaudio sepertinya tidak bekerja dengan baik; terutama pada tingkat volume yang lebih tinggi (> 50%) itu rusak, mendeteksi dirinya sendiri dan terus naik. Saya hanya harus pergi dan mengambil mic, itu tidak seperti itu mahal pula :)
Luc
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.