Compare commits

...

18 Commits
v0.9.3 ... main

Author SHA1 Message Date
cd5b8b0636 upd lockfile 2026-03-03 20:29:04 +00:00
77e21617af increase subheading size 2026-03-03 20:05:26 +00:00
5f448fa48e add Strip Denoiser to README 2026-03-03 16:29:44 +00:00
7eb8dc0bb6 patch bump 2026-03-03 15:55:42 +00:00
81b3841241 annotate optional args as Optional. 2026-03-03 15:13:47 +00:00
6e6a60e9bd remove meta launchers for comp, gate, denoiser. 2026-03-03 15:13:29 +00:00
a2ae240605 upd call to vban_cmd
minor bump
2026-03-02 23:27:11 +00:00
18ed3ea7fb bump development status classifier 2026-03-02 22:11:30 +00:00
d5ca50e9bd patch bump 2026-03-02 22:08:07 +00:00
0f8be6de48 bp-sidechain should be float 2026-03-02 22:07:53 +00:00
aa6b156eff minor bump 2026-03-02 22:04:05 +00:00
5c60a382fd add Strip Gate Command to README
update  the usage lines
2026-03-02 22:03:51 +00:00
d7fef4f26a remove duplicates from help outputs.
this bug was introduced due to changes in the meta app launchers.
2026-03-02 22:03:32 +00:00
e6a17d5772 add more gate commands 2026-03-02 22:02:25 +00:00
5c3452bff5 md upd 2026-03-02 21:20:43 +00:00
b0a524d125 add Strip Comp Command to README 2026-03-02 21:18:05 +00:00
2693fcce2c bump vban-cmd dep version
minor bump
2026-03-02 21:13:39 +00:00
bf058e910e add more compressor commands 2026-03-02 21:13:12 +00:00
11 changed files with 363 additions and 96 deletions

View File

@ -5,8 +5,6 @@
--- ---
This CLI is still in an early stage of development with many more things that could be implemented. However, the commands that are implemented should be working without issues.
## Install ## Install
#### With uv #### With uv
@ -51,7 +49,7 @@ export VBAN_CLI_STREAMNAME=Command1
### Strip Command ### Strip Command
Usage: vban-cli strip \<index> COMMAND [ARGS] *Usage: vban-cli strip \<index> COMMAND [OPTIONS]*
examples: examples:
@ -67,7 +65,7 @@ see `vban-cli strip --help` for more info.
#### Strip EQ #### Strip EQ
Usage: vban-cli strip \<index> eq COMMAND [OPTIONS] *Usage: vban-cli strip \<index> eq COMMAND [OPTIONS]*
examples: examples:
@ -79,7 +77,7 @@ see `vban-cli strip eq --help` for more info.
#### Strip EQ Cell Command #### Strip EQ Cell Command
Usage: vban-cli strip \<index> eq cell \<band> COMMAND [ARGS] *Usage: vban-cli strip \<index> eq cell \<band> COMMAND [ARGS]*
examples: examples:
@ -93,9 +91,49 @@ vban-cli strip 4 eq cell 5 type 5
see `vban-cli strip eq cell --help` for more info. see `vban-cli strip eq cell --help` for more info.
#### Strip Comp Command
*Usage: vban-cli strip \<index> comp COMMAND [OPTIONS]*
examples:
```console
vban-cli strip 0 comp attack 2.0
vban-cli strip 3 comp auto-makeup true
```
see `vban-cli strip comp --help` for more info.
#### Strip Gate Command
*Usage: vban-cli strip \<index> gate COMMAND [OPTIONS]*
examples:
```console
vban-cli strip 2 gate attack 634
vban-cli strip 5 gate hold 2088.7
```
see `vban-cli strip comp --help` for more info.
#### Strip Denoiser Command
*Usage: vban-cli strip \<index> denoiser COMMAND [OPTIONS]*
examples:
```console
vban-cli strip 4 denoiser knob 3.6
```
see `vban-cli strip denoiser --help` for more info.
#### Strip Gainlayer Command #### Strip Gainlayer Command
Usage: vban-cli strip \<index> gainlayer \<gainlayer_index> COMMAND [OPTIONS] [ARGS] *Usage: vban-cli strip \<index> gainlayer \<gainlayer_index> COMMAND [OPTIONS] [ARGS]*
examples: examples:
@ -109,7 +147,7 @@ see `vban-cli strip gainlayer --help` for more info.
### Bus Command ### Bus Command
Usage: vban-cli bus \<index> COMMAND [ARGS] *Usage: vban-cli bus \<index> COMMAND [OPTIONS]*
examples: examples:
@ -123,7 +161,7 @@ see `vban-cli bus --help` for more info.
### Command Command ### Command Command
Usage: vban-cli command COMMAND *Usage: vban-cli command COMMAND*
examples: examples:
@ -137,7 +175,7 @@ see `vban-cli command --help` for more info.
### Recorder Command ### Recorder Command
Usage: vban-cli recorder COMMAND *Usage: vban-cli recorder COMMAND*
examples: examples:
@ -153,7 +191,7 @@ see `vban-cli recorder --help` for more info.
### Sendtext Command ### Sendtext Command
Usage: vban-cli sendtext TEXT *Usage: vban-cli sendtext TEXT*
examples: examples:

View File

@ -1,13 +1,13 @@
[project] [project]
name = "vban-cli" name = "vban-cli"
version = "0.9.3" version = "0.12.1"
description = "A command-line interface for Voicemeeter leveraging VBAN." description = "A command-line interface for Voicemeeter leveraging VBAN."
readme = "README.md" readme = "README.md"
license = { text = "LICENSE" } license = { text = "LICENSE" }
requires-python = ">=3.13" requires-python = ">=3.13"
dependencies = ["cyclopts>=4.6.0", "loguru>=0.7.3", "vban-cmd>=2.8.1"] dependencies = ["cyclopts>=4.6.0", "loguru>=0.7.3", "vban-cmd>=2.9.4"]
classifiers = [ classifiers = [
"Development Status :: 3 - Alpha", "Development Status :: 4 - Beta",
"Programming Language :: Python", "Programming Language :: Python",
"Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.11",

View File

@ -53,7 +53,7 @@ def launcher(
try: try:
with vban_cmd.api( with vban_cmd.api(
vban_config.kind, vban_config.kind,
ip=vban_config.host, host=vban_config.host,
port=vban_config.port, port=vban_config.port,
streamname=vban_config.streamname, streamname=vban_config.streamname,
disable_rt_listeners=disable_rt_listeners, disable_rt_listeners=disable_rt_listeners,

View File

@ -1,4 +1,4 @@
from typing import Annotated from typing import Annotated, Optional
from cyclopts import App, Argument, Parameter from cyclopts import App, Argument, Parameter
@ -8,24 +8,9 @@ from .help import StripHelpFormatter
app = App(name='comp', help_formatter=StripHelpFormatter()) app = App(name='comp', help_formatter=StripHelpFormatter())
@app.meta.default
def launcher(
*tokens: Annotated[str, Parameter(show=False, allow_leading_hyphen=True)],
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Control the compressor parameters."""
additional_kwargs = {}
command, bound, _ = app.parse_args(tokens)
additional_kwargs['index'] = index
additional_kwargs['ctx'] = ctx
return command(*bound.args, **bound.kwargs, **additional_kwargs)
@app.command(name='knob') @app.command(name='knob')
def knob( def knob(
new_knob: Annotated[float, Argument()] = None, new_knob: Annotated[Optional[float], Argument()] = None,
*, *,
index: Annotated[int, Parameter(parse=False)], index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)], ctx: Annotated[Context, Parameter(parse=False)],
@ -34,7 +19,7 @@ def knob(
Parameters Parameters
---------- ----------
new_knob : int, optional new_knob : float, optional
If provided, sets the knob to this value. If not provided, the current knob is printed. If provided, sets the knob to this value. If not provided, the current knob is printed.
""" """
if new_knob is None: if new_knob is None:
@ -46,7 +31,7 @@ def knob(
@app.command(name='input-gain') @app.command(name='input-gain')
def input_gain( def input_gain(
new_gain: Annotated[float, Argument()] = None, new_gain: Annotated[Optional[float], Argument()] = None,
*, *,
index: Annotated[int, Parameter(parse=False)], index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)], ctx: Annotated[Context, Parameter(parse=False)],
@ -63,3 +48,150 @@ def input_gain(
# app.console.print(ctx.client.strip[index].comp.gainin) # app.console.print(ctx.client.strip[index].comp.gainin)
return return
ctx.client.strip[index].comp.gainin = new_gain ctx.client.strip[index].comp.gainin = new_gain
@app.command(name='ratio')
def ratio(
new_ratio: Annotated[Optional[float], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the ratio of the specified compressor.
Parameters
----------
new_ratio : float, optional
If provided, sets the ratio to this value. If not provided, the current ratio is printed.
"""
if new_ratio is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].comp.ratio)
return
ctx.client.strip[index].comp.ratio = new_ratio
@app.command(name='threshold')
def threshold(
new_threshold: Annotated[Optional[float], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the threshold of the specified compressor.
Parameters
----------
new_threshold : float, optional
If provided, sets the threshold to this value. If not provided, the current threshold is printed.
"""
if new_threshold is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].comp.threshold)
return
ctx.client.strip[index].comp.threshold = new_threshold
@app.command(name='attack')
def attack(
new_attack: Annotated[Optional[float], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the attack of the specified compressor.
Parameters
----------
new_attack : float, optional
If provided, sets the attack to this value. If not provided, the current attack is printed.
"""
if new_attack is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].comp.attack)
return
ctx.client.strip[index].comp.attack = new_attack
@app.command(name='release')
def release(
new_release: Annotated[Optional[float], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the release of the specified compressor.
Parameters
----------
new_release : float, optional
If provided, sets the release to this value. If not provided, the current release is printed.
"""
if new_release is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].comp.release)
return
ctx.client.strip[index].comp.release = new_release
@app.command(name='knee')
def knee(
new_knee: Annotated[Optional[float], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the knee of the specified compressor.
Parameters
----------
new_knee : float, optional
If provided, sets the knee to this value. If not provided, the current knee is printed.
"""
if new_knee is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].comp.knee)
return
ctx.client.strip[index].comp.knee = new_knee
@app.command(name='output-gain')
def output_gain(
new_gain: Annotated[Optional[float], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the output gain of the specified compressor.
Parameters
----------
new_gain : float, optional
If provided, sets the output gain to this value. If not provided, the current output gain is printed.
"""
if new_gain is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].comp.gainout)
return
ctx.client.strip[index].comp.gainout = new_gain
@app.command(name='auto-makeup')
def makeup(
new_makeup: Annotated[Optional[bool], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the auto-makeup of the specified compressor.
Parameters
----------
new_makeup : bool, optional
If provided, sets the auto-makeup to this value. If not provided, the current auto-makeup is printed.
"""
if new_makeup is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].comp.makeup)
return
ctx.client.strip[index].comp.makeup = new_makeup

View File

@ -1,4 +1,4 @@
from typing import Annotated from typing import Annotated, Optional
from cyclopts import App, Argument, Parameter from cyclopts import App, Argument, Parameter
@ -8,24 +8,9 @@ from .help import StripHelpFormatter
app = App(name='denoiser', help_formatter=StripHelpFormatter()) app = App(name='denoiser', help_formatter=StripHelpFormatter())
@app.meta.default
def launcher(
*tokens: Annotated[str, Parameter(show=False, allow_leading_hyphen=True)],
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Control the denoiser parameters."""
additional_kwargs = {}
command, bound, _ = app.parse_args(tokens)
additional_kwargs['index'] = index
additional_kwargs['ctx'] = ctx
return command(*bound.args, **bound.kwargs, **additional_kwargs)
@app.command(name='knob') @app.command(name='knob')
def knob( def knob(
new_knob: Annotated[float, Argument()] = None, new_knob: Annotated[Optional[float], Argument()] = None,
*, *,
index: Annotated[int, Parameter(parse=False)], index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)], ctx: Annotated[Context, Parameter(parse=False)],
@ -34,7 +19,7 @@ def knob(
Parameters Parameters
---------- ----------
new_knob : int, optional new_knob : float, optional
If provided, sets the knob to this value. If not provided, the current knob is printed. If provided, sets the knob to this value. If not provided, the current knob is printed.
""" """
if new_knob is None: if new_knob is None:

View File

@ -1,4 +1,4 @@
from typing import Annotated from typing import Annotated, Optional
from cyclopts import App, Argument, Parameter from cyclopts import App, Argument, Parameter
@ -35,7 +35,7 @@ def launcher(
@app.command(name='on') @app.command(name='on')
def on( def on(
new_state: Annotated[bool, Argument()] = None, new_state: Annotated[Optional[bool], Argument()] = None,
*, *,
target: Annotated[object, Parameter(parse=False)], target: Annotated[object, Parameter(parse=False)],
): ):
@ -43,7 +43,7 @@ def on(
Parameters Parameters
---------- ----------
new_state : bool new_state : bool, optional
If provided, sets the on state to this value. If not provided, the current on state is printed. If provided, sets the on state to this value. If not provided, the current on state is printed.
""" """
if new_state is None: if new_state is None:
@ -73,7 +73,7 @@ def cell_launcher(
@cell_app.command(name='on') @cell_app.command(name='on')
def cell_on( def cell_on(
new_state: Annotated[bool, Argument()] = None, new_state: Annotated[Optional[bool], Argument()] = None,
*, *,
target: Annotated[object, Parameter(parse=False)], target: Annotated[object, Parameter(parse=False)],
): ):
@ -81,7 +81,7 @@ def cell_on(
Parameters Parameters
---------- ----------
new_state : bool new_state : bool, optional
If provided, sets the on state to this value. If not provided, the current on state is printed. If provided, sets the on state to this value. If not provided, the current on state is printed.
""" """
if new_state is None: if new_state is None:
@ -93,7 +93,7 @@ def cell_on(
@cell_app.command(name='freq') @cell_app.command(name='freq')
def cell_freq( def cell_freq(
new_freq: Annotated[float, Argument()] = None, new_freq: Annotated[Optional[float], Argument()] = None,
*, *,
target: Annotated[object, Parameter(parse=False)], target: Annotated[object, Parameter(parse=False)],
): ):
@ -101,7 +101,7 @@ def cell_freq(
Parameters Parameters
---------- ----------
new_freq : float new_freq : float, optional
If provided, sets the frequency to this value. If not provided, the current frequency is printed. If provided, sets the frequency to this value. If not provided, the current frequency is printed.
""" """
if new_freq is None: if new_freq is None:
@ -113,7 +113,7 @@ def cell_freq(
@cell_app.command(name='gain') @cell_app.command(name='gain')
def cell_gain( def cell_gain(
new_gain: Annotated[float, Argument()] = None, new_gain: Annotated[Optional[float], Argument()] = None,
*, *,
target: Annotated[object, Parameter(parse=False)], target: Annotated[object, Parameter(parse=False)],
): ):
@ -121,7 +121,7 @@ def cell_gain(
Parameters Parameters
---------- ----------
new_gain : float new_gain : float, optional
If provided, sets the gain to this value. If not provided, the current gain is printed. If provided, sets the gain to this value. If not provided, the current gain is printed.
""" """
if new_gain is None: if new_gain is None:
@ -133,7 +133,7 @@ def cell_gain(
@cell_app.command(name='quality') @cell_app.command(name='quality')
def cell_q( def cell_q(
new_q: Annotated[float, Argument()] = None, new_q: Annotated[Optional[float], Argument()] = None,
*, *,
target: Annotated[object, Parameter(parse=False)], target: Annotated[object, Parameter(parse=False)],
): ):
@ -141,7 +141,7 @@ def cell_q(
Parameters Parameters
---------- ----------
new_q : float new_q : float, optional
If provided, sets the Q to this value. If not provided, the current Q is printed. If provided, sets the Q to this value. If not provided, the current Q is printed.
""" """
if new_q is None: if new_q is None:
@ -153,7 +153,7 @@ def cell_q(
@cell_app.command(name='type') @cell_app.command(name='type')
def cell_type( def cell_type(
new_type: Annotated[int, Argument()] = None, new_type: Annotated[Optional[int], Argument()] = None,
*, *,
target: Annotated[object, Parameter(parse=False)], target: Annotated[object, Parameter(parse=False)],
): ):
@ -161,7 +161,7 @@ def cell_type(
Parameters Parameters
---------- ----------
new_type : int new_type : int, optional
If provided, sets the type to this value. If not provided, the current type is printed. If provided, sets the type to this value. If not provided, the current type is printed.
""" """
if new_type is None: if new_type is None:

View File

@ -1,4 +1,4 @@
from typing import Annotated from typing import Annotated, Optional
from cyclopts import App, Argument, Parameter from cyclopts import App, Argument, Parameter
@ -28,7 +28,7 @@ def launcher(
@app.command(name='level') @app.command(name='level')
def level( def level(
new_level: Annotated[float, Argument()] = None, new_level: Annotated[Optional[float], Argument()] = None,
*, *,
strip_index: Annotated[int, Parameter(parse=False)], strip_index: Annotated[int, Parameter(parse=False)],
gainlayer_index: Annotated[int, Parameter(parse=False)], gainlayer_index: Annotated[int, Parameter(parse=False)],
@ -38,7 +38,7 @@ def level(
Parameters Parameters
---------- ----------
new_level : float new_level : float, optional
If provided, sets the level to this value. If not provided, the current level is printed. If provided, sets the level to this value. If not provided, the current level is printed.
""" """
if new_level is None: if new_level is None:

View File

@ -1,4 +1,4 @@
from typing import Annotated from typing import Annotated, Optional
from cyclopts import App, Argument, Parameter from cyclopts import App, Argument, Parameter
@ -8,24 +8,9 @@ from .help import StripHelpFormatter
app = App(name='gate', help_formatter=StripHelpFormatter()) app = App(name='gate', help_formatter=StripHelpFormatter())
@app.meta.default
def launcher(
*tokens: Annotated[str, Parameter(show=False, allow_leading_hyphen=True)],
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Control the compressor parameters."""
additional_kwargs = {}
command, bound, _ = app.parse_args(tokens)
additional_kwargs['index'] = index
additional_kwargs['ctx'] = ctx
return command(*bound.args, **bound.kwargs, **additional_kwargs)
@app.command(name='knob') @app.command(name='knob')
def knob( def knob(
new_knob: Annotated[float, Argument()] = None, new_knob: Annotated[Optional[float], Argument()] = None,
*, *,
index: Annotated[int, Parameter(parse=False)], index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)], ctx: Annotated[Context, Parameter(parse=False)],
@ -34,7 +19,7 @@ def knob(
Parameters Parameters
---------- ----------
new_knob : int, optional new_knob : float, optional
If provided, sets the knob to this value. If not provided, the current knob is printed. If provided, sets the knob to this value. If not provided, the current knob is printed.
""" """
if new_knob is None: if new_knob is None:
@ -46,7 +31,7 @@ def knob(
@app.command(name='threshold') @app.command(name='threshold')
def threshold( def threshold(
new_threshold: Annotated[float, Argument()] = None, new_threshold: Annotated[Optional[float], Argument()] = None,
*, *,
index: Annotated[int, Parameter(parse=False)], index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)], ctx: Annotated[Context, Parameter(parse=False)],
@ -63,3 +48,108 @@ def threshold(
# app.console.print(ctx.client.strip[index].gate.threshold) # app.console.print(ctx.client.strip[index].gate.threshold)
return return
ctx.client.strip[index].gate.threshold = new_threshold ctx.client.strip[index].gate.threshold = new_threshold
@app.command(name='damping-max')
def damping_max(
new_damping_max: Annotated[Optional[float], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the damping max of the specified gate.
Parameters
----------
new_damping_max : float, optional
If provided, sets the damping max to this value. If not provided, the current damping max is printed.
"""
if new_damping_max is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].gate.damping)
return
ctx.client.strip[index].gate.damping = new_damping_max
@app.command(name='bp-sidechain')
def bp_sidechain(
new_bp_sidechain: Annotated[Optional[float], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the BP sidechain of the specified gate.
Parameters
----------
new_bp_sidechain : float, optional
If provided, sets the BP sidechain to this value. If not provided, the current BP sidechain is printed.
"""
if new_bp_sidechain is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].gate.bpsidechain)
return
ctx.client.strip[index].gate.bpsidechain = new_bp_sidechain
@app.command(name='attack')
def attack(
new_attack: Annotated[Optional[float], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the attack of the specified gate.
Parameters
----------
new_attack : float, optional
If provided, sets the attack to this value. If not provided, the current attack is printed.
"""
if new_attack is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].gate.attack)
return
ctx.client.strip[index].gate.attack = new_attack
@app.command(name='hold')
def hold(
new_hold: Annotated[Optional[float], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the hold of the specified gate.
Parameters
----------
new_hold : float, optional
If provided, sets the hold to this value. If not provided, the current hold is printed.
"""
if new_hold is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].gate.hold)
return
ctx.client.strip[index].gate.hold = new_hold
@app.command(name='release')
def release(
new_release: Annotated[Optional[float], Argument()] = None,
*,
index: Annotated[int, Parameter(parse=False)],
ctx: Annotated[Context, Parameter(parse=False)],
):
"""Get or set the release of the specified gate.
Parameters
----------
new_release : float, optional
If provided, sets the release to this value. If not provided, the current release is printed.
"""
if new_release is None:
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 2.
# app.console.print(ctx.client.strip[index].gate.release)
return
ctx.client.strip[index].gate.release = new_release

View File

@ -56,8 +56,16 @@ class StripHelpFormatter(BaseHelpFormatter):
) )
if modified_usage == str(usage): if modified_usage == str(usage):
modified_usage = re.sub( modified_usage = re.sub(
r'(\S+\s+strip)\s+(\w+)', r'\1 <index> \2', str(usage) r'(\S+\s+strip)\s+(\w+)',
r'\1 <index> \2 [OPTIONS] [ARGS]',
str(usage),
) )
# Handle main strip command and subcommand groups
modified_usage = re.sub(
r'\bCOMMAND\b(?!\s+\[)', 'COMMAND [OPTIONS]', modified_usage
)
# Remove the duplicate INDEX that gets automatically added by cyclopts
modified_usage = re.sub(r'\s+INDEX$', '', modified_usage)
console.print(f'[bold]Usage:[/bold] {modified_usage}') console.print(f'[bold]Usage:[/bold] {modified_usage}')
@ -76,8 +84,16 @@ class BusHelpFormatter(BaseHelpFormatter):
) )
if modified_usage == str(usage): if modified_usage == str(usage):
modified_usage = re.sub( modified_usage = re.sub(
r'(\S+\s+bus)\s+(\w+)', r'\1 <index> \2', str(usage) r'(\S+\s+bus)\s+(\w+)',
r'\1 <index> \2 [OPTIONS] [ARGS]',
str(usage),
) )
# Handle main bus command and subcommand groups
modified_usage = re.sub(
r'\bCOMMAND\b(?!\s+\[)', 'COMMAND [OPTIONS]', modified_usage
)
# Remove the duplicate INDEX that gets automatically added by cyclopts
modified_usage = re.sub(r'\s+INDEX$', '', modified_usage)
console.print(f'[bold]Usage:[/bold] {modified_usage}') console.print(f'[bold]Usage:[/bold] {modified_usage}')
@ -90,7 +106,9 @@ class EqHelpFormatter(BaseHelpFormatter):
"""Render the usage line with proper <index> placement for both strip and bus commands.""" """Render the usage line with proper <index> placement for both strip and bus commands."""
if usage: if usage:
modified_usage = re.sub( modified_usage = re.sub(
r'(\S+\s+)(\w+)(\s+eq\s+)(COMMAND)', r'\1\2 <index>\3\4', str(usage) r'(\S+\s+)(\w+)(\s+eq\s+)(COMMAND)',
r'\1\2 <index>\3\4 [OPTIONS]',
str(usage),
) )
console.print(f'[bold]Usage:[/bold] {modified_usage}') console.print(f'[bold]Usage:[/bold] {modified_usage}')
@ -105,9 +123,11 @@ class GainlayerHelpFormatter(BaseHelpFormatter):
if usage: if usage:
modified_usage = re.sub( modified_usage = re.sub(
r'(\S+\s+strip)(\s+gainlayer\s+)(COMMAND)', r'(\S+\s+strip)(\s+gainlayer\s+)(COMMAND)',
r'\1 <index>\2<[cyan]gainlayer_index[/cyan]> \3', r'\1 <index>\2<[cyan]gainlayer_index[/cyan]> \3 [OPTIONS] [ARGS]',
str(usage), str(usage),
) )
# Remove the duplicate GAINLAYER_INDEX that gets automatically added by cyclopts
modified_usage = re.sub(r'\s+GAINLAYER_INDEX$', '', modified_usage)
console.print(f'[bold]Usage:[/bold] {modified_usage}') console.print(f'[bold]Usage:[/bold] {modified_usage}')
@ -121,7 +141,9 @@ class CellHelpFormatter(BaseHelpFormatter):
if usage: if usage:
modified_usage = re.sub( modified_usage = re.sub(
r'(\S+\s+)(\w+)(\s+eq\s+cell\s+)(COMMAND)', r'(\S+\s+)(\w+)(\s+eq\s+cell\s+)(COMMAND)',
r'\1\2 <index>\3<[cyan]band[/cyan]> \4', r'\1\2 <index>\3<[cyan]band[/cyan]> \4 [ARGS]',
str(usage), str(usage),
) )
# Remove the duplicate BAND that gets automatically added by cyclopts
modified_usage = re.sub(r'\s+BAND$', '', modified_usage)
console.print(f'[bold]Usage:[/bold] {modified_usage}') console.print(f'[bold]Usage:[/bold] {modified_usage}')

View File

@ -8,9 +8,9 @@ from .help import StripHelpFormatter
app = App(name='strip', help_formatter=StripHelpFormatter()) app = App(name='strip', help_formatter=StripHelpFormatter())
app.command(eq.app.meta, name='eq') app.command(eq.app.meta, name='eq')
app.command(comp.app.meta, name='comp') app.command(comp.app, name='comp')
app.command(gate.app.meta, name='gate') app.command(gate.app, name='gate')
app.command(denoiser.app.meta, name='denoiser') app.command(denoiser.app, name='denoiser')
app.command(gainlayer.app.meta, name='gainlayer') app.command(gainlayer.app.meta, name='gainlayer')

4
uv.lock generated
View File

@ -124,7 +124,7 @@ wheels = [
[[package]] [[package]]
name = "vban-cli" name = "vban-cli"
version = "0.9.3" version = "0.12.1"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "cyclopts" }, { name = "cyclopts" },
@ -141,7 +141,7 @@ requires-dist = [
[[package]] [[package]]
name = "vban-cmd" name = "vban-cmd"
version = "2.8.1" version = "2.9.6"
source = { editable = "../vban-cmd-python" } source = { editable = "../vban-cmd-python" }
[package.metadata] [package.metadata]