0

I am trying to record with the input sound and output sound with PyAudio. Looking through the PyAudio documentation (here) and I have determined that I will having to use the input, output, input_device_index and output_device_index variables to edit the result of my sound stream.

Given the documentation, I believe that I should have a way to turn input and output on/off and configure what device corresponds to what stream. My devices are:

#{'index': 0, 'name': 'Microsoft Sound Mapper - Input'}

#{'index': 1, 'name': 'Microphone Array (Intel® Smart '}

#{'index': 2, 'name': 'Microsoft Sound Mapper - Output'}

#{'index': 3, 'name': 'Speakers (Realtek(R) Audio)'}

So far, I have the input working as I am able to record any sound detected by the microphone. The problems I'm encountering are:

  • Unable to turn input on
  • Unable to turn output off
  • Unable to get output audio only
  • Unable to get both audio streams together

When I try doing input=False I get the error raise IOError("Not input stream". My output stream seems to be not working at all.

My code thus far:

WAVE_OUTPUT_FILENAME = (r"C:\Users\USER\Downloads\output.wav")

p = pyaudio.PyAudio()

#{'index': 0, 'name': 'Microsoft Sound Mapper - Input'}
#{'index': 1, 'name': 'Microphone Array (Intel® Smart '}
#{'index': 2, 'name': 'Microsoft Sound Mapper - Output'}
#{'index': 3, 'name': 'Speakers (Realtek(R) Audio)'}

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

print("* recording")

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

print("* done recording")

stream.stop_stream()
stream.close()
p.terminate()

wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
Geneku2
  • 65
  • 8
  • 1
    Regarding capturing speakers' output, have you taken a look at [this post](https://stackoverflow.com/questions/26573556/record-speakers-output-with-pyaudio)? – Random Davis Jun 18 '21 at 16:38
  • @RandomDavis I've looked over that post and it seems to utilize some aspects outside of Python. I was first wondering if it could be done with only Python? Otherwise, I am unable to get the PortAudio end of the solution working – Geneku2 Jun 18 '21 at 22:20
  • It seems like this can be done on Windows using just the PyAudio fork mentioned in [this answer](https://stackoverflow.com/a/37218364/6273251) on that post. Assuming this is for Windows only. That's not really doing anything outside of Python (other than of course the native code that the module has to invoke in order to communicate with the OS's audio API). What about that answer made you think that aspects outside of Python are utilized? – Random Davis Jun 18 '21 at 22:27
  • It seemed that the PyAudio fork integrated PyAudio and PortAudio and PortAudio was supposed to be used with C/C++. I am not entirely sure what I should do with the fork or how it should be set up. – Geneku2 Jun 18 '21 at 22:50
  • To me it looks like that PyAudio fork just has PortAudio as a dependency. They modified the version that's in that forked project in order to set the `AUDCLNT_STREAMFLAGS_LOOPBACK` flag, but you don't ever have to use that library directly. It seems like you just have to build the forked project and then it'd work out of the box. At least, that's the impression I got from that answer. Maybe you don't realize, but lots of Python modules that interact with the OS or need native code run, will utilize C/C++ libraries in the background, while you only have to write Python code when using them. – Random Davis Jun 18 '21 at 22:57

1 Answers1

0

Windows actually offers a native way to record your systems audio without having to install to use other solutions. I primarily used this method because I had no idea how to install the PyAudio Fork mentioned here.

If you go to your system's sound settings, assuming its Windows, you will find a recording tab in the upper left hand corner. Upon clicking this, you'll also find a "Stereo Mix" icon which is normally disabled.Sound Settings with Stereo Mix shown2

If you enable this, this channel will capture all the devices output audio without needing to set up anything else. Therefore, you can set input_device_index with whatever the index of Stereo Mix on your computer is.

Geneku2
  • 65
  • 8