xair-api 2.3.2__tar.gz → 2.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {xair_api-2.3.2 → xair_api-2.4.1}/PKG-INFO +28 -18
- {xair_api-2.3.2 → xair_api-2.4.1}/README.md +20 -10
- xair_api-2.4.1/pyproject.toml +139 -0
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/__init__.py +1 -1
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/adapter.py +13 -6
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/bus.py +6 -6
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/config.py +44 -44
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/dca.py +9 -9
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/errors.py +1 -1
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/fx.py +9 -9
- xair_api-2.4.1/xair_api/headamp.py +49 -0
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/kinds.py +14 -15
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/lr.py +6 -6
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/meta.py +2 -2
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/rtn.py +12 -12
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/shared.py +168 -168
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/strip.py +7 -7
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/util.py +1 -1
- {xair_api-2.3.2 → xair_api-2.4.1}/xair_api/xair.py +27 -24
- xair_api-2.3.2/pyproject.toml +0 -43
- {xair_api-2.3.2 → xair_api-2.4.1}/LICENSE +0 -0
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: xair-api
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.1
|
|
4
4
|
Summary: Remote control Behringer X-Air | Midas MR mixers through OSC
|
|
5
|
-
Home-page: https://github.com/onyx-and-iris/xair-api-python
|
|
6
5
|
License: MIT
|
|
7
|
-
Author:
|
|
6
|
+
Author: Onyx and Iris
|
|
8
7
|
Author-email: code@onyxandiris.online
|
|
9
|
-
Requires-Python:
|
|
8
|
+
Requires-Python: <4.0,>=3.10
|
|
10
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
10
|
Classifier: Programming Language :: Python :: 3
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
13
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Requires-Dist: python-osc (>=1.9.3,<2.0.0)
|
|
16
|
+
Requires-Dist: tomli (>=2.0.1,<3.0) ; python_version < "3.11"
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
|
|
19
19
|
[](https://badge.fury.io/py/xair-api)
|
|
20
20
|
[](https://github.com/onyx-and-iris/xair-api-python/blob/dev/LICENSE)
|
|
21
|
-
[](https://pycqa.github.io/isort/)
|
|
21
|
+
[](https://github.com/astral-sh/ruff)
|
|
23
22
|

|
|
24
23
|
|
|
25
24
|
# Xair API
|
|
@@ -58,18 +57,18 @@ import xair_api
|
|
|
58
57
|
|
|
59
58
|
|
|
60
59
|
def main():
|
|
61
|
-
kind_id =
|
|
62
|
-
ip =
|
|
60
|
+
kind_id = 'XR18'
|
|
61
|
+
ip = '<ip address>'
|
|
63
62
|
|
|
64
63
|
with xair_api.connect(kind_id, ip=ip) as mixer:
|
|
65
|
-
mixer.strip[8].config.name =
|
|
64
|
+
mixer.strip[8].config.name = 'sm7b'
|
|
66
65
|
mixer.strip[8].mix.on = True
|
|
67
66
|
print(
|
|
68
|
-
f
|
|
67
|
+
f'strip 09 ({mixer.strip[8].config.name}) on has been set to {mixer.strip[8].mix.on}'
|
|
69
68
|
)
|
|
70
69
|
|
|
71
70
|
|
|
72
|
-
if __name__ ==
|
|
71
|
+
if __name__ == '__main__':
|
|
73
72
|
main()
|
|
74
73
|
```
|
|
75
74
|
|
|
@@ -132,6 +131,10 @@ A class representing auxreturn channel
|
|
|
132
131
|
|
|
133
132
|
A class representing the main config settings
|
|
134
133
|
|
|
134
|
+
`mixer.headamp`
|
|
135
|
+
|
|
136
|
+
A class representing the channel preamps (phantom power/gain).
|
|
137
|
+
|
|
135
138
|
### `LR`
|
|
136
139
|
|
|
137
140
|
Contains the subclasses:
|
|
@@ -162,6 +165,13 @@ Contains the subclasses:
|
|
|
162
165
|
Contains the subclasses:
|
|
163
166
|
(`Config`, `Preamp`, `EQ`, `Mix`, `Group`, `Send`)
|
|
164
167
|
|
|
168
|
+
### `HeadAmp`
|
|
169
|
+
|
|
170
|
+
The following properties are available:
|
|
171
|
+
|
|
172
|
+
- `gain`: float, from -12.0 to 60.0
|
|
173
|
+
- `phantom`: bool
|
|
174
|
+
|
|
165
175
|
### `Subclasses`
|
|
166
176
|
|
|
167
177
|
For each subclass the corresponding properties are available.
|
|
@@ -322,8 +332,8 @@ Send an OSC command directly to the mixer
|
|
|
322
332
|
for example:
|
|
323
333
|
|
|
324
334
|
```python
|
|
325
|
-
mixer.send(
|
|
326
|
-
mixer.send(
|
|
335
|
+
mixer.send('/ch/01/mix/on', 1)
|
|
336
|
+
mixer.send('/bus/2/config/name', 'somename')
|
|
327
337
|
```
|
|
328
338
|
|
|
329
339
|
Query the value of a command:
|
|
@@ -333,7 +343,7 @@ Query the value of a command:
|
|
|
333
343
|
for example:
|
|
334
344
|
|
|
335
345
|
```python
|
|
336
|
-
print(mixer.query(
|
|
346
|
+
print(mixer.query('/ch/01/mix/on'))
|
|
337
347
|
```
|
|
338
348
|
|
|
339
349
|
### Errors
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
[](https://badge.fury.io/py/xair-api)
|
|
2
2
|
[](https://github.com/onyx-and-iris/xair-api-python/blob/dev/LICENSE)
|
|
3
|
-
[](https://pycqa.github.io/isort/)
|
|
3
|
+
[](https://github.com/astral-sh/ruff)
|
|
5
4
|

|
|
6
5
|
|
|
7
6
|
# Xair API
|
|
@@ -40,18 +39,18 @@ import xair_api
|
|
|
40
39
|
|
|
41
40
|
|
|
42
41
|
def main():
|
|
43
|
-
kind_id =
|
|
44
|
-
ip =
|
|
42
|
+
kind_id = 'XR18'
|
|
43
|
+
ip = '<ip address>'
|
|
45
44
|
|
|
46
45
|
with xair_api.connect(kind_id, ip=ip) as mixer:
|
|
47
|
-
mixer.strip[8].config.name =
|
|
46
|
+
mixer.strip[8].config.name = 'sm7b'
|
|
48
47
|
mixer.strip[8].mix.on = True
|
|
49
48
|
print(
|
|
50
|
-
f
|
|
49
|
+
f'strip 09 ({mixer.strip[8].config.name}) on has been set to {mixer.strip[8].mix.on}'
|
|
51
50
|
)
|
|
52
51
|
|
|
53
52
|
|
|
54
|
-
if __name__ ==
|
|
53
|
+
if __name__ == '__main__':
|
|
55
54
|
main()
|
|
56
55
|
```
|
|
57
56
|
|
|
@@ -114,6 +113,10 @@ A class representing auxreturn channel
|
|
|
114
113
|
|
|
115
114
|
A class representing the main config settings
|
|
116
115
|
|
|
116
|
+
`mixer.headamp`
|
|
117
|
+
|
|
118
|
+
A class representing the channel preamps (phantom power/gain).
|
|
119
|
+
|
|
117
120
|
### `LR`
|
|
118
121
|
|
|
119
122
|
Contains the subclasses:
|
|
@@ -144,6 +147,13 @@ Contains the subclasses:
|
|
|
144
147
|
Contains the subclasses:
|
|
145
148
|
(`Config`, `Preamp`, `EQ`, `Mix`, `Group`, `Send`)
|
|
146
149
|
|
|
150
|
+
### `HeadAmp`
|
|
151
|
+
|
|
152
|
+
The following properties are available:
|
|
153
|
+
|
|
154
|
+
- `gain`: float, from -12.0 to 60.0
|
|
155
|
+
- `phantom`: bool
|
|
156
|
+
|
|
147
157
|
### `Subclasses`
|
|
148
158
|
|
|
149
159
|
For each subclass the corresponding properties are available.
|
|
@@ -304,8 +314,8 @@ Send an OSC command directly to the mixer
|
|
|
304
314
|
for example:
|
|
305
315
|
|
|
306
316
|
```python
|
|
307
|
-
mixer.send(
|
|
308
|
-
mixer.send(
|
|
317
|
+
mixer.send('/ch/01/mix/on', 1)
|
|
318
|
+
mixer.send('/bus/2/config/name', 'somename')
|
|
309
319
|
```
|
|
310
320
|
|
|
311
321
|
Query the value of a command:
|
|
@@ -315,7 +325,7 @@ Query the value of a command:
|
|
|
315
325
|
for example:
|
|
316
326
|
|
|
317
327
|
```python
|
|
318
|
-
print(mixer.query(
|
|
328
|
+
print(mixer.query('/ch/01/mix/on'))
|
|
319
329
|
```
|
|
320
330
|
|
|
321
331
|
### Errors
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "xair-api"
|
|
3
|
+
version = "2.4.1"
|
|
4
|
+
description = "Remote control Behringer X-Air | Midas MR mixers through OSC"
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "Onyx and Iris",email = "code@onyxandiris.online"}
|
|
7
|
+
]
|
|
8
|
+
license = {text = "MIT"}
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = "<4.0,>=3.10"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"python-osc (>=1.9.3,<2.0.0)",
|
|
13
|
+
"tomli (>=2.0.1,<3.0) ; python_version < '3.11'"
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[tool.poetry.requires-plugins]
|
|
17
|
+
poethepoet = "^0.32.1"
|
|
18
|
+
|
|
19
|
+
[tool.poetry.group.dev.dependencies]
|
|
20
|
+
pytest = "^8.3.4"
|
|
21
|
+
pytest-randomly = "^3.16.0"
|
|
22
|
+
ruff = "^0.8.6"
|
|
23
|
+
tox = "^4.23.2"
|
|
24
|
+
virtualenv-pyenv = "^0.5.0"
|
|
25
|
+
|
|
26
|
+
[build-system]
|
|
27
|
+
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
28
|
+
build-backend = "poetry.core.masonry.api"
|
|
29
|
+
|
|
30
|
+
[tool.poe.tasks]
|
|
31
|
+
obs.script = "scripts:ex_obs"
|
|
32
|
+
sends.script = "scripts:ex_sends"
|
|
33
|
+
headamp.script = "scripts:ex_headamp"
|
|
34
|
+
xair.script = "scripts:test_xair"
|
|
35
|
+
x32.script = "scripts:test_x32"
|
|
36
|
+
all.script = "scripts:test_all"
|
|
37
|
+
|
|
38
|
+
[tool.tox]
|
|
39
|
+
legacy_tox_ini = """
|
|
40
|
+
[tox]
|
|
41
|
+
envlist = py310,py311,py312
|
|
42
|
+
|
|
43
|
+
[testenv]
|
|
44
|
+
setenv = VIRTUALENV_DISCOVERY=pyenv
|
|
45
|
+
allowlist_externals = poetry
|
|
46
|
+
commands =
|
|
47
|
+
poetry install -v
|
|
48
|
+
poetry run pytest tests/
|
|
49
|
+
|
|
50
|
+
[testenv:obs]
|
|
51
|
+
setenv = VIRTUALENV_DISCOVERY=pyenv
|
|
52
|
+
allowlist_externals = poetry
|
|
53
|
+
deps = obsws-python
|
|
54
|
+
commands =
|
|
55
|
+
poetry install -v --without dev
|
|
56
|
+
poetry run python examples/xair_obs/
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
[tool.ruff]
|
|
60
|
+
exclude = [
|
|
61
|
+
".bzr",
|
|
62
|
+
".direnv",
|
|
63
|
+
".eggs",
|
|
64
|
+
".git",
|
|
65
|
+
".git-rewrite",
|
|
66
|
+
".hg",
|
|
67
|
+
".mypy_cache",
|
|
68
|
+
".nox",
|
|
69
|
+
".pants.d",
|
|
70
|
+
".pytype",
|
|
71
|
+
".ruff_cache",
|
|
72
|
+
".svn",
|
|
73
|
+
".tox",
|
|
74
|
+
".venv",
|
|
75
|
+
"__pypackages__",
|
|
76
|
+
"_build",
|
|
77
|
+
"buck-out",
|
|
78
|
+
"build",
|
|
79
|
+
"dist",
|
|
80
|
+
"node_modules",
|
|
81
|
+
"venv",
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
# Same as Black.
|
|
85
|
+
line-length = 88
|
|
86
|
+
indent-width = 4
|
|
87
|
+
|
|
88
|
+
# Assume Python 3.10
|
|
89
|
+
target-version = "py310"
|
|
90
|
+
|
|
91
|
+
[tool.ruff.lint]
|
|
92
|
+
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
|
|
93
|
+
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
|
|
94
|
+
# McCabe complexity (`C901`) by default.
|
|
95
|
+
select = ["E4", "E7", "E9", "F"]
|
|
96
|
+
ignore = []
|
|
97
|
+
|
|
98
|
+
# Allow fix for all enabled rules (when `--fix`) is provided.
|
|
99
|
+
fixable = ["ALL"]
|
|
100
|
+
unfixable = []
|
|
101
|
+
|
|
102
|
+
# Allow unused variables when underscore-prefixed.
|
|
103
|
+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
104
|
+
|
|
105
|
+
[tool.ruff.format]
|
|
106
|
+
# Unlike Black, use single quotes for strings.
|
|
107
|
+
quote-style = "single"
|
|
108
|
+
|
|
109
|
+
# Like Black, indent with spaces, rather than tabs.
|
|
110
|
+
indent-style = "space"
|
|
111
|
+
|
|
112
|
+
# Like Black, respect magic trailing commas.
|
|
113
|
+
skip-magic-trailing-comma = false
|
|
114
|
+
|
|
115
|
+
# Like Black, automatically detect the appropriate line ending.
|
|
116
|
+
line-ending = "auto"
|
|
117
|
+
|
|
118
|
+
# Enable auto-formatting of code examples in docstrings. Markdown,
|
|
119
|
+
# reStructuredText code/literal blocks and doctests are all supported.
|
|
120
|
+
#
|
|
121
|
+
# This is currently disabled by default, but it is planned for this
|
|
122
|
+
# to be opt-out in the future.
|
|
123
|
+
docstring-code-format = false
|
|
124
|
+
|
|
125
|
+
# Set the line length limit used when formatting code snippets in
|
|
126
|
+
# docstrings.
|
|
127
|
+
#
|
|
128
|
+
# This only has an effect when the `docstring-code-format` setting is
|
|
129
|
+
# enabled.
|
|
130
|
+
docstring-code-line-length = "dynamic"
|
|
131
|
+
|
|
132
|
+
[tool.ruff.lint.mccabe]
|
|
133
|
+
max-complexity = 10
|
|
134
|
+
|
|
135
|
+
[tool.ruff.lint.per-file-ignores]
|
|
136
|
+
"__init__.py" = [
|
|
137
|
+
"E402",
|
|
138
|
+
"F401",
|
|
139
|
+
]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from .bus import Bus as IBus
|
|
2
|
+
from .headamp import HeadAmp as IHeadAmp
|
|
2
3
|
from .lr import LR as ILR
|
|
3
4
|
from .rtn import AuxRtn as IAuxRtn
|
|
4
5
|
from .rtn import FxRtn as IFxRtn
|
|
@@ -7,34 +8,40 @@ from .rtn import FxRtn as IFxRtn
|
|
|
7
8
|
class Bus(IBus):
|
|
8
9
|
@property
|
|
9
10
|
def address(self):
|
|
10
|
-
return f
|
|
11
|
+
return f'/bus/{str(self.index).zfill(2)}'
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
class AuxRtn(IAuxRtn):
|
|
14
15
|
@property
|
|
15
16
|
def address(self):
|
|
16
|
-
return f
|
|
17
|
+
return f'/auxin/{str(self.index).zfill(2)}'
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class FxRtn(IFxRtn):
|
|
20
21
|
@property
|
|
21
22
|
def address(self):
|
|
22
|
-
return f
|
|
23
|
+
return f'/fxrtn/{str(self.index).zfill(2)}'
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
class MainStereo(ILR):
|
|
26
27
|
@property
|
|
27
28
|
def address(self) -> str:
|
|
28
|
-
return
|
|
29
|
+
return '/main/st'
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
class MainMono(ILR):
|
|
32
33
|
@property
|
|
33
34
|
def address(self) -> str:
|
|
34
|
-
return
|
|
35
|
+
return '/main/m'
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
class Matrix(ILR):
|
|
38
39
|
@property
|
|
39
40
|
def address(self) -> str:
|
|
40
|
-
return f
|
|
41
|
+
return f'/mtx/{str(self.index).zfill(2)}'
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class HeadAmp(IHeadAmp):
|
|
45
|
+
@property
|
|
46
|
+
def address(self):
|
|
47
|
+
return f'/headamp/{str(self.index).zfill(3)}'
|
|
@@ -16,10 +16,10 @@ class IBus(abc.ABC):
|
|
|
16
16
|
self.logger = logger.getChild(self.__class__.__name__)
|
|
17
17
|
|
|
18
18
|
def getter(self, param: str):
|
|
19
|
-
return self._remote.query(f
|
|
19
|
+
return self._remote.query(f'{self.address}/{param}')
|
|
20
20
|
|
|
21
21
|
def setter(self, param: str, val: int):
|
|
22
|
-
self._remote.send(f
|
|
22
|
+
self._remote.send(f'{self.address}/{param}', val)
|
|
23
23
|
|
|
24
24
|
@abc.abstractmethod
|
|
25
25
|
def address(self):
|
|
@@ -39,12 +39,12 @@ class Bus(IBus):
|
|
|
39
39
|
Returns a Bus class of a kind.
|
|
40
40
|
"""
|
|
41
41
|
BUS_cls = type(
|
|
42
|
-
f
|
|
42
|
+
f'Bus{remote.kind}',
|
|
43
43
|
(cls,),
|
|
44
44
|
{
|
|
45
45
|
**{
|
|
46
46
|
_cls.__name__.lower(): type(
|
|
47
|
-
f
|
|
47
|
+
f'{_cls.__name__}{remote.kind}', (_cls, cls), {}
|
|
48
48
|
)(remote, index)
|
|
49
49
|
for _cls in (
|
|
50
50
|
Config,
|
|
@@ -56,11 +56,11 @@ class Bus(IBus):
|
|
|
56
56
|
Group,
|
|
57
57
|
)
|
|
58
58
|
},
|
|
59
|
-
|
|
59
|
+
'mute': mute_prop(),
|
|
60
60
|
},
|
|
61
61
|
)
|
|
62
62
|
return BUS_cls(remote, index)
|
|
63
63
|
|
|
64
64
|
@property
|
|
65
65
|
def address(self) -> str:
|
|
66
|
-
return f
|
|
66
|
+
return f'/bus/{self.index}'
|
|
@@ -15,10 +15,10 @@ class IConfig(abc.ABC):
|
|
|
15
15
|
self.logger = logger.getChild(self.__class__.__name__)
|
|
16
16
|
|
|
17
17
|
def getter(self, param: str):
|
|
18
|
-
return self._remote.query(f
|
|
18
|
+
return self._remote.query(f'{self.address}/{param}')
|
|
19
19
|
|
|
20
20
|
def setter(self, param: str, val: int):
|
|
21
|
-
self._remote.send(f
|
|
21
|
+
self._remote.send(f'{self.address}/{param}', val)
|
|
22
22
|
|
|
23
23
|
@abc.abstractmethod
|
|
24
24
|
def address(self):
|
|
@@ -36,37 +36,37 @@ class Config(IConfig):
|
|
|
36
36
|
Returns a Config class of a kind.
|
|
37
37
|
"""
|
|
38
38
|
LINKS_cls = _make_links_mixins[remote.kind.id_]
|
|
39
|
-
MUTEGROUP_cls = type(
|
|
40
|
-
MONITOR_cls = type(
|
|
39
|
+
MUTEGROUP_cls = type('MuteGroup', (Config.MuteGroup, cls), {})
|
|
40
|
+
MONITOR_cls = type('ConfigMonitor', (Config.Monitor, cls), {})
|
|
41
41
|
CONFIG_cls = type(
|
|
42
|
-
f
|
|
42
|
+
f'Config{remote.kind}',
|
|
43
43
|
(cls, LINKS_cls),
|
|
44
44
|
{
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
'mute_group': tuple(MUTEGROUP_cls(remote, i) for i in range(4)),
|
|
46
|
+
'monitor': MONITOR_cls(remote),
|
|
47
47
|
},
|
|
48
48
|
)
|
|
49
49
|
return CONFIG_cls(remote)
|
|
50
50
|
|
|
51
51
|
@property
|
|
52
52
|
def address(self) -> str:
|
|
53
|
-
return
|
|
53
|
+
return '/config'
|
|
54
54
|
|
|
55
55
|
@property
|
|
56
56
|
def amixenable(self) -> bool:
|
|
57
|
-
return self.getter(
|
|
57
|
+
return self.getter('mute')[0] == 1
|
|
58
58
|
|
|
59
59
|
@amixenable.setter
|
|
60
60
|
def amixenable(self, val: bool):
|
|
61
|
-
self.setter(
|
|
61
|
+
self.setter('amixenable', 1 if val else 0)
|
|
62
62
|
|
|
63
63
|
@property
|
|
64
64
|
def amixlock(self) -> bool:
|
|
65
|
-
return self.getter(
|
|
65
|
+
return self.getter('amixlock')[0] == 1
|
|
66
66
|
|
|
67
67
|
@amixlock.setter
|
|
68
68
|
def amixlock(self, val: bool):
|
|
69
|
-
self.setter(
|
|
69
|
+
self.setter('amixlock', 1 if val else 0)
|
|
70
70
|
|
|
71
71
|
class MuteGroup:
|
|
72
72
|
def __init__(self, remote, i):
|
|
@@ -76,128 +76,128 @@ class Config(IConfig):
|
|
|
76
76
|
@property
|
|
77
77
|
def address(self) -> str:
|
|
78
78
|
root = super(Config.MuteGroup, self).address
|
|
79
|
-
return f
|
|
79
|
+
return f'{root}/mute'
|
|
80
80
|
|
|
81
81
|
@property
|
|
82
82
|
def on(self) -> bool:
|
|
83
|
-
return self.getter(f
|
|
83
|
+
return self.getter(f'{self.i}')[0] == 1
|
|
84
84
|
|
|
85
85
|
@on.setter
|
|
86
86
|
def on(self, val: bool):
|
|
87
|
-
self.setter(f
|
|
87
|
+
self.setter(f'{self.i}', 1 if val else 0)
|
|
88
88
|
|
|
89
89
|
class Monitor:
|
|
90
90
|
@property
|
|
91
91
|
def address(self) -> str:
|
|
92
92
|
root = super(Config.Monitor, self).address
|
|
93
|
-
return f
|
|
93
|
+
return f'{root}/solo'
|
|
94
94
|
|
|
95
95
|
@property
|
|
96
96
|
@util.db_from
|
|
97
97
|
def level(self) -> float:
|
|
98
|
-
return self.getter(
|
|
98
|
+
return self.getter('level')[0]
|
|
99
99
|
|
|
100
100
|
@level.setter
|
|
101
101
|
@util.db_to
|
|
102
102
|
def level(self, val: float):
|
|
103
|
-
self.setter(
|
|
103
|
+
self.setter('level', val)
|
|
104
104
|
|
|
105
105
|
@property
|
|
106
106
|
def source(self) -> int:
|
|
107
|
-
return int(self.getter(
|
|
107
|
+
return int(self.getter('source')[0])
|
|
108
108
|
|
|
109
109
|
@source.setter
|
|
110
110
|
def source(self, val: int):
|
|
111
|
-
self.setter(
|
|
111
|
+
self.setter('source', val)
|
|
112
112
|
|
|
113
113
|
@property
|
|
114
114
|
def sourcetrim(self) -> float:
|
|
115
|
-
return round(util.lin_get(-18, 18, self.getter(
|
|
115
|
+
return round(util.lin_get(-18, 18, self.getter('sourcetrim')[0]), 1)
|
|
116
116
|
|
|
117
117
|
@sourcetrim.setter
|
|
118
118
|
def sourcetrim(self, val: float):
|
|
119
119
|
if not -18 <= val <= 18:
|
|
120
120
|
self.logger.warning(
|
|
121
|
-
f
|
|
121
|
+
f'sourcetrim got {val}, expected value in range -18.0 to 18.0'
|
|
122
122
|
)
|
|
123
|
-
self.setter(
|
|
123
|
+
self.setter('sourcetrim', util.lin_set(-18, 18, val))
|
|
124
124
|
|
|
125
125
|
@property
|
|
126
126
|
def chmode(self) -> bool:
|
|
127
|
-
return self.getter(
|
|
127
|
+
return self.getter('chmode')[0] == 1
|
|
128
128
|
|
|
129
129
|
@chmode.setter
|
|
130
130
|
def chmode(self, val: bool):
|
|
131
|
-
self.setter(
|
|
131
|
+
self.setter('chmode', 1 if val else 0)
|
|
132
132
|
|
|
133
133
|
@property
|
|
134
134
|
def busmode(self) -> bool:
|
|
135
|
-
return self.getter(
|
|
135
|
+
return self.getter('busmode')[0] == 1
|
|
136
136
|
|
|
137
137
|
@busmode.setter
|
|
138
138
|
def busmode(self, val: bool):
|
|
139
|
-
self.setter(
|
|
139
|
+
self.setter('busmode', 1 if val else 0)
|
|
140
140
|
|
|
141
141
|
@property
|
|
142
142
|
def dimgain(self) -> int:
|
|
143
|
-
return int(util.lin_get(-40, 0, self.getter(
|
|
143
|
+
return int(util.lin_get(-40, 0, self.getter('dimatt')[0]))
|
|
144
144
|
|
|
145
145
|
@dimgain.setter
|
|
146
146
|
def dimgain(self, val: int):
|
|
147
147
|
if not -40 <= val <= 0:
|
|
148
148
|
self.logger.warning(
|
|
149
|
-
f
|
|
149
|
+
f'dimgain got {val}, expected value in range -40 to 0'
|
|
150
150
|
)
|
|
151
|
-
self.setter(
|
|
151
|
+
self.setter('dimatt', util.lin_set(-40, 0, val))
|
|
152
152
|
|
|
153
153
|
@property
|
|
154
154
|
def dim(self) -> bool:
|
|
155
|
-
return self.getter(
|
|
155
|
+
return self.getter('dim')[0] == 1
|
|
156
156
|
|
|
157
157
|
@dim.setter
|
|
158
158
|
def dim(self, val: bool):
|
|
159
|
-
self.setter(
|
|
159
|
+
self.setter('dim', 1 if val else 0)
|
|
160
160
|
|
|
161
161
|
@property
|
|
162
162
|
def mono(self) -> bool:
|
|
163
|
-
return self.getter(
|
|
163
|
+
return self.getter('mono')[0] == 1
|
|
164
164
|
|
|
165
165
|
@mono.setter
|
|
166
166
|
def mono(self, val: bool):
|
|
167
|
-
self.setter(
|
|
167
|
+
self.setter('mono', 1 if val else 0)
|
|
168
168
|
|
|
169
169
|
@property
|
|
170
170
|
def mute(self) -> bool:
|
|
171
|
-
return self.getter(
|
|
171
|
+
return self.getter('mute')[0] == 1
|
|
172
172
|
|
|
173
173
|
@mute.setter
|
|
174
174
|
def mute(self, val: bool):
|
|
175
|
-
self.setter(
|
|
175
|
+
self.setter('mute', 1 if val else 0)
|
|
176
176
|
|
|
177
177
|
@property
|
|
178
178
|
def dimfpl(self) -> bool:
|
|
179
|
-
return self.getter(
|
|
179
|
+
return self.getter('dimfpl')[0] == 1
|
|
180
180
|
|
|
181
181
|
@dimfpl.setter
|
|
182
182
|
def dimfpl(self, val: bool):
|
|
183
|
-
self.setter(
|
|
183
|
+
self.setter('dimfpl', 1 if val else 0)
|
|
184
184
|
|
|
185
185
|
|
|
186
186
|
def _make_links_mixin(kind):
|
|
187
187
|
"""Creates a links mixin"""
|
|
188
188
|
return type(
|
|
189
|
-
f
|
|
189
|
+
f'Links{kind}',
|
|
190
190
|
(),
|
|
191
191
|
{
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
192
|
+
'link_eq': bool_prop('linkcfg/eq'),
|
|
193
|
+
'link_dyn': bool_prop('linkcfg/dyn'),
|
|
194
|
+
'link_fader_mute': bool_prop('linkcfg/fdrmute'),
|
|
195
195
|
**{
|
|
196
|
-
f
|
|
196
|
+
f'chlink{i}_{i+1}': bool_prop(f'chlink/{i}-{i+1}')
|
|
197
197
|
for i in range(1, kind.num_strip, 2)
|
|
198
198
|
},
|
|
199
199
|
**{
|
|
200
|
-
f
|
|
200
|
+
f'buslink{i}_{i+1}': bool_prop(f'buslink/{i}-{i+1}')
|
|
201
201
|
for i in range(1, kind.num_bus, 2)
|
|
202
202
|
},
|
|
203
203
|
},
|