122 lines
3.8 KiB
Python
122 lines
3.8 KiB
Python
from __future__ import unicode_literals # So that `print` can print Unicode characters in names
|
|
import logging
|
|
import sys
|
|
|
|
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.
|
|
|
|
:param audio: An instance of PyAudio to use.
|
|
:type audio: pyaudio.PyAudio
|
|
|
|
:return: A dictionary from PyAudio containing information about the microphone to use, or None
|
|
if there is no microphone.
|
|
:rtype: dict | None
|
|
"""
|
|
microphones = list(get_microphones(audio))
|
|
if len(microphones) == 0: return None
|
|
|
|
print("Found {} microphones:".format(len(microphones)))
|
|
for i, mic in enumerate(microphones):
|
|
print("- {}: {}".format(i, mic["name"]))
|
|
|
|
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 >= len(microphones): raise ValueError()
|
|
chosen_microphone = microphones[chosen]
|
|
except ValueError:
|
|
print("Please enter a number between 0 and {}".format(len(microphones)-1))
|
|
|
|
logger.info("Chose microphone \"{}\"".format(chosen_microphone["name"]))
|
|
return chosen_microphone
|
|
|
|
|
|
def choose_mic_default(audio):
|
|
"""
|
|
Get the system's default microphone to use.
|
|
|
|
:param audio: An instance of PyAudio to use.
|
|
:type audio: pyaudio.PyAudio
|
|
|
|
:return: A dictionary from PyAudio containing information about the microphone to use, or None
|
|
if there is no microphone.
|
|
:rtype: dict | None
|
|
"""
|
|
try:
|
|
return audio.get_default_input_device_info()
|
|
except IOError:
|
|
return None
|
|
|
|
|
|
def choose_mic_arguments(audio):
|
|
"""
|
|
Get a microphone to use from command line arguments.
|
|
|
|
:param audio: An instance of PyAudio to use.
|
|
:type audio: pyaudio.PyAudio
|
|
|
|
:return: A dictionary from PyAudio containing information about the microphone to use, or None
|
|
if there is no microphone satisfied by the arguments.
|
|
:rtype: dict | None
|
|
"""
|
|
microphone_name = None
|
|
for i, arg in enumerate(sys.argv):
|
|
if arg == "--microphone" and len(sys.argv) > i+1:
|
|
microphone_name = sys.argv[i+1].strip()
|
|
if arg.startswith("--microphone="):
|
|
pre_fix_len = len("--microphone=")
|
|
microphone_name = arg[pre_fix_len:].strip()
|
|
|
|
if not microphone_name: return None
|
|
|
|
available_mics = list(get_microphones(audio))
|
|
for mic in available_mics:
|
|
if mic["name"] == microphone_name:
|
|
return mic
|
|
|
|
available_mic_names = [mic["name"] for mic in available_mics]
|
|
logger.warning("Microphone \"{}\" not found. Choose one of {}"
|
|
.format(microphone_name, available_mic_names))
|
|
|
|
return None
|
|
|
|
|
|
def choose_mic(audio):
|
|
"""
|
|
Get a microphone to use. Firstly, tries to see if there's an application argument specifying the
|
|
microphone to use. If not, get the default microphone.
|
|
|
|
:param audio: An instance of PyAudio to use.
|
|
:type audio: pyaudio.PyAudio
|
|
|
|
:return: A dictionary from PyAudio containing information about the microphone to use, or None
|
|
if there is no microphone.
|
|
:rtype: dict | None
|
|
"""
|
|
chosen_mic = choose_mic_arguments(audio)
|
|
if chosen_mic: return chosen_mic
|
|
|
|
return choose_mic_default(audio)
|