Compare commits

..

No commits in common. "58866b794b6fa2661a692e365d7f06079f49b590" and "106f896c453e206537ff8c247456964716b98c04" have entirely different histories.

18 changed files with 80 additions and 129 deletions

View File

@ -46,10 +46,9 @@ type CLI struct {
Version VersionFlag `help:"Print x32-cli version information and quit" name:"version" short:"v"`
Completion kongcompletion.Completion `help:"Generate shell completion scripts." cmd:""`
Info InfoCmd `help:"Print mixer information." cmd:""`
Raw RawCmd `help:"Send raw OSC messages to the mixer." cmd:""`
Completion kongcompletion.Completion `help:"Generate shell completion scripts." cmd:"" aliases:"c"`
Raw RawCmd `help:"Send raw OSC messages to the mixer." cmd:"" group:"Raw"`
Main MainCmdGroup `help:"Control the Main L/R output" cmd:"" group:"Main"`
Mainmono MainMonoCmdGroup `help:"Control the Main Mono output" cmd:"" group:"MainMono"`
Matrix MatrixCmdGroup `help:"Control the matrix outputs." cmd:"" group:"Matrix"`

View File

@ -1,18 +0,0 @@
package main
import "fmt"
type InfoCmd struct {
}
func (c *InfoCmd) Run(ctx *context) error {
fmt.Fprintf(
ctx.Out,
"Host: %s | Name: %s | Model: %s | Firmware: %s\n",
ctx.Client.Info.Host,
ctx.Client.Info.Name,
ctx.Client.Info.Model,
ctx.Client.Info.Firmware,
)
return nil
}

View File

@ -46,10 +46,9 @@ type CLI struct {
Version VersionFlag `help:"Print xair-cli version information and quit" name:"version" short:"v"`
Completion kongcompletion.Completion `help:"Generate shell completion scripts." cmd:""`
Info InfoCmd `help:"Print mixer information." cmd:""`
Raw RawCmd `help:"Send raw OSC messages to the mixer." cmd:""`
Completion kongcompletion.Completion `help:"Generate shell completion scripts." cmd:"" aliases:"c"`
Raw RawCmd `help:"Send raw OSC messages to the mixer." cmd:"" group:"Raw"`
Main MainCmdGroup `help:"Control the Main L/R output" cmd:"" group:"Main"`
Strip StripCmdGroup `help:"Control the strips." cmd:"" group:"Strip"`
Bus BusCmdGroup `help:"Control the buses." cmd:"" group:"Bus"`

View File

@ -1,18 +0,0 @@
package main
import "fmt"
type InfoCmd struct {
}
func (c *InfoCmd) Run(ctx *context) error {
fmt.Fprintf(
ctx.Out,
"Host: %s | Name: %s | Model: %s | Firmware: %s\n",
ctx.Client.Info.Host,
ctx.Client.Info.Name,
ctx.Client.Info.Model,
ctx.Client.Info.Firmware,
)
return nil
}

View File

@ -3,14 +3,14 @@ package xair
import "fmt"
type Bus struct {
client *client
client *Client
baseAddress string
Eq *Eq
Comp *Comp
}
// newBus creates a new Bus instance
func newBus(c *client) *Bus {
func newBus(c *Client) *Bus {
return &Bus{
client: c,
baseAddress: c.addressMap["bus"],

View File

@ -9,9 +9,13 @@ import (
"github.com/hypebeast/go-osc/osc"
)
type Client struct {
*engine
}
// XAirClient is a client for controlling XAir mixers
type XAirClient struct {
client
Client
Main *Main
Strip *Strip
Bus *Bus
@ -20,29 +24,9 @@ type XAirClient struct {
DCA *DCA
}
// NewXAirClient creates a new XAirClient instance with optional engine configuration
func NewXAirClient(mixerIP string, mixerPort int, opts ...EngineOption) (*XAirClient, error) {
e, err := newEngine(mixerIP, mixerPort, kindXAir, opts...)
if err != nil {
return nil, err
}
c := &XAirClient{
client: client{e, InfoResponse{}},
}
c.Main = newMainStereo(&c.client)
c.Strip = newStrip(&c.client)
c.Bus = newBus(&c.client)
c.HeadAmp = newHeadAmp(&c.client)
c.Snapshot = newSnapshot(&c.client)
c.DCA = newDCA(&c.client)
return c, nil
}
// X32Client is a client for controlling X32 mixers
type X32Client struct {
client
Client
Main *Main
MainMono *Main
Matrix *Matrix
@ -61,33 +45,48 @@ func NewX32Client(mixerIP string, mixerPort int, opts ...EngineOption) (*X32Clie
}
c := &X32Client{
client: client{e, InfoResponse{}},
Client: Client{e},
}
c.Main = newMainStereo(&c.client)
c.MainMono = newMainMono(&c.client)
c.Matrix = newMatrix(&c.client)
c.Strip = newStrip(&c.client)
c.Bus = newBus(&c.client)
c.HeadAmp = newHeadAmp(&c.client)
c.Snapshot = newSnapshot(&c.client)
c.DCA = newDCA(&c.client)
c.Main = newMainStereo(&c.Client)
c.MainMono = newMainMono(&c.Client)
c.Matrix = newMatrix(&c.Client)
c.Strip = newStrip(&c.Client)
c.Bus = newBus(&c.Client)
c.HeadAmp = newHeadAmp(&c.Client)
c.Snapshot = newSnapshot(&c.Client)
c.DCA = newDCA(&c.Client)
return c, nil
}
type client struct {
*engine
Info InfoResponse
// NewXAirClient creates a new XAirClient instance with optional engine configuration
func NewXAirClient(mixerIP string, mixerPort int, opts ...EngineOption) (*XAirClient, error) {
e, err := newEngine(mixerIP, mixerPort, kindXAir, opts...)
if err != nil {
return nil, err
}
c := &XAirClient{
Client: Client{e},
}
c.Main = newMainStereo(&c.Client)
c.Strip = newStrip(&c.Client)
c.Bus = newBus(&c.Client)
c.HeadAmp = newHeadAmp(&c.Client)
c.Snapshot = newSnapshot(&c.Client)
c.DCA = newDCA(&c.Client)
return c, nil
}
// Start begins listening for messages in a goroutine
func (c *client) StartListening() {
func (c *Client) StartListening() {
go c.engine.receiveLoop()
log.Debugf("Started listening on %s...", c.engine.conn.LocalAddr().String())
}
// Close stops the client and closes the connection
func (c *client) Close() {
func (c *Client) Close() {
close(c.engine.done)
if c.engine.conn != nil {
c.engine.conn.Close()
@ -95,12 +94,12 @@ func (c *client) Close() {
}
// SendMessage sends an OSC message to the mixer using the unified connection
func (c *client) SendMessage(address string, args ...any) error {
func (c *Client) SendMessage(address string, args ...any) error {
return c.engine.sendToAddress(c.mixerAddr, address, args...)
}
// ReceiveMessage receives an OSC message from the mixer
func (c *client) ReceiveMessage() (*osc.Message, error) {
func (c *Client) ReceiveMessage() (*osc.Message, error) {
t := time.Tick(c.engine.timeout)
select {
case <-t:
@ -114,7 +113,7 @@ func (c *client) ReceiveMessage() (*osc.Message, error) {
}
// RequestInfo requests mixer information
func (c *client) RequestInfo() (InfoResponse, error) {
func (c *Client) RequestInfo() (InfoResponse, error) {
var info InfoResponse
err := c.SendMessage("/xinfo")
if err != nil {
@ -125,31 +124,20 @@ func (c *client) RequestInfo() (InfoResponse, error) {
if err != nil {
return info, err
}
if len(msg.Arguments) == 4 {
if host, ok := msg.Arguments[0].(string); ok {
info.Host = host
}
if name, ok := msg.Arguments[1].(string); ok {
info.Name = name
}
if model, ok := msg.Arguments[2].(string); ok {
info.Model = model
}
if firmware, ok := msg.Arguments[3].(string); ok {
info.Firmware = firmware
}
if len(msg.Arguments) >= 3 {
info.Host = msg.Arguments[0].(string)
info.Name = msg.Arguments[1].(string)
info.Model = msg.Arguments[2].(string)
}
c.Info = info
return info, nil
}
// KeepAlive sends keep-alive message (required for multi-client usage)
func (c *client) KeepAlive() error {
func (c *Client) KeepAlive() error {
return c.SendMessage("/xremote")
}
// RequestStatus requests mixer status
func (c *client) RequestStatus() error {
func (c *Client) RequestStatus() error {
return c.SendMessage("/status")
}

View File

@ -4,13 +4,13 @@ import "fmt"
// Comp represents the compressor parameters.
type Comp struct {
client *client
client *Client
baseAddress string
AddressFunc func(fmtString string, args ...any) string
}
// Factory function to create Comp instance with optional configuration
func newComp(c *client, baseAddress string, opts ...CompOption) *Comp {
func newComp(c *Client, baseAddress string, opts ...CompOption) *Comp {
comp := &Comp{
client: c,
baseAddress: fmt.Sprintf("%s/dyn", baseAddress),

View File

@ -3,12 +3,12 @@ package xair
import "fmt"
type DCA struct {
client *client
client *Client
baseAddress string
}
// newDCA creates a new DCA instance
func newDCA(c *client) *DCA {
func newDCA(c *Client) *DCA {
return &DCA{
client: c,
baseAddress: c.addressMap["dca"],

View File

@ -6,13 +6,13 @@ import (
// Eq represents the EQ parameters.
type Eq struct {
client *client
client *Client
baseAddress string
AddressFunc func(fmtString string, args ...any) string
}
// Factory function to create Eq instance with optional configuration
func newEq(c *client, baseAddress string, opts ...EqOption) *Eq {
func newEq(c *Client, baseAddress string, opts ...EqOption) *Eq {
eq := &Eq{
client: c,
baseAddress: fmt.Sprintf("%s/eq", baseAddress),

View File

@ -4,13 +4,13 @@ import "fmt"
// Gate represents the gate parameters.
type Gate struct {
client *client
client *Client
baseAddress string
AddressFunc func(fmtString string, args ...any) string
}
// Factory function to create Gate instance with optional configuration
func newGate(c *client, baseAddress string, opts ...GateOption) *Gate {
func newGate(c *Client, baseAddress string, opts ...GateOption) *Gate {
gate := &Gate{
client: c,
baseAddress: fmt.Sprintf("%s/gate", baseAddress),

View File

@ -3,12 +3,12 @@ package xair
import "fmt"
type HeadAmp struct {
client *client
client *Client
baseAddress string
}
// newHeadAmp creates a new HeadAmp instance with the provided client.
func newHeadAmp(c *client) *HeadAmp {
func newHeadAmp(c *Client) *HeadAmp {
return &HeadAmp{
client: c,
baseAddress: c.addressMap["headamp"],

View File

@ -3,14 +3,14 @@ package xair
import "fmt"
type Main struct {
client *client
client *Client
baseAddress string
Eq *Eq
Comp *Comp
}
// newMainStereo creates a new Main instance for stereo main output
func newMainStereo(c *client) *Main {
func newMainStereo(c *Client) *Main {
addressFunc := func(fmtString string, args ...any) string {
return fmtString
}
@ -24,7 +24,7 @@ func newMainStereo(c *client) *Main {
}
// newMainMono creates a new MainMono instance for mono main output (X32 only)
func newMainMono(c *client) *Main {
func newMainMono(c *Client) *Main {
addressFunc := func(fmtString string, args ...any) string {
return fmtString
}

View File

@ -3,14 +3,14 @@ package xair
import "fmt"
type Matrix struct {
client *client
client *Client
baseAddress string
Eq *Eq
Comp *Comp
}
// newMatrix creates a new Matrix instance
func newMatrix(c *client) *Matrix {
func newMatrix(c *Client) *Matrix {
return &Matrix{
client: c,
baseAddress: c.addressMap["matrix"],

View File

@ -1,8 +1,7 @@
package xair
type InfoResponse struct {
Host string
Name string
Model string
Firmware string
Host string
Name string
Model string
}

View File

@ -3,12 +3,12 @@ package xair
import "fmt"
type Snapshot struct {
client *client
client *Client
baseAddress string
}
// newSnapshot creates a new Snapshot instance
func newSnapshot(c *client) *Snapshot {
func newSnapshot(c *Client) *Snapshot {
return &Snapshot{
client: c,
baseAddress: c.addressMap["snapshot"],

View File

@ -3,7 +3,7 @@ package xair
import "fmt"
type Strip struct {
client *client
client *Client
baseAddress string
Gate *Gate
Eq *Eq
@ -11,7 +11,7 @@ type Strip struct {
}
// newStrip creates a new Strip instance
func newStrip(c *client) *Strip {
func newStrip(c *Client) *Strip {
return &Strip{
client: c,
baseAddress: c.addressMap["strip"],

View File

@ -12,9 +12,10 @@ Flags:
-v, --version Print x32-cli version information and quit
Commands:
completion Generate shell completion scripts.
info Print mixer information.
raw Send raw OSC messages to the mixer.
completion (c) Generate shell completion scripts.
Raw
raw Send raw OSC messages to the mixer.
Main
main mute Get or set the mute state of the Main L/R output.

View File

@ -12,9 +12,10 @@ Flags:
-v, --version Print xair-cli version information and quit
Commands:
completion Generate shell completion scripts.
info Print mixer information.
raw Send raw OSC messages to the mixer.
completion (c) Generate shell completion scripts.
Raw
raw Send raw OSC messages to the mixer.
Main
main mute Get or set the mute state of the Main L/R output.