Compare commits

..

6 Commits

Author SHA1 Message Date
1ad214ba4a add validation to --kind flag 2026-02-06 00:52:12 +00:00
66da965edd fix default value for kind 2026-02-06 00:47:34 +00:00
079a0b240d ensure all optional args are marked as optional 2026-02-06 00:41:26 +00:00
fe711f79f1 Main struct now uses address map 2026-02-06 00:41:06 +00:00
c94ac62cb8 upd address maps 2026-02-06 00:40:52 +00:00
5933b25114 move parser interface into engine.go
add snapshot field to Client
2026-02-06 00:40:42 +00:00
9 changed files with 54 additions and 34 deletions

View File

@ -37,9 +37,9 @@ A CLI to control Behringer X-Air mixers.
Flags:
-h, --help Show context-sensitive help.
--host="mixer.local" The host of the X-Air device ($XAIR_CLI_HOST).
--port=10024 The port of the X-Air device ($XAIR_CLI_PORT).
--kind="xr18" The kind of the X-Air device ($XAIR_CLI_KIND).
-H, --host="mixer.local" The host of the X-Air device ($XAIR_CLI_HOST).
-P, --port=10024 The port of the X-Air device ($XAIR_CLI_PORT).
-K, --kind="xair" The kind of the X-Air device ($XAIR_CLI_KIND).
-v, --version Print gobs-cli version information and quit
Commands:

22
bus.go
View File

@ -148,7 +148,7 @@ func (cmd *BusFadeoutCmd) Run(ctx *context, bus *BusCmdGroup) error {
// BusNameCmd defines the command for getting or setting the name of a bus.
type BusNameCmd struct {
Name *string `arg:"" help:"The name to set for the bus. If not provided, the current name will be returned."`
Name *string `arg:"" help:"The name to set for the bus. If not provided, the current name will be returned." optional:""`
}
// Run executes the BusNameCmd command, either retrieving the current name of the bus or setting it based on the provided argument.
@ -238,7 +238,7 @@ func (cmd *BusEqModeCmd) Run(ctx *context, bus *BusCmdGroup) error {
// BusEqBandGainCmd defines the command for getting or setting the gain of a specific EQ band of a bus.
type BusEqBandGainCmd struct {
Gain *float64 `arg:"" help:"The gain to set for the EQ band (in dB). If not provided, the current gain will be returned."`
Gain *float64 `arg:"" help:"The gain to set for the EQ band (in dB). If not provided, the current gain will be returned." optional:""`
}
// Run executes the BusEqBandGainCmd command, either retrieving the current gain of the specified EQ band of the bus or setting it based on the provided argument.
@ -261,7 +261,7 @@ func (cmd *BusEqBandGainCmd) Run(ctx *context, bus *BusCmdGroup, busEq *BusEqCmd
// BusEqBandFreqCmd defines the command for getting or setting the frequency of a specific EQ band of a bus.
type BusEqBandFreqCmd struct {
Freq *float64 `arg:"" help:"The frequency to set for the EQ band (in Hz). If not provided, the current frequency will be returned."`
Freq *float64 `arg:"" help:"The frequency to set for the EQ band (in Hz). If not provided, the current frequency will be returned." optional:""`
}
// Run executes the BusEqBandFreqCmd command, either retrieving the current frequency of the specified EQ band of the bus or setting it based on the provided argument.
@ -284,7 +284,7 @@ func (cmd *BusEqBandFreqCmd) Run(ctx *context, bus *BusCmdGroup, busEq *BusEqCmd
// BusEqBandQCmd defines the command for getting or setting the Q factor of a specific EQ band of a bus.
type BusEqBandQCmd struct {
Q *float64 `arg:"" help:"The Q factor to set for the EQ band. If not provided, the current Q factor will be returned."`
Q *float64 `arg:"" help:"The Q factor to set for the EQ band. If not provided, the current Q factor will be returned." optional:""`
}
// Run executes the BusEqBandQCmd command, either retrieving the current Q factor of the specified EQ band of the bus or setting it based on the provided argument.
@ -389,7 +389,7 @@ func (cmd *BusCompModeCmd) Run(ctx *context, bus *BusCmdGroup) error {
// BusCompThresholdCmd defines the command for getting or setting the compressor threshold of a bus.
type BusCompThresholdCmd struct {
Threshold *float64 `arg:"" help:"The compressor threshold to set (in dB). If not provided, the current compressor threshold will be returned."`
Threshold *float64 `arg:"" help:"The compressor threshold to set (in dB). If not provided, the current compressor threshold will be returned." optional:""`
}
// Run executes the BusCompThresholdCmd command, either retrieving the current compressor threshold of the bus or setting it based on the provided argument.
@ -412,7 +412,7 @@ func (cmd *BusCompThresholdCmd) Run(ctx *context, bus *BusCmdGroup) error {
// BusCompRatioCmd defines the command for getting or setting the compressor ratio of a bus.
type BusCompRatioCmd struct {
Ratio *float64 `arg:"" help:"The compressor ratio to set. If not provided, the current compressor ratio will be returned."`
Ratio *float64 `arg:"" help:"The compressor ratio to set. If not provided, the current compressor ratio will be returned." optional:""`
}
// Run executes the BusCompRatioCmd command, either retrieving the current compressor ratio of the bus or setting it based on the provided argument.
@ -435,7 +435,7 @@ func (cmd *BusCompRatioCmd) Run(ctx *context, bus *BusCmdGroup) error {
// BusCompMixCmd defines the command for getting or setting the compressor mix level of a bus.
type BusCompMixCmd struct {
Mix *float64 `arg:"" help:"The compressor mix level to set (in %). If not provided, the current compressor mix level will be returned."`
Mix *float64 `arg:"" help:"The compressor mix level to set (in %). If not provided, the current compressor mix level will be returned." optional:""`
}
// Run executes the BusCompMixCmd command, either retrieving the current compressor mix level of the bus or setting it based on the provided argument.
@ -458,7 +458,7 @@ func (cmd *BusCompMixCmd) Run(ctx *context, bus *BusCmdGroup) error {
// BusCompMakeupCmd defines the command for getting or setting the compressor makeup gain of a bus.
type BusCompMakeupCmd struct {
Makeup *float64 `arg:"" help:"The compressor makeup gain to set (in dB). If not provided, the current compressor makeup gain will be returned."`
Makeup *float64 `arg:"" help:"The compressor makeup gain to set (in dB). If not provided, the current compressor makeup gain will be returned." optional:""`
}
// Run executes the BusCompMakeupCmd command, either retrieving the current compressor makeup gain of the bus or setting it based on the provided argument.
@ -481,7 +481,7 @@ func (cmd *BusCompMakeupCmd) Run(ctx *context, bus *BusCmdGroup) error {
// BusCompAttackCmd defines the command for getting or setting the compressor attack time of a bus.
type BusCompAttackCmd struct {
Attack *float64 `arg:"" help:"The compressor attack time to set (in ms). If not provided, the current compressor attack time will be returned."`
Attack *float64 `arg:"" help:"The compressor attack time to set (in ms). If not provided, the current compressor attack time will be returned." optional:""`
}
// Run executes the BusCompAttackCmd command, either retrieving the current compressor attack time of the bus or setting it based on the provided argument.
@ -504,7 +504,7 @@ func (cmd *BusCompAttackCmd) Run(ctx *context, bus *BusCmdGroup) error {
// BusCompHoldCmd defines the command for getting or setting the compressor hold time of a bus.
type BusCompHoldCmd struct {
Hold *float64 `arg:"" help:"The compressor hold time to set (in ms). If not provided, the current compressor hold time will be returned."`
Hold *float64 `arg:"" help:"The compressor hold time to set (in ms). If not provided, the current compressor hold time will be returned." optional:""`
}
// Run executes the BusCompHoldCmd command, either retrieving the current compressor hold time of the bus or setting it based on the provided argument.
@ -527,7 +527,7 @@ func (cmd *BusCompHoldCmd) Run(ctx *context, bus *BusCmdGroup) error {
// BusCompReleaseCmd defines the command for getting or setting the compressor release time of a bus.
type BusCompReleaseCmd struct {
Release *float64 `arg:"" help:"The compressor release time to set (in ms). If not provided, the current compressor release time will be returned."`
Release *float64 `arg:"" help:"The compressor release time to set (in ms). If not provided, the current compressor release time will be returned." optional:""`
}
// Run executes the BusCompReleaseCmd command, either retrieving the current compressor release time of the bus or setting it based on the provided argument.

View File

@ -19,7 +19,7 @@ type HeadampCmdGroup struct {
// HeadampGainCmd defines the command for getting or setting the gain of a headamp, allowing users to specify the gain in dB and an optional duration for a gradual fade when setting the gain.
type HeadampGainCmd struct {
Duration time.Duration `help:"The duration of the fade in/out when setting the gain." default:"5s"`
Gain *float64 `help:"The gain of the headamp in dB." arg:""`
Gain *float64 `help:"The gain of the headamp in dB." arg:"" optional:""`
}
// Run executes the HeadampGainCmd command, either retrieving the current gain of the headamp or setting it based on the provided argument, with an optional fade duration for smooth transitions.

View File

@ -1,6 +1,7 @@
package xair
var xairAddressMap = map[string]string{
"main": "/lr",
"strip": "/ch/%02d",
"bus": "/bus/%01d",
"headamp": "/headamp/%02d",
@ -8,9 +9,12 @@ var xairAddressMap = map[string]string{
}
var x32AddressMap = map[string]string{
"strip": "/ch/%02d",
"bus": "/bus/%02d",
"headamp": "/headamp/%02d",
"main": "/main/st",
"mainmono": "/main/mono",
"strip": "/ch/%02d",
"bus": "/bus/%02d",
"headamp": "/headamp/%02d",
"snapshot": "/-snap",
}
func addressMapForMixerKind(kind MixerKind) map[string]string {

View File

@ -10,10 +10,6 @@ import (
"github.com/hypebeast/go-osc/osc"
)
type parser interface {
Parse(data []byte) (*osc.Message, error)
}
type Client struct {
engine
Main *Main
@ -60,10 +56,11 @@ func NewClient(mixerIP string, mixerPort int, opts ...Option) (*Client, error) {
c := &Client{
engine: *e,
}
c.Main = newMain(c)
c.Main = newMainStereo(c)
c.Strip = NewStrip(c)
c.Bus = NewBus(c)
c.HeadAmp = NewHeadAmp(c)
c.Snapshot = NewSnapshot(c)
return c, nil
}

View File

@ -9,6 +9,10 @@ import (
"github.com/hypebeast/go-osc/osc"
)
type parser interface {
Parse(data []byte) (*osc.Message, error)
}
type engine struct {
Kind MixerKind
conn *net.UDPConn

View File

@ -3,18 +3,30 @@ package xair
import "fmt"
type Main struct {
client *Client
baseAddress string
client *Client
}
func newMain(c *Client) *Main {
func newMainStereo(c *Client) *Main {
return &Main{
client: c,
baseAddress: c.addressMap["main"],
client: c,
}
}
/* Still considering the best way to implement main mono support.
func newMainMono(c *Client) *Main {
return &Main{
baseAddress: c.addressMap["mainmono"],
client: c,
}
}
*/
// Fader requests the current main L/R fader level
func (m *Main) Fader() (float64, error) {
err := m.client.SendMessage("/lr/mix/fader")
address := m.baseAddress + "/mix/fader"
err := m.client.SendMessage(address)
if err != nil {
return 0, err
}
@ -29,12 +41,14 @@ func (m *Main) Fader() (float64, error) {
// SetFader sets the main L/R fader level
func (m *Main) SetFader(level float64) error {
return m.client.SendMessage("/lr/mix/fader", float32(mustDbInto(level)))
address := m.baseAddress + "/mix/fader"
return m.client.SendMessage(address, float32(mustDbInto(level)))
}
// Mute requests the current main L/R mute status
func (m *Main) Mute() (bool, error) {
err := m.client.SendMessage("/lr/mix/on")
address := m.baseAddress + "/mix/on"
err := m.client.SendMessage(address)
if err != nil {
return false, err
}
@ -49,9 +63,10 @@ func (m *Main) Mute() (bool, error) {
// SetMute sets the main L/R mute status
func (m *Main) SetMute(muted bool) error {
address := m.baseAddress + "/mix/on"
var value int32
if !muted {
value = 1
}
return m.client.SendMessage("/lr/mix/on", value)
return m.client.SendMessage(address, value)
}

4
lr.go
View File

@ -16,7 +16,7 @@ type MainCmdGroup struct {
// MainMuteCmd defines the command for getting or setting the mute state of the Main L/R output, allowing users to specify the desired state as "true"/"on" or "false"/"off".
type MainMuteCmd struct {
Mute *bool `arg:"" help:"The mute state to set. If not provided, the current state will be printed."`
Mute *bool `arg:"" help:"The mute state to set. If not provided, the current state will be printed." optional:""`
}
// Run executes the MainMuteCmd command, either retrieving the current mute state of the Main L/R output or setting it based on the provided argument.
@ -39,7 +39,7 @@ func (cmd *MainMuteCmd) Run(ctx *context) error {
// MainFaderCmd defines the command for getting or setting the fader level of the Main L/R output, allowing users to specify the desired level in dB.
type MainFaderCmd struct {
Level *float64 `arg:"" help:"The fader level to set. If not provided, the current level will be printed."`
Level *float64 `arg:"" help:"The fader level to set. If not provided, the current level will be printed." optional:""`
}
// Run executes the MainFaderCmd command, either retrieving the current fader level of the Main L/R output or setting it based on the provided argument.

View File

@ -34,7 +34,7 @@ type context struct {
type Config struct {
Host string `default:"mixer.local" help:"The host of the X-Air device." env:"XAIR_CLI_HOST" short:"H"`
Port int `default:"10024" help:"The port of the X-Air device." env:"XAIR_CLI_PORT" short:"P"`
Kind string `default:"xr18" help:"The kind of the X-Air device." env:"XAIR_CLI_KIND" short:"K"`
Kind string `default:"xair" help:"The kind of the X-Air device." env:"XAIR_CLI_KIND" short:"K" enum:"xair,x32"`
}
// CLI is the main struct for the command-line interface.
@ -42,7 +42,7 @@ type Config struct {
type CLI struct {
Config `embed:"" prefix:"" help:"The configuration for the CLI."`
Version VersionFlag `help:"Print gobs-cli version information and quit" name:"version" short:"v"`
Version VersionFlag `help:"Print xair-cli version information and quit" name:"version" short:"v"`
Completion kongcompletion.Completion `help:"Generate shell completion scripts." cmd:"" aliases:"c"`