views:

2288

answers:

3

I need to capture audio clips as WAV files that I can then pass to another bit of python for processing. The problem is that I need to determine when there is audio present and then record it, stop when it goes silent and then pass that file to the processing module.

I'm thinking it should be possible with the wave module to detect when there is pure silence and discard it then as soon as something other than silence is detected start recording, then when the line goes silent again stop the recording.

Just can't quite get my head around it, can anyone get me started with a basic example.

+4  A: 

I believe the WAVE module does not support recording, just processing existing files. You might want to look at PyAudio for actually recording. WAV is about the world's simplest file format. In paInt16 you just get a signed integer representing a level, and closer to 0 is quieter. I can't remember if WAV files are high byte first or low byte, but something like this ought to work (sorry, I'm not really a python programmer:

from array import array

# you'll probably want to experiment on threshold
# depends how noisy the signal
threshold = 10 
maxValue = 0

asInts = array('h', data)
for i in range(len(asInts)):
   maxValue = max(maxValue, value)
if value > threshold:
    # not silence

PyAudio code for recording kept for reference:

import pyaudio
import sys

chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 5

p = pyaudio.PyAudio()

stream = p.open(format = FORMAT,
                channels = CHANNELS, 
                rate = RATE, 
                input = True,
                output = True,
                frames_per_buffer = chunk)

print "* recording"
for i in range(0, 44100 / chunk * RECORD_SECONDS):
    data = stream.read(chunk)
    # check for silence here by comparing the level with 0 (or some threshold) for 
    # the contents of data.
    # then write data or not to a file

print "* done"

stream.stop_stream()
stream.close()
p.terminate()
Nick Fortescue
Thanks Nick,Yes should have said I'm also using portaudio for the capture, the bit I'm stuck on is the checking for silence, how to I get the level in the chunk of data?
I've added some really simple untested code above, but it ought to do the job you want
Nick Fortescue
awesome thanks Nick
My previous version had a bug, wasn't dealing with the sign properly. I've used the library function array() to parse properly now
Nick Fortescue
A: 

You might want to look at csounds, also. It has several API's, including Python. It might be able to interact with an A-D interface and gather sound samples.

S.Lott
A: 
from array import array  

# you'll probably want to experiment on threshold  
# depends how noisy the signal  
threshold = 10   
maxValue = 0  

asInts = array('h', data)  
for i in range(len(asInts)):  
   maxValue = max(maxValue, value)  
if value > threshold:  
    # not silence  

Where is the value of 'value'?

Carolus89