fix: disallow selecting non-microphone audio device

Previously any audio device was allowed to be selected as microphone. Now, only ones with at least one input channel can be selected.

ref: N25B-119
This commit is contained in:
Twirre Meulenbelt
2025-10-22 13:24:46 +02:00
parent 0f60f67ab9
commit 1e3e077029

View File

@@ -1,8 +1,25 @@
from __future__ import unicode_literals # So that `print` can print the Unicode strings in names
import logging
logger = logging.getLogger(__name__)
def get_microphones(audio):
"""
Get audio devices which have input channels.
:param audio: An instance of PyAudio to use.
:type audio: pyaudio.PyAudio
:return: An interator of PaAudio dicts containing information about the microphone devices.
:rtype: Iterator[dict]
"""
for i in range(audio.get_device_count()):
device = audio.get_device_info_by_index(i)
if device["maxInputChannels"] > 0:
yield device
def choose_mic_interactive(audio):
"""
Choose a microphone to use, interactively in the CLI.
@@ -14,24 +31,23 @@ def choose_mic_interactive(audio):
if there is no microphone.
:rtype: dict | None
"""
device_count = audio.get_device_count()
if device_count == 0: return None
microphones = list(get_microphones(audio))
if len(microphones) == 0: return None
print("Found {} audio devices:".format(device_count))
for i in range(device_count):
print("- {}: {}".format(i, audio.get_device_info_by_index(i)["name"]))
print("Found {} microphones:".format(len(microphones)))
for i, mic in enumerate(microphones):
print("- {}: {}".format(i, mic["name"]))
microphone_index = None
while microphone_index is None:
chosen_microphone = None
while chosen_microphone is None:
chosen = raw_input("Which device would you like to use?\n> ")
try:
chosen = int(chosen)
if chosen < 0 or chosen >= device_count: raise ValueError()
microphone_index = chosen
if chosen < 0 or chosen >= len(microphones): raise ValueError()
chosen_microphone = microphones[chosen]
except ValueError:
print("Please enter a number between 0 and {}".format(device_count-1))
print("Please enter a number between 0 and {}".format(len(microphones)-1))
chosen_microphone = audio.get_device_info_by_index(microphone_index)
logger.info("Chose microphone \"{}\"".format(chosen_microphone["name"]))
return chosen_microphone
@@ -47,8 +63,7 @@ def choose_mic_default(audio):
if there is no microphone.
:rtype: dict | None
"""
device_count = audio.get_device_count()
if device_count == 0: return None
default_device = audio.get_default_input_device_info()
return default_device
try:
return audio.get_default_input_device_info()
except IOError:
return None