voicemeeter-api-python/voicemeeterlib/cbindings.py
onyx-and-iris df473d89ae remove __str__ override in VMError
move error message for code -9 into CAPIError class
2023-08-13 16:50:58 +01:00

126 lines
4.4 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")
bind_login = libc.VBVMR_Login
bind_login.restype = LONG
bind_login.argtypes = None
bind_logout = libc.VBVMR_Logout
bind_logout.restype = LONG
bind_logout.argtypes = None
bind_run_voicemeeter = libc.VBVMR_RunVoicemeeter
bind_run_voicemeeter.restype = LONG
bind_run_voicemeeter.argtypes = [LONG]
bind_get_voicemeeter_type = libc.VBVMR_GetVoicemeeterType
bind_get_voicemeeter_type.restype = LONG
bind_get_voicemeeter_type.argtypes = [ct.POINTER(LONG)]
bind_get_voicemeeter_version = libc.VBVMR_GetVoicemeeterVersion
bind_get_voicemeeter_version.restype = LONG
bind_get_voicemeeter_version.argtypes = [ct.POINTER(LONG)]
if hasattr(libc, "VBVMR_MacroButton_IsDirty"):
bind_macro_button_is_dirty = libc.VBVMR_MacroButton_IsDirty
bind_macro_button_is_dirty.restype = LONG
bind_macro_button_is_dirty.argtypes = None
if hasattr(libc, "VBVMR_MacroButton_GetStatus"):
bind_macro_button_get_status = libc.VBVMR_MacroButton_GetStatus
bind_macro_button_get_status.restype = LONG
bind_macro_button_get_status.argtypes = [LONG, ct.POINTER(FLOAT), LONG]
if hasattr(libc, "VBVMR_MacroButton_SetStatus"):
bind_macro_button_set_status = libc.VBVMR_MacroButton_SetStatus
bind_macro_button_set_status.restype = LONG
bind_macro_button_set_status.argtypes = [LONG, FLOAT, LONG]
bind_is_parameters_dirty = libc.VBVMR_IsParametersDirty
bind_is_parameters_dirty.restype = LONG
bind_is_parameters_dirty.argtypes = None
bind_get_parameter_float = libc.VBVMR_GetParameterFloat
bind_get_parameter_float.restype = LONG
bind_get_parameter_float.argtypes = [ct.POINTER(CHAR), ct.POINTER(FLOAT)]
bind_set_parameter_float = libc.VBVMR_SetParameterFloat
bind_set_parameter_float.restype = LONG
bind_set_parameter_float.argtypes = [ct.POINTER(CHAR), FLOAT]
bind_get_parameter_string_w = libc.VBVMR_GetParameterStringW
bind_get_parameter_string_w.restype = LONG
bind_get_parameter_string_w.argtypes = [ct.POINTER(CHAR), ct.POINTER(WCHAR * 512)]
bind_set_parameter_string_w = libc.VBVMR_SetParameterStringW
bind_set_parameter_string_w.restype = LONG
bind_set_parameter_string_w.argtypes = [ct.POINTER(CHAR), ct.POINTER(WCHAR)]
bind_set_parameters = libc.VBVMR_SetParameters
bind_set_parameters.restype = LONG
bind_set_parameters.argtypes = [ct.POINTER(CHAR)]
bind_get_level = libc.VBVMR_GetLevel
bind_get_level.restype = LONG
bind_get_level.argtypes = [LONG, LONG, ct.POINTER(FLOAT)]
bind_input_get_device_number = libc.VBVMR_Input_GetDeviceNumber
bind_input_get_device_number.restype = LONG
bind_input_get_device_number.argtypes = None
bind_input_get_device_desc_w = libc.VBVMR_Input_GetDeviceDescW
bind_input_get_device_desc_w.restype = LONG
bind_input_get_device_desc_w.argtypes = [
LONG,
ct.POINTER(LONG),
ct.POINTER(WCHAR * 256),
ct.POINTER(WCHAR * 256),
]
bind_output_get_device_number = libc.VBVMR_Output_GetDeviceNumber
bind_output_get_device_number.restype = LONG
bind_output_get_device_number.argtypes = None
bind_output_get_device_desc_w = libc.VBVMR_Output_GetDeviceDescW
bind_output_get_device_desc_w.restype = LONG
bind_output_get_device_desc_w.argtypes = [
LONG,
ct.POINTER(LONG),
ct.POINTER(WCHAR * 256),
ct.POINTER(WCHAR * 256),
]
bind_get_midi_message = libc.VBVMR_GetMidiMessage
bind_get_midi_message.restype = LONG
bind_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(func.__name__, res)
elif not ok_exp(res) and res not in ok:
raise CAPIError(func.__name__, res)
return res
except CAPIError as e:
self.logger_cbindings.exception(f"{type(e).__name__}: {e}")
raise