import sounddevice as sd import numpy as np import json class WindowsAudioManager: _instance = None def __new__(cls, *args, **kwargs): if cls._instance is None: cls._instance = super().__new__(cls) cls._instance.init() return cls._instance def init(self): """ Initialize Windows audio device and volume management. """ host_apis = sd.query_hostapis() wasapi_device_indexes = None for api in host_apis: if api['name'].lower() == 'Windows WASAPI'.lower(): wasapi_device_indexes = api['devices'] break # print(f"Host APIs: {host_apis}") # print(f"WASAPI Device Indexes: {wasapi_device_indexes}") wasapi_device_indexes = set(wasapi_device_indexes) if wasapi_device_indexes is not None else set() self.devices = [dev for dev in sd.query_devices() if dev['index'] in wasapi_device_indexes] # self.devices = sd.query_devices() # print(f"devices: {self.devices}") self.default_input = sd.default.device[0] self.default_output = sd.default.device[1] def list_audio_devices(self, kind='input'): """ List available audio devices. :param kind: 'input' or 'output' :return: List of audio devices """ if kind == 'input': return [ { 'index': dev['index'], 'name': dev['name'], 'channels': dev['max_input_channels'], 'default_samplerate': dev['default_samplerate'] } for dev in self.devices if dev['max_input_channels'] > 0 ] elif kind == 'output': return [ { 'index': dev['index'], 'name': dev['name'], 'channels': dev['max_output_channels'], 'default_samplerate': dev['default_samplerate'] } for dev in self.devices if dev['max_output_channels'] > 0 ] def get_default_device(self, kind='input'): """ Get the default audio device. :param kind: 'input' or 'output' :return: Default audio device information """ if kind == 'input': dev = self.devices[self.default_input] return [ { 'index': dev['index'], 'name': dev['name'], 'max_input_channels': dev['max_input_channels'], 'default_samplerate': dev['default_samplerate'] } ] def set_default_input_device(self, device_index): if(device_index is None): return 0 """ Set the default input audio device. :param device_index: Index of the audio device :return: Sample rate of the selected device """ sd.default.device[0] = device_index self.default_input = device_index # Get the sample rate of the selected device device_info = sd.query_devices(device_index) return device_info['default_samplerate'] def set_default_output_device(self, device_index): if(device_index is None): return self.get_current_output_device_sample_rate() """ Set the default output audio device. :param device_index: Index of the audio device :return: Sample rate of the selected device """ sd.default.device[1] = device_index self.default_output = device_index # Get the sample rate of the selected device device_info = sd.query_devices(device_index) return device_info['default_samplerate']