Code source de mirza.audio.deviceManager

"""
Module de gestion et de routage dynamique des peripheriques audio.
Permet d'enumerer et de selectionner dynamiquement les entrees micro et sorties audio
sans regles materielles specifiques hardcodees.
"""

from typing import Any

import sounddevice as sd

from ..core.logger import getMirzaLogger

logger = getMirzaLogger("mirza.audio.devices")


[docs] class DeviceManager: """Selection des peripheriques audio d'entree et de sortie, a chaud depuis le widget. Attributes ---------- micId : int Index du micro selectionne. micName : str Libelle du micro selectionne. speakerId : int Index de la sortie selectionnee. speakerName : str Libelle de la sortie selectionnee. """
[docs] def __init__(self): """ Initialise le gestionnaire et prend les interfaces par defaut. Returns ------- None """ self.micId: int = 0 self.micName: str = "" self.speakerId: int = 0 self.speakerName: str = "" self.detectDefaultDevices()
[docs] def getAvailableDevices(self) -> dict[str, list[dict[str, Any]]]: """ Renvoie la liste exhaustive de tous les peripheriques audio disponibles. Returns ------- dict Dictionnaire contenant deux cles : 'inputs' et 'outputs', chacune associant une liste de dictionnaires descriptifs des peripheriques. """ allDevices = sd.query_devices() defaultIn = sd.default.device[0] defaultOut = sd.default.device[1] inputs: list[dict[str, Any]] = [] outputs: list[dict[str, Any]] = [] for index, device in enumerate(allDevices): if device["max_input_channels"] > 0: inputs.append({ "id": index, "name": device["name"], "channels": device["max_input_channels"], "sampleRate": device["default_samplerate"], "isDefault": (index == defaultIn), }) if device["max_output_channels"] > 0: outputs.append({ "id": index, "name": device["name"], "channels": device["max_output_channels"], "sampleRate": device["default_samplerate"], "isDefault": (index == defaultOut), }) return {"inputs": inputs, "outputs": outputs}
[docs] def detectDefaultDevices(self) -> tuple[int, str, int, str]: """ Initialise les peripheriques sur les valeurs par defaut du systeme d'exploitation. Returns ------- tuple Tuple contenant (micId, micName, speakerId, speakerName). """ allDevices = sd.query_devices() defaultIn = sd.default.device[0] defaultOut = sd.default.device[1] # Entree par defaut if ( defaultIn is not None and isinstance(defaultIn, int) and 0 <= defaultIn < len(allDevices) and allDevices[defaultIn].get("max_input_channels", 0) > 0 ): self.micId = defaultIn self.micName = allDevices[defaultIn]["name"] else: for index, device in enumerate(allDevices): if device.get("max_input_channels", 0) > 0: self.micId = index self.micName = device["name"] break # Sortie par defaut if ( defaultOut is not None and isinstance(defaultOut, int) and 0 <= defaultOut < len(allDevices) and allDevices[defaultOut].get("max_output_channels", 0) > 0 ): self.speakerId = defaultOut self.speakerName = allDevices[defaultOut]["name"] else: for index, device in enumerate(allDevices): if device.get("max_output_channels", 0) > 0: self.speakerId = index self.speakerName = device["name"] break return self.micId, self.micName, self.speakerId, self.speakerName
[docs] def setMicDevice(self, deviceId: int) -> bool: """ Modifie le microphone actif. Parameters ---------- deviceId : int Identifiant entier du peripherique audio d'entree. Returns ------- bool True si le peripherique a ete selectionne avec succes, False sinon. """ try: device = sd.query_devices(deviceId) if device["max_input_channels"] > 0: self.micId = deviceId self.micName = device["name"] return True logger.warning("Le peripherique d'entree %s n'a pas le bon nombre de canaux.", deviceId) except Exception as exc: logger.warning("Peripherique d'entree %s introuvable : %s", deviceId, exc) return False
[docs] def setSpeakerDevice(self, deviceId: int) -> bool: """ Modifie la sortie audio active. Parameters ---------- deviceId : int Identifiant entier du peripherique audio de sortie. Returns ------- bool True si le peripherique a ete selectionne avec succes, False sinon. """ try: device = sd.query_devices(deviceId) if device["max_output_channels"] > 0: self.speakerId = deviceId self.speakerName = device["name"] return True logger.warning("Le peripherique de sortie %s n'a pas le bon nombre de canaux.", deviceId) except Exception as exc: logger.warning("Peripherique de sortie %s introuvable : %s", deviceId, exc) return False