import sounddevice as sd from dataclasses import dataclass, field import numpy as np from const import ServerAudioDeviceType from mods.log_control import VoiceChangaerLogger # from const import SERVER_DEVICE_SAMPLE_RATES logger = VoiceChangaerLogger.get_instance().getLogger() @dataclass class ServerAudioDevice: kind: ServerAudioDeviceType = "audioinput" index: int = 0 name: str = "" hostAPI: str = "" maxInputChannels: int = 0 maxOutputChannels: int = 0 default_samplerate: int = 0 available_samplerates: list[int] = field(default_factory=lambda: []) def dummy_callback(data: np.ndarray, frames, times, status): pass def checkSamplingRate( deviceId: int, desiredSamplingRate: int, type: ServerAudioDeviceType ): if type == "input": try: with sd.InputStream( device=deviceId, callback=dummy_callback, dtype="float32", samplerate=desiredSamplingRate, ): pass return True except Exception as e: # NOQA # print("[checkSamplingRate]", e) return False else: try: with sd.OutputStream( device=deviceId, callback=dummy_callback, dtype="float32", samplerate=desiredSamplingRate, ): pass return True except Exception as e: # NOQA # print("[checkSamplingRate]", e) return False def list_audio_device(): try: audioDeviceList = sd.query_devices() except Exception as e: logger.error("[Voice Changer] ex:query_devices") logger.exception(e) raise e inputAudioDeviceList = [d for d in audioDeviceList if d["max_input_channels"] > 0] outputAudioDeviceList = [d for d in audioDeviceList if d["max_output_channels"] > 0] hostapis = sd.query_hostapis() # print("input:", inputAudioDeviceList) # print("output:", outputDeviceList) # print("hostapis", hostapis) serverAudioInputDevices: list[ServerAudioDevice] = [] serverAudioOutputDevices: list[ServerAudioDevice] = [] for d in inputAudioDeviceList: serverInputAudioDevice: ServerAudioDevice = ServerAudioDevice( kind="audioinput", index=d["index"], name=d["name"], hostAPI=hostapis[d["hostapi"]]["name"], maxInputChannels=d["max_input_channels"], maxOutputChannels=d["max_output_channels"], default_samplerate=d["default_samplerate"], ) serverAudioInputDevices.append(serverInputAudioDevice) for d in outputAudioDeviceList: serverOutputAudioDevice: ServerAudioDevice = ServerAudioDevice( kind="audiooutput", index=d["index"], name=d["name"], hostAPI=hostapis[d["hostapi"]]["name"], maxInputChannels=d["max_input_channels"], maxOutputChannels=d["max_output_channels"], default_samplerate=d["default_samplerate"], ) serverAudioOutputDevices.append(serverOutputAudioDevice) # print("check sample rate1") # for d in serverAudioInputDevices: # print("check sample rate1-1") # for sr in SERVER_DEVICE_SAMPLE_RATES: # print("check sample rate1-2") # if checkSamplingRate(d.index, sr, "input"): # d.available_samplerates.append(sr) # print("check sample rate2") # for d in serverAudioOutputDevices: # print("check sample rate2-1") # for sr in SERVER_DEVICE_SAMPLE_RATES: # print("check sample rate2-2") # if checkSamplingRate(d.index, sr, "output"): # d.available_samplerates.append(sr) # print("check sample rate3") return serverAudioInputDevices, serverAudioOutputDevices