Come faccio a regolare automaticamente il volume in base al suono che mi circonda?


8

Vivo accanto a una grande strada. Avere la finestra aperta di notte è beato e, a intermittenza, molto rumoroso. Come potrei regolare automaticamente il volume, in base all'ingresso del microfono incorporato? Se imposto il volume in modo da poter sentire i discorsi in un film mentre passa un'auto, altre volte sarà molto rumoroso e si sentirà molto odioso nei confronti delle persone vicine (fuori e vicini).

Il mio sistema è Debian Buster, anche se probabilmente riesco a far funzionare una soluzione generica. Se non è disponibile alcun pacchetto che lo faccia, un comando per estrarre il volume dal microfono predefinito sarebbe già utile per scrivere questo.


1
È possibile utilizzare soxper calcolare il volume medio (IIRC ci sono altre domande su stackexchange al riguardo) e pacmdper modificare il volume di Pulseaudio.
Dirkt

1
@dirkt Grazie per i suggerimenti! Ho trovato questa domanda, cercherò di implementarla domani e riferire (forse posso rispondere alla mia domanda): superuser.com/questions/306701/…
Luc

Risposte:


2

Ho realizzato uno script Python per fare il lavoro. Un altro problema è che il microfono del mio laptop, ovviamente, rileverà anche i propri altoparlanti. Penso che la "cancellazione dell'eco" potrebbe essere ciò che sto cercando, ma non avrei idea di come implementarlo da solo. L'uso di un microfono esterno potrebbe tuttavia funzionare.

python-alsaaudioPurtroppo è Python 2 a causa della dipendenza.

#!/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 può annullare l'eco in una certa misura, vedere ad esempio qui e qui , google per ulteriori informazioni. Se vuoi farlo da solo, devi sottrarre il segnale di uscita dal segnale di ingresso, ritardato e con la giusta ampiezza. Trovare questi due parametri automaticamente è la parte divertente. :-) (Google "correlazione")
dirkt

@dirkt Grazie ancora! Tuttavia, Pulseaudio non sembra funzionare molto bene; specialmente a livelli di volume più alti (> 50%) si rompe, si rileva e continua a salire. Devo solo andare a prendere un microfono, non è che siano comunque costosi :)
Luc
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.