Created
February 9, 2019 14:39
-
-
Save Jarry1250/96c9758dcc68de2717d5b17ebf1f4820 to your computer and use it in GitHub Desktop.
Monitor input audio and only output when volume is sustained
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Sources: | |
# https://www.raspberrypi.org/forums/viewtopic.php?t=144374 | |
# https://github.com/ev3dev/ev3dev/issues/198 | |
# https://askubuntu.com/questions/71863/how-to-change-pulseaudio-sink-with-pacmd-set-default-sink-during-playback | |
# Remember to reboot | |
# CHANGE THESE | |
VOLUME_TRIGGER = 45 # Relative Decibels. Bigger number = louder | |
PROPORTION_TRIGGER = 0.5 # Should be between 0 (any peak, however short) and 1 (only continuous sound) | |
LENGTH_OF_SAMPLE = 5 # The period to look at in second | |
# YOU CAN CHANGE THESE BUT YOU SHOULDN'T NEED TO | |
PER_SECOND = 10 # Number of samples per second | |
RATE = 44100 # Audio quality | |
DISCONNECT_AFTER = 1 * PER_SECOND | |
# CHANGE THE BELOW AT YOUR OWN RISK | |
import pyaudio | |
import audioop | |
import math | |
p = pyaudio.PyAudio() | |
chunksize = int(RATE / PER_SECOND) | |
store = [] | |
how_many_to_store = PER_SECOND * LENGTH_OF_SAMPLE | |
countdown_to_disccnnect = DISCONNECT_AFTER | |
input = p.open(format=pyaudio.paInt16, | |
channels=2, | |
rate=RATE, | |
input=True, | |
frames_per_buffer=chunksize) | |
output = None | |
def create_stream(): | |
global output | |
if output is None: | |
output = p.open(format=pyaudio.paInt16, | |
channels=2, | |
rate=RATE, | |
output=True, | |
frames_per_buffer=chunksize) | |
print( "Listening..." ) | |
while True: # Loop forever | |
data = input.read(chunksize) | |
dB = 20 * math.log10( audioop.rms(data, 2) ) | |
# Let's keep a rotating list of whether the last x measurements triggered or not | |
store.append( 1 if (dB > VOLUME_TRIGGER) else 0 ) | |
if len(store) == (how_many_to_store + 1): | |
store.pop(0) | |
# And if a certain proportion of them did, trigger our action | |
if( sum(store)/how_many_to_store > PROPORTION_TRIGGER): | |
if (dB > (VOLUME_TRIGGER - 10)): | |
create_stream() | |
output.write(data) | |
countdown_to_disccnnect = DISCONNECT_AFTER | |
else: | |
countdown_to_disccnnect -= 1 | |
if countdown_to_disccnnect == 0 and output is not None: | |
output.close() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment