2

I'm trying to create a program to talk back at once. I can't seem to get it to work. Some websites say use numpy arrays but I don't know how.

import pyaudio
import wave
import time
import multiprocessing as mp
import pyaudio
import numpy as np
import sounddevice as sd

fs = 44100
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
CHUNK = 1024
audio = pyaudio.PyAudio()
RECORD_SECONDS = 5
stream = audio.open(format=FORMAT, channels=CHANNELS,
                rate=RATE, input=True,
                frames_per_buffer=CHUNK)
myarray = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    myarray.append(data)

    myrecording = sd.play(myarray, fs, channels=2)

Traceback (most recent call last): File "SoundTest.py", line 24, in myrecording = sd.play(myarray, fs, channels=2) line 2170, in check_data dtype = _check_dtype(data.dtype) File "/home/lordvile/.local/lib/python2.7/site-packages/sounddevice.py", line 2316, in _check_dtype raise TypeError('Unsupported data type: ' + repr(dtype)) TypeError: Unsupported data type: 'string32768'

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • What isn't workng? Explain. – Michael Aug 10 '16 at 16:28
  • @Michael I really have no idea. This is the error. I removed a few lines since it wont fit...Traceback (most recent call last): File "SoundTest.py", line 24, in myrecording = sd.play(myarray, fs, channels=2) line 2170, in check_data dtype = _check_dtype(data.dtype) File "/home/lordvile/.local/lib/python2.7/site-packages/sounddevice.py", line 2316, in _check_dtype raise TypeError('Unsupported data type: ' + repr(dtype)) TypeError: Unsupported data type: 'string32768' – Subhaditya Mukherjee Aug 10 '16 at 16:33
  • @SubhadityaMukherjee Update your question with your Tracebak please. – julian salas Aug 10 '16 at 16:38
  • Looks like `sounddevice` does not like `pyaudio`s data. Have you checked that the format is compatible? – handle Aug 10 '16 at 17:25
  • myarray is not a numpy array, but a list! – handle Aug 10 '16 at 17:27
  • @handle It appears so.. No I havent checked actually. To be honest im still in school and I dont think we will be doing numpy at all.. I dont understand how do I create the list with the audio data? It doesnt seem to be working. And thanks for helping.. – Subhaditya Mukherjee Aug 11 '16 at 06:04
  • You shouldn't mix `PyAudio` and the `sounddevice` module. Use either one or the other. – Matthias Aug 25 '16 at 13:32

2 Answers2

3

Below are examples for both 'PyAudio' and 'Sounddevice' for simultaneous recording and playback. The most important thing for me was to explicitly set the input and output devices to a valid value. Hence, I included printing for sound devices for both examples.

Sounddevice:

Works like a charm compared to PyAudio. At least for me, sounddevice offers a stable interface for simultaneous audio recording and playback. Though there are a few console outputs complaining about a input/output over-/underflow, the record/playback regenerates and eventually I get a fluently working 'echo'.

import sounddevice as sd

fs = 44100

def callback(indata, outdata, frames, time, status):
    if status:
        print(status)
    outdata[:] = indata

print(sd.query_devices())

try:
    with sd.Stream(device=(0,1), samplerate=fs, dtype='float32', latency=None, channels=2, callback=callback):
        input()
except KeyboardInterrupt:
    pass

PyAudio:

This code should(?) work. For me it does not work consistently. It already worked for about a minute once but usually I get the Error: "OSError: [Errno -9981] Input overflowed". I don't know why it always throws this error, but feel free to try it out yourself.

import pyaudio
import json

FORMAT = pyaudio.paInt16
CHANNELS = 1
CHUNK = 1024
RATE = 44100

audio = pyaudio.PyAudio()

for i in range(audio.get_device_count()):
    print(json.dumps(audio.get_device_info_by_index(i), indent=2))

stream = audio.open(format              = FORMAT,
                    channels            = CHANNELS,
                    rate                = RATE,
                    input               = True,
                    output              = True,
                    input_device_index  = 0,
                    output_device_index = 1,
                    frames_per_buffer   = CHUNK)

try:
    frames = []
    print("* echoing")
    print("Press CTRL+C to stop")
    while True:
        data = stream.read(CHUNK)
        frames.append(data)
        if len(frames)>0:
            stream.write(frames.pop(0),CHUNK)
    print("* done echoing")
except KeyboardInterrupt:
    stream.stop_stream()
    stream.close()
    audio.terminate()
AnthonyZ
  • 61
  • 3
  • For me who uses PyAudio, explicitly specifying the input device index and output device index solves the problem – goodahn Jul 07 '20 at 15:52
  • The two examples compare `sounddevice` using "callback" mode with `pyaudio` using "blocking" mode. Both modules can use both modes, so it would be more meaningful to compare them using the same mode. – Matthias Apr 16 '21 at 08:19
  • Note that `pyaudio` has the `exception_on_overflow` parameter for `read()` (see https://people.csail.mit.edu/hubert/pyaudio/docs/#pyaudio.Stream.read), which is `True` by default. If you set this to `False`, you can avoid raising the mentioned exception (but I don't recommend ignoring those over- and underflows!). – Matthias Apr 16 '21 at 08:22
2

Not sure if you have requirement to use pyaudio, but here is an example using sounddevice.

Below example records audio from microphone for #seconds as per variable duration which you can modify as per your requirements.

Same contents are played back using standard audio output (speakers).

More on this here

Working Code

import sounddevice as sd
import numpy as np
import scipy.io.wavfile as wav

fs=44100
duration = 10  # seconds
myrecording = sd.rec(duration * fs, samplerate=fs, channels=2, dtype='float64')
print "Recording Audio for %s seconds" %(duration)
sd.wait()
print "Audio recording complete , Playing recorded Audio"
sd.play(myrecording, fs)
sd.wait()
print "Play Audio Complete"

Output

Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>> 
Recording Audio for 10 seconds
Audio recording complete , Playing recorded Audio
Play Audio Complete
>>> 
Anil_M
  • 10,893
  • 6
  • 47
  • 74