Initial setup adding classes for channels and cells

This commit is contained in:
William Young 2025-06-15 10:43:50 -05:00
parent f7abc5248b
commit f8f10e358f
6 changed files with 162 additions and 3 deletions

View 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.

View 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()

View File

@ -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,){},
)()

View File

@ -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,

View File

@ -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):

View File

@ -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):