mirror of
https://github.com/onyx-and-iris/voicemeeter-api-python.git
synced 2025-07-18 02:01:46 +00:00
Initial setup adding classes for channels and cells
This commit is contained in:
parent
f7abc5248b
commit
f8f10e358f
9
examples/eq_edit/README.md
Normal file
9
examples/eq_edit/README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
## About
|
||||||
|
|
||||||
|
The purpose of this script is to demonstratehow to utilize the channels and cells that are available as part of the EQ. It should take audio playing in the second virtual strip and then apply a LGF on the first physical at 500 Hz.
|
||||||
|
|
||||||
|
## Use
|
||||||
|
|
||||||
|
Configured for banana version.
|
||||||
|
|
||||||
|
Make sure you are playing audio into the second virtual strip and out of the first physical bus, both channels are unmuted and that you aren't monitoring another mixbus. Then run the script.
|
21
examples/eq_edit/__main__.py
Normal file
21
examples/eq_edit/__main__.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import time
|
||||||
|
|
||||||
|
import voicemeeterlib
|
||||||
|
|
||||||
|
def main():
|
||||||
|
KIND_ID = 'banana'
|
||||||
|
|
||||||
|
with voicemeeterlib.api(KIND_ID) as vm:
|
||||||
|
vm.bus[0].eq.on = True
|
||||||
|
vm.bus[0].eq.channel[0].cell[0].on = True
|
||||||
|
vm.bus[0].eq.channel[0].cell[0].f = 500
|
||||||
|
vm.bus[0].eq.channel[0].cell[0].type = 3 # Should correspond to LPF
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
vm.bus[0].eq.on = False
|
||||||
|
vm.bus[0].eq.channel[0].cell[0].on = False
|
||||||
|
vm.bus[0].eq.channel[0].cell[0].f = 50
|
||||||
|
vm.bus[0].eq.channel[0].cell[0].type = 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -108,6 +108,56 @@ class BusEQ(IRemote):
|
|||||||
def ab(self, val: bool):
|
def ab(self, val: bool):
|
||||||
self.setter('ab', 1 if val else 0)
|
self.setter('ab', 1 if val else 0)
|
||||||
|
|
||||||
|
class BusEQCh(IRemote):
|
||||||
|
@property
|
||||||
|
def identifier(self) -> str:
|
||||||
|
return f'Bus[{self.index}].eq.channel[{self.index}]'
|
||||||
|
|
||||||
|
|
||||||
|
class BusEQChCell(IRemote):
|
||||||
|
@property
|
||||||
|
def identifier(self) -> str:
|
||||||
|
return f'Bus[{self.index}].eq.channel[{self.index}].cell[{self.kndex}]'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def on(self) -> bool:
|
||||||
|
return self.getter('on') == 1
|
||||||
|
|
||||||
|
@on.setter
|
||||||
|
def on(self,val: bool):
|
||||||
|
self.setter('on', 1 if val else 0)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def type(self) -> int:
|
||||||
|
return int(self.getter('type'))
|
||||||
|
|
||||||
|
@type.setter
|
||||||
|
def type(self, val: int):
|
||||||
|
self.setter('type', val)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def f(self) -> float:
|
||||||
|
return round(self.getter('f'),1)
|
||||||
|
|
||||||
|
@f.setter
|
||||||
|
def f(self,val: float):
|
||||||
|
self.setter('f', val)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gain(self) -> float:
|
||||||
|
return round(self.getter('gain'),1)
|
||||||
|
|
||||||
|
@gain.setter
|
||||||
|
def gain(self,val: float):
|
||||||
|
self.setter('gain', val)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def q(self) -> float:
|
||||||
|
return round(self.getter('q'),1)
|
||||||
|
|
||||||
|
@q.setter
|
||||||
|
def q(self,val: float):
|
||||||
|
self.setter('q', val)
|
||||||
|
|
||||||
class PhysicalBus(Bus):
|
class PhysicalBus(Bus):
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -250,6 +300,20 @@ def make_bus_level_map(kind):
|
|||||||
|
|
||||||
_make_bus_level_maps = {kind.name: make_bus_level_map(kind) for kind in kinds.all}
|
_make_bus_level_maps = {kind.name: make_bus_level_map(kind) for kind in kinds.all}
|
||||||
|
|
||||||
|
def _make_bus_eq(remote, i):
|
||||||
|
"""
|
||||||
|
Factory function for bus.eq.
|
||||||
|
|
||||||
|
Returns a BusEQ class of a kind.
|
||||||
|
"""
|
||||||
|
return type(
|
||||||
|
'BusEQ',
|
||||||
|
(),
|
||||||
|
{
|
||||||
|
'channel': BusEQCh(remote, i)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _make_bus_mode_mixin():
|
def _make_bus_mode_mixin():
|
||||||
"""Creates a mixin of Bus Modes."""
|
"""Creates a mixin of Bus Modes."""
|
||||||
@ -315,13 +379,14 @@ def bus_factory(is_phys_bus, remote, i) -> Union[PhysicalBus, VirtualBus]:
|
|||||||
else VirtualBus.make(remote, i, remote.kind)
|
else VirtualBus.make(remote, i, remote.kind)
|
||||||
)
|
)
|
||||||
BUSMODEMIXIN_cls = _make_bus_mode_mixin()
|
BUSMODEMIXIN_cls = _make_bus_mode_mixin()
|
||||||
|
BUSEQ_cls = _make_bus_eq(remote, i)
|
||||||
return type(
|
return type(
|
||||||
f'{BUS_cls.__name__}{remote.kind}',
|
f'{BUS_cls.__name__}{remote.kind}',
|
||||||
(BUS_cls,),
|
(BUS_cls,),
|
||||||
{
|
{
|
||||||
'levels': BusLevel(remote, i),
|
'levels': BusLevel(remote, i),
|
||||||
'mode': BUSMODEMIXIN_cls(remote, i),
|
'mode': BUSMODEMIXIN_cls(remote, i),
|
||||||
'eq': BusEQ(remote, i),
|
'eq': BUSEQ_cls,
|
||||||
},
|
},
|
||||||
)(remote, i)
|
)(remote, i)
|
||||||
|
|
||||||
@ -333,3 +398,29 @@ def request_bus_obj(phys_bus, remote, i) -> Bus:
|
|||||||
Returns a reference to a bus subclass of a kind
|
Returns a reference to a bus subclass of a kind
|
||||||
"""
|
"""
|
||||||
return bus_factory(phys_bus, remote, i)
|
return bus_factory(phys_bus, remote, i)
|
||||||
|
|
||||||
|
def request_busCh_obj(channel, remote, i) -> BusEQCh:
|
||||||
|
"""
|
||||||
|
Bus EQ Channel entry point. Wraps factory method
|
||||||
|
|
||||||
|
Returns a reference to a bus EQ channel subcless of a kind
|
||||||
|
"""
|
||||||
|
kls = ()
|
||||||
|
BusEQChCls = type('channel',kls,{})
|
||||||
|
return type(
|
||||||
|
f'{BusEQChCls.__name__}{remote.kind}',
|
||||||
|
(BusEQChCls,){},
|
||||||
|
)()
|
||||||
|
|
||||||
|
def request_busChCe_obj(cell, remote, i) -> BusEQChCell:
|
||||||
|
"""
|
||||||
|
Bus EQ Channel Cell entry point. Wraps factory method
|
||||||
|
|
||||||
|
Returns a reference to a bus EQ channel cell subcless of a kind
|
||||||
|
"""
|
||||||
|
kls = ()
|
||||||
|
BusEQCellCls = type('cell',kls,{})
|
||||||
|
return type(
|
||||||
|
f'{BusEQCellCls.__name__}{remote.kind}',
|
||||||
|
(BusEQCellCls,){},
|
||||||
|
)()
|
||||||
|
@ -6,6 +6,8 @@ from typing import Iterable
|
|||||||
|
|
||||||
from . import misc
|
from . import misc
|
||||||
from .bus import request_bus_obj as bus
|
from .bus import request_bus_obj as bus
|
||||||
|
from .bus import request_busCh_obj as channel
|
||||||
|
from .bus import request_busChCe_obj as cell
|
||||||
from .command import Command
|
from .command import Command
|
||||||
from .config import request_config as configs
|
from .config import request_config as configs
|
||||||
from .device import Device
|
from .device import Device
|
||||||
@ -30,7 +32,7 @@ class FactoryBuilder:
|
|||||||
|
|
||||||
BuilderProgress = IntEnum(
|
BuilderProgress = IntEnum(
|
||||||
'BuilderProgress',
|
'BuilderProgress',
|
||||||
'strip bus command macrobutton vban device option recorder patch fx',
|
'strip bus channels cells command macrobutton vban device option recorder patch fx',
|
||||||
start=0,
|
start=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,6 +42,8 @@ class FactoryBuilder:
|
|||||||
self._info = (
|
self._info = (
|
||||||
f'Finished building strips for {self._factory}',
|
f'Finished building strips for {self._factory}',
|
||||||
f'Finished building buses for {self._factory}',
|
f'Finished building buses for {self._factory}',
|
||||||
|
f'Finished building channels for {self._factory}',
|
||||||
|
f'Finished building cells for {self._factory}',
|
||||||
f'Finished building commands for {self._factory}',
|
f'Finished building commands for {self._factory}',
|
||||||
f'Finished building macrobuttons for {self._factory}',
|
f'Finished building macrobuttons for {self._factory}',
|
||||||
f'Finished building vban in/out streams for {self._factory}',
|
f'Finished building vban in/out streams for {self._factory}',
|
||||||
@ -70,6 +74,20 @@ class FactoryBuilder:
|
|||||||
)
|
)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def make_channels(self):
|
||||||
|
self._factory.channels = tuple(
|
||||||
|
channel(i < self.kind.channels, self._factory, i)
|
||||||
|
for i in range(self.kind.channels)
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def make_cells(self):
|
||||||
|
self._factory.cells = tuple(
|
||||||
|
cell(i < self.kind.cells, self._factory, i)
|
||||||
|
for i in range(self.kind.cells)
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
|
||||||
def make_command(self):
|
def make_command(self):
|
||||||
self._factory.command = Command.make(self._factory)
|
self._factory.command = Command.make(self._factory)
|
||||||
return self
|
return self
|
||||||
@ -126,6 +144,8 @@ class FactoryBase(Remote):
|
|||||||
self._steps = (
|
self._steps = (
|
||||||
self.builder.make_strip,
|
self.builder.make_strip,
|
||||||
self.builder.make_bus,
|
self.builder.make_bus,
|
||||||
|
self.builder.make_channels,
|
||||||
|
self.builder.make_cells,
|
||||||
self.builder.make_command,
|
self.builder.make_command,
|
||||||
self.builder.make_macrobutton,
|
self.builder.make_macrobutton,
|
||||||
self.builder.make_vban,
|
self.builder.make_vban,
|
||||||
|
@ -12,9 +12,11 @@ class IRemote(metaclass=ABCMeta):
|
|||||||
Provides some default implementation
|
Provides some default implementation
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, remote, index=None):
|
def __init__(self, remote, index=None):#, jndex = None, kndex = None):
|
||||||
self._remote = remote
|
self._remote = remote
|
||||||
self.index = index
|
self.index = index
|
||||||
|
#self.jndex = jndex
|
||||||
|
#self.kndex = kndex
|
||||||
self.logger = logger.getChild(self.__class__.__name__)
|
self.logger = logger.getChild(self.__class__.__name__)
|
||||||
|
|
||||||
def getter(self, param, **kwargs):
|
def getter(self, param, **kwargs):
|
||||||
|
@ -31,6 +31,8 @@ class KindMapClass(metaclass=SingletonType):
|
|||||||
asio: tuple
|
asio: tuple
|
||||||
insert: int
|
insert: int
|
||||||
composite: int
|
composite: int
|
||||||
|
channels: int
|
||||||
|
cells: int
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def phys_in(self) -> int:
|
def phys_in(self) -> int:
|
||||||
@ -64,6 +66,14 @@ class KindMapClass(metaclass=SingletonType):
|
|||||||
def num_bus_levels(self) -> int:
|
def num_bus_levels(self) -> int:
|
||||||
return 8 * (self.phys_out + self.virt_out)
|
return 8 * (self.phys_out + self.virt_out)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def num_bus_channels(self) -> int:
|
||||||
|
return self.channels
|
||||||
|
|
||||||
|
@property
|
||||||
|
def num_bus_cells(self) -> int:
|
||||||
|
return self.cells
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return self.name.capitalize()
|
return self.name.capitalize()
|
||||||
|
|
||||||
@ -76,6 +86,8 @@ class BasicMap(KindMapClass):
|
|||||||
asio: tuple = (0, 0)
|
asio: tuple = (0, 0)
|
||||||
insert: int = 0
|
insert: int = 0
|
||||||
composite: int = 0
|
composite: int = 0
|
||||||
|
channels: int = 8
|
||||||
|
cells: int = 7
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
@ -86,6 +98,8 @@ class BananaMap(KindMapClass):
|
|||||||
asio: tuple = (6, 8)
|
asio: tuple = (6, 8)
|
||||||
insert: int = 22
|
insert: int = 22
|
||||||
composite: int = 8
|
composite: int = 8
|
||||||
|
channels: int = 9
|
||||||
|
cells: int = 7
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
@ -96,6 +110,8 @@ class PotatoMap(KindMapClass):
|
|||||||
asio: tuple = (10, 8)
|
asio: tuple = (10, 8)
|
||||||
insert: int = 34
|
insert: int = 34
|
||||||
composite: int = 8
|
composite: int = 8
|
||||||
|
channels: int = 0
|
||||||
|
cells: int = 0
|
||||||
|
|
||||||
|
|
||||||
def kind_factory(kind_id):
|
def kind_factory(kind_id):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user