mirror of
https://github.com/onyx-and-iris/vban-cmd-python.git
synced 2026-03-03 16:49:19 +00:00
Compare commits
No commits in common. "e58d6c7242e8024b3f7b723ab5f6578ecf462bc4" and "7f3b0ac7c9cf915233389bc83d144a9c1c3ad14b" have entirely different histories.
e58d6c7242
...
7f3b0ac7c9
47
README.md
47
README.md
@ -171,7 +171,9 @@ example:
|
||||
print(vban.strip[4].comp.knob)
|
||||
```
|
||||
|
||||
Strip Comp `knob` is defined for all versions, all other parameters potato only.
|
||||
Strip Comp properties are defined as write only.
|
||||
|
||||
`knob` defined for all versions, all other parameters potato only.
|
||||
|
||||
##### Strip.Gate
|
||||
|
||||
@ -191,7 +193,9 @@ example:
|
||||
vban.strip[2].gate.attack = 300.8
|
||||
```
|
||||
|
||||
Strip Gate `knob` is defined for all versions, all other parameters potato only.
|
||||
Strip Gate properties are defined as write only, potato version only.
|
||||
|
||||
`knob` defined for all versions, all other parameters potato only.
|
||||
|
||||
##### Strip.Denoiser
|
||||
|
||||
@ -208,32 +212,7 @@ The following properties are available.
|
||||
- `on`: boolean
|
||||
- `ab`: boolean
|
||||
|
||||
example:
|
||||
|
||||
```python
|
||||
vban.strip[0].eq.ab = True
|
||||
```
|
||||
|
||||
##### Strip.EQ.Channel.Cell
|
||||
|
||||
The following properties are available.
|
||||
|
||||
- `on`: boolean
|
||||
- `type`: int, from 0 up to 6
|
||||
- `f`: float, from 20.0 up to 20_000.0
|
||||
- `gain`: float, from -36.0 up to 18.0
|
||||
- `q`: float, from 0.3 up to 100
|
||||
|
||||
example:
|
||||
|
||||
```python
|
||||
vban.strip[0].eq.channel[0].cell[2].on = True
|
||||
vban.strip[1].eq.channel[0].cell[2].f = 5000
|
||||
```
|
||||
|
||||
Strip EQ parameters are defined for PhysicalStrips, potato version only.
|
||||
|
||||
Only channel[0] properties are readable over VBAN.
|
||||
Strip EQ properties are defined as write only, potato version only.
|
||||
|
||||
##### Gainlayers
|
||||
|
||||
@ -549,15 +528,13 @@ with vban_cmd.api('banana', **opts) as vban:
|
||||
...
|
||||
```
|
||||
|
||||
### Run tests
|
||||
## Tests
|
||||
|
||||
Install [poetry](https://python-poetry.org/docs/#installation) and then:
|
||||
First make sure you installed the [development dependencies](https://github.com/onyx-and-iris/vban-cmd-python#installation)
|
||||
|
||||
```powershell
|
||||
poetry poe test-basic
|
||||
poetry poe test-banana
|
||||
poetry poe test-potato
|
||||
```
|
||||
Then from tests directory:
|
||||
|
||||
`pytest -v`
|
||||
|
||||
## Resources
|
||||
|
||||
|
||||
@ -24,34 +24,34 @@ class VbanRtPacket:
|
||||
|
||||
nbs: NBS
|
||||
_kind: KindMapClass
|
||||
_voicemeeterType: bytes
|
||||
_reserved: bytes
|
||||
_buffersize: bytes
|
||||
_voicemeeterVersion: bytes
|
||||
_optionBits: bytes
|
||||
_samplerate: bytes
|
||||
_voicemeeterType: bytes # data[28:29]
|
||||
_reserved: bytes # data[29:30]
|
||||
_buffersize: bytes # data[30:32]
|
||||
_voicemeeterVersion: bytes # data[32:36]
|
||||
_optionBits: bytes # data[36:40]
|
||||
_samplerate: bytes # data[40:44]
|
||||
|
||||
|
||||
@dataclass
|
||||
class VbanRtPacketNBS0(VbanRtPacket):
|
||||
"""Represents the body of a VBAN RT data packet with NBS 0"""
|
||||
|
||||
_inputLeveldB100: bytes
|
||||
_outputLeveldB100: bytes
|
||||
_TransportBit: bytes
|
||||
_stripState: bytes
|
||||
_busState: bytes
|
||||
_stripGaindB100Layer1: bytes
|
||||
_stripGaindB100Layer2: bytes
|
||||
_stripGaindB100Layer3: bytes
|
||||
_stripGaindB100Layer4: bytes
|
||||
_stripGaindB100Layer5: bytes
|
||||
_stripGaindB100Layer6: bytes
|
||||
_stripGaindB100Layer7: bytes
|
||||
_stripGaindB100Layer8: bytes
|
||||
_busGaindB100: bytes
|
||||
_stripLabelUTF8c60: bytes
|
||||
_busLabelUTF8c60: bytes
|
||||
_inputLeveldB100: bytes # data[44:112]
|
||||
_outputLeveldB100: bytes # data[112:240]
|
||||
_TransportBit: bytes # data[240:244]
|
||||
_stripState: bytes # data[244:276]
|
||||
_busState: bytes # data[276:308]
|
||||
_stripGaindB100Layer1: bytes # data[308:324]
|
||||
_stripGaindB100Layer2: bytes # data[324:340]
|
||||
_stripGaindB100Layer3: bytes # data[340:356]
|
||||
_stripGaindB100Layer4: bytes # data[356:372]
|
||||
_stripGaindB100Layer5: bytes # data[372:388]
|
||||
_stripGaindB100Layer6: bytes # data[388:404]
|
||||
_stripGaindB100Layer7: bytes # data[404:420]
|
||||
_stripGaindB100Layer8: bytes # data[420:436]
|
||||
_busGaindB100: bytes # data[436:452]
|
||||
_stripLabelUTF8c60: bytes # data[452:932]
|
||||
_busLabelUTF8c60: bytes # data[932:1412]
|
||||
|
||||
@classmethod
|
||||
def from_bytes(cls, nbs: NBS, kind: KindMapClass, data: bytes):
|
||||
@ -260,7 +260,7 @@ class CompressorSettings(NamedTuple):
|
||||
attack_ms: float
|
||||
release_ms: float
|
||||
n_knee: float
|
||||
ratio: float
|
||||
comprate: float
|
||||
threshold: float
|
||||
c_enabled: bool
|
||||
makeup: bool
|
||||
@ -268,9 +268,9 @@ class CompressorSettings(NamedTuple):
|
||||
|
||||
|
||||
class GateSettings(NamedTuple):
|
||||
threshold_in: float
|
||||
damping_max: float
|
||||
bp_sidechain: bool
|
||||
dBThreshold_in: float
|
||||
dBDamping_max: float
|
||||
BP_Sidechain: bool
|
||||
attack_ms: float
|
||||
hold_ms: float
|
||||
release_ms: float
|
||||
@ -293,60 +293,60 @@ class PitchSettings(NamedTuple):
|
||||
class VbanVMParamStrip:
|
||||
"""Represents the VBAN_VMPARAMSTRIP_PACKET structure"""
|
||||
|
||||
_mode: bytes
|
||||
_dblevel: bytes
|
||||
_audibility: bytes
|
||||
_pos3D_x: bytes
|
||||
_pos3D_y: bytes
|
||||
_posColor_x: bytes
|
||||
_posColor_y: bytes
|
||||
_EQgain1: bytes
|
||||
_EQgain2: bytes
|
||||
_EQgain3: bytes
|
||||
_mode: bytes # long = 4 bytes data[0:4]
|
||||
_dblevel: bytes # float = 4 bytes data[4:8]
|
||||
_audibility: bytes # short = 2 bytes data[8:10]
|
||||
_pos3D_x: bytes # short = 2 bytes data[10:12]
|
||||
_pos3D_y: bytes # short = 2 bytes data[12:14]
|
||||
_posColor_x: bytes # short = 2 bytes data[14:16]
|
||||
_posColor_y: bytes # short = 2 bytes data[16:18]
|
||||
_EQgain1: bytes # short = 2 bytes data[18:20]
|
||||
_EQgain2: bytes # short = 2 bytes data[20:22]
|
||||
_EQgain3: bytes # short = 2 bytes data[22:24]
|
||||
|
||||
# First channel parametric EQ
|
||||
_PEQ_eqOn: bytes
|
||||
_PEQ_eqtype: bytes
|
||||
_PEQ_eqgain: bytes
|
||||
_PEQ_eqfreq: bytes
|
||||
_PEQ_eqq: bytes
|
||||
_PEQ_eqOn: bytes # 6 * char = 6 bytes data[24:30]
|
||||
_PEQ_eqtype: bytes # 6 * char = 6 bytes data[30:36]
|
||||
_PEQ_eqgain: bytes # 6 * float = 24 bytes data[36:60]
|
||||
_PEQ_eqfreq: bytes # 6 * float = 24 bytes data[60:84]
|
||||
_PEQ_eqq: bytes # 6 * float = 24 bytes data[84:108]
|
||||
|
||||
_audibility_c: bytes
|
||||
_audibility_g: bytes
|
||||
_audibility_d: bytes
|
||||
_posMod_x: bytes
|
||||
_posMod_y: bytes
|
||||
_send_reverb: bytes
|
||||
_send_delay: bytes
|
||||
_send_fx1: bytes
|
||||
_send_fx2: bytes
|
||||
_dblimit: bytes
|
||||
_nKaraoke: bytes
|
||||
_audibility_c: bytes # short = 2 bytes data[108:110]
|
||||
_audibility_g: bytes # short = 2 bytes data[110:112]
|
||||
_audibility_d: bytes # short = 2 bytes data[112:114]
|
||||
_posMod_x: bytes # short = 2 bytes data[114:116]
|
||||
_posMod_y: bytes # short = 2 bytes data[116:118]
|
||||
_send_reverb: bytes # short = 2 bytes data[118:120]
|
||||
_send_delay: bytes # short = 2 bytes data[120:122]
|
||||
_send_fx1: bytes # short = 2 bytes data[122:124]
|
||||
_send_fx2: bytes # short = 2 bytes data[124:126]
|
||||
_dblimit: bytes # short = 2 bytes data[126:128]
|
||||
_nKaraoke: bytes # short = 2 bytes data[128:130]
|
||||
|
||||
_COMP_gain_in: bytes
|
||||
_COMP_attack_ms: bytes
|
||||
_COMP_release_ms: bytes
|
||||
_COMP_n_knee: bytes
|
||||
_COMP_comprate: bytes
|
||||
_COMP_threshold: bytes
|
||||
_COMP_c_enabled: bytes
|
||||
_COMP_c_auto: bytes
|
||||
_COMP_gain_out: bytes
|
||||
_COMP_gain_in: bytes # short = 2 bytes data[130:132]
|
||||
_COMP_attack_ms: bytes # short = 2 bytes data[132:134]
|
||||
_COMP_release_ms: bytes # short = 2 bytes data[134:136]
|
||||
_COMP_n_knee: bytes # short = 2 bytes data[136:138]
|
||||
_COMP_comprate: bytes # short = 2 bytes data[138:140]
|
||||
_COMP_threshold: bytes # short = 2 bytes data[140:142]
|
||||
_COMP_c_enabled: bytes # short = 2 bytes data[142:144]
|
||||
_COMP_c_auto: bytes # short = 2 bytes data[144:146]
|
||||
_COMP_gain_out: bytes # short = 2 bytes data[146:148]
|
||||
|
||||
_GATE_dBThreshold_in: bytes
|
||||
_GATE_dBDamping_max: bytes
|
||||
_GATE_BP_Sidechain: bytes
|
||||
_GATE_attack_ms: bytes
|
||||
_GATE_hold_ms: bytes
|
||||
_GATE_release_ms: bytes
|
||||
_GATE_dBThreshold_in: bytes # short = 2 bytes data[148:150]
|
||||
_GATE_dBDamping_max: bytes # short = 2 bytes data[150:152]
|
||||
_GATE_BP_Sidechain: bytes # short = 2 bytes data[152:154]
|
||||
_GATE_attack_ms: bytes # short = 2 bytes data[154:156]
|
||||
_GATE_hold_ms: bytes # short = 2 bytes data[156:158]
|
||||
_GATE_release_ms: bytes # short = 2 bytes data[158:160]
|
||||
|
||||
_DenoiserThreshold: bytes
|
||||
_PitchEnabled: bytes
|
||||
_Pitch_DryWet: bytes
|
||||
_Pitch_Value: bytes
|
||||
_Pitch_formant_lo: bytes
|
||||
_Pitch_formant_med: bytes
|
||||
_Pitch_formant_high: bytes
|
||||
_DenoiserThreshold: bytes # short = 2 bytes data[160:162]
|
||||
_PitchEnabled: bytes # short = 2 bytes data[162:164]
|
||||
_Pitch_DryWet: bytes # short = 2 bytes data[164:166]
|
||||
_Pitch_Value: bytes # short = 2 bytes data[166:168]
|
||||
_Pitch_formant_lo: bytes # short = 2 bytes data[168:170]
|
||||
_Pitch_formant_med: bytes # short = 2 bytes data[170:172]
|
||||
_Pitch_formant_high: bytes # short = 2 bytes data[172:174]
|
||||
|
||||
@classmethod
|
||||
def from_bytes(cls, data: bytes):
|
||||
@ -473,7 +473,7 @@ class VbanVMParamStrip:
|
||||
attack_ms=round(int.from_bytes(self._COMP_attack_ms, 'little') * 0.1, 2),
|
||||
release_ms=round(int.from_bytes(self._COMP_release_ms, 'little') * 0.1, 2),
|
||||
n_knee=round(int.from_bytes(self._COMP_n_knee, 'little') * 0.01, 2),
|
||||
ratio=round(int.from_bytes(self._COMP_comprate, 'little') * 0.01, 2),
|
||||
comprate=round(int.from_bytes(self._COMP_comprate, 'little') * 0.01, 2),
|
||||
threshold=round(
|
||||
int.from_bytes(self._COMP_threshold, 'little', signed=True) * 0.01, 2
|
||||
),
|
||||
@ -487,15 +487,15 @@ class VbanVMParamStrip:
|
||||
@property
|
||||
def gate(self) -> GateSettings:
|
||||
return GateSettings(
|
||||
threshold_in=round(
|
||||
dBThreshold_in=round(
|
||||
int.from_bytes(self._GATE_dBThreshold_in, 'little', signed=True) * 0.01,
|
||||
2,
|
||||
),
|
||||
damping_max=round(
|
||||
dBDamping_max=round(
|
||||
int.from_bytes(self._GATE_dBDamping_max, 'little', signed=True) * 0.01,
|
||||
2,
|
||||
),
|
||||
bp_sidechain=round(
|
||||
BP_Sidechain=round(
|
||||
int.from_bytes(self._GATE_BP_Sidechain, 'little') * 0.1, 2
|
||||
),
|
||||
attack_ms=round(int.from_bytes(self._GATE_attack_ms, 'little') * 0.1, 2),
|
||||
|
||||
@ -115,7 +115,7 @@ class StripComp(IRemote):
|
||||
def ratio(self) -> float:
|
||||
if self.public_packets[NBS.one] is None:
|
||||
return 0.0
|
||||
return self.public_packets[NBS.one].strips[self.index].compressor.ratio
|
||||
return self.public_packets[NBS.one].strips[self.index].compressor.comprate
|
||||
|
||||
@ratio.setter
|
||||
def ratio(self, val: float):
|
||||
@ -199,9 +199,7 @@ class StripGate(IRemote):
|
||||
|
||||
@property
|
||||
def threshold(self) -> float:
|
||||
if self.public_packets[NBS.one] is None:
|
||||
return 0.0
|
||||
return self.public_packets[NBS.one].strips[self.index].gate.threshold_in
|
||||
return
|
||||
|
||||
@threshold.setter
|
||||
def threshold(self, val: float):
|
||||
@ -209,9 +207,7 @@ class StripGate(IRemote):
|
||||
|
||||
@property
|
||||
def damping(self) -> float:
|
||||
if self.public_packets[NBS.one] is None:
|
||||
return 0.0
|
||||
return self.public_packets[NBS.one].strips[self.index].gate.damping_max
|
||||
return
|
||||
|
||||
@damping.setter
|
||||
def damping(self, val: float):
|
||||
@ -219,9 +215,7 @@ class StripGate(IRemote):
|
||||
|
||||
@property
|
||||
def bpsidechain(self) -> int:
|
||||
if self.public_packets[NBS.one] is None:
|
||||
return 0
|
||||
return self.public_packets[NBS.one].strips[self.index].gate.bp_sidechain
|
||||
return
|
||||
|
||||
@bpsidechain.setter
|
||||
def bpsidechain(self, val: int):
|
||||
@ -229,9 +223,7 @@ class StripGate(IRemote):
|
||||
|
||||
@property
|
||||
def attack(self) -> float:
|
||||
if self.public_packets[NBS.one] is None:
|
||||
return 0.0
|
||||
return self.public_packets[NBS.one].strips[self.index].gate.attack_ms
|
||||
return
|
||||
|
||||
@attack.setter
|
||||
def attack(self, val: float):
|
||||
@ -239,9 +231,7 @@ class StripGate(IRemote):
|
||||
|
||||
@property
|
||||
def hold(self) -> float:
|
||||
if self.public_packets[NBS.one] is None:
|
||||
return 0.0
|
||||
return self.public_packets[NBS.one].strips[self.index].gate.hold_ms
|
||||
return
|
||||
|
||||
@hold.setter
|
||||
def hold(self, val: float):
|
||||
@ -249,9 +239,7 @@ class StripGate(IRemote):
|
||||
|
||||
@property
|
||||
def release(self) -> float:
|
||||
if self.public_packets[NBS.one] is None:
|
||||
return 0.0
|
||||
return self.public_packets[NBS.one].strips[self.index].gate.release_ms
|
||||
return
|
||||
|
||||
@release.setter
|
||||
def release(self, val: float):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user