The current top answer is a bit outdated and works only for python 2. Here is the version updated for python 3. It combines functions into classes and packs everything into one easy-to-use version. Note that there is one key difference between the main answer and my script:
The script at the top writes one file and then stops, while my script continues to write whenever a noise is detected, and writes the entries to the directory as it arrives.
The basic idea of ββboth scenarios is pretty similar:
Step 1: βListenβ until rms gets over the threshold
Step 2. Start recording, set a timer when you want to stop recording, == TIMEOUT_LENGTH
Step 3: If the standard deviation again exceeds the threshold before the timer expires, reset the timer
Step 4. Now that the timer has expired, write the entry in the directory and return to step 1.
import pyaudio import math import struct import wave import time import os Threshold = 10 SHORT_NORMALIZE = (1.0/32768.0) chunk = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 16000 swidth = 2 TIMEOUT_LENGTH = 5 f_name_directory = r'C:\Users\Jason\PyCharmProjects\AutoRecorder\records' class Recorder: @staticmethod def rms(frame): count = len(frame) / swidth format = "%dh" % (count) shorts = struct.unpack(format, frame) sum_squares = 0.0 for sample in shorts: n = sample * SHORT_NORMALIZE sum_squares += n * n rms = math.pow(sum_squares / count, 0.5) return rms * 1000 def __init__(self): self.p = pyaudio.PyAudio() self.stream = self.p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, output=True, frames_per_buffer=chunk) def record(self): print('Noise detected, recording beginning') rec = [] current = time.time() end = time.time() + TIMEOUT_LENGTH while current <= end: data = self.stream.read(chunk) if self.rms(data) >= Threshold: end = time.time() + TIMEOUT_LENGTH current = time.time() rec.append(data) self.write(b''.join(rec)) def write(self, recording): n_files = len(os.listdir(f_name_directory)) filename = os.path.join(f_name_directory, '{}.wav'.format(n_files)) wf = wave.open(filename, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(self.p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(recording) wf.close() print('Written to file: {}'.format(filename)) print('Returning to listening') def listen(self): print('Listening beginning') while True: input = self.stream.read(chunk) rms_val = self.rms(input) if rms_val > Threshold: self.record() a = Recorder() a.listen()
source share