Skip to content

Instantly share code, notes, and snippets.

@johnowhitaker
Created July 30, 2023 15:44
Show Gist options
  • Save johnowhitaker/8963e8c43f0ec0ecd4d1d8232991eeff to your computer and use it in GitHub Desktop.
Save johnowhitaker/8963e8c43f0ec0ecd4d1d8232991eeff to your computer and use it in GitHub Desktop.
Quick script co-written with Bing AI that listens to mic input and triggers an action (pressing 'x' key) when a loud noise starts. Configure min_time and threshold to your liking. Fun as a controller for 'russian subway dogs' game!
# Import the required modules
import sounddevice as sd # For accessing the microphone
import pynput # For sending keypresses
import numpy as np # For numerical calculations
import time as tm # For measuring time
# Define a function that checks the loudness of the sound input
def check_loudness(indata, outdata, frames, time, status):
global prev_state, last_trigger
# Convert the sound input to a numpy array
indata = np.array(indata)
# Calculate the root mean square (RMS) of the sound input
rms = np.sqrt(np.mean(indata**2))
# Compare the RMS with a threshold value (adjustable)
threshold = 0.04 # Change this value as needed
# Define a minimum time between triggers (in seconds)
min_time = 0.1 # Change this value as needed
# Get the current time (in seconds)
current_time = tm.time()
# Check if the sound input is above or below the threshold
if rms > threshold:
# If the sound input is above the threshold, set the state to True
state = True
else:
# If the sound input is below the threshold, set the state to False
state = False
# Check if the state has changed from False to True
if state and not prev_state:
# If the state has changed from False to True, check if enough time has passed since the last trigger
if current_time - last_trigger > min_time:
# If enough time has passed since the last trigger, trigger an event
print("Loud sound detected!")
# Send a keypress of the letter 'x'
pynput.keyboard.Controller().press('x')
pynput.keyboard.Controller().release('x')
# Update the last trigger time to the current time
last_trigger = current_time
# Update the previous state to the current state
prev_state = state
# Create a stream object that listens to the microphone in real time
stream = sd.Stream(callback=check_loudness,
blocksize=1024,
samplerate=8000)
# Start the stream
stream.start()
# Initialize the variables for storing the last trigger time and the previous state
last_trigger = 0
prev_state = False
# Wait for the user to press 'q' to quit
print("Press 'q' to quit")
while True:
# infinite loop
tm.sleep(0.1)
# Stop and close the stream
stream.stop()
stream.close()
@johnowhitaker
Copy link
Author

pip install pynput sounddevice to get the requirements. Tested on Ubuntu 22.04 aka "works on my machine"

@johnowhitaker
Copy link
Author

You can get better latency at the cost of potential underruns by reducing the blocksize

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment