mirror of
https://github.com/w-okada/voice-changer.git
synced 2025-01-23 21:45:00 +03:00
116 lines
3.9 KiB
Python
116 lines
3.9 KiB
Python
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
|