mirror of
https://github.com/onyx-and-iris/xair-api-python.git
synced 2026-04-18 13:33:31 +00:00
Compare commits
17 Commits
a1062e92b5
...
add-send-c
| Author | SHA1 | Date | |
|---|---|---|---|
| 6e017b4afc | |||
| 85664c8465 | |||
| a3473d5922 | |||
| e9ef113b5c | |||
| 56ec9a17c0 | |||
| 9a7d98d58b | |||
| f3cf215a76 | |||
| a62a46d61a | |||
| 5eeaff2371 | |||
| c2cf2fe523 | |||
| 265c26eb67 | |||
| 467b769ea4 | |||
| 27d0811091 | |||
| df2d158618 | |||
| 035c8d6507 | |||
| cab3888946 | |||
| eddfb89fa9 |
81
CHANGELOG.md
81
CHANGELOG.md
@@ -9,18 +9,25 @@ Before any major/minor/patch bump all unit tests will be run to verify they pass
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- [ ]
|
||||
- [x] Send class mixed into Strip, AuxRtn, FxRtn. May now be accessed with {Class}.send
|
||||
- [x] Sends example added
|
||||
|
||||
## [2.2.0] - 2022-11-08
|
||||
|
||||
### Added
|
||||
|
||||
- mute prop to Bus, FX, LR, RTN, Strip classes.
|
||||
|
||||
## [2.1.0] - 2022-11-08
|
||||
|
||||
### Added
|
||||
|
||||
- delay keyword argument
|
||||
- bounds checks for vals passed to lin_set/log_set
|
||||
- delay keyword argument
|
||||
- bounds checks for vals passed to lin_set/log_set
|
||||
|
||||
### Removed
|
||||
|
||||
- type checks, prefer duck typing
|
||||
- type checks, prefer duck typing
|
||||
|
||||
## [2.0.0] - 2022-11-07
|
||||
|
||||
@@ -29,76 +36,76 @@ However, a couple of changes have been made which are breaking, they are as foll
|
||||
|
||||
### Changed
|
||||
|
||||
- FX class added to fx module. This now deals with osc addresses that begin with "/fx/". Call it with mixer.fx.
|
||||
- FxRtn class added to rtn module. This now deals with addresses that begin with "/rtn/". Call it with mixer.fxreturn
|
||||
- Aux class renamed to AuxRtn in rtn module. Call it with mixer.auxreturn.
|
||||
- FX class added to fx module. This now deals with osc addresses that begin with "/fx/". Call it with mixer.fx.
|
||||
- FxRtn class added to rtn module. This now deals with addresses that begin with "/rtn/". Call it with mixer.fxreturn
|
||||
- Aux class renamed to AuxRtn in rtn module. Call it with mixer.auxreturn.
|
||||
|
||||
These changes were made to better resemble the underlying osc api and to better describe the function of the classes.
|
||||
|
||||
### Added
|
||||
|
||||
- A small number of X32 tests. More will be added. XAir tests moved into it's own test module.
|
||||
- XAirRemote lower level section added to README.
|
||||
- Links to OSC command documentation added to README.
|
||||
- A small number of X32 tests. More will be added. XAir tests moved into it's own test module.
|
||||
- XAirRemote lower level section added to README.
|
||||
- Links to OSC command documentation added to README.
|
||||
|
||||
### Removed
|
||||
|
||||
- mixer.aux was renamed to mixer.auxreturn
|
||||
- mixer.aux was renamed to mixer.auxreturn
|
||||
|
||||
## [1.1.0] - 2022-09-05
|
||||
|
||||
### Added
|
||||
|
||||
- tomli/tomllib compatibility layer to support python 3.10
|
||||
- tomli/tomllib compatibility layer to support python 3.10
|
||||
|
||||
## [1.0.2] - 2022-08-07
|
||||
|
||||
### Added
|
||||
|
||||
- now packaged with poetry
|
||||
- package added to pypi
|
||||
- pypi, isort badges added to readme
|
||||
- now packaged with poetry
|
||||
- package added to pypi
|
||||
- pypi, isort badges added to readme
|
||||
|
||||
### Changed
|
||||
|
||||
- package renamed to xair-api
|
||||
- now using tomllib for config, requires python 3.11
|
||||
- readme, example updated.
|
||||
- imports isorted.
|
||||
- package renamed to xair-api
|
||||
- now using tomllib for config, requires python 3.11
|
||||
- readme, example updated.
|
||||
- imports isorted.
|
||||
|
||||
## [0.1.0] - 2022-05-01
|
||||
|
||||
### Added
|
||||
|
||||
- kind maps for "XR16", "XR12" added.
|
||||
- get() added to kind module.
|
||||
- pre-commit.ps1 added for use with git hook.
|
||||
- tests passed badge added to readme.
|
||||
- kind maps for "XR16", "XR12" added.
|
||||
- get() added to kind module.
|
||||
- pre-commit.ps1 added for use with git hook.
|
||||
- tests passed badge added to readme.
|
||||
|
||||
### Changed
|
||||
|
||||
- readme updated to reflect changes.
|
||||
- readme updated to reflect changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- link to clone repo fixed in readme.
|
||||
- unit tests migrated from nose to pytest since nose will not be supported from python 3.10 onwards.
|
||||
- link to clone repo fixed in readme.
|
||||
- unit tests migrated from nose to pytest since nose will not be supported from python 3.10 onwards.
|
||||
|
||||
## [0.0.1] - 2022-04-05
|
||||
|
||||
### Added
|
||||
|
||||
- \_query() added to base class, allows testing a single parameter.
|
||||
- Interface entry point defined.
|
||||
- Kind map for XR18/MR18 added
|
||||
- Higher level classes (lr, strip, bus, fxsend, aux, rtn) implemented
|
||||
- Subclass mixin implemented (shared classes)
|
||||
- meta module added
|
||||
- util module added, mostly functions that perform math operations.
|
||||
- readme initial commit.
|
||||
- \_query() added to base class, allows testing a single parameter.
|
||||
- Interface entry point defined.
|
||||
- Kind map for XR18/MR18 added
|
||||
- Higher level classes (lr, strip, bus, fxsend, aux, rtn) implemented
|
||||
- Subclass mixin implemented (shared classes)
|
||||
- meta module added
|
||||
- util module added, mostly functions that perform math operations.
|
||||
- readme initial commit.
|
||||
|
||||
### Changed
|
||||
|
||||
- base class now supports context manager.
|
||||
- load ip from ini
|
||||
- unit tests initial commit. tests for shared classes added.
|
||||
- base class now supports context manager.
|
||||
- load ip from ini
|
||||
- unit tests initial commit. tests for shared classes added.
|
||||
|
||||
176
README.md
176
README.md
@@ -12,7 +12,7 @@ For an outline of past/future changes refer to: [CHANGELOG](CHANGELOG.md)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.10 or greater
|
||||
- Python 3.10 or greater
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -59,19 +59,19 @@ if __name__ == "__main__":
|
||||
|
||||
Currently the following devices are supported:
|
||||
|
||||
- `MR18`
|
||||
- `XR18`
|
||||
- `XR16`
|
||||
- `XR12`
|
||||
- `MR18`
|
||||
- `XR18`
|
||||
- `XR16`
|
||||
- `XR12`
|
||||
|
||||
The `X32` is partially supported. However, this document covers specifically the `XAir` series.
|
||||
|
||||
The following keyword arguments may be passed:
|
||||
|
||||
- `ip`: ip address of the mixer
|
||||
- `port`: mixer port, defaults to 10023 for x32 and 10024 for xair
|
||||
- `delay`: a delay between each command, defaults to 20ms.
|
||||
- a note about delay, stability may rely on network connection. For wired connections the delay can be safely reduced.
|
||||
- `ip`: ip address of the mixer
|
||||
- `port`: mixer port, defaults to 10023 for x32 and 10024 for xair
|
||||
- `delay`: a delay between each command (applies to the getters). Defaults to 20ms.
|
||||
- a note about delay, stability may rely on network connection. For wired connections the delay can be safely reduced.
|
||||
|
||||
## API
|
||||
|
||||
@@ -149,134 +149,134 @@ For each subclass the corresponding properties are available.
|
||||
|
||||
`Config`
|
||||
|
||||
- `name`: string
|
||||
- `color`: int, from 0, 16
|
||||
- `inputsource`: int
|
||||
- `usbreturn`: int
|
||||
- `name`: string
|
||||
- `color`: int, from 0, 16
|
||||
- `inputsource`: int
|
||||
- `usbreturn`: int
|
||||
|
||||
`Preamp`
|
||||
|
||||
- `on`: bool
|
||||
- `usbtrim`: float, from -18.0 to 18.0
|
||||
- `usbinput`: bool
|
||||
- `invert`: bool
|
||||
- `highpasson`: bool
|
||||
- `highpassfilter`: int, from 20 to 400
|
||||
- `on`: bool
|
||||
- `usbtrim`: float, from -18.0 to 18.0
|
||||
- `usbinput`: bool
|
||||
- `invert`: bool
|
||||
- `highpasson`: bool
|
||||
- `highpassfilter`: int, from 20 to 400
|
||||
|
||||
`Gate`
|
||||
|
||||
- `on`: bool
|
||||
- `mode`: str, one of ('gate', 'exp2', 'exp3', 'exp4', 'duck')
|
||||
- `threshold`: float, from -80.0 to 0.0
|
||||
- `range`: int, from 3 to 60
|
||||
- `attack`: int, from 0 to 120
|
||||
- `hold`: float, from 0.02 to 2000
|
||||
- `release`: int, from 5 to 4000
|
||||
- `keysource`, from 0 to 22
|
||||
- `filteron`: bool
|
||||
- `filtertype`: int, from 0 to 8
|
||||
- `filterfreq`: float, from 20 to 20000
|
||||
- `on`: bool
|
||||
- `mode`: str, one of ('gate', 'exp2', 'exp3', 'exp4', 'duck')
|
||||
- `threshold`: float, from -80.0 to 0.0
|
||||
- `range`: int, from 3 to 60
|
||||
- `attack`: int, from 0 to 120
|
||||
- `hold`: float, from 0.02 to 2000
|
||||
- `release`: int, from 5 to 4000
|
||||
- `keysource`, from 0 to 22
|
||||
- `filteron`: bool
|
||||
- `filtertype`: int, from 0 to 8
|
||||
- `filterfreq`: float, from 20 to 20000
|
||||
|
||||
`Dyn`
|
||||
|
||||
- `on`: bool
|
||||
- `mode`: str, one of ('comp', 'exp')
|
||||
- `det`: str, one of ('peak', 'rms')
|
||||
- `env`: str, one of ('lin', 'log')
|
||||
- `threshold`: float, from -60.0 to 0.0
|
||||
- `ratio`: int, from 0 to 11
|
||||
- `knee`: int, from 0 to 5
|
||||
- `mgain`: float, from 0.0 to 24.0
|
||||
- `attack`: int, from 0 to 120
|
||||
- `hold`: float, from 0.02 to 2000
|
||||
- `release`: int, from 5 to 4000
|
||||
- `mix`: int, from 0 to 100
|
||||
- `keysource`: int, from 0 to 22
|
||||
- `auto`: bool
|
||||
- `filteron`: bool
|
||||
- `filtertype`: int, from 0 to 8
|
||||
- `filterfreq`: float, from 20 to 20000
|
||||
- `on`: bool
|
||||
- `mode`: str, one of ('comp', 'exp')
|
||||
- `det`: str, one of ('peak', 'rms')
|
||||
- `env`: str, one of ('lin', 'log')
|
||||
- `threshold`: float, from -60.0 to 0.0
|
||||
- `ratio`: int, from 0 to 11
|
||||
- `knee`: int, from 0 to 5
|
||||
- `mgain`: float, from 0.0 to 24.0
|
||||
- `attack`: int, from 0 to 120
|
||||
- `hold`: float, from 0.02 to 2000
|
||||
- `release`: int, from 5 to 4000
|
||||
- `mix`: int, from 0 to 100
|
||||
- `keysource`: int, from 0 to 22
|
||||
- `auto`: bool
|
||||
- `filteron`: bool
|
||||
- `filtertype`: int, from 0 to 8
|
||||
- `filterfreq`: float, from 20 to 20000
|
||||
|
||||
`Insert`
|
||||
|
||||
- `on`: bool
|
||||
- `sel`: int
|
||||
- `on`: bool
|
||||
- `sel`: int
|
||||
|
||||
`GEQ`
|
||||
The following method names preceded by `slider_`
|
||||
|
||||
- `20`, `25`, `31_5`, `40`, `50`, `63`, `80`, `100`, `125`, `160`,
|
||||
- `200`, `250`, `315`, `400`, `500`, `630`, `800`, `1k`, `1k25`, `1k6`, `2k`,
|
||||
- `2k5`, `3k15`, `4k`, `5k`, `6k3`, `8k`, `10k`, `12k5`, `16k`, `20k`: float, from -15.0 to 15.0
|
||||
- `20`, `25`, `31_5`, `40`, `50`, `63`, `80`, `100`, `125`, `160`,
|
||||
- `200`, `250`, `315`, `400`, `500`, `630`, `800`, `1k`, `1k25`, `1k6`, `2k`,
|
||||
- `2k5`, `3k15`, `4k`, `5k`, `6k3`, `8k`, `10k`, `12k5`, `16k`, `20k`: float, from -15.0 to 15.0
|
||||
|
||||
for example: `slider_20`, `slider_6k3` etc..
|
||||
|
||||
`EQ`
|
||||
|
||||
- `on`: bool
|
||||
- `mode`: str, one of ('peq', 'geq', 'teq')
|
||||
- `on`: bool
|
||||
- `mode`: str, one of ('peq', 'geq', 'teq')
|
||||
|
||||
For the subclasses: `low`, `low2`, `lomid`, `himid`, `high2`, `high` the following properties are available:
|
||||
|
||||
- `type`: int, from 0 to 5
|
||||
- `frequency`: float, from 20.0 to 20000.0
|
||||
- `gain`: float, -15.0 to 15.0
|
||||
- `quality`: float, from 0.3 to 10.0
|
||||
- `type`: int, from 0 to 5
|
||||
- `frequency`: float, from 20.0 to 20000.0
|
||||
- `gain`: float, -15.0 to 15.0
|
||||
- `quality`: float, from 0.3 to 10.0
|
||||
|
||||
for example: `eq.low2.type`
|
||||
|
||||
`Mix`
|
||||
|
||||
- `on`: bool
|
||||
- `fader`: float, -inf, to 10.0
|
||||
- `lr`: bool
|
||||
- `on`: bool
|
||||
- `fader`: float, -inf, to 10.0
|
||||
- `lr`: bool
|
||||
|
||||
`Group`
|
||||
|
||||
- `dca`: int, from 0 to 15
|
||||
- `mute`: int, from 0 to 15
|
||||
- `dca`: int, from 0 to 15
|
||||
- `mute`: int, from 0 to 15
|
||||
|
||||
`Automix`
|
||||
|
||||
- `group`: int, from 0 to 2
|
||||
- `weight`: float, from -12.0 to 12.0
|
||||
- `group`: int, from 0 to 2
|
||||
- `weight`: float, from -12.0 to 12.0
|
||||
|
||||
### `DCA`
|
||||
|
||||
- `on`: bool
|
||||
- `name`: str
|
||||
- `color`: int, from 0 to 15
|
||||
- `on`: bool
|
||||
- `name`: str
|
||||
- `color`: int, from 0 to 15
|
||||
|
||||
### `Config`
|
||||
|
||||
The following method names preceded by `chlink`
|
||||
|
||||
- `1_2`, `3_4`, `5_6`, `7_8`, `9_10`, `11_12`, `13_14`, `15_16`
|
||||
- `1_2`, `3_4`, `5_6`, `7_8`, `9_10`, `11_12`, `13_14`, `15_16`
|
||||
|
||||
The following method names preceded by `buslink`
|
||||
|
||||
- `1_2`, `3_4`, `5_6`
|
||||
- `1_2`, `3_4`, `5_6`
|
||||
|
||||
for example: `chlink1_2`, `buslink5_6` etc..
|
||||
|
||||
- `link_eq`: bool
|
||||
- `link_dyn`: bool
|
||||
- `link_fader_mute`: bool
|
||||
- `amixenable`: bool
|
||||
- `amixlock`: bool
|
||||
- `link_eq`: bool
|
||||
- `link_dyn`: bool
|
||||
- `link_fader_mute`: bool
|
||||
- `amixenable`: bool
|
||||
- `amixlock`: bool
|
||||
|
||||
For the subclass `monitor` the following properties are available
|
||||
|
||||
- `level`: float, -inf to 10.0
|
||||
- `source`: int, from 0 to 14
|
||||
- `sourcetrim`: float, from -18.0 to 18.0
|
||||
- `chmode`: bool
|
||||
- `busmode`: bool
|
||||
- `dim`: bool
|
||||
- `dimgain`: float, from -40.0 to 0.0
|
||||
- `mono`: bool
|
||||
- `mute`: bool
|
||||
- `dimfpl`: bool
|
||||
- `level`: float, -inf to 10.0
|
||||
- `source`: int, from 0 to 14
|
||||
- `sourcetrim`: float, from -18.0 to 18.0
|
||||
- `chmode`: bool
|
||||
- `busmode`: bool
|
||||
- `dim`: bool
|
||||
- `dimgain`: float, from -40.0 to 0.0
|
||||
- `mono`: bool
|
||||
- `mute`: bool
|
||||
- `dimfpl`: bool
|
||||
|
||||
for example: `config.monitor.chmode`
|
||||
|
||||
@@ -284,7 +284,7 @@ for example: `config.monitor.chmode`
|
||||
|
||||
tuple containing a class for each mute group
|
||||
|
||||
- `on`: bool, from 0 to 3
|
||||
- `on`: bool, from 0 to 3
|
||||
|
||||
for example: `config.mute_group[0].on = True`
|
||||
|
||||
@@ -292,7 +292,7 @@ for example: `config.mute_group[0].on = True`
|
||||
|
||||
Send an OSC command directly to the mixer
|
||||
|
||||
- `send(osc command, value)`
|
||||
- `send(osc command, value)`
|
||||
|
||||
for example:
|
||||
|
||||
@@ -303,7 +303,7 @@ mixer.send("/bus/2/config/name", "somename")
|
||||
|
||||
Query the value of a command:
|
||||
|
||||
- `query(osc command)`
|
||||
- `query(osc command)`
|
||||
|
||||
for example:
|
||||
|
||||
|
||||
24
examples/sends/__main__.py
Normal file
24
examples/sends/__main__.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import logging
|
||||
|
||||
import xair_api
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
|
||||
def main():
|
||||
with xair_api.connect("XR18", ip="mixer.local") as mixer:
|
||||
for send in mixer.strip[0].send:
|
||||
send.level = -22.8
|
||||
|
||||
mixer.strip[15].send[0].level = -16.5
|
||||
print(mixer.strip[15].send[0].level)
|
||||
|
||||
mixer.auxreturn.send[0].level = -15.5
|
||||
print(mixer.auxreturn.send[0].level)
|
||||
|
||||
mixer.fxreturn[0].send[0].level = -14.5
|
||||
print(mixer.fxreturn[0].send[0].level)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,12 +1,19 @@
|
||||
import obsws_python as obs
|
||||
|
||||
import xair_api
|
||||
|
||||
|
||||
class Observer:
|
||||
def __init__(self, mixer):
|
||||
self._mixer = mixer
|
||||
self._cl = obs.EventClient()
|
||||
self._cl.callback.register(self.on_current_program_scene_changed)
|
||||
self._client = obs.EventClient()
|
||||
self._client.callback.register(self.on_current_program_scene_changed)
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, exc_traceback):
|
||||
self._client.disconnect()
|
||||
|
||||
def on_current_program_scene_changed(self, data):
|
||||
scene = data.scene_name
|
||||
@@ -28,11 +35,9 @@ class Observer:
|
||||
|
||||
def main():
|
||||
with xair_api.connect("MR18", ip="mixer.local") as mixer:
|
||||
Observer(mixer)
|
||||
|
||||
while cmd := input("<Enter> to exit\n"):
|
||||
if not cmd:
|
||||
break
|
||||
with Observer(mixer):
|
||||
while _ := input("Press <Enter> to exit\n"):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
185
poetry.lock
generated
185
poetry.lock
generated
@@ -1,24 +1,53 @@
|
||||
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "attrs"
|
||||
version = "22.1.0"
|
||||
description = "Classes Without Boilerplate"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"},
|
||||
{file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
|
||||
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
|
||||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
|
||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"]
|
||||
dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"]
|
||||
docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"]
|
||||
tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"]
|
||||
tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"]
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "22.8.0"
|
||||
description = "The uncompromising code formatter."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.2"
|
||||
files = [
|
||||
{file = "black-22.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ce957f1d6b78a8a231b18e0dd2d94a33d2ba738cd88a7fe64f53f659eea49fdd"},
|
||||
{file = "black-22.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5107ea36b2b61917956d018bd25129baf9ad1125e39324a9b18248d362156a27"},
|
||||
{file = "black-22.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8166b7bfe5dcb56d325385bd1d1e0f635f24aae14b3ae437102dedc0c186747"},
|
||||
{file = "black-22.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd82842bb272297503cbec1a2600b6bfb338dae017186f8f215c8958f8acf869"},
|
||||
{file = "black-22.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d839150f61d09e7217f52917259831fe2b689f5c8e5e32611736351b89bb2a90"},
|
||||
{file = "black-22.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a05da0430bd5ced89176db098567973be52ce175a55677436a271102d7eaa3fe"},
|
||||
{file = "black-22.8.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a098a69a02596e1f2a58a2a1c8d5a05d5a74461af552b371e82f9fa4ada8342"},
|
||||
{file = "black-22.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5594efbdc35426e35a7defa1ea1a1cb97c7dbd34c0e49af7fb593a36bd45edab"},
|
||||
{file = "black-22.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a983526af1bea1e4cf6768e649990f28ee4f4137266921c2c3cee8116ae42ec3"},
|
||||
{file = "black-22.8.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b2c25f8dea5e8444bdc6788a2f543e1fb01494e144480bc17f806178378005e"},
|
||||
{file = "black-22.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:78dd85caaab7c3153054756b9fe8c611efa63d9e7aecfa33e533060cb14b6d16"},
|
||||
{file = "black-22.8.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cea1b2542d4e2c02c332e83150e41e3ca80dc0fb8de20df3c5e98e242156222c"},
|
||||
{file = "black-22.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5b879eb439094751185d1cfdca43023bc6786bd3c60372462b6f051efa6281a5"},
|
||||
{file = "black-22.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0a12e4e1353819af41df998b02c6742643cfef58282915f781d0e4dd7a200411"},
|
||||
{file = "black-22.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3a73f66b6d5ba7288cd5d6dad9b4c9b43f4e8a4b789a94bf5abfb878c663eb3"},
|
||||
{file = "black-22.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:e981e20ec152dfb3e77418fb616077937378b322d7b26aa1ff87717fb18b4875"},
|
||||
{file = "black-22.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8ce13ffed7e66dda0da3e0b2eb1bdfc83f5812f66e09aca2b0978593ed636b6c"},
|
||||
{file = "black-22.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:32a4b17f644fc288c6ee2bafdf5e3b045f4eff84693ac069d87b1a347d861497"},
|
||||
{file = "black-22.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ad827325a3a634bae88ae7747db1a395d5ee02cf05d9aa7a9bd77dfb10e940c"},
|
||||
{file = "black-22.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53198e28a1fb865e9fe97f88220da2e44df6da82b18833b588b1883b16bb5d41"},
|
||||
{file = "black-22.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:bc4d4123830a2d190e9cc42a2e43570f82ace35c3aeb26a512a2102bce5af7ec"},
|
||||
{file = "black-22.8.0-py3-none-any.whl", hash = "sha256:d2c21d439b2baf7aa80d6dd4e3659259be64c6f49dfd0f32091063db0e006db4"},
|
||||
{file = "black-22.8.0.tar.gz", hash = "sha256:792f7eb540ba9a17e8656538701d3eb1afcb134e3b45b71f20b25c77a8db7e6e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
click = ">=8.0.0"
|
||||
@@ -37,9 +66,12 @@ uvloop = ["uvloop (>=0.15.2)"]
|
||||
name = "click"
|
||||
version = "8.1.3"
|
||||
description = "Composable command line interface toolkit"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
|
||||
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
@@ -48,47 +80,62 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
name = "colorama"
|
||||
version = "0.4.5"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
files = [
|
||||
{file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
|
||||
{file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "1.1.1"
|
||||
description = "iniconfig: brain-dead simple config-ini parsing"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
||||
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "isort"
|
||||
version = "5.10.1"
|
||||
description = "A Python utility / library to sort Python imports."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.1,<4.0"
|
||||
files = [
|
||||
{file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"},
|
||||
{file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
|
||||
requirements_deprecated_finder = ["pipreqs", "pip-api"]
|
||||
colors = ["colorama (>=0.4.3,<0.5.0)"]
|
||||
pipfile-deprecated-finder = ["pipreqs", "requirementslib"]
|
||||
plugins = ["setuptools"]
|
||||
requirements-deprecated-finder = ["pip-api", "pipreqs"]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "0.4.3"
|
||||
description = "Experimental type system extensions for programs checked with the mypy typechecker."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
|
||||
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "21.3"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
|
||||
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
|
||||
@@ -97,29 +144,38 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
|
||||
name = "pathspec"
|
||||
version = "0.10.1"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"},
|
||||
{file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "2.5.2"
|
||||
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"},
|
||||
{file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"]
|
||||
test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"]
|
||||
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)"]
|
||||
test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.0.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
|
||||
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
@@ -129,28 +185,37 @@ testing = ["pytest", "pytest-benchmark"]
|
||||
name = "py"
|
||||
version = "1.11.0"
|
||||
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
files = [
|
||||
{file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
|
||||
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyparsing"
|
||||
version = "3.0.9"
|
||||
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.8"
|
||||
files = [
|
||||
{file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
|
||||
{file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
diagrams = ["railroad-diagrams", "jinja2"]
|
||||
diagrams = ["jinja2", "railroad-diagrams"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "7.1.3"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pytest-7.1.3-py3-none-any.whl", hash = "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7"},
|
||||
{file = "pytest-7.1.3.tar.gz", hash = "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
attrs = ">=19.2.0"
|
||||
@@ -168,9 +233,12 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.
|
||||
name = "pytest-randomly"
|
||||
version = "3.12.0"
|
||||
description = "Pytest plugin to randomly order tests and control random.seed."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pytest-randomly-3.12.0.tar.gz", hash = "sha256:d60c2db71ac319aee0fc6c4110a7597d611a8b94a5590918bfa8583f00caccb2"},
|
||||
{file = "pytest_randomly-3.12.0-py3-none-any.whl", hash = "sha256:f4f2e803daf5d1ba036cc22bf4fe9dbbf99389ec56b00e5cba732fb5c1d07fdd"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pytest = "*"
|
||||
@@ -179,74 +247,25 @@ pytest = "*"
|
||||
name = "python-osc"
|
||||
version = "1.8.0"
|
||||
description = "Open Sound Control server and client implementations in pure Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "python-osc-1.8.0.tar.gz", hash = "sha256:2f8c187c68d239960fb2eddcb5346a62a9b35e64f2de045b3e5e509f475ca73d"},
|
||||
{file = "python_osc-1.8.0-py3-none-any.whl", hash = "sha256:9e2abb2fc9ba2c356f8e951609a03c9c7017bf0bad82cca8490e9b8af9e92a0b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "80440f75f4191b46dc73824fbfc4fd2fc1ea4dfbdba08591cabb600a86ae2400"
|
||||
|
||||
[metadata.files]
|
||||
attrs = []
|
||||
black = []
|
||||
click = [
|
||||
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
|
||||
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
|
||||
]
|
||||
colorama = [
|
||||
{file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
|
||||
{file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
|
||||
]
|
||||
iniconfig = [
|
||||
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
||||
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
||||
]
|
||||
isort = [
|
||||
{file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"},
|
||||
{file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"},
|
||||
]
|
||||
mypy-extensions = [
|
||||
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
|
||||
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
||||
]
|
||||
packaging = [
|
||||
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
|
||||
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
|
||||
]
|
||||
pathspec = []
|
||||
platformdirs = [
|
||||
{file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"},
|
||||
{file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"},
|
||||
]
|
||||
pluggy = [
|
||||
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
|
||||
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
|
||||
]
|
||||
py = [
|
||||
{file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
|
||||
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
|
||||
]
|
||||
pyparsing = [
|
||||
{file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
|
||||
{file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
|
||||
]
|
||||
pytest = []
|
||||
pytest-randomly = [
|
||||
{file = "pytest-randomly-3.12.0.tar.gz", hash = "sha256:d60c2db71ac319aee0fc6c4110a7597d611a8b94a5590918bfa8583f00caccb2"},
|
||||
{file = "pytest_randomly-3.12.0-py3-none-any.whl", hash = "sha256:f4f2e803daf5d1ba036cc22bf4fe9dbbf99389ec56b00e5cba732fb5c1d07fdd"},
|
||||
]
|
||||
python-osc = []
|
||||
tomli = [
|
||||
files = [
|
||||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||
]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "def96d1658f870a9820fef363ee6a04455f1d895e15a189ea4f39801f168552f"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "xair-api"
|
||||
version = "2.2.2"
|
||||
version = "2.2.4a0"
|
||||
description = "Remote control Behringer X-Air | Midas MR mixers through OSC"
|
||||
authors = ["onyx-and-iris <code@onyxandiris.online>"]
|
||||
license = "MIT"
|
||||
@@ -12,7 +12,7 @@ python = "^3.10"
|
||||
python-osc = "^1.8.0"
|
||||
tomli = { version = "^2.0.1", python = "<3.11" }
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pytest = "^7.1.2"
|
||||
pytest-randomly = "^3.12.0"
|
||||
black = "^22.6.0"
|
||||
@@ -24,5 +24,6 @@ build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
obs = "scripts:ex_obs"
|
||||
sends = "scripts:ex_sends"
|
||||
xair = "scripts:test_xair"
|
||||
x32 = "scripts:test_x32"
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def ex_obs():
|
||||
path = Path.cwd() / "examples" / "xair_obs" / "."
|
||||
subprocess.run(["py", str(path)])
|
||||
subprocess.run([sys.executable, str(path)])
|
||||
|
||||
|
||||
def ex_sends():
|
||||
path = Path.cwd() / "examples" / "sends" / "."
|
||||
subprocess.run([sys.executable, str(path)])
|
||||
|
||||
|
||||
def test_xair():
|
||||
|
||||
@@ -13,8 +13,7 @@ class IBus(abc.ABC):
|
||||
self.index = index + 1
|
||||
|
||||
def getter(self, param: str):
|
||||
self._remote.send(f"{self.address}/{param}")
|
||||
return self._remote.info_response
|
||||
return self._remote.query(f"{self.address}/{param}")
|
||||
|
||||
def setter(self, param: str, val: int):
|
||||
self._remote.send(f"{self.address}/{param}", val)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import abc
|
||||
|
||||
from . import kinds
|
||||
from . import kinds, util
|
||||
from .errors import XAirRemoteError
|
||||
from .meta import bool_prop
|
||||
from .util import _get_level_val, _set_level_val, lin_get, lin_set
|
||||
|
||||
|
||||
class IConfig(abc.ABC):
|
||||
@@ -13,8 +12,7 @@ class IConfig(abc.ABC):
|
||||
self._remote = remote
|
||||
|
||||
def getter(self, param: str):
|
||||
self._remote.send(f"{self.address}/{param}")
|
||||
return self._remote.info_response
|
||||
return self._remote.query(f"{self.address}/{param}")
|
||||
|
||||
def setter(self, param: str, val: int):
|
||||
self._remote.send(f"{self.address}/{param}", val)
|
||||
@@ -92,13 +90,14 @@ class Config(IConfig):
|
||||
return f"{root}/solo"
|
||||
|
||||
@property
|
||||
@util.db_from
|
||||
def level(self) -> float:
|
||||
retval = self.getter("level")[0]
|
||||
return _get_level_val(retval)
|
||||
return self.getter("level")[0]
|
||||
|
||||
@level.setter
|
||||
@util.db_to
|
||||
def level(self, val: float):
|
||||
_set_level_val(self, val)
|
||||
self.setter("level", val)
|
||||
|
||||
@property
|
||||
def source(self) -> int:
|
||||
@@ -110,13 +109,13 @@ class Config(IConfig):
|
||||
|
||||
@property
|
||||
def sourcetrim(self) -> float:
|
||||
return round(lin_get(-18, 18, self.getter("sourcetrim")[0]), 1)
|
||||
return round(util.lin_get(-18, 18, self.getter("sourcetrim")[0]), 1)
|
||||
|
||||
@sourcetrim.setter
|
||||
def sourcetrim(self, val: float):
|
||||
if not -18 <= val <= 18:
|
||||
raise XAirRemoteError("expected value in range -18.0 to 18.0")
|
||||
self.setter("sourcetrim", lin_set(-18, 18, val))
|
||||
self.setter("sourcetrim", util.lin_set(-18, 18, val))
|
||||
|
||||
@property
|
||||
def chmode(self) -> bool:
|
||||
@@ -136,13 +135,13 @@ class Config(IConfig):
|
||||
|
||||
@property
|
||||
def dimgain(self) -> int:
|
||||
return int(lin_get(-40, 0, self.getter("dimatt")[0]))
|
||||
return int(util.lin_get(-40, 0, self.getter("dimatt")[0]))
|
||||
|
||||
@dimgain.setter
|
||||
def dimgain(self, val: int):
|
||||
if not -40 <= val <= 0:
|
||||
raise XAirRemoteError("expected value in range -40 to 0")
|
||||
self.setter("dimatt", lin_set(-40, 0, val))
|
||||
self.setter("dimatt", util.lin_set(-40, 0, val))
|
||||
|
||||
@property
|
||||
def dim(self) -> bool:
|
||||
|
||||
@@ -11,8 +11,7 @@ class IDCA(abc.ABC):
|
||||
self.index = index + 1
|
||||
|
||||
def getter(self, param: str) -> tuple:
|
||||
self._remote.send(f"{self.address}/{param}")
|
||||
return self._remote.info_response
|
||||
return self._remote.query(f"{self.address}/{param}")
|
||||
|
||||
def setter(self, param: str, val: int):
|
||||
self._remote.send(f"{self.address}/{param}", val)
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
class XAirRemoteError(Exception):
|
||||
"""Base error class for XAIR Remote."""
|
||||
|
||||
pass
|
||||
|
||||
@@ -13,8 +13,7 @@ class IFX(abc.ABC):
|
||||
self.index = index + 1
|
||||
|
||||
def getter(self, param: str):
|
||||
self._remote.send(f"{self.address}/{param}")
|
||||
return self._remote.info_response
|
||||
return self._remote.query(f"{self.address}/{param}")
|
||||
|
||||
def setter(self, param: str, val: int):
|
||||
self._remote.send(f"{self.address}/{param}", val)
|
||||
|
||||
@@ -7,7 +7,7 @@ from .shared import EQ, GEQ, Automix, Config, Dyn, Gate, Group, Insert, Mix, Pre
|
||||
|
||||
|
||||
class ILR(abc.ABC):
|
||||
"""Abstract Base Class for buses"""
|
||||
"""Abstract Base Class for lr"""
|
||||
|
||||
def __init__(self, remote, index: Optional[int] = None):
|
||||
self._remote = remote
|
||||
@@ -15,8 +15,7 @@ class ILR(abc.ABC):
|
||||
self.index = index + 1
|
||||
|
||||
def getter(self, param: str):
|
||||
self._remote.send(f"{self.address}/{param}")
|
||||
return self._remote.info_response
|
||||
return self._remote.query(f"{self.address}/{param}")
|
||||
|
||||
def setter(self, param: str, val: int):
|
||||
self._remote.send(f"{self.address}/{param}", val)
|
||||
@@ -27,7 +26,7 @@ class ILR(abc.ABC):
|
||||
|
||||
|
||||
class LR(ILR):
|
||||
"""Concrete class for buses"""
|
||||
"""Concrete class for lr"""
|
||||
|
||||
@classmethod
|
||||
def make(cls, remote, index=None):
|
||||
|
||||
@@ -3,11 +3,23 @@ from typing import Optional
|
||||
|
||||
from .errors import XAirRemoteError
|
||||
from .meta import mute_prop
|
||||
from .shared import EQ, GEQ, Automix, Config, Dyn, Gate, Group, Insert, Mix, Preamp
|
||||
from .shared import (
|
||||
EQ,
|
||||
GEQ,
|
||||
Automix,
|
||||
Config,
|
||||
Dyn,
|
||||
Gate,
|
||||
Group,
|
||||
Insert,
|
||||
Mix,
|
||||
Preamp,
|
||||
Send,
|
||||
)
|
||||
|
||||
|
||||
class IRtn(abc.ABC):
|
||||
"""Abstract Base Class for aux"""
|
||||
"""Abstract Base Class for rtn"""
|
||||
|
||||
def __init__(self, remote, index: Optional[int] = None):
|
||||
self._remote = remote
|
||||
@@ -15,8 +27,7 @@ class IRtn(abc.ABC):
|
||||
self.index = index + 1
|
||||
|
||||
def getter(self, param: str):
|
||||
self._remote.send(f"{self.address}/{param}")
|
||||
return self._remote.info_response
|
||||
return self._remote.query(f"{self.address}/{param}")
|
||||
|
||||
def setter(self, param: str, val: int):
|
||||
self._remote.send(f"{self.address}/{param}", val)
|
||||
@@ -27,13 +38,15 @@ class IRtn(abc.ABC):
|
||||
|
||||
|
||||
class AuxRtn(IRtn):
|
||||
"""Concrete class for aux"""
|
||||
"""Concrete class for auxrtn"""
|
||||
|
||||
@classmethod
|
||||
def make(cls, remote, index=None):
|
||||
"""
|
||||
Factory function for auxrtn
|
||||
|
||||
Creates a mixin of shared subclasses, sets them as class attributes.
|
||||
|
||||
Returns an AuxRtn class of a kind.
|
||||
"""
|
||||
AUXRTN_cls = type(
|
||||
@@ -52,6 +65,10 @@ class AuxRtn(IRtn):
|
||||
Group,
|
||||
)
|
||||
},
|
||||
"send": tuple(
|
||||
Send.make(cls, i, remote)
|
||||
for i in range(remote.kind.num_bus + remote.kind.num_fx)
|
||||
),
|
||||
"mute": mute_prop(),
|
||||
},
|
||||
)
|
||||
@@ -63,13 +80,15 @@ class AuxRtn(IRtn):
|
||||
|
||||
|
||||
class FxRtn(IRtn):
|
||||
"""Concrete class for rtn"""
|
||||
"""Concrete class for fxrtn"""
|
||||
|
||||
@classmethod
|
||||
def make(cls, remote, index):
|
||||
"""
|
||||
Factory function for fxrtn
|
||||
|
||||
Creates a mixin of shared subclasses, sets them as class attributes.
|
||||
|
||||
Returns an FxRtn class of a kind.
|
||||
"""
|
||||
FXRTN_cls = type(
|
||||
@@ -88,6 +107,10 @@ class FxRtn(IRtn):
|
||||
Group,
|
||||
)
|
||||
},
|
||||
"send": tuple(
|
||||
Send.make(cls, i, remote, index)
|
||||
for i in range(remote.kind.num_bus + remote.kind.num_fx)
|
||||
),
|
||||
"mute": mute_prop(),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from typing import Union
|
||||
from typing import Optional, Union
|
||||
|
||||
from . import util
|
||||
from .errors import XAirRemoteError
|
||||
from .meta import geq_prop
|
||||
from .util import _get_fader_val, _set_fader_val, lin_get, lin_set, log_get, log_set
|
||||
|
||||
"""
|
||||
Classes shared by /ch, /rtn, /rtn/aux, /bus, /fxsend, /lr
|
||||
@@ -56,13 +56,13 @@ class Preamp:
|
||||
|
||||
@property
|
||||
def usbtrim(self) -> float:
|
||||
return round(lin_get(-18, 18, self.getter("rtntrim")[0]), 1)
|
||||
return round(util.lin_get(-18, 18, self.getter("rtntrim")[0]), 1)
|
||||
|
||||
@usbtrim.setter
|
||||
def usbtrim(self, val: float):
|
||||
if not -18 <= val <= 18:
|
||||
raise XAirRemoteError("expected value in range -18.0 to 18.0")
|
||||
self.setter("rtntrim", lin_set(-18, 18, val))
|
||||
self.setter("rtntrim", util.lin_set(-18, 18, val))
|
||||
|
||||
@property
|
||||
def usbinput(self) -> bool:
|
||||
@@ -90,13 +90,13 @@ class Preamp:
|
||||
|
||||
@property
|
||||
def highpassfilter(self) -> int:
|
||||
return int(log_get(20, 400, self.getter("hpf")[0]))
|
||||
return int(util.log_get(20, 400, self.getter("hpf")[0]))
|
||||
|
||||
@highpassfilter.setter
|
||||
def highpassfilter(self, val: int):
|
||||
if not 20 <= val <= 400:
|
||||
raise XAirRemoteError("expected value in range 20 to 400")
|
||||
self.setter("hpf", log_set(20, 400, val))
|
||||
self.setter("hpf", util.log_set(20, 400, val))
|
||||
|
||||
|
||||
class Gate:
|
||||
@@ -127,54 +127,54 @@ class Gate:
|
||||
|
||||
@property
|
||||
def threshold(self) -> float:
|
||||
return round(lin_get(-80, 0, self.getter("thr")[0]), 1)
|
||||
return round(util.lin_get(-80, 0, self.getter("thr")[0]), 1)
|
||||
|
||||
@threshold.setter
|
||||
def threshold(self, val: float):
|
||||
if not -80 <= val <= 0:
|
||||
raise XAirRemoteError("expected value in range -80.0 to 0.0")
|
||||
self.setter("thr", lin_set(-80, 0, val))
|
||||
self.setter("thr", util.lin_set(-80, 0, val))
|
||||
|
||||
@property
|
||||
def range(self) -> int:
|
||||
return int(lin_get(3, 60, self.getter("range")[0]))
|
||||
return int(util.lin_get(3, 60, self.getter("range")[0]))
|
||||
|
||||
@range.setter
|
||||
def range(self, val: int):
|
||||
if not 3 <= val <= 60:
|
||||
raise XAirRemoteError("expected value in range 3 to 60")
|
||||
self.setter("range", lin_set(3, 60, val))
|
||||
self.setter("range", util.lin_set(3, 60, val))
|
||||
|
||||
@property
|
||||
def attack(self) -> int:
|
||||
return int(lin_get(0, 120, self.getter("attack")[0]))
|
||||
return int(util.lin_get(0, 120, self.getter("attack")[0]))
|
||||
|
||||
@attack.setter
|
||||
def attack(self, val: int):
|
||||
if not 0 <= val <= 120:
|
||||
raise XAirRemoteError("expected value in range 0 to 120")
|
||||
self.setter("attack", lin_set(0, 120, val))
|
||||
self.setter("attack", util.lin_set(0, 120, val))
|
||||
|
||||
@property
|
||||
def hold(self) -> Union[float, int]:
|
||||
val = log_get(0.02, 2000, self.getter("hold")[0])
|
||||
val = util.log_get(0.02, 2000, self.getter("hold")[0])
|
||||
return round(val, 1) if val < 100 else int(val)
|
||||
|
||||
@hold.setter
|
||||
def hold(self, val: float):
|
||||
if not 0.02 <= val <= 2000:
|
||||
raise XAirRemoteError("expected value in range 0.02 to 2000.0")
|
||||
self.setter("hold", log_set(0.02, 2000, val))
|
||||
self.setter("hold", util.log_set(0.02, 2000, val))
|
||||
|
||||
@property
|
||||
def release(self) -> int:
|
||||
return int(log_get(5, 4000, self.getter("release")[0]))
|
||||
return int(util.log_get(5, 4000, self.getter("release")[0]))
|
||||
|
||||
@release.setter
|
||||
def release(self, val: int):
|
||||
if not 5 <= val <= 4000:
|
||||
raise XAirRemoteError("expected value in range 5 to 4000")
|
||||
self.setter("release", log_set(5, 4000, val))
|
||||
self.setter("release", util.log_set(5, 4000, val))
|
||||
|
||||
@property
|
||||
def keysource(self):
|
||||
@@ -202,14 +202,14 @@ class Gate:
|
||||
|
||||
@property
|
||||
def filterfreq(self) -> Union[float, int]:
|
||||
retval = log_get(20, 20000, self.getter("filter/f")[0])
|
||||
retval = util.log_get(20, 20000, self.getter("filter/f")[0])
|
||||
return int(retval) if retval > 1000 else round(retval, 1)
|
||||
|
||||
@filterfreq.setter
|
||||
def filterfreq(self, val: Union[float, int]):
|
||||
if not 20 <= val <= 20000:
|
||||
raise XAirRemoteError("expected value in range 20 to 20000")
|
||||
self.setter("filter/f", log_set(20, 20000, val))
|
||||
self.setter("filter/f", util.log_set(20, 20000, val))
|
||||
|
||||
|
||||
class Dyn:
|
||||
@@ -264,13 +264,13 @@ class Dyn:
|
||||
|
||||
@property
|
||||
def threshold(self) -> float:
|
||||
return round(lin_get(-60, 0, self.getter("thr")[0]), 1)
|
||||
return round(util.lin_get(-60, 0, self.getter("thr")[0]), 1)
|
||||
|
||||
@threshold.setter
|
||||
def threshold(self, val: float):
|
||||
if not -60 <= val <= 0:
|
||||
raise XAirRemoteError("expected value in range -60.0 to 0")
|
||||
self.setter("thr", lin_set(-60, 0, val))
|
||||
self.setter("thr", util.lin_set(-60, 0, val))
|
||||
|
||||
@property
|
||||
def ratio(self) -> Union[float, int]:
|
||||
@@ -283,64 +283,64 @@ class Dyn:
|
||||
|
||||
@property
|
||||
def knee(self) -> int:
|
||||
return int(lin_get(0, 5, self.getter("knee")[0]))
|
||||
return int(util.lin_get(0, 5, self.getter("knee")[0]))
|
||||
|
||||
@knee.setter
|
||||
def knee(self, val: int):
|
||||
if not 0 <= val <= 5:
|
||||
raise XAirRemoteError("expected value in range 0 to 5")
|
||||
self.setter("knee", lin_set(0, 5, val))
|
||||
self.setter("knee", util.lin_set(0, 5, val))
|
||||
|
||||
@property
|
||||
def mgain(self) -> float:
|
||||
return round(lin_get(0, 24, self.getter("mgain")[0]), 1)
|
||||
return round(util.lin_get(0, 24, self.getter("mgain")[0]), 1)
|
||||
|
||||
@mgain.setter
|
||||
def mgain(self, val: float):
|
||||
if not 0 <= val <= 24:
|
||||
raise XAirRemoteError("expected value in range 0.0 to 24.0")
|
||||
self.setter("mgain", lin_set(0, 24, val))
|
||||
self.setter("mgain", util.lin_set(0, 24, val))
|
||||
|
||||
@property
|
||||
def attack(self) -> int:
|
||||
return int(lin_get(0, 120, self.getter("attack")[0]))
|
||||
return int(util.lin_get(0, 120, self.getter("attack")[0]))
|
||||
|
||||
@attack.setter
|
||||
def attack(self, val: int):
|
||||
if not 0 <= val <= 120:
|
||||
raise XAirRemoteError("expected value in range 0 to 120")
|
||||
self.setter("attack", lin_set(0, 120, val))
|
||||
self.setter("attack", util.lin_set(0, 120, val))
|
||||
|
||||
@property
|
||||
def hold(self) -> Union[float, int]:
|
||||
val = log_get(0.02, 2000, self.getter("hold")[0])
|
||||
val = util.log_get(0.02, 2000, self.getter("hold")[0])
|
||||
return round(val, 1) if val < 100 else int(val)
|
||||
|
||||
@hold.setter
|
||||
def hold(self, val: float):
|
||||
if not 0.02 <= val <= 2000:
|
||||
raise XAirRemoteError("expected value in range 0.02 to 2000.0")
|
||||
self.setter("hold", log_set(0.02, 2000, val))
|
||||
self.setter("hold", util.log_set(0.02, 2000, val))
|
||||
|
||||
@property
|
||||
def release(self) -> int:
|
||||
return int(log_get(5, 4000, self.getter("release")[0]))
|
||||
return int(util.log_get(5, 4000, self.getter("release")[0]))
|
||||
|
||||
@release.setter
|
||||
def release(self, val: int):
|
||||
if not 5 <= val <= 4000:
|
||||
raise XAirRemoteError("expected value in range 5 to 4000")
|
||||
self.setter("release", log_set(5, 4000, val))
|
||||
self.setter("release", util.log_set(5, 4000, val))
|
||||
|
||||
@property
|
||||
def mix(self) -> int:
|
||||
return int(lin_get(0, 100, self.getter("mix")[0]))
|
||||
return int(util.lin_get(0, 100, self.getter("mix")[0]))
|
||||
|
||||
@mix.setter
|
||||
def mix(self, val: int):
|
||||
if not 0 <= val <= 100:
|
||||
raise XAirRemoteError("expected value in range 0 to 100")
|
||||
self.setter("mix", lin_set(0, 100, val))
|
||||
self.setter("mix", util.lin_set(0, 100, val))
|
||||
|
||||
@property
|
||||
def keysource(self):
|
||||
@@ -376,14 +376,14 @@ class Dyn:
|
||||
|
||||
@property
|
||||
def filterfreq(self) -> Union[float, int]:
|
||||
retval = log_get(20, 20000, self.getter("filter/f")[0])
|
||||
retval = util.log_get(20, 20000, self.getter("filter/f")[0])
|
||||
return int(retval) if retval > 1000 else round(retval, 1)
|
||||
|
||||
@filterfreq.setter
|
||||
def filterfreq(self, val: Union[float, int]):
|
||||
if not 20 <= val <= 20000:
|
||||
raise XAirRemoteError("expected value in range 20 to 20000")
|
||||
self.setter("filter/f", log_set(20, 20000, val))
|
||||
self.setter("filter/f", util.log_set(20, 20000, val))
|
||||
|
||||
|
||||
class Insert:
|
||||
@@ -467,10 +467,7 @@ class EQ:
|
||||
|
||||
class EQBand:
|
||||
def __init__(self, i, remote, index):
|
||||
if index is None:
|
||||
super(EQ.EQBand, self).__init__(remote)
|
||||
else:
|
||||
super(EQ.EQBand, self).__init__(remote, index)
|
||||
super(EQ.EQBand, self).__init__(remote, index)
|
||||
self.i = i
|
||||
|
||||
@property
|
||||
@@ -488,35 +485,35 @@ class EQ:
|
||||
|
||||
@property
|
||||
def frequency(self) -> float:
|
||||
retval = log_get(20, 20000, self.getter("f")[0])
|
||||
retval = util.log_get(20, 20000, self.getter("f")[0])
|
||||
return round(retval, 1)
|
||||
|
||||
@frequency.setter
|
||||
def frequency(self, val: float):
|
||||
if not 20 <= val <= 20000:
|
||||
raise XAirRemoteError("expected value in range 20.0 to 20000.0")
|
||||
self.setter("f", log_set(20, 20000, val))
|
||||
self.setter("f", util.log_set(20, 20000, val))
|
||||
|
||||
@property
|
||||
def gain(self) -> float:
|
||||
return round(lin_get(-15, 15, self.getter("g")[0]), 1)
|
||||
return round(util.lin_get(-15, 15, self.getter("g")[0]), 1)
|
||||
|
||||
@gain.setter
|
||||
def gain(self, val: float):
|
||||
if not -15 <= val <= 15:
|
||||
raise XAirRemoteError("expected value in range -15.0 to 15.0")
|
||||
self.setter("g", lin_set(-15, 15, val))
|
||||
self.setter("g", util.lin_set(-15, 15, val))
|
||||
|
||||
@property
|
||||
def quality(self) -> float:
|
||||
retval = log_get(0.3, 10, self.getter("q")[0])
|
||||
retval = util.log_get(0.3, 10, self.getter("q")[0])
|
||||
return round(retval, 1)
|
||||
|
||||
@quality.setter
|
||||
def quality(self, val: float):
|
||||
if not 0.3 <= val <= 10:
|
||||
raise XAirRemoteError("expected value in range 0.3 to 10.0")
|
||||
self.setter("q", log_set(0.3, 10, val))
|
||||
self.setter("q", util.log_set(0.3, 10, val))
|
||||
|
||||
|
||||
class GEQ:
|
||||
@@ -561,13 +558,14 @@ class Mix:
|
||||
self.setter("on", 1 if val else 0)
|
||||
|
||||
@property
|
||||
@util.db_from
|
||||
def fader(self) -> float:
|
||||
retval = self.getter("fader")[0]
|
||||
return _get_fader_val(retval)
|
||||
return self.getter("fader")[0]
|
||||
|
||||
@fader.setter
|
||||
@util.db_to
|
||||
def fader(self, val: float):
|
||||
_set_fader_val(self, val)
|
||||
self.setter("fader", val)
|
||||
|
||||
@property
|
||||
def lr(self) -> bool:
|
||||
@@ -617,10 +615,36 @@ class Automix:
|
||||
|
||||
@property
|
||||
def weight(self) -> float:
|
||||
return round(lin_get(-12, 12, self.getter("weight")[0]), 1)
|
||||
return round(util.lin_get(-12, 12, self.getter("weight")[0]), 1)
|
||||
|
||||
@weight.setter
|
||||
def weight(self, val: float):
|
||||
if not -12 <= val <= 12:
|
||||
raise XAirRemoteError("expected value in range -12.0 to 12.0")
|
||||
self.setter("weight", lin_set(-12, 12, val))
|
||||
self.setter("weight", util.lin_set(-12, 12, val))
|
||||
|
||||
|
||||
class Send:
|
||||
def __init__(self, i, remote, index: Optional[int] = None):
|
||||
super(Send, self).__init__(remote, index)
|
||||
self.i = i + 1
|
||||
|
||||
@classmethod
|
||||
def make(cls, _cls, i, remote, index=None):
|
||||
SEND_cls = type("Send", (cls, _cls), {})
|
||||
return SEND_cls(i, remote, index)
|
||||
|
||||
@property
|
||||
def address(self) -> str:
|
||||
root = super(Send, self).address
|
||||
return f"{root}/mix/{str(self.i).zfill(2)}"
|
||||
|
||||
@property
|
||||
@util.db_from
|
||||
def level(self):
|
||||
return self.getter("level")[0]
|
||||
|
||||
@level.setter
|
||||
@util.db_to
|
||||
def level(self, val):
|
||||
self.setter("level", val)
|
||||
|
||||
@@ -2,7 +2,19 @@ import abc
|
||||
|
||||
from .errors import XAirRemoteError
|
||||
from .meta import mute_prop
|
||||
from .shared import EQ, GEQ, Automix, Config, Dyn, Gate, Group, Insert, Mix, Preamp
|
||||
from .shared import (
|
||||
EQ,
|
||||
GEQ,
|
||||
Automix,
|
||||
Config,
|
||||
Dyn,
|
||||
Gate,
|
||||
Group,
|
||||
Insert,
|
||||
Mix,
|
||||
Preamp,
|
||||
Send,
|
||||
)
|
||||
|
||||
|
||||
class IStrip(abc.ABC):
|
||||
@@ -13,8 +25,7 @@ class IStrip(abc.ABC):
|
||||
self.index = index + 1
|
||||
|
||||
def getter(self, param: str) -> tuple:
|
||||
self._remote.send(f"{self.address}/{param}")
|
||||
return self._remote.info_response
|
||||
return self._remote.query(f"{self.address}/{param}")
|
||||
|
||||
def setter(self, param: str, val: int):
|
||||
self._remote.send(f"{self.address}/{param}", val)
|
||||
@@ -57,6 +68,10 @@ class Strip(IStrip):
|
||||
Automix,
|
||||
)
|
||||
},
|
||||
"send": tuple(
|
||||
Send.make(cls, i, remote, index)
|
||||
for i in range(remote.kind.num_bus + remote.kind.num_fx)
|
||||
),
|
||||
"mute": mute_prop(),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import functools
|
||||
from math import exp, log
|
||||
|
||||
|
||||
@@ -17,61 +18,48 @@ def log_set(min, max, val):
|
||||
return log(val / min) / log(max / min)
|
||||
|
||||
|
||||
def _get_fader_val(retval):
|
||||
if retval >= 1:
|
||||
return 10
|
||||
elif retval >= 0.5:
|
||||
return round((40 * retval) - 30, 1)
|
||||
elif retval >= 0.25:
|
||||
return round((80 * retval) - 50, 1)
|
||||
elif retval >= 0.0625:
|
||||
return round((160 * retval) - 70, 1)
|
||||
elif retval >= 0:
|
||||
return round((480 * retval) - 90, 1)
|
||||
else:
|
||||
return -90
|
||||
def db_from(func):
|
||||
"""fader|level converter for getters"""
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
retval = func(*args, **kwargs)
|
||||
|
||||
if retval >= 1:
|
||||
return 10
|
||||
elif retval >= 0.5:
|
||||
return round((40 * retval) - 30, 1)
|
||||
elif retval >= 0.25:
|
||||
return round((80 * retval) - 50, 1)
|
||||
elif retval >= 0.0625:
|
||||
return round((160 * retval) - 70, 1)
|
||||
elif retval >= 0:
|
||||
return round((480 * retval) - 90, 1)
|
||||
else:
|
||||
return -90
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def _set_fader_val(self, val):
|
||||
if val >= 10:
|
||||
self.setter("fader", 1)
|
||||
elif val >= -10:
|
||||
self.setter("fader", (val + 30) / 40)
|
||||
elif val >= -30:
|
||||
self.setter("fader", (val + 50) / 80)
|
||||
elif val >= -60:
|
||||
self.setter("fader", (val + 70) / 160)
|
||||
elif val >= -90:
|
||||
self.setter("fader", (val + 90) / 480)
|
||||
else:
|
||||
self.setter("fader", 0)
|
||||
def db_to(func):
|
||||
"""fader|level converter for setters"""
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
param, val = args
|
||||
if val >= 10:
|
||||
val = 1
|
||||
elif val >= -10:
|
||||
val = (val + 30) / 40
|
||||
elif val >= -30:
|
||||
val = (val + 50) / 80
|
||||
elif val >= -60:
|
||||
val = (val + 70) / 160
|
||||
elif val >= -90:
|
||||
val = (val + 90) / 480
|
||||
else:
|
||||
val = 0
|
||||
|
||||
def _get_level_val(retval):
|
||||
if retval >= 1:
|
||||
return 10
|
||||
elif retval >= 0.5:
|
||||
return round((40 * retval) - 30, 1)
|
||||
elif retval >= 0.25:
|
||||
return round((80 * retval) - 50, 1)
|
||||
elif retval >= 0.0625:
|
||||
return round((160 * retval) - 70, 1)
|
||||
elif retval >= 0:
|
||||
return round((480 * retval) - 90, 1)
|
||||
else:
|
||||
return -90
|
||||
func(param, val, **kwargs)
|
||||
|
||||
|
||||
def _set_level_val(self, val):
|
||||
if val >= 10:
|
||||
self.setter("level", 1)
|
||||
elif val >= -10:
|
||||
self.setter("level", (val + 30) / 40)
|
||||
elif val >= -30:
|
||||
self.setter("level", (val + 50) / 80)
|
||||
elif val >= -60:
|
||||
self.setter("level", (val + 70) / 160)
|
||||
elif val >= -90:
|
||||
self.setter("level", (val + 90) / 480)
|
||||
else:
|
||||
self.setter("level", 0)
|
||||
return wrapper
|
||||
|
||||
@@ -98,10 +98,10 @@ class XAirRemote(abc.ABC):
|
||||
def send(self, addr: str, param: Optional[str] = None):
|
||||
self.logger.debug(f"sending: {addr} {param if param is not None else ''}")
|
||||
self.server.send_message(addr, param)
|
||||
time.sleep(self._delay)
|
||||
|
||||
def query(self, address):
|
||||
self.send(address)
|
||||
time.sleep(self._delay)
|
||||
return self.info_response
|
||||
|
||||
def __exit__(self, exc_type, exc_value, exc_tr):
|
||||
|
||||
Reference in New Issue
Block a user