6 Commits

Author SHA1 Message Date
a9110f0986 implement strip/bus gate/comp on commands 2026-02-01 15:50:11 +00:00
72f43452a8 pass pointers to factory methods 2026-02-01 15:09:45 +00:00
89ab8ee258 setup the skeletal structure for Eq, Comp and Gate.
implement strip/bus eq on commands.
2026-02-01 15:09:38 +00:00
c4a86adf14 upd fadeout main lr desc 2026-02-01 04:17:55 +00:00
1623b53cff headamp gain now accepts a --duration flag for safe gain staging. 2026-02-01 04:15:59 +00:00
98e131d4ad reword 2026-02-01 03:43:21 +00:00
13 changed files with 609 additions and 56 deletions

View File

@@ -38,22 +38,20 @@ Use "xair-cli [command] --help" for more information about a command.
### Examples
Things that are possible with this CLI:
*Fade out main LR all the way to -∞*
*Fade out main LR all the way to -∞ over a 5s duration*
```console
xair-cli main fadeout
```
*enable phantom power and set the gain to 28dB for strip 09*
*enable phantom power and set the gain to 28.0dB over a 10s duration for strip 09*
```console
xair-cli headamp 9 phantom on
xair-cli headamp 9 gain 28
xair-cli headamp 9 gain 28.0 --duration 10s
```
*adjust strip 09 send level to bus 5*
*set strip 09 send level for bus 5 to -18.0dB*
```console
xair-cli strip send 9 5 -- -18.0
```

View File

@@ -104,7 +104,7 @@ var busFadeOutCmd = &cobra.Command{
Long: "Fade out the bus fader to minimum level over a specified duration in seconds.",
Use: "fadeout [bus number] --duration [seconds] [target level in dB]",
Example: ` # Fade out bus 1 over 5 seconds
xair-cli bus fadeout 1 --duration 5 -- -90.0`,
xair-cli bus fadeout 1 --duration 5s -- -90.0`,
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
@@ -117,7 +117,7 @@ var busFadeOutCmd = &cobra.Command{
busIndex := mustConvToInt(args[0])
duration, err := cmd.Flags().GetFloat64("duration")
duration, err := cmd.Flags().GetDuration("duration")
if err != nil {
return fmt.Errorf("Error getting duration flag: %w", err)
}
@@ -139,7 +139,7 @@ var busFadeOutCmd = &cobra.Command{
return nil
}
stepDelay := time.Duration(duration*1000/totalSteps) * time.Millisecond
stepDelay := time.Duration(duration.Seconds()*1000/totalSteps) * time.Millisecond
for currentFader > target {
currentFader -= 1.0
@@ -161,7 +161,7 @@ var busFadeInCmd = &cobra.Command{
Long: "Fade in the bus fader to maximum level over a specified duration in seconds.",
Use: "fadein [bus number] --duration [seconds] [target level in dB]",
Example: ` # Fade in bus 1 over 5 seconds
xair-cli bus fadein 1 --duration 5 -- 0.0`,
xair-cli bus fadein 1 --duration 5s -- 0.0`,
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
@@ -174,7 +174,7 @@ var busFadeInCmd = &cobra.Command{
busIndex := mustConvToInt(args[0])
duration, err := cmd.Flags().GetFloat64("duration")
duration, err := cmd.Flags().GetDuration("duration")
if err != nil {
return fmt.Errorf("Error getting duration flag: %w", err)
}
@@ -196,7 +196,7 @@ var busFadeInCmd = &cobra.Command{
return nil
}
stepDelay := time.Duration(duration*1000/totalSteps) * time.Millisecond
stepDelay := time.Duration(duration.Seconds()*1000/totalSteps) * time.Millisecond
for currentFader < target {
currentFader += 1.0
@@ -254,16 +254,112 @@ var busNameCmd = &cobra.Command{
},
}
// busEqCmd represents the bus EQ command.
var busEqCmd = &cobra.Command{
Short: "Commands to control bus EQ settings",
Long: `Commands to control the EQ of individual buses, including turning the EQ on or off.`,
Use: "eq",
Run: func(cmd *cobra.Command, _ []string) {
cmd.Help()
},
}
// busEqOnCmd represents the bus EQ on/off command.
var busEqOnCmd = &cobra.Command{
Short: "Get or set the bus EQ on/off status",
Long: `Get or set the EQ on/off status of a specific bus.`,
Use: "on [bus number] [true|false]",
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 2 {
return fmt.Errorf("Please provide bus number and EQ on status (true/false)")
}
busNum := mustConvToInt(args[0])
var eqOn bool
switch args[1] {
case "true", "1":
eqOn = true
case "false", "0":
eqOn = false
default:
return fmt.Errorf("Invalid EQ on status. Use true/false or 1/0")
}
err := client.Bus.Eq.SetOn(busNum, eqOn)
if err != nil {
return fmt.Errorf("Error setting bus EQ on status: %w", err)
}
cmd.Printf("Bus %d EQ on set to %v\n", busNum, eqOn)
return nil
},
}
// busCompCmd represents the bus Compressor command.
var busCompCmd = &cobra.Command{
Short: "Commands to control bus Compressor settings",
Long: `Commands to control the Compressor of individual buses, including turning the Compressor on or off.`,
Use: "comp",
Run: func(cmd *cobra.Command, _ []string) {
cmd.Help()
},
}
// busCompOnCmd represents the bus Compressor on/off command.
var busCompOnCmd = &cobra.Command{
Short: "Get or set the bus Compressor on/off status",
Long: `Get or set the Compressor on/off status of a specific bus.`,
Use: "on [bus number] [true|false]",
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 2 {
return fmt.Errorf("Please provide bus number and Compressor on status (true/false)")
}
busNum := mustConvToInt(args[0])
var compOn bool
switch args[1] {
case "true", "1":
compOn = true
case "false", "0":
compOn = false
default:
return fmt.Errorf("Invalid Compressor on status. Use true/false or 1/0")
}
err := client.Bus.Comp.SetOn(busNum, compOn)
if err != nil {
return fmt.Errorf("Error setting bus Compressor on status: %w", err)
}
cmd.Printf("Bus %d Compressor on set to %v\n", busNum, compOn)
return nil
},
}
func init() {
rootCmd.AddCommand(busCmd)
busCmd.AddCommand(busMuteCmd)
busCmd.AddCommand(busFaderCmd)
busCmd.AddCommand(busFadeOutCmd)
busFadeOutCmd.Flags().Float64P("duration", "d", 5.0, "Duration for fade out in seconds")
busFadeOutCmd.Flags().DurationP("duration", "d", 5*time.Second, "Duration for fade out in seconds")
busCmd.AddCommand(busFadeInCmd)
busFadeInCmd.Flags().Float64P("duration", "d", 5.0, "Duration for fade in in seconds")
busFadeInCmd.Flags().DurationP("duration", "d", 5*time.Second, "Duration for fade in in seconds")
busCmd.AddCommand(busNameCmd)
busCmd.AddCommand(busEqCmd)
busEqCmd.AddCommand(busEqOnCmd)
busCmd.AddCommand(busCompCmd)
busCompCmd.AddCommand(busCompOnCmd)
}

View File

@@ -2,7 +2,10 @@ package cmd
import (
"fmt"
"time"
"github.com/charmbracelet/log"
"github.com/onyx-and-iris/xair-cli/internal/xair"
"github.com/spf13/cobra"
)
@@ -23,12 +26,16 @@ var headampGainCmd = &cobra.Command{
Use: "gain",
Short: "Get or set headamp gain level",
Long: `Get or set the gain level for a specified headamp index.
When setting gain, it will gradually increase from the current level to prevent
sudden jumps that could cause feedback or equipment damage.
Examples:
# Get gain level for headamp index 1
xairctl headamp gain 1
# Set gain level for headamp index 1 to 3.5 dB
xairctl headamp gain 1 3.5`,
xair-cli headamp gain 1
# Set gain level for headamp index 1 to 3.5 dB (gradually over 5 seconds)
xair-cli headamp gain 1 3.5
# Set gain level for headamp index 1 to 3.5 dB over 10 seconds
xair-cli headamp gain 1 3.5 --duration 10s`,
Args: cobra.RangeArgs(1, 2),
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
@@ -55,18 +62,79 @@ Examples:
return fmt.Errorf("Please provide a gain level in dB")
}
level := mustConvToFloat64(args[1])
targetLevel := mustConvToFloat64(args[1])
err := client.HeadAmp.SetGain(index, level)
currentGain, err := client.HeadAmp.Gain(index)
if err != nil {
return fmt.Errorf("Error setting headamp gain level: %w", err)
return fmt.Errorf("Error getting current headamp gain level: %w", err)
}
cmd.Printf("Headamp %d Gain set to %.2f dB\n", index, level)
duration, err := cmd.Flags().GetDuration("duration")
if err != nil {
return fmt.Errorf("Error getting duration flag: %w", err)
}
if currentGain == targetLevel {
cmd.Printf("Headamp %d Gain already at %.2f dB\n", index, targetLevel)
return nil
}
if err := gradualGainAdjust(client, cmd, index, currentGain, targetLevel, duration); err != nil {
return fmt.Errorf("Error adjusting headamp gain level: %w", err)
}
cmd.Printf("Headamp %d Gain set to %.2f dB\n", index, targetLevel)
return nil
},
}
// gradualGainAdjust gradually adjusts gain from current to target over specified duration
func gradualGainAdjust(
client *xair.Client,
cmd *cobra.Command,
index int,
currentGain, targetGain float64,
duration time.Duration,
) error {
gainDiff := targetGain - currentGain
stepInterval := 100 * time.Millisecond
totalSteps := int(duration / stepInterval)
if totalSteps < 1 {
totalSteps = 1
stepInterval = duration
}
stepIncrement := gainDiff / float64(totalSteps)
log.Debugf("Adjusting Headamp %d gain from %.2f dB to %.2f dB over %v...\n",
index, currentGain, targetGain, duration)
for step := 1; step <= totalSteps; step++ {
newGain := currentGain + (stepIncrement * float64(step))
if step == totalSteps {
newGain = targetGain
}
err := client.HeadAmp.SetGain(index, newGain)
if err != nil {
return err
}
if step%10 == 0 || step == totalSteps {
log.Debugf(" Step %d/%d: %.2f dB\n", step, totalSteps, newGain)
}
if step < totalSteps {
time.Sleep(stepInterval)
}
}
return nil
}
// headampPhantomPowerCmd represents the headamp phantom power command
var headampPhantomPowerCmd = &cobra.Command{
Use: "phantom",
@@ -137,5 +205,7 @@ func init() {
rootCmd.AddCommand(headampCmd)
headampCmd.AddCommand(headampGainCmd)
headampGainCmd.Flags().DurationP("duration", "d", 5*time.Second, "Duration over which to gradually adjust gain")
headampCmd.AddCommand(headampPhantomPowerCmd)
}

View File

@@ -116,7 +116,7 @@ This command will fade out the main output to the specified dB level.
`,
Use: "fadeout --duration [seconds] [target_db]",
Example: ` # Fade out main output over 5 seconds
xair-cli main fadeout --duration 5 -- -90.0`,
xair-cli main fadeout --duration 5s -- -90.0`,
Run: func(cmd *cobra.Command, args []string) {
client := ClientFromContext(cmd.Context())
if client == nil {
@@ -124,7 +124,7 @@ This command will fade out the main output to the specified dB level.
return
}
duration, err := cmd.Flags().GetFloat64("duration")
duration, err := cmd.Flags().GetDuration("duration")
if err != nil {
cmd.PrintErrln("Error getting duration flag:", err)
return
@@ -150,7 +150,7 @@ This command will fade out the main output to the specified dB level.
}
// Calculate delay per step to achieve exact duration
stepDelay := time.Duration(duration*1000/totalSteps) * time.Millisecond
stepDelay := time.Duration(duration.Seconds()*1000/totalSteps) * time.Millisecond
for currentFader > target {
currentFader -= 1.0
@@ -175,7 +175,7 @@ This command will fade in the main output to the specified dB level.
`,
Use: "fadein --duration [seconds] [target_db]",
Example: ` # Fade in main output over 5 seconds
xair-cli main fadein --duration 5 -- 0.0`,
xair-cli main fadein --duration 5s -- 0.0`,
Run: func(cmd *cobra.Command, args []string) {
client := ClientFromContext(cmd.Context())
if client == nil {
@@ -183,7 +183,7 @@ This command will fade in the main output to the specified dB level.
return
}
duration, err := cmd.Flags().GetFloat64("duration")
duration, err := cmd.Flags().GetDuration("duration")
if err != nil {
cmd.PrintErrln("Error getting duration flag:", err)
return
@@ -208,7 +208,7 @@ This command will fade in the main output to the specified dB level.
}
// Calculate delay per step to achieve exact duration
stepDelay := time.Duration(duration*1000/totalSteps) * time.Millisecond
stepDelay := time.Duration(duration.Seconds()*1000/totalSteps) * time.Millisecond
for currentFader < target {
currentFader += 1.0
@@ -231,7 +231,7 @@ func init() {
mainCmd.AddCommand(mainFaderCmd)
mainCmd.AddCommand(mainFadeOutCmd)
mainFadeOutCmd.Flags().Float64P("duration", "d", 5, "Duration for fade out in seconds")
mainFadeOutCmd.Flags().DurationP("duration", "d", 5*time.Second, "Duration for fade out in seconds")
mainCmd.AddCommand(mainFadeInCmd)
mainFadeInCmd.Flags().Float64P("duration", "d", 5, "Duration for fade in in seconds")
mainFadeInCmd.Flags().DurationP("duration", "d", 5*time.Second, "Duration for fade in in seconds")
}

View File

@@ -134,7 +134,7 @@ var stripFadeOutCmd = &cobra.Command{
Long: "Fade out the strip over a specified duration in seconds.",
Use: "fadeout [strip number] --duration [seconds] [target level in dB]",
Example: ` # Fade out strip 1 over 5 seconds
xair-cli strip fadeout 1 --duration 5.0 -- -90.0`,
xair-cli strip fadeout 1 --duration 5s -- -90.0`,
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
@@ -147,7 +147,7 @@ var stripFadeOutCmd = &cobra.Command{
stripIndex := mustConvToInt(args[0])
duration, err := cmd.Flags().GetFloat64("duration")
duration, err := cmd.Flags().GetDuration("duration")
if err != nil {
return fmt.Errorf("Error getting duration flag: %w", err)
}
@@ -168,7 +168,7 @@ var stripFadeOutCmd = &cobra.Command{
return nil
}
stepDelay := time.Duration(duration*1000/totalSteps) * time.Millisecond
stepDelay := time.Duration(duration.Seconds()*1000/totalSteps) * time.Millisecond
for currentFader > target {
currentFader -= 1.0
@@ -179,7 +179,7 @@ var stripFadeOutCmd = &cobra.Command{
time.Sleep(stepDelay)
}
cmd.Printf("Strip %d faded out to %.2f dB over %.2f seconds\n", stripIndex, target, duration)
cmd.Printf("Strip %d faded out to %.2f dB over %.2f seconds\n", stripIndex, target, duration.Seconds())
return nil
},
}
@@ -190,7 +190,7 @@ var stripFadeInCmd = &cobra.Command{
Long: "Fade in the strip over a specified duration in seconds.",
Use: "fadein [strip number] --duration [seconds] [target level in dB]",
Example: ` # Fade in strip 1 over 5 seconds
xair-cli strip fadein 1 --duration 5.0 0`,
xair-cli strip fadein 1 --duration 5s 0`,
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
@@ -203,7 +203,7 @@ var stripFadeInCmd = &cobra.Command{
stripIndex := mustConvToInt(args[0])
duration, err := cmd.Flags().GetFloat64("duration")
duration, err := cmd.Flags().GetDuration("duration")
if err != nil {
return fmt.Errorf("Error getting duration flag: %w", err)
}
@@ -224,7 +224,7 @@ var stripFadeInCmd = &cobra.Command{
return nil
}
stepDelay := time.Duration(duration*1000/totalSteps) * time.Millisecond
stepDelay := time.Duration(duration.Seconds()*1000/totalSteps) * time.Millisecond
for currentFader < target {
currentFader += 1.0
@@ -235,7 +235,7 @@ var stripFadeInCmd = &cobra.Command{
time.Sleep(stepDelay)
}
cmd.Printf("Strip %d faded in to %.2f dB over %.2f seconds\n", stripIndex, target, duration)
cmd.Printf("Strip %d faded in to %.2f dB over %.2f seconds\n", stripIndex, target, duration.Seconds())
return nil
},
}
@@ -333,18 +333,237 @@ If a name argument is provided, the strip name is set to that value.`,
},
}
// stripGateCmd represents the strip Gate command.
var stripGateCmd = &cobra.Command{
Short: "Commands to control the Gate of individual strips.",
Long: `Commands to control the Gate of individual strips, including turning the Gate on or off.`,
Use: "gate",
Run: func(cmd *cobra.Command, _ []string) {
cmd.Help()
},
}
// stripGateOnCmd represents the strip Gate on command.
var stripGateOnCmd = &cobra.Command{
Short: "Get or set the Gate on/off status of a strip",
Long: `Get or set the Gate on/off status of a specific strip.
If no status argument is provided, the current Gate status is retrieved.
If "true" or "1" is provided as an argument, the Gate is turned on.
If "false" or "0" is provided, the Gate is turned off.`,
Use: "on [strip number] [true|false]",
Example: ` # Get the current Gate status of strip 1
xair-cli strip gate on 1
# Turn on Gate for strip 1
xair-cli strip gate on 1 true
# Turn off Gate for strip 1
xair-cli strip gate on 1 false`,
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 1 {
return fmt.Errorf("Please provide a strip number")
}
stripIndex := mustConvToInt(args[0])
if len(args) == 1 {
on, err := client.Strip.Gate.On(stripIndex)
if err != nil {
return fmt.Errorf("Error getting strip Gate on status: %w", err)
}
cmd.Printf("Strip %d Gate on: %v\n", stripIndex, on)
return nil
}
var on bool
switch args[1] {
case "true", "1":
on = true
case "false", "0":
on = false
default:
return fmt.Errorf("Invalid Gate status. Use true/false or 1/0")
}
err := client.Strip.Gate.SetOn(stripIndex, on)
if err != nil {
return fmt.Errorf("Error setting strip Gate on status: %w", err)
}
if on {
cmd.Printf("Strip %d Gate turned on successfully\n", stripIndex)
} else {
cmd.Printf("Strip %d Gate turned off successfully\n", stripIndex)
}
return nil
},
}
// stripEqCmd represents the strip EQ command.
var stripEqCmd = &cobra.Command{
Short: "Commands to control the EQ of individual strips.",
Long: `Commands to control the EQ of individual strips, including turning the EQ on or off.`,
Use: "eq",
Run: func(cmd *cobra.Command, _ []string) {
cmd.Help()
},
}
// stripEqOnCmd represents the strip EQ on command.
var stripEqOnCmd = &cobra.Command{
Short: "Get or set the EQ on/off status of a strip",
Long: `Get or set the EQ on/off status of a specific strip.
If no status argument is provided, the current EQ status is retrieved.
If "true" or "1" is provided as an argument, the EQ is turned on.
If "false" or "0" is provided, the EQ is turned off.`,
Use: "on [strip number] [true|false]",
Example: ` # Get the current EQ status of strip 1
xair-cli strip eq on 1
# Turn on EQ for strip 1
xair-cli strip eq on 1 true
# Turn off EQ for strip 1
xair-cli strip eq on 1 false`,
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 1 {
return fmt.Errorf("Please provide a strip number")
}
stripIndex := mustConvToInt(args[0])
if len(args) == 1 {
on, err := client.Strip.Eq.On(stripIndex)
if err != nil {
return fmt.Errorf("Error getting strip EQ on status: %w", err)
}
cmd.Printf("Strip %d EQ on: %v\n", stripIndex, on)
return nil
}
var on bool
switch args[1] {
case "true", "1":
on = true
case "false", "0":
on = false
default:
return fmt.Errorf("Invalid EQ status. Use true/false or 1/0")
}
err := client.Strip.Eq.SetOn(stripIndex, on)
if err != nil {
return fmt.Errorf("Error setting strip EQ on status: %w", err)
}
if on {
cmd.Printf("Strip %d EQ turned on successfully\n", stripIndex)
} else {
cmd.Printf("Strip %d EQ turned off successfully\n", stripIndex)
}
return nil
},
}
// stripCompCmd represents the strip Compressor command.
var stripCompCmd = &cobra.Command{
Short: "Commands to control the Compressor of individual strips.",
Long: `Commands to control the Compressor of individual strips, including turning the Compressor on or off.`,
Use: "comp",
Run: func(cmd *cobra.Command, _ []string) {
cmd.Help()
},
}
// stripCompOnCmd represents the strip Compressor on command.
var stripCompOnCmd = &cobra.Command{
Short: "Get or set the Compressor on/off status of a strip",
Long: `Get or set the Compressor on/off status of a specific strip.
If no status argument is provided, the current Compressor status is retrieved.
If "true" or "1" is provided as an argument, the Compressor is turned on.
If "false" or "0" is provided, the Compressor is turned off.`,
Use: "on [strip number] [true|false]",
Example: ` # Get the current Compressor status of strip 1
xair-cli strip comp on 1
# Turn on Compressor for strip 1
xair-cli strip comp on 1 true
# Turn off Compressor for strip 1
xair-cli strip comp on 1 false`,
RunE: func(cmd *cobra.Command, args []string) error {
client := ClientFromContext(cmd.Context())
if client == nil {
return fmt.Errorf("OSC client not found in context")
}
if len(args) < 1 {
return fmt.Errorf("Please provide a strip number")
}
stripIndex := mustConvToInt(args[0])
if len(args) == 1 {
on, err := client.Strip.Comp.On(stripIndex)
if err != nil {
return fmt.Errorf("Error getting strip Compressor on status: %w", err)
}
cmd.Printf("Strip %d Compressor on: %v\n", stripIndex, on)
return nil
}
var on bool
switch args[1] {
case "true", "1":
on = true
case "false", "0":
on = false
default:
return fmt.Errorf("Invalid Compressor status. Use true/false or 1/0")
}
err := client.Strip.Comp.SetOn(stripIndex, on)
if err != nil {
return fmt.Errorf("Error setting strip Compressor on status: %w", err)
}
if on {
cmd.Printf("Strip %d Compressor turned on successfully\n", stripIndex)
} else {
cmd.Printf("Strip %d Compressor turned off successfully\n", stripIndex)
}
return nil
},
}
func init() {
rootCmd.AddCommand(stripCmd)
stripCmd.AddCommand(stripMuteCmd)
stripCmd.AddCommand(stripFaderCmd)
stripCmd.AddCommand(stripFadeOutCmd)
stripFadeOutCmd.Flags().Float64P("duration", "d", 5.0, "Duration of the fade out in seconds")
stripFadeOutCmd.Flags().DurationP("duration", "d", 5*time.Second, "Duration of the fade out in seconds")
stripCmd.AddCommand(stripFadeInCmd)
stripFadeInCmd.Flags().Float64P("duration", "d", 5.0, "Duration of the fade in in seconds")
stripFadeInCmd.Flags().DurationP("duration", "d", 5*time.Second, "Duration of the fade in in seconds")
stripCmd.AddCommand(stripSendCmd)
stripCmd.AddCommand(stripNameCmd)
stripCmd.AddCommand(stripGateCmd)
stripGateCmd.AddCommand(stripGateOnCmd)
stripCmd.AddCommand(stripEqCmd)
stripEqCmd.AddCommand(stripEqOnCmd)
stripCmd.AddCommand(stripCompCmd)
stripCompCmd.AddCommand(stripCompOnCmd)
}

View File

@@ -4,13 +4,17 @@ import "fmt"
type Bus struct {
baseAddress string
client Client
client *Client
Eq *Eq
Comp *Comp
}
func NewBus(c Client) *Bus {
func NewBus(c *Client) *Bus {
return &Bus{
baseAddress: c.addressMap["bus"],
client: c,
Eq: newEqForBus(c),
Comp: newCompForBus(c),
}
}

View File

@@ -58,10 +58,10 @@ func NewClient(mixerIP string, mixerPort int, opts ...Option) (*Client, error) {
c := &Client{
engine: *e,
}
c.Main = newMain(*c)
c.Strip = NewStrip(*c)
c.Bus = NewBus(*c)
c.HeadAmp = NewHeadAmp(*c)
c.Main = newMain(c)
c.Strip = NewStrip(c)
c.Bus = NewBus(c)
c.HeadAmp = NewHeadAmp(c)
return c, nil
}

50
internal/xair/comp.go Normal file
View File

@@ -0,0 +1,50 @@
package xair
import "fmt"
type Comp struct {
client *Client
baseAddress string
}
// Factory function to create Comp instance for Strip
func newCompForStrip(c *Client) *Comp {
return &Comp{
client: c,
baseAddress: c.addressMap["strip"],
}
}
// Factory function to create Comp instance for Bus
func newCompForBus(c *Client) *Comp {
return &Comp{
client: c,
baseAddress: c.addressMap["bus"],
}
}
// On retrieves the on/off status of the Compressor for a specific strip or bus (1-based indexing).
func (c *Comp) On(index int) (bool, error) {
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/on"
err := c.client.SendMessage(address)
if err != nil {
return false, err
}
resp := <-c.client.respChan
val, ok := resp.Arguments[0].(int32)
if !ok {
return false, fmt.Errorf("unexpected argument type for Compressor on value")
}
return val != 0, nil
}
// SetOn sets the on/off status of the Compressor for a specific strip or bus (1-based indexing).
func (c *Comp) SetOn(index int, on bool) error {
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/on"
var value int32
if on {
value = 1
}
return c.client.SendMessage(address, value)
}

72
internal/xair/eq.go Normal file
View File

@@ -0,0 +1,72 @@
package xair
import "fmt"
type Eq struct {
client *Client
baseAddress string
}
// Factory function to create Eq instance for Strip
func newEqForStrip(c *Client) *Eq {
return &Eq{
client: c,
baseAddress: c.addressMap["strip"],
}
}
// Factory function to create Eq instance for Bus
func newEqForBus(c *Client) *Eq {
return &Eq{
client: c,
baseAddress: c.addressMap["bus"],
}
}
// On retrieves the on/off status of the EQ for a specific strip or bus (1-based indexing).
func (e *Eq) On(index int) (bool, error) {
address := fmt.Sprintf(e.baseAddress, index) + "/eq/on"
err := e.client.SendMessage(address)
if err != nil {
return false, err
}
resp := <-e.client.respChan
val, ok := resp.Arguments[0].(int32)
if !ok {
return false, fmt.Errorf("unexpected argument type for EQ on value")
}
return val != 0, nil
}
// SetOn sets the on/off status of the EQ for a specific strip or bus (1-based indexing).
func (e *Eq) SetOn(index int, on bool) error {
address := fmt.Sprintf(e.baseAddress, index) + "/eq/on"
var value int32
if on {
value = 1
}
return e.client.SendMessage(address, value)
}
// Gain retrieves the gain for a specific EQ band on a strip or bus (1-based indexing).
func (e *Eq) Gain(index int, band int) (float64, error) {
address := fmt.Sprintf(e.baseAddress, index) + fmt.Sprintf("/eq/%d/g", band)
err := e.client.SendMessage(address)
if err != nil {
return 0, err
}
resp := <-e.client.respChan
val, ok := resp.Arguments[0].(float32)
if !ok {
return 0, fmt.Errorf("unexpected argument type for EQ gain value")
}
return float64(val), nil
}
// SetGain sets the gain for a specific EQ band on a strip or bus (1-based indexing).
func (e *Eq) SetGain(index int, band int, gain float64) error {
address := fmt.Sprintf(e.baseAddress, index) + fmt.Sprintf("/eq/%d/g", band)
return e.client.SendMessage(address, float32(gain))
}

38
internal/xair/gate.go Normal file
View File

@@ -0,0 +1,38 @@
package xair
import "fmt"
type Gate struct {
client *Client
baseAddress string
}
func newGate(c *Client) *Gate {
return &Gate{client: c, baseAddress: c.addressMap["strip"]}
}
// On retrieves the on/off status of the Gate for a specific strip (1-based indexing).
func (g *Gate) On(index int) (bool, error) {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/on"
err := g.client.SendMessage(address)
if err != nil {
return false, err
}
resp := <-g.client.respChan
val, ok := resp.Arguments[0].(int32)
if !ok {
return false, fmt.Errorf("unexpected argument type for Gate on value")
}
return val != 0, nil
}
// SetOn sets the on/off status of the Gate for a specific strip (1-based indexing).
func (g *Gate) SetOn(index int, on bool) error {
address := fmt.Sprintf(g.baseAddress, index) + "/gate/on"
var value int32
if on {
value = 1
}
return g.client.SendMessage(address, value)
}

View File

@@ -4,10 +4,10 @@ import "fmt"
type HeadAmp struct {
baseAddress string
client Client
client *Client
}
func NewHeadAmp(c Client) *HeadAmp {
func NewHeadAmp(c *Client) *HeadAmp {
return &HeadAmp{
baseAddress: c.addressMap["headamp"],
client: c,

View File

@@ -3,10 +3,10 @@ package xair
import "fmt"
type Main struct {
client Client
client *Client
}
func newMain(c Client) *Main {
func newMain(c *Client) *Main {
return &Main{
client: c,
}

View File

@@ -4,13 +4,19 @@ import "fmt"
type Strip struct {
baseAddress string
client Client
client *Client
Gate *Gate
Eq *Eq
Comp *Comp
}
func NewStrip(c Client) *Strip {
func NewStrip(c *Client) *Strip {
return &Strip{
baseAddress: c.addressMap["strip"],
client: c,
Gate: newGate(c),
Eq: newEqForStrip(c),
Comp: newCompForStrip(c),
}
}