Aran Bins
Aran Bins

Reputation: 488

python-sounddevice - Playing back audio from microphone

I can get the audio to play back from my microphone but it's extremely muffled and it honestly sounds like the program is going to crash.

I tried using an InputStream but the sound is just horrible when I play it back, any idea what I'm doing wrong?

10 is my Microphone while 13 is my output device (speakers)

import sounddevice as sd

device_info = sd.query_devices(10, 'input')
samplerate = int(device_info['default_samplerate'])

sd.default.samplerate = samplerate
sd.default.channels = 2
devices = sd.query_devices()
print(devices)

def callback(indata, frames, time, status):
    #print(indata)
    sd.play(indata, device=13, blocking=True)

with sd.InputStream(device = 10, samplerate=44100, dtype='float32', callback=callback):
    print('#' * 80)
    print('press Return to quit')
    print('#' * 80)
    input()

I have a feeling I need to add it to a queue and play it from the queue?

Upvotes: 3

Views: 8634

Answers (1)

Matthias
Matthias

Reputation: 4884

The high-level convenience functions sd.play(), sd.rec() and sd.playrec() simply play and/or record whole NumPy arrays of arbitrary (but fixed) length (as long as they fit into memory). They are supposed to be simple and convenient, but their use cases are quite limited.

If you need more control (e.g. continuous recording, realtime processing, ...), you can use the lower-level "stream" classes (e.g. sd.Stream, sd.InputStream, sd.RawInputStream) either with the "non-blocking" callback interface or with the "blocking" read() and write() methods.

The high-level functions internally already use the "stream" classes, therefore you are not supposed to mix them! If you use sd.play() in the callback function of a stream, it creates yet another stream within the callback function. This is bound to fail!

Long story short, you should use either the high-level or the low-level interface, but not both at the same time.

If you want to play back the microphone input immediately, you should use an sd.Stream (including both input and output) with a callback function, just as it's shown in the documentation and in the example application wire.py.

Upvotes: 5

Related Questions