Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to record from microphone and playback in real time

I'm trying to record data from my microphone and then play it back through the speakers in real time, and with some delays, but I'm having some problems with it. I chose to use python and alsaaudio, and my current script I'm having problems with can be found here. This works with what I have this far(not the delay part), but produces some clicking. alsaaudio docs has this to say:

The most common reason for problems with playback of PCM audio is that writes to PCM devices must exactly match the data rate of the device.

If too little data is written to the device, it will underrun, and ugly clicking sounds will occur. Conversely, of too much data is written to the device, the write function will either block (PCM_NORMAL mode) or return zero (PCM_NONBLOCK mode).

I seem to be misunderstanding the docs, it says this about write():

PCM.write(data)

Writes (plays) the sound in data. The length of data must be a multiple of the frame size, and should be exactly the size of a period

a period in my script is 160.

it says this about read():

In PCM_NORMAL mode, this function blocks until a full period is available, and then returns a tuple (length,data) where length is the number of frames of captured data, and data is the captured sound frames as a string. The length of the returned data will be periodsize*framesize bytes.

in my script, period_size*frame_size should also be equal to 160, but when I print the length(part of tuple read() returns) i'm getting 940. Obviously I seem to not be passing the right amount of data to out.write(), but I'm not sure where to go. I put this code together mostly through examples I found, and I just started working with alsaaudio / sound, trying to put together some interesting projects, so I don't know a whole lot yet.

I also wanted to record live from the microphone, then playback with a 100ms delay, hence the commented time.sleep(). If I uncomment it, the length seems to go from 940 to -32 repeatedly, eventually causing out.write() to throw an exception (not enough data).

Could someone tell me how (or what's wrong with my script) I'd go about recording and playing back sound data in real time, and with a 100ms delay?

like image 701
src Avatar asked Aug 18 '11 05:08

src


People also ask

How can I record my mic and computer playback simultaneously?

Right-click the microphone and click "Properties" under the "Listen" tab, and tick the box before "Listen to this device." In this way, the audio from the microphone can be simultaneously recorded with the audio playing on your computer. Step 2.


1 Answers

you can't use sleep(0.1) to delay the output by 100ms. you need to create a buffer which hold the 100ms audio data:

buf = []
while True:
    l, data = inp.read()
    buf.append(data)
    if len(buffer)>=10:
        out.write(buf[0])
        del buf[0]

change 10 to some number that will cause 100ms delay.

like image 186
HYRY Avatar answered Sep 20 '22 15:09

HYRY