1

I want to use sounddevice to capture (record?) audio that is coming out of my speakers. My speakers have two channels.

This is my code (which I found here https://realpython.com/playing-and-recording-sound-python/#python-sounddevice_1):

import sounddevice as sd
from scipy.io.wavfile import write

fs = 44100/2  # Sample rate
seconds = 3  # Duration of recording

myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2)
sd.wait()  # Wait until recording is finished
write('output.wav', fs, myrecording)  # Save as WAV file

I get the following error:

Traceback (most recent call last):
  File "main.py", line 24, in <module>
    myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2)
  File "/usr/local/lib/python3.7/site-packages/sounddevice.py", line 277, in rec
    ctx.input_dtype, callback, blocking, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/sounddevice.py", line 2587, in start_stream
    **kwargs)
  File "/usr/local/lib/python3.7/site-packages/sounddevice.py", line 1422, in __init__
    **_remove_self(locals()))
  File "/usr/local/lib/python3.7/site-packages/sounddevice.py", line 901, in __init__
    f'Error opening {self.__class__.__name__}')
  File "/usr/local/lib/python3.7/site-packages/sounddevice.py", line 2747, in _check
    raise PortAudioError(errormsg, err)
sounddevice.PortAudioError: Error opening InputStream: Invalid number of channels [PaErrorCode -9998]

I'm on a Mac M1 running rosetta-emulated python.

When I set the channels to '1' it works, but it only records from one channel.

I tried to get the index of my speakers by running print(sd.query_devices()), this was the output:

> 0 MacBook Pro Microphone, Core Audio (1 in, 0 out)
< 1 MacBook Pro Speakers, Core Audio (0 in, 2 out)
  2 Microsoft Teams Audio, Core Audio (2 in, 2 out)

So I tried to manually set this index, like so:

myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2, device=1)

But this also produced the same error.

koegl
  • 505
  • 2
  • 13

1 Answers1

0

By default, sounddevice captures audio from your input device. If you want to use a signal from your speakers, you can try set the argument 'device' in sd.rec function to the index of your speakers.

To find the index of your speakers run:

print(sd.query_devices())

For example, if the index of your speakers is 3. Sd.rec should look like:

myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2, device=3)
Usr Ustym
  • 11
  • 2