29

When recording audio via PyAudio, how do you specify the exact input device to use?

My computer has two microphones, one built-in and one via USB, and I want to record using the USB mic. The Stream class has an input_device_index for selecting the device, but it's unclear how this index correlates to the devices. For example, how do I know which device index 0 refers to? If I had to guess, I'd say 0 refers to the built-in device while 1 refers to the USB device, but I'd like to find some programmatic way of confirming this. On Linux, is there a way to get a list of these indexes and the devices they refer to?

Cerin
  • 60,957
  • 96
  • 316
  • 522

8 Answers8

42

you can use get_device_info_by_host_api_device_index.

For instance:

import pyaudio

p = pyaudio.PyAudio()
info = p.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')

for i in range(0, numdevices):
    if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
        print("Input Device id ", i, " - ", p.get_device_info_by_host_api_device_index(0, i).get('name'))
slegroux
  • 610
  • 5
  • 11
  • 1
    This code failed for me. Needed to also add: info = p.get_host_api_info_by_index(0) and then numdevices = info.get('deviceCount'). Also I needed to use p instead of self.p, and then it worked. Please fix your answer and I'll upvote it then. Thanks. – Wayne Piekarski Dec 11 '16 at 03:52
  • @WaynePiekarski Done. Thanks! – slegroux Dec 14 '16 at 18:09
  • 3
    How do you then assign one of the devices listed to be the pyaudio device? – TestinginProd Apr 25 '18 at 17:16
  • 2
    and how to select a input device? get_device_info_by_host_api_device_index only gets me information – fsp Jun 07 '18 at 02:17
  • 11
    `input_device_index=x` is the solution. – fsp Jun 07 '18 at 02:33
  • That is also for output devices too? – Chris P Mar 13 '21 at 03:56
  • for output channels, change 'if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:' to 'if (p.get_device_info_by_host_api_device_index(0, i).get('maxOutputChannels')) > 0:' – Charlie Jan 19 '22 at 15:22
3

I havent looked at pyaudio but I've used sounddevice as well on few occasions.

Here is an example code that lists available input and output audio devices.

import sounddevice as sd
print sd.query_devices() 

As you can see from below output, when I put my headset to mic jack , Index 1is available as input. 1 Jack Mic (IDT High Definition A, MME (2 in, 0 out)

While default laptop audio microphone comes up as index 2

2 Microphone Array (IDT High Defi, MME (2 in, 0 out)

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 ================================
>>> 
   0 Microsoft Sound Mapper - Input, MME (2 in, 0 out)
>  1 Jack Mic (IDT High Definition A, MME (2 in, 0 out)
   2 Microphone Array (IDT High Defi, MME (2 in, 0 out)
   3 Microsoft Sound Mapper - Output, MME (0 in, 2 out)
<  4 Speakers / Headphones (IDT High, MME (0 in, 2 out)
   5 Communication Headphones (IDT H, MME (0 in, 2 out)
   6 Primary Sound Capture Driver, Windows DirectSound (2 in, 0 out)
   7 Jack Mic (IDT High Definition Audio CODEC), Windows DirectSound (2 in, 0 out)
   8 Microphone Array (IDT High Definition Audio CODEC), Windows DirectSound (2 in, 0 out)
   9 Primary Sound Driver, Windows DirectSound (0 in, 2 out)
  10 Speakers / Headphones (IDT High Definition Audio CODEC), Windows DirectSound (0 in, 2 out)
  11 Communication Headphones (IDT High Definition Audio CODEC), Windows DirectSound (0 in, 2 out)
  12 Communication Headphones (IDT High Definition Audio CODEC), Windows WASAPI (0 in, 2 out)
  13 Speakers / Headphones (IDT High Definition Audio CODEC), Windows WASAPI (0 in, 2 out)
  14 Jack Mic (IDT High Definition Audio CODEC), Windows WASAPI (2 in, 0 out)
  15 Microphone Array (IDT High Definition Audio CODEC), Windows WASAPI (2 in, 0 out)
  16 Headset Microphone (Bluetooth Hands-free Audio), Windows WDM-KS (1 in, 0 out)
  17 Headphones (Bluetooth Hands-free Audio), Windows WDM-KS (0 in, 2 out)
  18 Headphones (HpOut), Windows WDM-KS (0 in, 2 out)
  19 Microphone Array (MicIn2), Windows WDM-KS (2 in, 0 out)
  20 Jack Mic (MuxedIn), Windows WDM-KS (2 in, 0 out)
  21 Dock Mic (MuxedIn), Windows WDM-KS (2 in, 0 out)
  22 Rec. Playback (MuxedIn), Windows WDM-KS (2 in, 0 out)
  23 Speakers (Speaker/HP), Windows WDM-KS (0 in, 2 out)
Anil_M
  • 10,893
  • 6
  • 47
  • 74
3

Use @slegroux awesome code to find the audio index:

import pyaudio

p = pyaudio.PyAudio()
info = p.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')

for i in range(0, numdevices):
    if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
        print("Input Device id ", i, " - ", p.get_device_info_by_host_api_device_index(0, i).get('name'))

Once you find which index the microphone you want to use is on, add the input_device_index option followed by the index of the microphone (in my case the mic was on index 1) to your p.open() like so:

stream = p.open(
    format=FORMAT,
    channels=CHANNELS,
    rate=RATE,
    input=True,
    frames_per_buffer=FRAMES_PER_BUFFER,
    input_device_index=1
)

Hope this helps!

Max Irvine
  • 31
  • 1
1

The index of your microphone (that you are currently using) is always 1. You can test this with the code by @Anil_M:

import sounddevice as sd
print(sd.query_devices())

Run this code and then look at index one. Now unplug your mic and run the code again. Mic will still be on 1

Only if you want use another device, like in my case i need the OS audio you can to use following code:

p = pyaudio.PyAudio()

# if there is no speaker device this all makes no sense anyways
try:
    wasapi_info = p.get_host_api_info_by_type(pyaudio.paWASAPI)
except OSError:
    exit()

#choosing the speaker device 
default_speakers=p.get_device_info_by_index(wasapi_info["defaultOutputDevice"]) 

# or "defaultInputDevice"

I do have to mention that this code only works on windows

morigan
  • 23
  • 9
0

In the PyAudio Documentation it states that you can define an input_device_index.

To find out what that device index is, you can follow the code provided in this Github Gist or by following the code found on the Raspberry Pi Forum which provides an example of the outputted code.

imbatman
  • 508
  • 5
  • 16
0

You can select the input device using PulseAudio.

Rodrigo
  • 103
  • 2
  • 6
-3

I don't know about PyAudio, but with the sounddevice module it goes like that:

python3 -m sounddevice
Matthias
  • 4,524
  • 2
  • 31
  • 50
-3

Just use arecord -l to list all available input devices.