voicemeeter-api-python/voicemeeterlib/cbindings.py
2023-06-23 01:15:27 +01:00

126 lines
4.0 KiB
Python

import ctypes as ct
import logging
from abc import ABCMeta
from ctypes.wintypes import CHAR, FLOAT, LONG, WCHAR
from .error import CAPIError
from .inst import libc
logger = logging.getLogger(__name__)
class CBindings(metaclass=ABCMeta):
"""
C bindings defined here.
Maps expected ctype argument and res types for each binding.
"""
logger_cbindings = logger.getChild("Cbindings")
vm_login = libc.VBVMR_Login
vm_login.restype = LONG
vm_login.argtypes = None
vm_logout = libc.VBVMR_Logout
vm_logout.restype = LONG
vm_logout.argtypes = None
vm_runvm = libc.VBVMR_RunVoicemeeter
vm_runvm.restype = LONG
vm_runvm.argtypes = [LONG]
vm_get_type = libc.VBVMR_GetVoicemeeterType
vm_get_type.restype = LONG
vm_get_type.argtypes = [ct.POINTER(LONG)]
vm_get_version = libc.VBVMR_GetVoicemeeterVersion
vm_get_version.restype = LONG
vm_get_version.argtypes = [ct.POINTER(LONG)]
if hasattr(libc, "VBVMR_MacroButton_IsDirty"):
vm_mdirty = libc.VBVMR_MacroButton_IsDirty
vm_mdirty.restype = LONG
vm_mdirty.argtypes = None
if hasattr(libc, "VBVMR_MacroButton_GetStatus"):
vm_get_buttonstatus = libc.VBVMR_MacroButton_GetStatus
vm_get_buttonstatus.restype = LONG
vm_get_buttonstatus.argtypes = [LONG, ct.POINTER(FLOAT), LONG]
if hasattr(libc, "VBVMR_MacroButton_SetStatus"):
vm_set_buttonstatus = libc.VBVMR_MacroButton_SetStatus
vm_set_buttonstatus.restype = LONG
vm_set_buttonstatus.argtypes = [LONG, FLOAT, LONG]
vm_pdirty = libc.VBVMR_IsParametersDirty
vm_pdirty.restype = LONG
vm_pdirty.argtypes = None
vm_get_parameter_float = libc.VBVMR_GetParameterFloat
vm_get_parameter_float.restype = LONG
vm_get_parameter_float.argtypes = [ct.POINTER(CHAR), ct.POINTER(FLOAT)]
vm_set_parameter_float = libc.VBVMR_SetParameterFloat
vm_set_parameter_float.restype = LONG
vm_set_parameter_float.argtypes = [ct.POINTER(CHAR), FLOAT]
vm_get_parameter_string = libc.VBVMR_GetParameterStringW
vm_get_parameter_string.restype = LONG
vm_get_parameter_string.argtypes = [ct.POINTER(CHAR), ct.POINTER(WCHAR * 512)]
vm_set_parameter_string = libc.VBVMR_SetParameterStringW
vm_set_parameter_string.restype = LONG
vm_set_parameter_string.argtypes = [ct.POINTER(CHAR), ct.POINTER(WCHAR)]
vm_set_parameter_multi = libc.VBVMR_SetParameters
vm_set_parameter_multi.restype = LONG
vm_set_parameter_multi.argtypes = [ct.POINTER(CHAR)]
vm_get_level = libc.VBVMR_GetLevel
vm_get_level.restype = LONG
vm_get_level.argtypes = [LONG, LONG, ct.POINTER(FLOAT)]
vm_get_num_indevices = libc.VBVMR_Input_GetDeviceNumber
vm_get_num_indevices.restype = LONG
vm_get_num_indevices.argtypes = None
vm_get_desc_indevices = libc.VBVMR_Input_GetDeviceDescW
vm_get_desc_indevices.restype = LONG
vm_get_desc_indevices.argtypes = [
LONG,
ct.POINTER(LONG),
ct.POINTER(WCHAR * 256),
ct.POINTER(WCHAR * 256),
]
vm_get_num_outdevices = libc.VBVMR_Output_GetDeviceNumber
vm_get_num_outdevices.restype = LONG
vm_get_num_outdevices.argtypes = None
vm_get_desc_outdevices = libc.VBVMR_Output_GetDeviceDescW
vm_get_desc_outdevices.restype = LONG
vm_get_desc_outdevices.argtypes = [
LONG,
ct.POINTER(LONG),
ct.POINTER(WCHAR * 256),
ct.POINTER(WCHAR * 256),
]
vm_get_midi_message = libc.VBVMR_GetMidiMessage
vm_get_midi_message.restype = LONG
vm_get_midi_message.argtypes = [ct.POINTER(CHAR * 1024), LONG]
def call(self, func, *args, ok=(0,), ok_exp=None):
try:
res = func(*args)
if ok_exp is None:
if res not in ok:
raise CAPIError(f"{func.__name__} returned {res}")
elif not ok_exp(res):
raise CAPIError(f"{func.__name__} returned {res}")
return res
except CAPIError as e:
self.logger_cbindings.exception(f"{type(e).__name__}: {e}")
raise