--- a/snd.py +++ b/snd.py @@ -1,15 +1,12 @@ -""" Record a few seconds of audio and save to a WAVE file. +""" Record a few seconds of audio and save to a WAVE file. Based on http://stackoverflow.com/questions/892199/detect-record-audio-in-python/6743593#6743593 """ import pyaudio import wave import sys -import audioop # http://docs.python.org/library/audioop -from os.path import exists from array import array from struct import unpack, pack -import threading from pydispatch import dispatcher THRESHOLD = 500 @@ -17,11 +14,11 @@ FORMAT = pyaudio.paInt16 RATE = 44100 if sys.platform.startswith('darwin'): - CHANNELS = 2 + CHANNELS = 2 elif sys.platform.startswith('win32'): - CHANNELS = 1 + CHANNELS = 1 -MAX_SILENT = 30 +MAX_SILENT = 80 def is_silent(L): "Returns `True` if below the 'silent' threshold" @@ -72,16 +69,16 @@ def record(): """ - Record a word or words from the microphone and + Record a word or words from the microphone and return the data as an array of signed shorts. - Normalizes the audio, trims silence from the - start and end, and pads with 0.5 seconds of - blank sound to make sure VLC et al can play + Normalizes the audio, trims silence from the + start and end, and pads with 0.5 seconds of + blank sound to make sure VLC et al can play it without getting chopped off. """ p = pyaudio.PyAudio() - stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, + stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK_SIZE) @@ -91,7 +88,12 @@ LRtn = array('h') while 1: - data = stream.read(CHUNK_SIZE) + try: + data = stream.read(CHUNK_SIZE) + except IOError as ex: + if ex[1] != pyaudio.paInputOverflowed: + raise + data = '\x00' * CHUNK_SIZE L = unpack('<' + ('h'*(len(data)/2)), data) # little endian, signed short L = array('h', L) @@ -100,11 +102,13 @@ if silent and snd_started: num_silent += 1 - print num_silent + #print num_silent elif not silent and not snd_started: dispatcher.send( signal='SND_STARTED') snd_started = True print snd_started + if snd_started and not silent: + num_silent = 0 if snd_started: LRtn.extend(L) if snd_started and num_silent > MAX_SILENT: @@ -126,7 +130,7 @@ data = pack('<' + ('h'*len(data)), *data) wf = wave.open(path, 'wb') - wf.setnchannels(1) + wf.setnchannels(CHANNELS) wf.setsampwidth(sample_width) wf.setframerate(RATE) wf.writeframes(data)