Last active
May 15, 2020 15:52
-
-
Save SlimeBOOS/0c036d2a667456d413f7c704aa7ed592 to your computer and use it in GitHub Desktop.
Clap twice and pewdiepies subreddit will open.
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
# Things that need to be installed via pip: | |
# - PyAudio | |
import pyaudio | |
import struct | |
import math | |
import webbrowser | |
import asyncio | |
import time | |
# If claps are not being detected increase INITIAL_TAP_THRESHOLD | |
# If claps are being over detected decrease INITIAL_TAP_THRESHOLD | |
INITIAL_TAP_THRESHOLD = 0.1 | |
INPUT_BLOCK_TIME = 0.05 | |
# if the noise was longer than this many blocks, it's not a 'tap' | |
MAX_TAP_BLOCKS = 0.15/INPUT_BLOCK_TIME | |
class ClapDetector(object): | |
pa = pyaudio.PyAudio() | |
def __init__(self, tap_threshold=None): | |
self.tap_threshold = tap_threshold or INITIAL_TAP_THRESHOLD | |
self.noisycount = MAX_TAP_BLOCKS+1 | |
self.quietcount = 0 | |
self.errorcount = 0 | |
self.stream = None | |
self.device = None | |
self.start() | |
def __del__(self): | |
if self.stream != None: | |
self.stop() | |
@staticmethod | |
def getInputDevices(): | |
input_devices = [] | |
for i in range(ClapDetector.pa.get_device_count() ): | |
device_info = ClapDetector.pa.get_device_info_by_index(i) | |
if device_info["maxInputChannels"] > 0: | |
input_devices.append(device_info) | |
return input_devices | |
@staticmethod | |
def getRMS(block): | |
# RMS amplitude is defined as the square root of the | |
# mean over time of the square of the amplitude. | |
# so we need to convert this string of bytes into | |
# a string of 16-bit samples... | |
# we will get one short out for each | |
# two chars in the string. | |
count = len(block)/2 | |
shorts = struct.unpack( "%dh"%(count), block ) | |
# iterate over the block. | |
sum_squares = 0.0 | |
for sample in shorts: | |
# sample is a signed short in +/- 32768. | |
# normalize it to 1.0 | |
sum_squares += (sample / 32768.0)**2 | |
return math.sqrt( sum_squares / count ) | |
def stop(self): | |
if self.stream != None: | |
self.stream.close() | |
return True | |
else: | |
print("Tried to close an already closed stream") | |
return False | |
def start(self): | |
if self.device == None: | |
self.device = ClapDetector.getInputDevices()[0] | |
if self.device == None: | |
print("No input devices found") | |
return False | |
self.stream = self.pa.open(format = pyaudio.paInt16, | |
channels = self.device["maxInputChannels"], | |
rate = int(self.device["defaultSampleRate"]), | |
input = True, | |
input_device_index = self.device["index"], | |
frames_per_buffer = int(self.device["defaultSampleRate"]*INPUT_BLOCK_TIME)) | |
return True | |
def listen(self): | |
if self.stream == None: | |
print("Stream is not opened") | |
return False | |
try: | |
block = self.stream.read(self.stream._frames_per_buffer) | |
except Exception as e: | |
# dammit. | |
self.errorcount += 1 | |
print( "(%d) Error recording: %s"%(self.errorcount,e) ) | |
self.noisycount = 1 | |
return | |
rms = ClapDetector.getRMS(block) | |
if rms > self.tap_threshold: | |
# noisy block | |
self.quietcount = 0 | |
self.noisycount += 1 | |
else: | |
# quiet block. | |
is_clap = (1 <= self.noisycount <= MAX_TAP_BLOCKS) | |
self.noisycount = 0 | |
self.quietcount += 1 | |
return is_clap | |
return False | |
if __name__ == "__main__": | |
last_clap = 0 | |
clap_detector = ClapDetector() | |
clap_detector.device = ClapDetector.getInputDevices()[1] | |
print("Listening on "+clap_detector.device["name"]) | |
while True: | |
if clap_detector.listen(): | |
current_time = time.time() | |
print("CLAP:", current_time) | |
diff = current_time - last_clap | |
if diff >= 0.2: | |
if diff <= 1.5: | |
webbrowser.open("https://www.reddit.com/r/PewdiepieSubmissions/") | |
last_clap = 0 | |
else: | |
last_clap = current_time |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment