108 lines
3.9 KiB
Python
108 lines
3.9 KiB
Python
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'] |