mirror of
https://github.com/onyx-and-iris/xair-cli.git
synced 2026-02-04 07:27:47 +00:00
Compare commits
No commits in common. "main" and "v0.2.0" have entirely different histories.
52
README.md
52
README.md
@ -1,10 +1,4 @@
|
|||||||
# xair-cli
|
# Xair-CLI
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
```console
|
|
||||||
go install github.com/onyx-and-iris/xair-cli@latest
|
|
||||||
```
|
|
||||||
|
|
||||||
### Use
|
### Use
|
||||||
|
|
||||||
@ -20,7 +14,6 @@ Usage:
|
|||||||
Available Commands:
|
Available Commands:
|
||||||
bus Commands to control individual buses
|
bus Commands to control individual buses
|
||||||
completion Generate the autocompletion script for the specified shell
|
completion Generate the autocompletion script for the specified shell
|
||||||
headamp Commands to control headamp gain and phantom power
|
|
||||||
help Help about any command
|
help Help about any command
|
||||||
main Commands to control the main output
|
main Commands to control the main output
|
||||||
strip Commands to control individual strips
|
strip Commands to control individual strips
|
||||||
@ -31,49 +24,6 @@ Flags:
|
|||||||
-k, --kind string Kind of mixer (xair, x32) (default "xair")
|
-k, --kind string Kind of mixer (xair, x32) (default "xair")
|
||||||
-l, --loglevel string Log level (debug, info, warn, error, fatal, panic) (default "warn")
|
-l, --loglevel string Log level (debug, info, warn, error, fatal, panic) (default "warn")
|
||||||
-p, --port int Port number of the X Air mixer (default 10024)
|
-p, --port int Port number of the X Air mixer (default 10024)
|
||||||
-v, --version version for xair-cli
|
|
||||||
|
|
||||||
Use "xair-cli [command] --help" for more information about a command.
|
Use "xair-cli [command] --help" for more information about a command.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
*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 28.0dB over a 10s duration for strip 09*
|
|
||||||
```console
|
|
||||||
xair-cli headamp phantom 9 on
|
|
||||||
|
|
||||||
xair-cli headamp gain 9 28.0 --duration 10s
|
|
||||||
```
|
|
||||||
|
|
||||||
*set strip 09 send level for bus 5 to -18.0dB*
|
|
||||||
```console
|
|
||||||
xair-cli strip send 9 5 -- -18.0
|
|
||||||
```
|
|
||||||
|
|
||||||
*enable eq for strip 01*
|
|
||||||
```console
|
|
||||||
xair-cli strip eq on 1 true
|
|
||||||
```
|
|
||||||
|
|
||||||
*rename bus 01 to 'vocal mix'*
|
|
||||||
```console
|
|
||||||
xair-cli bus name 1 'vocal mix'
|
|
||||||
```
|
|
||||||
|
|
||||||
For every command/subcommand there exists a `--help` flag which you can use to get usage information.
|
|
||||||
|
|
||||||
|
|
||||||
### Notes
|
|
||||||
|
|
||||||
This CLI is useful if just want to run some commands on the terminal using a single binary, no further downloads. However, there exists an alternative you should check out that has wider support of the XAir OSC protocol including support for operations like batch commands and network discovery (which I have no plans to implement on this CLI). Check out [dc-xair-cli](https://pypi.org/project/dc-xair-cli/) on pypi.
|
|
||||||
|
|
||||||
|
|
||||||
### License
|
|
||||||
|
|
||||||
`xair-cli` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
|
|
||||||
|
|||||||
761
cmd/bus.go
761
cmd/bus.go
@ -1,7 +1,6 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -22,14 +21,16 @@ var busMuteCmd = &cobra.Command{
|
|||||||
Short: "Get or set the bus mute status",
|
Short: "Get or set the bus mute status",
|
||||||
Long: `Get or set the mute status of a specific bus.`,
|
Long: `Get or set the mute status of a specific bus.`,
|
||||||
Use: "mute [bus number] [true|false]",
|
Use: "mute [bus number] [true|false]",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
client := ClientFromContext(cmd.Context())
|
client := ClientFromContext(cmd.Context())
|
||||||
if client == nil {
|
if client == nil {
|
||||||
return fmt.Errorf("OSC client not found in context")
|
cmd.PrintErrln("OSC client not found in context")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
return fmt.Errorf("Please provide bus number and mute status (true/false)")
|
cmd.PrintErrln("Please provide bus number and mute status (true/false)")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
busNum := mustConvToInt(args[0])
|
busNum := mustConvToInt(args[0])
|
||||||
@ -40,16 +41,16 @@ var busMuteCmd = &cobra.Command{
|
|||||||
case "false", "0":
|
case "false", "0":
|
||||||
muted = false
|
muted = false
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Invalid mute status. Use true/false or 1/0")
|
cmd.PrintErrln("Invalid mute status. Use true/false or 1/0")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := client.Bus.SetMute(busNum, muted)
|
err := client.Bus.SetMute(busNum, muted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error setting bus mute status: %w", err)
|
cmd.PrintErrln("Error setting bus mute status:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Printf("Bus %d mute set to %v\n", busNum, muted)
|
cmd.Printf("Bus %d mute set to %v\n", busNum, muted)
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,10 +66,11 @@ If a level argument (in dB) is provided, the bus fader is set to that level.`,
|
|||||||
|
|
||||||
# Set the fader level of bus 1 to -10.0 dB
|
# Set the fader level of bus 1 to -10.0 dB
|
||||||
xair-cli bus fader 1 -10.0`,
|
xair-cli bus fader 1 -10.0`,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
client := ClientFromContext(cmd.Context())
|
client := ClientFromContext(cmd.Context())
|
||||||
if client == nil {
|
if client == nil {
|
||||||
return fmt.Errorf("OSC client not found in context")
|
cmd.PrintErrln("OSC client not found in context")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
busIndex := mustConvToInt(args[0])
|
||||||
@ -76,25 +78,26 @@ If a level argument (in dB) is provided, the bus fader is set to that level.`,
|
|||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
level, err := client.Bus.Fader(busIndex)
|
level, err := client.Bus.Fader(busIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting bus fader level: %w", err)
|
cmd.PrintErrln("Error getting bus fader level:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
cmd.Printf("Bus %d fader level: %.1f dB\n", busIndex, level)
|
cmd.Printf("Bus %d fader level: %.1f dB\n", busIndex, level)
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
return fmt.Errorf("Please provide bus number and fader level (in dB)")
|
cmd.PrintErrln("Please provide bus number and fader level (in dB)")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
level := mustConvToFloat64(args[1])
|
level := mustConvToFloat64(args[1])
|
||||||
|
|
||||||
err := client.Bus.SetFader(busIndex, level)
|
err := client.Bus.SetFader(busIndex, level)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error setting bus fader level: %w", err)
|
cmd.PrintErrln("Error setting bus fader level:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Printf("Bus %d fader set to %.2f dB\n", busIndex, level)
|
cmd.Printf("Bus %d fader set to %.2f dB\n", busIndex, level)
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,22 +107,25 @@ var busFadeOutCmd = &cobra.Command{
|
|||||||
Long: "Fade out the bus fader to minimum level over a specified duration in seconds.",
|
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]",
|
Use: "fadeout [bus number] --duration [seconds] [target level in dB]",
|
||||||
Example: ` # Fade out bus 1 over 5 seconds
|
Example: ` # Fade out bus 1 over 5 seconds
|
||||||
xair-cli bus fadeout 1 --duration 5s -- -90.0`,
|
xair-cli bus fadeout 1 --duration 5 -- -90.0`,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
client := ClientFromContext(cmd.Context())
|
client := ClientFromContext(cmd.Context())
|
||||||
if client == nil {
|
if client == nil {
|
||||||
return fmt.Errorf("OSC client not found in context")
|
cmd.PrintErrln("OSC client not found in context")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return fmt.Errorf("Please provide bus number")
|
cmd.PrintErrln("Please provide bus number")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
busIndex := mustConvToInt(args[0])
|
||||||
|
|
||||||
duration, err := cmd.Flags().GetDuration("duration")
|
duration, err := cmd.Flags().GetFloat64("duration")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting duration flag: %w", err)
|
cmd.PrintErrln("Error getting duration flag:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
target := -90.0
|
target := -90.0
|
||||||
@ -129,29 +135,30 @@ var busFadeOutCmd = &cobra.Command{
|
|||||||
|
|
||||||
currentFader, err := client.Bus.Fader(busIndex)
|
currentFader, err := client.Bus.Fader(busIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting current bus fader level: %w", err)
|
cmd.PrintErrln("Error getting current bus fader level:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate total steps needed to reach target dB
|
// Calculate total steps needed to reach target dB
|
||||||
totalSteps := float64(currentFader - target)
|
totalSteps := float64(currentFader - target)
|
||||||
if totalSteps <= 0 {
|
if totalSteps <= 0 {
|
||||||
cmd.Println("Bus is already at or below target level")
|
cmd.Println("Bus is already at or below target level")
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
stepDelay := time.Duration(duration.Seconds()*1000/totalSteps) * time.Millisecond
|
stepDelay := time.Duration(duration*1000/totalSteps) * time.Millisecond
|
||||||
|
|
||||||
for currentFader > target {
|
for currentFader > target {
|
||||||
currentFader -= 1.0
|
currentFader -= 1.0
|
||||||
err := client.Bus.SetFader(busIndex, currentFader)
|
err := client.Bus.SetFader(busIndex, currentFader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error setting bus fader level: %w", err)
|
cmd.PrintErrln("Error setting bus fader level:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
time.Sleep(stepDelay)
|
time.Sleep(stepDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Bus fade out completed")
|
cmd.Println("Bus fade out completed")
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,22 +168,25 @@ var busFadeInCmd = &cobra.Command{
|
|||||||
Long: "Fade in the bus fader to maximum level over a specified duration in seconds.",
|
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]",
|
Use: "fadein [bus number] --duration [seconds] [target level in dB]",
|
||||||
Example: ` # Fade in bus 1 over 5 seconds
|
Example: ` # Fade in bus 1 over 5 seconds
|
||||||
xair-cli bus fadein 1 --duration 5s -- 0.0`,
|
xair-cli bus fadein 1 --duration 5 -- 0.0`,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
client := ClientFromContext(cmd.Context())
|
client := ClientFromContext(cmd.Context())
|
||||||
if client == nil {
|
if client == nil {
|
||||||
return fmt.Errorf("OSC client not found in context")
|
cmd.PrintErrln("OSC client not found in context")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return fmt.Errorf("Please provide bus number")
|
cmd.PrintErrln("Please provide bus number")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
busIndex := mustConvToInt(args[0])
|
||||||
|
|
||||||
duration, err := cmd.Flags().GetDuration("duration")
|
duration, err := cmd.Flags().GetFloat64("duration")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting duration flag: %w", err)
|
cmd.PrintErrln("Error getting duration flag:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
target := 0.0
|
target := 0.0
|
||||||
@ -186,679 +196,30 @@ var busFadeInCmd = &cobra.Command{
|
|||||||
|
|
||||||
currentFader, err := client.Bus.Fader(busIndex)
|
currentFader, err := client.Bus.Fader(busIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting current bus fader level: %w", err)
|
cmd.PrintErrln("Error getting current bus fader level:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate total steps needed to reach target dB
|
// Calculate total steps needed to reach target dB
|
||||||
totalSteps := float64(target - currentFader)
|
totalSteps := float64(target - currentFader)
|
||||||
if totalSteps <= 0 {
|
if totalSteps <= 0 {
|
||||||
cmd.Println("Bus is already at or above target level")
|
cmd.Println("Bus is already at or above target level")
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
stepDelay := time.Duration(duration.Seconds()*1000/totalSteps) * time.Millisecond
|
stepDelay := time.Duration(duration*1000/totalSteps) * time.Millisecond
|
||||||
|
|
||||||
for currentFader < target {
|
for currentFader < target {
|
||||||
currentFader += 1.0
|
currentFader += 1.0
|
||||||
err := client.Bus.SetFader(busIndex, currentFader)
|
err := client.Bus.SetFader(busIndex, currentFader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error setting bus fader level: %w", err)
|
cmd.PrintErrln("Error setting bus fader level:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
time.Sleep(stepDelay)
|
time.Sleep(stepDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Bus fade in completed")
|
cmd.Println("Bus fade in completed")
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busNameCmd represents the bus name command.
|
|
||||||
var busNameCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus name",
|
|
||||||
Long: `Get or set the name of a specific bus.`,
|
|
||||||
Use: "name [bus number] [new name]",
|
|
||||||
Example: ` # Get the name of bus 1
|
|
||||||
xair-cli bus name 1
|
|
||||||
|
|
||||||
# Set the name of bus 1 to "Vocals"
|
|
||||||
xair-cli bus name 1 Vocals`,
|
|
||||||
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 bus number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
|
||||||
name, err := client.Bus.Name(busIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus name: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d name: %s\n", busIndex, name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
newName := args[1]
|
|
||||||
err := client.Bus.SetName(busIndex, newName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus name: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d name set to: %s\n", busIndex, newName)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busEqModeCmd represents the bus EQ mode command.
|
|
||||||
var busEqModeCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus EQ mode",
|
|
||||||
Long: `Get or set the EQ mode of a specific bus.`,
|
|
||||||
Use: "mode [bus number] [mode]",
|
|
||||||
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 bus number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
|
||||||
|
|
||||||
modeNames := []string{"peq", "geq", "teq"}
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
|
||||||
mode, err := client.Bus.Eq.Mode(busIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus EQ mode: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d EQ mode: %s\n", busIndex, modeNames[mode])
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
mode := indexOf(modeNames, args[1])
|
|
||||||
if mode == -1 {
|
|
||||||
return fmt.Errorf("Invalid EQ mode. Valid modes are: %v", modeNames)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.Bus.Eq.SetMode(busIndex, mode)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus EQ mode: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d EQ mode set to %s\n", busIndex, modeNames[mode])
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busEqGainCmd represents the bus EQ gain command.
|
|
||||||
var busEqGainCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus EQ gain for a specific band",
|
|
||||||
Long: `Get or set the EQ gain (in dB) for a specific band of a bus.
|
|
||||||
|
|
||||||
Gain values range from -15.0 dB to +15.0 dB.`,
|
|
||||||
Use: "gain [bus number] [band number] [gain in dB]",
|
|
||||||
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 band number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex, bandIndex := func() (int, int) {
|
|
||||||
return mustConvToInt(args[0]), mustConvToInt(args[1])
|
|
||||||
}()
|
|
||||||
|
|
||||||
if len(args) == 2 {
|
|
||||||
gain, err := client.Bus.Eq.Gain(busIndex, bandIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus EQ gain: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d EQ band %d gain: %.1f dB\n", busIndex, bandIndex, gain)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 3 {
|
|
||||||
return fmt.Errorf("Please provide bus number, band number, and gain (in dB)")
|
|
||||||
}
|
|
||||||
|
|
||||||
gain := mustConvToFloat64(args[2])
|
|
||||||
|
|
||||||
err := client.Bus.Eq.SetGain(busIndex, bandIndex, gain)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus EQ gain: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d EQ band %d gain set to %.1f dB\n", busIndex, bandIndex, gain)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busEqFreqCmd represents the bus EQ frequency command.
|
|
||||||
var busEqFreqCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus EQ frequency for a specific band",
|
|
||||||
Long: `Get or set the EQ frequency (in Hz) for a specific band of a bus.`,
|
|
||||||
Use: "freq [bus number] [band number] [frequency in Hz]",
|
|
||||||
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 band number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex, bandIndex := func() (int, int) {
|
|
||||||
return mustConvToInt(args[0]), mustConvToInt(args[1])
|
|
||||||
}()
|
|
||||||
|
|
||||||
if len(args) == 2 {
|
|
||||||
freq, err := client.Bus.Eq.Frequency(busIndex, bandIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus EQ frequency: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d EQ band %d frequency: %.1f Hz\n", busIndex, bandIndex, freq)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 3 {
|
|
||||||
return fmt.Errorf("Please provide bus number, band number, and frequency (in Hz)")
|
|
||||||
}
|
|
||||||
|
|
||||||
freq := mustConvToFloat64(args[2])
|
|
||||||
|
|
||||||
err := client.Bus.Eq.SetFrequency(busIndex, bandIndex, freq)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus EQ frequency: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d EQ band %d frequency set to %.1f Hz\n", busIndex, bandIndex, freq)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busEqQCmd represents the bus EQ Q command.
|
|
||||||
var busEqQCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus EQ Q factor for a specific band",
|
|
||||||
Long: `Get or set the EQ Q factor for a specific band of a bus.`,
|
|
||||||
Use: "q [bus number] [band number] [Q factor]",
|
|
||||||
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 band number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex, bandIndex := func() (int, int) {
|
|
||||||
return mustConvToInt(args[0]), mustConvToInt(args[1])
|
|
||||||
}()
|
|
||||||
|
|
||||||
if len(args) == 2 {
|
|
||||||
qFactor, err := client.Bus.Eq.Q(busIndex, bandIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus EQ Q factor: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d EQ band %d Q factor: %.2f\n", busIndex, bandIndex, qFactor)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 3 {
|
|
||||||
return fmt.Errorf("Please provide bus number, band number, and Q factor")
|
|
||||||
}
|
|
||||||
|
|
||||||
qFactor := mustConvToFloat64(args[2])
|
|
||||||
|
|
||||||
err := client.Bus.Eq.SetQ(busIndex, bandIndex, qFactor)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus EQ Q factor: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d EQ band %d Q factor set to %.2f\n", busIndex, bandIndex, qFactor)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busEqTypeCmd represents the bus EQ type command.
|
|
||||||
var busEqTypeCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus EQ band type",
|
|
||||||
Long: `Get or set the EQ band type for a specific band of a bus.`,
|
|
||||||
Use: "type [bus number] [band number] [type]",
|
|
||||||
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 band number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex, bandIndex := func() (int, int) {
|
|
||||||
return mustConvToInt(args[0]), mustConvToInt(args[1])
|
|
||||||
}()
|
|
||||||
|
|
||||||
eqTypeNames := []string{"lcut", "lshv", "peq", "veq", "hshv", "hcut"}
|
|
||||||
|
|
||||||
if len(args) == 2 {
|
|
||||||
currentType, err := client.Bus.Eq.Type(busIndex, bandIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus EQ band type: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d EQ band %d type: %s\n", busIndex, bandIndex, eqTypeNames[currentType])
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
eqType := indexOf(eqTypeNames, args[2])
|
|
||||||
if eqType == -1 {
|
|
||||||
return fmt.Errorf("Invalid EQ band type. Valid types are: %v", eqTypeNames)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.Bus.Eq.SetType(busIndex, bandIndex, eqType)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus EQ band type: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d EQ band %d type set to %s\n", busIndex, bandIndex, eqTypeNames[eqType])
|
|
||||||
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
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busCompThresholdCmd represents the bus Compressor threshold command.
|
|
||||||
var busCompThresholdCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus Compressor threshold",
|
|
||||||
Long: `Get or set the Compressor threshold (in dB) for a specific bus.`,
|
|
||||||
Use: "threshold [bus number] [threshold in dB]",
|
|
||||||
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 bus number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
|
||||||
threshold, err := client.Bus.Comp.Threshold(busIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus Compressor threshold: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d Compressor threshold: %.1f dB\n", busIndex, threshold)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 2 {
|
|
||||||
return fmt.Errorf("Please provide bus number and threshold (in dB)")
|
|
||||||
}
|
|
||||||
|
|
||||||
threshold := mustConvToFloat64(args[1])
|
|
||||||
|
|
||||||
err := client.Bus.Comp.SetThreshold(busIndex, threshold)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus Compressor threshold: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d Compressor threshold set to %.1f dB\n", busIndex, threshold)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busCompRatioCmd represents the bus Compressor ratio command.
|
|
||||||
var busCompRatioCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus Compressor ratio",
|
|
||||||
Long: `Get or set the Compressor ratio for a specific bus.`,
|
|
||||||
Use: "ratio [bus number] [ratio]",
|
|
||||||
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 bus number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
|
||||||
ratio, err := client.Bus.Comp.Ratio(busIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus Compressor ratio: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d Compressor ratio: %.2f\n", busIndex, ratio)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 2 {
|
|
||||||
return fmt.Errorf("Please provide bus number and ratio")
|
|
||||||
}
|
|
||||||
|
|
||||||
ratio := mustConvToFloat64(args[1])
|
|
||||||
|
|
||||||
err := client.Bus.Comp.SetRatio(busIndex, ratio)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus Compressor ratio: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d Compressor ratio set to %.2f\n", busIndex, ratio)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busMixCmd represents the bus Compressor mix command.
|
|
||||||
var busCompMixCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus Compressor mix",
|
|
||||||
Long: `Get or set the Compressor mix (0-100%) for a specific bus.`,
|
|
||||||
Use: "mix [bus number] [mix percentage]",
|
|
||||||
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 bus number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
|
||||||
mix, err := client.Bus.Comp.Mix(busIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus Compressor mix: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d Compressor mix: %.1f%%\n", busIndex, mix)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 2 {
|
|
||||||
return fmt.Errorf("Please provide bus number and mix percentage")
|
|
||||||
}
|
|
||||||
|
|
||||||
mix := mustConvToFloat64(args[1])
|
|
||||||
|
|
||||||
err := client.Bus.Comp.SetMix(busIndex, mix)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus Compressor mix: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d Compressor mix set to %.1f%%\n", busIndex, mix)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busMakeUpCmd represents the bus Compressor make-up gain command.
|
|
||||||
var busCompMakeUpCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus Compressor make-up gain",
|
|
||||||
Long: `Get or set the Compressor make-up gain (in dB) for a specific bus.`,
|
|
||||||
Use: "makeup [bus number] [make-up gain in dB]",
|
|
||||||
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 bus number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
|
||||||
makeUp, err := client.Bus.Comp.MakeUp(busIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus Compressor make-up gain: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d Compressor make-up gain: %.1f dB\n", busIndex, makeUp)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 2 {
|
|
||||||
return fmt.Errorf("Please provide bus number and make-up gain (in dB)")
|
|
||||||
}
|
|
||||||
|
|
||||||
makeUp := mustConvToFloat64(args[1])
|
|
||||||
|
|
||||||
err := client.Bus.Comp.SetMakeUp(busIndex, makeUp)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus Compressor make-up gain: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d Compressor make-up gain set to %.1f dB\n", busIndex, makeUp)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busAttackCmd represents the bus Compressor attack time command.
|
|
||||||
var busCompAttackCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus Compressor attack time",
|
|
||||||
Long: `Get or set the Compressor attack time (in milliseconds) for a specific bus.`,
|
|
||||||
Use: "attack [bus number] [attack time in ms]",
|
|
||||||
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 bus number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
|
||||||
attack, err := client.Bus.Comp.Attack(busIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus Compressor attack time: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d Compressor attack time: %.1f ms\n", busIndex, attack)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 2 {
|
|
||||||
return fmt.Errorf("Please provide bus number and attack time (in ms)")
|
|
||||||
}
|
|
||||||
|
|
||||||
attack := mustConvToFloat64(args[1])
|
|
||||||
|
|
||||||
err := client.Bus.Comp.SetAttack(busIndex, attack)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus Compressor attack time: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d Compressor attack time set to %.1f ms\n", busIndex, attack)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busHoldCmd represents the bus Compressor hold time command.
|
|
||||||
var busCompHoldCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus Compressor hold time",
|
|
||||||
Long: `Get or set the Compressor hold time (in milliseconds) for a specific bus.`,
|
|
||||||
Use: "hold [bus number] [hold time in ms]",
|
|
||||||
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 bus number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
|
||||||
hold, err := client.Bus.Comp.Hold(busIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus Compressor hold time: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d Compressor hold time: %.2f ms\n", busIndex, hold)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 2 {
|
|
||||||
return fmt.Errorf("Please provide bus number and hold time (in ms)")
|
|
||||||
}
|
|
||||||
|
|
||||||
hold := mustConvToFloat64(args[1])
|
|
||||||
|
|
||||||
err := client.Bus.Comp.SetHold(busIndex, hold)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus Compressor hold time: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d Compressor hold time set to %.2f ms\n", busIndex, hold)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// busReleaseCmd represents the bus Compressor release time command.
|
|
||||||
var busCompReleaseCmd = &cobra.Command{
|
|
||||||
Short: "Get or set the bus Compressor release time",
|
|
||||||
Long: `Get or set the Compressor release time (in milliseconds) for a specific bus.`,
|
|
||||||
Use: "release [bus number] [release time in ms]",
|
|
||||||
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 bus number")
|
|
||||||
}
|
|
||||||
|
|
||||||
busIndex := mustConvToInt(args[0])
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
|
||||||
release, err := client.Bus.Comp.Release(busIndex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bus Compressor release time: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Bus %d Compressor release time: %.1f ms\n", busIndex, release)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 2 {
|
|
||||||
return fmt.Errorf("Please provide bus number and release time (in ms)")
|
|
||||||
}
|
|
||||||
|
|
||||||
release := mustConvToFloat64(args[1])
|
|
||||||
|
|
||||||
err := client.Bus.Comp.SetRelease(busIndex, release)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting bus Compressor release time: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Bus %d Compressor release time set to %.1f ms\n", busIndex, release)
|
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -866,28 +227,10 @@ func init() {
|
|||||||
rootCmd.AddCommand(busCmd)
|
rootCmd.AddCommand(busCmd)
|
||||||
|
|
||||||
busCmd.AddCommand(busMuteCmd)
|
busCmd.AddCommand(busMuteCmd)
|
||||||
|
|
||||||
busCmd.AddCommand(busFaderCmd)
|
busCmd.AddCommand(busFaderCmd)
|
||||||
busCmd.AddCommand(busFadeOutCmd)
|
busCmd.AddCommand(busFadeOutCmd)
|
||||||
busFadeOutCmd.Flags().DurationP("duration", "d", 5*time.Second, "Duration for fade out in seconds")
|
busFadeOutCmd.Flags().Float64P("duration", "d", 5.0, "Duration for fade out in seconds")
|
||||||
busCmd.AddCommand(busFadeInCmd)
|
busCmd.AddCommand(busFadeInCmd)
|
||||||
busFadeInCmd.Flags().DurationP("duration", "d", 5*time.Second, "Duration for fade in in seconds")
|
busFadeInCmd.Flags().Float64P("duration", "d", 5.0, "Duration for fade in in seconds")
|
||||||
busCmd.AddCommand(busNameCmd)
|
|
||||||
|
|
||||||
busCmd.AddCommand(busEqCmd)
|
|
||||||
busEqCmd.AddCommand(busEqOnCmd)
|
|
||||||
busEqCmd.AddCommand(busEqModeCmd)
|
|
||||||
busEqCmd.AddCommand(busEqGainCmd)
|
|
||||||
busEqCmd.AddCommand(busEqFreqCmd)
|
|
||||||
busEqCmd.AddCommand(busEqQCmd)
|
|
||||||
busEqCmd.AddCommand(busEqTypeCmd)
|
|
||||||
|
|
||||||
busCmd.AddCommand(busCompCmd)
|
|
||||||
busCompCmd.AddCommand(busCompOnCmd)
|
|
||||||
busCompCmd.AddCommand(busCompThresholdCmd)
|
|
||||||
busCompCmd.AddCommand(busCompRatioCmd)
|
|
||||||
busCompCmd.AddCommand(busCompMixCmd)
|
|
||||||
busCompCmd.AddCommand(busCompMakeUpCmd)
|
|
||||||
busCompCmd.AddCommand(busCompAttackCmd)
|
|
||||||
busCompCmd.AddCommand(busCompHoldCmd)
|
|
||||||
busCompCmd.AddCommand(busCompReleaseCmd)
|
|
||||||
}
|
}
|
||||||
|
|||||||
211
cmd/headamp.go
211
cmd/headamp.go
@ -1,211 +0,0 @@
|
|||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/log"
|
|
||||||
"github.com/onyx-and-iris/xair-cli/internal/xair"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
// headampCmd represents the headamp command
|
|
||||||
var headampCmd = &cobra.Command{
|
|
||||||
Short: "Commands to control headamp gain and phantom power",
|
|
||||||
Long: `Commands to control the headamp gain and phantom power settings of the XAir mixer.
|
|
||||||
|
|
||||||
You can get or set the gain level for individual headamps, as well as enable or disable phantom power.`,
|
|
||||||
Use: "headamp",
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
cmd.Help()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// headampGainCmd represents the headamp gain command
|
|
||||||
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
|
|
||||||
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())
|
|
||||||
if client == nil {
|
|
||||||
return fmt.Errorf("OSC client not found in context")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 1 {
|
|
||||||
return fmt.Errorf("Please provide a headamp index")
|
|
||||||
}
|
|
||||||
|
|
||||||
index := mustConvToInt(args[0])
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
|
||||||
gain, err := client.HeadAmp.Gain(index)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting headamp gain level: %w", err)
|
|
||||||
}
|
|
||||||
cmd.Printf("Headamp %d Gain: %.2f dB\n", index, gain)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 2 {
|
|
||||||
return fmt.Errorf("Please provide a gain level in dB")
|
|
||||||
}
|
|
||||||
|
|
||||||
targetLevel := mustConvToFloat64(args[1])
|
|
||||||
|
|
||||||
currentGain, err := client.HeadAmp.Gain(index)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting current headamp gain level: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
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",
|
|
||||||
Short: "Get or set headamp phantom power status",
|
|
||||||
Long: `Get or set the phantom power status for a specified headamp index.
|
|
||||||
Examples:
|
|
||||||
# Get phantom power status for headamp index 1
|
|
||||||
xairctl headamp phantom 1
|
|
||||||
# Enable phantom power for headamp index 1
|
|
||||||
xairctl headamp phantom 1 on
|
|
||||||
# Disable phantom power for headamp index 1
|
|
||||||
xairctl headamp phantom 1 off`,
|
|
||||||
Args: cobra.RangeArgs(1, 2),
|
|
||||||
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 headamp index")
|
|
||||||
}
|
|
||||||
|
|
||||||
index := mustConvToInt(args[0])
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
|
||||||
enabled, err := client.HeadAmp.PhantomPower(index)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting headamp phantom power status: %w", err)
|
|
||||||
}
|
|
||||||
status := "disabled"
|
|
||||||
if enabled {
|
|
||||||
status = "enabled"
|
|
||||||
}
|
|
||||||
cmd.Printf("Headamp %d Phantom Power is %s\n", index, status)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) < 2 {
|
|
||||||
return fmt.Errorf("Please provide phantom power status: on or off")
|
|
||||||
}
|
|
||||||
|
|
||||||
var enable bool
|
|
||||||
switch args[1] {
|
|
||||||
case "on", "enable":
|
|
||||||
enable = true
|
|
||||||
case "off", "disable":
|
|
||||||
enable = false
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Invalid phantom power status. Use 'on' or 'off'")
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.HeadAmp.SetPhantomPower(index, enable)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error setting headamp phantom power status: %w", err)
|
|
||||||
}
|
|
||||||
status := "disabled"
|
|
||||||
if enable {
|
|
||||||
status = "enabled"
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf("Headamp %d Phantom Power %s successfully\n", index, status)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
52
cmd/main.go
52
cmd/main.go
@ -1,7 +1,6 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -34,19 +33,21 @@ If "false" or "0" is provided, the main output is unmuted.`,
|
|||||||
|
|
||||||
# Unmute the main output
|
# Unmute the main output
|
||||||
xair-cli main mute false`,
|
xair-cli main mute false`,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
client := ClientFromContext(cmd.Context())
|
client := ClientFromContext(cmd.Context())
|
||||||
if client == nil {
|
if client == nil {
|
||||||
return fmt.Errorf("OSC client not found in context")
|
cmd.PrintErrln("OSC client not found in context")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
resp, err := client.Main.Mute()
|
resp, err := client.Main.Mute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting main LR mute status: %w", err)
|
cmd.PrintErrln("Error getting main LR mute status:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
cmd.Printf("Main LR mute: %v\n", resp)
|
cmd.Printf("Main LR mute: %v\n", resp)
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var muted bool
|
var muted bool
|
||||||
@ -56,16 +57,16 @@ If "false" or "0" is provided, the main output is unmuted.`,
|
|||||||
case "false", "0":
|
case "false", "0":
|
||||||
muted = false
|
muted = false
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Invalid mute status. Use true/false or 1/0")
|
cmd.PrintErrln("Invalid mute status. Use true/false or 1/0")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := client.Main.SetMute(muted)
|
err := client.Main.SetMute(muted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error setting main LR mute status: %w", err)
|
cmd.PrintErrln("Error setting main LR mute status:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Main LR mute status set successfully")
|
cmd.Println("Main LR mute status set successfully")
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,28 +83,29 @@ If a dB value is provided as an argument, the fader level is set to that value.`
|
|||||||
|
|
||||||
# Set the main LR fader level to -10.0 dB
|
# Set the main LR fader level to -10.0 dB
|
||||||
xair-cli main fader -- -10.0`,
|
xair-cli main fader -- -10.0`,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
client := ClientFromContext(cmd.Context())
|
client := ClientFromContext(cmd.Context())
|
||||||
if client == nil {
|
if client == nil {
|
||||||
return fmt.Errorf("OSC client not found in context")
|
cmd.PrintErrln("OSC client not found in context")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
resp, err := client.Main.Fader()
|
resp, err := client.Main.Fader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting main LR fader: %w", err)
|
cmd.PrintErrln("Error getting main LR fader:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
cmd.Printf("Main LR fader: %.1f dB\n", resp)
|
cmd.Printf("Main LR fader: %.1f dB\n", resp)
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := client.Main.SetFader(mustConvToFloat64(args[0]))
|
err := client.Main.SetFader(mustConvToFloat64(args[0]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error setting main LR fader: %w", err)
|
cmd.PrintErrln("Error setting main LR fader:", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Main LR fader set successfully")
|
cmd.Println("Main LR fader set successfully")
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +118,7 @@ This command will fade out the main output to the specified dB level.
|
|||||||
`,
|
`,
|
||||||
Use: "fadeout --duration [seconds] [target_db]",
|
Use: "fadeout --duration [seconds] [target_db]",
|
||||||
Example: ` # Fade out main output over 5 seconds
|
Example: ` # Fade out main output over 5 seconds
|
||||||
xair-cli main fadeout --duration 5s -- -90.0`,
|
xair-cli main fadeout --duration 5 -- -90.0`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
client := ClientFromContext(cmd.Context())
|
client := ClientFromContext(cmd.Context())
|
||||||
if client == nil {
|
if client == nil {
|
||||||
@ -124,7 +126,7 @@ This command will fade out the main output to the specified dB level.
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
duration, err := cmd.Flags().GetDuration("duration")
|
duration, err := cmd.Flags().GetFloat64("duration")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.PrintErrln("Error getting duration flag:", err)
|
cmd.PrintErrln("Error getting duration flag:", err)
|
||||||
return
|
return
|
||||||
@ -150,7 +152,7 @@ This command will fade out the main output to the specified dB level.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate delay per step to achieve exact duration
|
// Calculate delay per step to achieve exact duration
|
||||||
stepDelay := time.Duration(duration.Seconds()*1000/totalSteps) * time.Millisecond
|
stepDelay := time.Duration(duration*1000/totalSteps) * time.Millisecond
|
||||||
|
|
||||||
for currentFader > target {
|
for currentFader > target {
|
||||||
currentFader -= 1.0
|
currentFader -= 1.0
|
||||||
@ -161,7 +163,6 @@ This command will fade out the main output to the specified dB level.
|
|||||||
}
|
}
|
||||||
time.Sleep(stepDelay)
|
time.Sleep(stepDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Main output faded out successfully")
|
cmd.Println("Main output faded out successfully")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -175,7 +176,7 @@ This command will fade in the main output to the specified dB level.
|
|||||||
`,
|
`,
|
||||||
Use: "fadein --duration [seconds] [target_db]",
|
Use: "fadein --duration [seconds] [target_db]",
|
||||||
Example: ` # Fade in main output over 5 seconds
|
Example: ` # Fade in main output over 5 seconds
|
||||||
xair-cli main fadein --duration 5s -- 0.0`,
|
xair-cli main fadein --duration 5 -- 0.0`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
client := ClientFromContext(cmd.Context())
|
client := ClientFromContext(cmd.Context())
|
||||||
if client == nil {
|
if client == nil {
|
||||||
@ -183,7 +184,7 @@ This command will fade in the main output to the specified dB level.
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
duration, err := cmd.Flags().GetDuration("duration")
|
duration, err := cmd.Flags().GetFloat64("duration")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.PrintErrln("Error getting duration flag:", err)
|
cmd.PrintErrln("Error getting duration flag:", err)
|
||||||
return
|
return
|
||||||
@ -208,7 +209,7 @@ This command will fade in the main output to the specified dB level.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate delay per step to achieve exact duration
|
// Calculate delay per step to achieve exact duration
|
||||||
stepDelay := time.Duration(duration.Seconds()*1000/totalSteps) * time.Millisecond
|
stepDelay := time.Duration(duration*1000/totalSteps) * time.Millisecond
|
||||||
|
|
||||||
for currentFader < target {
|
for currentFader < target {
|
||||||
currentFader += 1.0
|
currentFader += 1.0
|
||||||
@ -219,7 +220,6 @@ This command will fade in the main output to the specified dB level.
|
|||||||
}
|
}
|
||||||
time.Sleep(stepDelay)
|
time.Sleep(stepDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Main output faded in successfully")
|
cmd.Println("Main output faded in successfully")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -231,7 +231,7 @@ func init() {
|
|||||||
|
|
||||||
mainCmd.AddCommand(mainFaderCmd)
|
mainCmd.AddCommand(mainFaderCmd)
|
||||||
mainCmd.AddCommand(mainFadeOutCmd)
|
mainCmd.AddCommand(mainFadeOutCmd)
|
||||||
mainFadeOutCmd.Flags().DurationP("duration", "d", 5*time.Second, "Duration for fade out in seconds")
|
mainFadeOutCmd.Flags().Float64P("duration", "d", 5, "Duration for fade out in seconds")
|
||||||
mainCmd.AddCommand(mainFadeInCmd)
|
mainCmd.AddCommand(mainFadeInCmd)
|
||||||
mainFadeInCmd.Flags().DurationP("duration", "d", 5*time.Second, "Duration for fade in in seconds")
|
mainFadeInCmd.Flags().Float64P("duration", "d", 5, "Duration for fade in in seconds")
|
||||||
}
|
}
|
||||||
|
|||||||
16
cmd/root.go
16
cmd/root.go
@ -2,7 +2,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"runtime/debug"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/charmbracelet/log"
|
"github.com/charmbracelet/log"
|
||||||
@ -12,8 +11,6 @@ import (
|
|||||||
"github.com/onyx-and-iris/xair-cli/internal/xair"
|
"github.com/onyx-and-iris/xair-cli/internal/xair"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version string // Version of the CLI, set during build time
|
|
||||||
|
|
||||||
// rootCmd represents the base command when called without any subcommands.
|
// rootCmd represents the base command when called without any subcommands.
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "xair-cli",
|
Use: "xair-cli",
|
||||||
@ -21,7 +18,6 @@ var rootCmd = &cobra.Command{
|
|||||||
Long: `xair-cli is a command-line tool that allows users to send OSC messages
|
Long: `xair-cli is a command-line tool that allows users to send OSC messages
|
||||||
to Behringer X Air mixers for remote control and configuration. It supports
|
to Behringer X Air mixers for remote control and configuration. It supports
|
||||||
various commands to manage mixer settings directly from the terminal.`,
|
various commands to manage mixer settings directly from the terminal.`,
|
||||||
Version: versionFromBuild(),
|
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
|
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
level, err := log.ParseLevel(viper.GetString("loglevel"))
|
level, err := log.ParseLevel(viper.GetString("loglevel"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -92,15 +88,3 @@ func init() {
|
|||||||
viper.BindPFlag("loglevel", rootCmd.PersistentFlags().Lookup("loglevel"))
|
viper.BindPFlag("loglevel", rootCmd.PersistentFlags().Lookup("loglevel"))
|
||||||
viper.BindPFlag("kind", rootCmd.PersistentFlags().Lookup("kind"))
|
viper.BindPFlag("kind", rootCmd.PersistentFlags().Lookup("kind"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func versionFromBuild() string {
|
|
||||||
if version == "" {
|
|
||||||
info, ok := debug.ReadBuildInfo()
|
|
||||||
if !ok {
|
|
||||||
return "(unable to read version)"
|
|
||||||
}
|
|
||||||
version = strings.Split(info.Main.Version, "-")[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return version
|
|
||||||
}
|
|
||||||
|
|||||||
883
cmd/strip.go
883
cmd/strip.go
File diff suppressed because it is too large
Load Diff
15
cmd/util.go
15
cmd/util.go
@ -21,18 +21,3 @@ func mustConvToInt(intStr string) int {
|
|||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
// generic indexOf returns the index of elem in slice, or -1 if not found.
|
|
||||||
func indexOf[T comparable](slice []T, elem T) int {
|
|
||||||
for i, v := range slice {
|
|
||||||
if v == elem {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// generic contains checks if elem is in slice.
|
|
||||||
func contains[T comparable](slice []T, elem T) bool {
|
|
||||||
return indexOf(slice, elem) != -1
|
|
||||||
}
|
|
||||||
|
|||||||
24
go.mod
24
go.mod
@ -11,17 +11,17 @@ require (
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
github.com/charmbracelet/colorprofile v0.4.1 // indirect
|
github.com/charmbracelet/colorprofile v0.3.3 // indirect
|
||||||
github.com/charmbracelet/lipgloss v1.1.0 // indirect
|
github.com/charmbracelet/lipgloss v1.1.0 // indirect
|
||||||
github.com/charmbracelet/x/ansi v0.11.4 // indirect
|
github.com/charmbracelet/x/ansi v0.10.3 // indirect
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.14 // indirect
|
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
|
||||||
github.com/charmbracelet/x/term v0.2.2 // indirect
|
github.com/charmbracelet/x/term v0.2.2 // indirect
|
||||||
github.com/clipperhouse/displaywidth v0.9.0 // indirect
|
github.com/clipperhouse/displaywidth v0.4.1 // indirect
|
||||||
github.com/clipperhouse/stringish v0.1.1 // indirect
|
github.com/clipperhouse/stringish v0.1.1 // indirect
|
||||||
github.com/clipperhouse/uax29/v2 v2.5.0 // indirect
|
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||||
github.com/go-logfmt/logfmt v0.6.1 // indirect
|
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||||
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
|
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
|
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
@ -29,15 +29,15 @@ require (
|
|||||||
github.com/muesli/termenv v0.16.0 // indirect
|
github.com/muesli/termenv v0.16.0 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/sagikazarmark/locafero v0.12.0 // indirect
|
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||||
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||||
github.com/spf13/afero v1.15.0 // indirect
|
github.com/spf13/afero v1.15.0 // indirect
|
||||||
github.com/spf13/cast v1.10.0 // indirect
|
github.com/spf13/cast v1.10.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.10 // indirect
|
github.com/spf13/pflag v1.0.10 // indirect
|
||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect
|
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||||
golang.org/x/sys v0.40.0 // indirect
|
golang.org/x/sys v0.37.0 // indirect
|
||||||
golang.org/x/text v0.33.0 // indirect
|
golang.org/x/text v0.28.0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
|
||||||
)
|
)
|
||||||
|
|||||||
50
go.sum
50
go.sum
@ -1,23 +1,23 @@
|
|||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||||
github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk=
|
github.com/charmbracelet/colorprofile v0.3.3 h1:DjJzJtLP6/NZ8p7Cgjno0CKGr7wwRJGxWUwh2IyhfAI=
|
||||||
github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk=
|
github.com/charmbracelet/colorprofile v0.3.3/go.mod h1:nB1FugsAbzq284eJcjfah2nhdSLppN2NqvfotkfRYP4=
|
||||||
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
||||||
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
||||||
github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig=
|
github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig=
|
||||||
github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw=
|
github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw=
|
||||||
github.com/charmbracelet/x/ansi v0.11.4 h1:6G65PLu6HjmE858CnTUQY1LXT3ZUWwfvqEROLF8vqHI=
|
github.com/charmbracelet/x/ansi v0.10.3 h1:3WoV9XN8uMEnFRZZ+vBPRy59TaIWa+gJodS4Vg5Fut0=
|
||||||
github.com/charmbracelet/x/ansi v0.11.4/go.mod h1:/5AZ+UfWExW3int5H5ugnsG/PWjNcSQcwYsHBlPFQN4=
|
github.com/charmbracelet/x/ansi v0.10.3/go.mod h1:uQt8bOrq/xgXjlGcFMc8U2WYbnxyjrKhnvTQluvfCaE=
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4=
|
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA=
|
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
|
||||||
github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
|
github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
|
||||||
github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
|
github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
|
||||||
github.com/clipperhouse/displaywidth v0.9.0 h1:Qb4KOhYwRiN3viMv1v/3cTBlz3AcAZX3+y9OLhMtAtA=
|
github.com/clipperhouse/displaywidth v0.4.1 h1:uVw9V8UDfnggg3K2U84VWY1YLQ/x2aKSCtkRyYozfoU=
|
||||||
github.com/clipperhouse/displaywidth v0.9.0/go.mod h1:aCAAqTlh4GIVkhQnJpbL0T/WfcrJXHcj8C0yjYcjOZA=
|
github.com/clipperhouse/displaywidth v0.4.1/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
|
||||||
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
|
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
|
||||||
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
|
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
|
||||||
github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U=
|
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
|
||||||
github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
|
github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@ -25,12 +25,12 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
|
|||||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||||
github.com/go-logfmt/logfmt v0.6.1 h1:4hvbpePJKnIzH1B+8OR/JPbTx37NktoI9LE2QZBBkvE=
|
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||||
github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/z6CO0XAk=
|
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||||
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
|
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||||
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/hypebeast/go-osc v0.0.0-20220308234300-cec5a8a1e5f5 h1:fqwINudmUrvGCuw+e3tedZ2UJ0hklSw6t8UPomctKyQ=
|
github.com/hypebeast/go-osc v0.0.0-20220308234300-cec5a8a1e5f5 h1:fqwINudmUrvGCuw+e3tedZ2UJ0hklSw6t8UPomctKyQ=
|
||||||
github.com/hypebeast/go-osc v0.0.0-20220308234300-cec5a8a1e5f5/go.mod h1:lqMjoCs0y0GoRRujSPZRBaGb4c5ER6TfkFKSClxkMbY=
|
github.com/hypebeast/go-osc v0.0.0-20220308234300-cec5a8a1e5f5/go.mod h1:lqMjoCs0y0GoRRujSPZRBaGb4c5ER6TfkFKSClxkMbY=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
@ -56,8 +56,10 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc
|
|||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4=
|
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||||
github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=
|
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||||
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||||
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||||
@ -77,13 +79,13 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM
|
|||||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
||||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU=
|
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||||
golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU=
|
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|||||||
@ -1,15 +1,11 @@
|
|||||||
package xair
|
package xair
|
||||||
|
|
||||||
var xairAddressMap = map[string]string{
|
var xairAddressMap = map[string]string{
|
||||||
"strip": "/ch/%02d",
|
|
||||||
"bus": "/bus/%01d",
|
"bus": "/bus/%01d",
|
||||||
"headamp": "/headamp/%02d",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var x32AddressMap = map[string]string{
|
var x32AddressMap = map[string]string{
|
||||||
"strip": "/ch/%02d",
|
|
||||||
"bus": "/bus/%02d",
|
"bus": "/bus/%02d",
|
||||||
"headamp": "/headamp/%02d",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addressMapForMixerKind(kind MixerKind) map[string]string {
|
func addressMapForMixerKind(kind MixerKind) map[string]string {
|
||||||
|
|||||||
@ -3,24 +3,19 @@ package xair
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
type Bus struct {
|
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{
|
return &Bus{
|
||||||
baseAddress: c.addressMap["bus"],
|
|
||||||
client: c,
|
client: c,
|
||||||
Eq: newEqForBus(c),
|
|
||||||
Comp: newCompForBus(c),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mute requests the current mute status for a bus
|
// Mute requests the current mute status for a bus
|
||||||
func (b *Bus) Mute(bus int) (bool, error) {
|
func (b *Bus) Mute(bus int) (bool, error) {
|
||||||
address := fmt.Sprintf(b.baseAddress, bus) + "/mix/on"
|
formatter := b.client.addressMap["bus"]
|
||||||
|
address := fmt.Sprintf(formatter, bus) + "/mix/on"
|
||||||
err := b.client.SendMessage(address)
|
err := b.client.SendMessage(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@ -36,7 +31,8 @@ func (b *Bus) Mute(bus int) (bool, error) {
|
|||||||
|
|
||||||
// SetMute sets the mute status for a specific bus (1-based indexing)
|
// SetMute sets the mute status for a specific bus (1-based indexing)
|
||||||
func (b *Bus) SetMute(bus int, muted bool) error {
|
func (b *Bus) SetMute(bus int, muted bool) error {
|
||||||
address := fmt.Sprintf(b.baseAddress, bus) + "/mix/on"
|
formatter := b.client.addressMap["bus"]
|
||||||
|
address := fmt.Sprintf(formatter, bus) + "/mix/on"
|
||||||
var value int32
|
var value int32
|
||||||
if !muted {
|
if !muted {
|
||||||
value = 1
|
value = 1
|
||||||
@ -46,7 +42,8 @@ func (b *Bus) SetMute(bus int, muted bool) error {
|
|||||||
|
|
||||||
// Fader requests the current fader level for a bus
|
// Fader requests the current fader level for a bus
|
||||||
func (b *Bus) Fader(bus int) (float64, error) {
|
func (b *Bus) Fader(bus int) (float64, error) {
|
||||||
address := fmt.Sprintf(b.baseAddress, bus) + "/mix/fader"
|
formatter := b.client.addressMap["bus"]
|
||||||
|
address := fmt.Sprintf(formatter, bus) + "/mix/fader"
|
||||||
err := b.client.SendMessage(address)
|
err := b.client.SendMessage(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -63,28 +60,7 @@ func (b *Bus) Fader(bus int) (float64, error) {
|
|||||||
|
|
||||||
// SetFader sets the fader level for a specific bus (1-based indexing)
|
// SetFader sets the fader level for a specific bus (1-based indexing)
|
||||||
func (b *Bus) SetFader(bus int, level float64) error {
|
func (b *Bus) SetFader(bus int, level float64) error {
|
||||||
address := fmt.Sprintf(b.baseAddress, bus) + "/mix/fader"
|
formatter := b.client.addressMap["bus"]
|
||||||
|
address := fmt.Sprintf(formatter, bus) + "/mix/fader"
|
||||||
return b.client.SendMessage(address, float32(mustDbInto(level)))
|
return b.client.SendMessage(address, float32(mustDbInto(level)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name requests the name for a specific bus
|
|
||||||
func (b *Bus) Name(bus int) (string, error) {
|
|
||||||
address := fmt.Sprintf(b.baseAddress, bus) + "/config/name"
|
|
||||||
err := b.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to send bus name request: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := <-b.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(string)
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("unexpected argument type for bus name value")
|
|
||||||
}
|
|
||||||
return val, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetName sets the name for a specific bus
|
|
||||||
func (b *Bus) SetName(bus int, name string) error {
|
|
||||||
address := fmt.Sprintf(b.baseAddress, bus) + "/config/name"
|
|
||||||
return b.client.SendMessage(address, name)
|
|
||||||
}
|
|
||||||
|
|||||||
@ -18,7 +18,6 @@ type Client struct {
|
|||||||
Main *Main
|
Main *Main
|
||||||
Strip *Strip
|
Strip *Strip
|
||||||
Bus *Bus
|
Bus *Bus
|
||||||
HeadAmp *HeadAmp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates a new XAirClient instance
|
// NewClient creates a new XAirClient instance
|
||||||
@ -58,10 +57,9 @@ func NewClient(mixerIP string, mixerPort int, opts ...Option) (*Client, error) {
|
|||||||
c := &Client{
|
c := &Client{
|
||||||
engine: *e,
|
engine: *e,
|
||||||
}
|
}
|
||||||
c.Main = newMain(c)
|
c.Main = newMain(*c)
|
||||||
c.Strip = NewStrip(c)
|
c.Strip = NewStrip(*c)
|
||||||
c.Bus = NewBus(c)
|
c.Bus = NewBus(*c)
|
||||||
c.HeadAmp = NewHeadAmp(c)
|
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,209 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Threshold retrieves the threshold value of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) Threshold(index int) (float64, error) {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/thr"
|
|
||||||
err := c.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := <-c.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(float32)
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unexpected argument type for Compressor threshold value")
|
|
||||||
}
|
|
||||||
return linGet(-60, 0, float64(val)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetThreshold sets the threshold value of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) SetThreshold(index int, threshold float64) error {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/thr"
|
|
||||||
return c.client.SendMessage(address, float32(linSet(-60, 0, threshold)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ratio retrieves the ratio value of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) Ratio(index int) (float32, error) {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/ratio"
|
|
||||||
err := c.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
possibleValues := []float32{1.1, 1.3, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 7.0, 10, 20, 100}
|
|
||||||
|
|
||||||
resp := <-c.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(int32)
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unexpected argument type for Compressor ratio value")
|
|
||||||
}
|
|
||||||
|
|
||||||
return possibleValues[val], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRatio sets the ratio value of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) SetRatio(index int, ratio float64) error {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/ratio"
|
|
||||||
possibleValues := []float32{1.1, 1.3, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 7.0, 10, 20, 100}
|
|
||||||
|
|
||||||
return c.client.SendMessage(address, int32(indexOf(possibleValues, float32(ratio))))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attack retrieves the attack time of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) Attack(index int) (float64, error) {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/attack"
|
|
||||||
err := c.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := <-c.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(float32)
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unexpected argument type for Compressor attack value")
|
|
||||||
}
|
|
||||||
return linGet(0, 120, float64(val)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAttack sets the attack time of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) SetAttack(index int, attack float64) error {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/attack"
|
|
||||||
return c.client.SendMessage(address, float32(linSet(0, 120, attack)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hold retrieves the hold time of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) Hold(index int) (float64, error) {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/hold"
|
|
||||||
err := c.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := <-c.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(float32)
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unexpected argument type for Compressor hold value")
|
|
||||||
}
|
|
||||||
return logGet(0.02, 2000, float64(val)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetHold sets the hold time of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) SetHold(index int, hold float64) error {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/hold"
|
|
||||||
return c.client.SendMessage(address, float32(logSet(0.02, 2000, hold)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release retrieves the release time of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) Release(index int) (float64, error) {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/release"
|
|
||||||
err := c.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := <-c.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(float32)
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unexpected argument type for Compressor release value")
|
|
||||||
}
|
|
||||||
return logGet(4, 4000, float64(val)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRelease sets the release time of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) SetRelease(index int, release float64) error {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/release"
|
|
||||||
return c.client.SendMessage(address, float32(logSet(4, 4000, release)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeUp retrieves the make-up gain of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) MakeUp(index int) (float64, error) {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/mgain"
|
|
||||||
err := c.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := <-c.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(float32)
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unexpected argument type for Compressor make-up gain value")
|
|
||||||
}
|
|
||||||
return linGet(0, 24, float64(val)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMakeUp sets the make-up gain of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) SetMakeUp(index int, makeUp float64) error {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/mgain"
|
|
||||||
return c.client.SendMessage(address, float32(linSet(0, 24, makeUp)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mix retrieves the mix value of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) Mix(index int) (float64, error) {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/mix"
|
|
||||||
err := c.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := <-c.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(float32)
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unexpected argument type for Compressor mix value")
|
|
||||||
}
|
|
||||||
return linGet(0, 100, float64(val)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMix sets the mix value of the Compressor for a specific strip or bus (1-based indexing).
|
|
||||||
func (c *Comp) SetMix(index int, mix float64) error {
|
|
||||||
address := fmt.Sprintf(c.baseAddress, index) + "/dyn/mix"
|
|
||||||
return c.client.SendMessage(address, float32(linSet(0, 100, mix)))
|
|
||||||
}
|
|
||||||
@ -1,158 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Eq) Mode(index int) (int, error) {
|
|
||||||
address := fmt.Sprintf(e.baseAddress, index) + "/eq/mode"
|
|
||||||
err := e.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := <-e.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(int32)
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unexpected argument type for EQ mode value")
|
|
||||||
}
|
|
||||||
return int(val), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Eq) SetMode(index int, mode int) error {
|
|
||||||
address := fmt.Sprintf(e.baseAddress, index) + "/eq/mode"
|
|
||||||
return e.client.SendMessage(address, int32(mode))
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 linGet(-15, 15, 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(linSet(-15, 15, gain)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Frequency retrieves the frequency for a specific EQ band on a strip or bus (1-based indexing).
|
|
||||||
func (e *Eq) Frequency(index int, band int) (float64, error) {
|
|
||||||
address := fmt.Sprintf(e.baseAddress, index) + fmt.Sprintf("/eq/%d/f", 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 frequency value")
|
|
||||||
}
|
|
||||||
return logGet(20, 20000, float64(val)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFrequency sets the frequency for a specific EQ band on a strip or bus (1-based indexing).
|
|
||||||
func (e *Eq) SetFrequency(index int, band int, frequency float64) error {
|
|
||||||
address := fmt.Sprintf(e.baseAddress, index) + fmt.Sprintf("/eq/%d/f", band)
|
|
||||||
return e.client.SendMessage(address, float32(logSet(20, 20000, frequency)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Q retrieves the Q factor for a specific EQ band on a strip or bus (1-based indexing).
|
|
||||||
func (e *Eq) Q(index int, band int) (float64, error) {
|
|
||||||
address := fmt.Sprintf(e.baseAddress, index) + fmt.Sprintf("/eq/%d/q", 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 Q value")
|
|
||||||
}
|
|
||||||
return logGet(0.3, 10, 1.0-float64(val)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetQ sets the Q factor for a specific EQ band on a strip or bus (1-based indexing).
|
|
||||||
func (e *Eq) SetQ(index int, band int, q float64) error {
|
|
||||||
address := fmt.Sprintf(e.baseAddress, index) + fmt.Sprintf("/eq/%d/q", band)
|
|
||||||
return e.client.SendMessage(address, float32(1.0-logSet(0.3, 10, q)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type retrieves the type for a specific EQ band on a strip or bus (1-based indexing).
|
|
||||||
func (e *Eq) Type(index int, band int) (int, error) {
|
|
||||||
address := fmt.Sprintf(e.baseAddress, index) + fmt.Sprintf("/eq/%d/type", band)
|
|
||||||
err := e.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := <-e.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(int32)
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unexpected argument type for EQ type value")
|
|
||||||
}
|
|
||||||
return int(val), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetType sets the type for a specific EQ band on a strip or bus (1-based indexing).
|
|
||||||
func (e *Eq) SetType(index int, band int, eqType int) error {
|
|
||||||
address := fmt.Sprintf(e.baseAddress, index) + fmt.Sprintf("/eq/%d/type", band)
|
|
||||||
return e.client.SendMessage(address, int32(eqType))
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
package xair
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type HeadAmp struct {
|
|
||||||
baseAddress string
|
|
||||||
client *Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHeadAmp(c *Client) *HeadAmp {
|
|
||||||
return &HeadAmp{
|
|
||||||
baseAddress: c.addressMap["headamp"],
|
|
||||||
client: c,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gain gets the gain level for the specified headamp index.
|
|
||||||
func (h *HeadAmp) Gain(index int) (float64, error) {
|
|
||||||
address := fmt.Sprintf(h.baseAddress, index) + "/gain"
|
|
||||||
err := h.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := <-h.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(float32)
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unexpected argument type for headamp gain value")
|
|
||||||
}
|
|
||||||
|
|
||||||
return linGet(-12, 60, float64(val)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGain sets the gain level for the specified headamp index.
|
|
||||||
func (h *HeadAmp) SetGain(index int, level float64) error {
|
|
||||||
address := fmt.Sprintf(h.baseAddress, index) + "/gain"
|
|
||||||
return h.client.SendMessage(address, float32(linSet(-12, 60, level)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// PhantomPower gets the phantom power status for the specified headamp index.
|
|
||||||
func (h *HeadAmp) PhantomPower(index int) (bool, error) {
|
|
||||||
address := fmt.Sprintf(h.baseAddress, index) + "/phantom"
|
|
||||||
err := h.client.SendMessage(address)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := <-h.client.respChan
|
|
||||||
val, ok := resp.Arguments[0].(int32)
|
|
||||||
if !ok {
|
|
||||||
return false, fmt.Errorf("unexpected argument type for phantom power value")
|
|
||||||
}
|
|
||||||
|
|
||||||
return val != 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPhantomPower sets the phantom power status for the specified headamp index.
|
|
||||||
func (h *HeadAmp) SetPhantomPower(index int, enabled bool) error {
|
|
||||||
address := fmt.Sprintf(h.baseAddress, index) + "/phantom"
|
|
||||||
var val int32
|
|
||||||
if enabled {
|
|
||||||
val = 1
|
|
||||||
} else {
|
|
||||||
val = 0
|
|
||||||
}
|
|
||||||
return h.client.SendMessage(address, val)
|
|
||||||
}
|
|
||||||
@ -3,10 +3,10 @@ package xair
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
type Main struct {
|
type Main struct {
|
||||||
client *Client
|
client Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMain(c *Client) *Main {
|
func newMain(c Client) *Main {
|
||||||
return &Main{
|
return &Main{
|
||||||
client: c,
|
client: c,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,26 +3,18 @@ package xair
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
type Strip struct {
|
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{
|
return &Strip{
|
||||||
baseAddress: c.addressMap["strip"],
|
|
||||||
client: c,
|
client: c,
|
||||||
Gate: newGate(c),
|
|
||||||
Eq: newEqForStrip(c),
|
|
||||||
Comp: newCompForStrip(c),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mute gets the mute status of the specified strip (1-based indexing).
|
// Mute gets the mute status of the specified strip (1-based indexing).
|
||||||
func (s *Strip) Mute(index int) (bool, error) {
|
func (s *Strip) Mute(strip int) (bool, error) {
|
||||||
address := fmt.Sprintf(s.baseAddress, index) + "/mix/on"
|
address := fmt.Sprintf("/ch/%02d/mix/on", strip)
|
||||||
err := s.client.SendMessage(address)
|
err := s.client.SendMessage(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@ -38,7 +30,7 @@ func (s *Strip) Mute(index int) (bool, error) {
|
|||||||
|
|
||||||
// SetMute sets the mute status of the specified strip (1-based indexing).
|
// SetMute sets the mute status of the specified strip (1-based indexing).
|
||||||
func (s *Strip) SetMute(strip int, muted bool) error {
|
func (s *Strip) SetMute(strip int, muted bool) error {
|
||||||
address := fmt.Sprintf(s.baseAddress, strip) + "/mix/on"
|
address := fmt.Sprintf("/ch/%02d/mix/on", strip)
|
||||||
var value int32 = 0
|
var value int32 = 0
|
||||||
if !muted {
|
if !muted {
|
||||||
value = 1
|
value = 1
|
||||||
@ -48,7 +40,7 @@ func (s *Strip) SetMute(strip int, muted bool) error {
|
|||||||
|
|
||||||
// Fader gets the fader level of the specified strip (1-based indexing).
|
// Fader gets the fader level of the specified strip (1-based indexing).
|
||||||
func (s *Strip) Fader(strip int) (float64, error) {
|
func (s *Strip) Fader(strip int) (float64, error) {
|
||||||
address := fmt.Sprintf(s.baseAddress, strip) + "/mix/fader"
|
address := fmt.Sprintf("/ch/%02d/mix/fader", strip)
|
||||||
err := s.client.SendMessage(address)
|
err := s.client.SendMessage(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -65,13 +57,35 @@ func (s *Strip) Fader(strip int) (float64, error) {
|
|||||||
|
|
||||||
// SetFader sets the fader level of the specified strip (1-based indexing).
|
// SetFader sets the fader level of the specified strip (1-based indexing).
|
||||||
func (s *Strip) SetFader(strip int, level float64) error {
|
func (s *Strip) SetFader(strip int, level float64) error {
|
||||||
address := fmt.Sprintf(s.baseAddress, strip) + "/mix/fader"
|
address := fmt.Sprintf("/ch/%02d/mix/fader", strip)
|
||||||
return s.client.SendMessage(address, float32(mustDbInto(level)))
|
return s.client.SendMessage(address, float32(mustDbInto(level)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MicGain requests the phantom gain for a specific strip (1-based indexing).
|
||||||
|
func (s *Strip) MicGain(strip int) (float64, error) {
|
||||||
|
address := fmt.Sprintf("/ch/%02d/mix/gain", strip)
|
||||||
|
err := s.client.SendMessage(address)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to send strip gain request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := <-s.client.respChan
|
||||||
|
val, ok := resp.Arguments[0].(float32)
|
||||||
|
if !ok {
|
||||||
|
return 0, fmt.Errorf("unexpected argument type for strip gain value")
|
||||||
|
}
|
||||||
|
return mustDbFrom(float64(val)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMicGain sets the phantom gain for a specific strip (1-based indexing).
|
||||||
|
func (s *Strip) SetMicGain(strip int, gain float32) error {
|
||||||
|
address := fmt.Sprintf("/ch/%02d/mix/gain", strip)
|
||||||
|
return s.client.SendMessage(address, gain)
|
||||||
|
}
|
||||||
|
|
||||||
// Name requests the name for a specific strip
|
// Name requests the name for a specific strip
|
||||||
func (s *Strip) Name(strip int) (string, error) {
|
func (s *Strip) Name(strip int) (string, error) {
|
||||||
address := fmt.Sprintf(s.baseAddress, strip) + "/config/name"
|
address := fmt.Sprintf("/ch/%02d/config/name", strip)
|
||||||
err := s.client.SendMessage(address)
|
err := s.client.SendMessage(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to send strip name request: %v", err)
|
return "", fmt.Errorf("failed to send strip name request: %v", err)
|
||||||
@ -87,13 +101,13 @@ func (s *Strip) Name(strip int) (string, error) {
|
|||||||
|
|
||||||
// SetName sets the name for a specific strip
|
// SetName sets the name for a specific strip
|
||||||
func (s *Strip) SetName(strip int, name string) error {
|
func (s *Strip) SetName(strip int, name string) error {
|
||||||
address := fmt.Sprintf(s.baseAddress, strip) + "/config/name"
|
address := fmt.Sprintf("/ch/%02d/config/name", strip)
|
||||||
return s.client.SendMessage(address, name)
|
return s.client.SendMessage(address, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color requests the color for a specific strip
|
// Color requests the color for a specific strip
|
||||||
func (s *Strip) Color(strip int) (int32, error) {
|
func (s *Strip) Color(strip int) (int32, error) {
|
||||||
address := fmt.Sprintf(s.baseAddress, strip) + "/config/color"
|
address := fmt.Sprintf("/ch/%02d/config/color", strip)
|
||||||
err := s.client.SendMessage(address)
|
err := s.client.SendMessage(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("failed to send strip color request: %v", err)
|
return 0, fmt.Errorf("failed to send strip color request: %v", err)
|
||||||
@ -109,13 +123,13 @@ func (s *Strip) Color(strip int) (int32, error) {
|
|||||||
|
|
||||||
// SetColor sets the color for a specific strip (0-15)
|
// SetColor sets the color for a specific strip (0-15)
|
||||||
func (s *Strip) SetColor(strip int, color int32) error {
|
func (s *Strip) SetColor(strip int, color int32) error {
|
||||||
address := fmt.Sprintf(s.baseAddress, strip) + "/config/color"
|
address := fmt.Sprintf("/ch/%02d/config/color", strip)
|
||||||
return s.client.SendMessage(address, color)
|
return s.client.SendMessage(address, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends requests the sends level for a mixbus.
|
// Sends requests the sends level for a mixbus.
|
||||||
func (s *Strip) SendLevel(strip int, bus int) (float64, error) {
|
func (s *Strip) SendLevel(strip int, bus int) (float64, error) {
|
||||||
address := fmt.Sprintf(s.baseAddress, strip) + fmt.Sprintf("/mix/%02d/level", bus)
|
address := fmt.Sprintf("/ch/%02d/mix/%02d/level", strip, bus)
|
||||||
err := s.client.SendMessage(address)
|
err := s.client.SendMessage(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("failed to send strip send level request: %v", err)
|
return 0, fmt.Errorf("failed to send strip send level request: %v", err)
|
||||||
@ -131,6 +145,6 @@ func (s *Strip) SendLevel(strip int, bus int) (float64, error) {
|
|||||||
|
|
||||||
// SetSendLevel sets the sends level for a mixbus.
|
// SetSendLevel sets the sends level for a mixbus.
|
||||||
func (s *Strip) SetSendLevel(strip int, bus int, level float64) error {
|
func (s *Strip) SetSendLevel(strip int, bus int, level float64) error {
|
||||||
address := fmt.Sprintf(s.baseAddress, strip) + fmt.Sprintf("/mix/%02d/level", bus)
|
address := fmt.Sprintf("/ch/%02d/mix/%02d/level", strip, bus)
|
||||||
return s.client.SendMessage(address, float32(mustDbInto(level)))
|
return s.client.SendMessage(address, float32(mustDbInto(level)))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,22 +2,6 @@ package xair
|
|||||||
|
|
||||||
import "math"
|
import "math"
|
||||||
|
|
||||||
func linGet(min float64, max float64, value float64) float64 {
|
|
||||||
return min + (max-min)*value
|
|
||||||
}
|
|
||||||
|
|
||||||
func linSet(min float64, max float64, value float64) float64 {
|
|
||||||
return (value - min) / (max - min)
|
|
||||||
}
|
|
||||||
|
|
||||||
func logGet(min float64, max float64, value float64) float64 {
|
|
||||||
return min * math.Exp(math.Log(max/min)*value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func logSet(min float64, max float64, value float64) float64 {
|
|
||||||
return math.Log(value/min) / math.Log(max/min)
|
|
||||||
}
|
|
||||||
|
|
||||||
func mustDbInto(db float64) float64 {
|
func mustDbInto(db float64) float64 {
|
||||||
switch {
|
switch {
|
||||||
case db >= 10:
|
case db >= 10:
|
||||||
@ -56,13 +40,3 @@ func toFixed(num float64, precision int) float64 {
|
|||||||
output := math.Pow(10, float64(precision))
|
output := math.Pow(10, float64(precision))
|
||||||
return float64(math.Round(num*output)) / output
|
return float64(math.Round(num*output)) / output
|
||||||
}
|
}
|
||||||
|
|
||||||
// generic indexOf returns the index of elem in slice, or -1 if not found.
|
|
||||||
func indexOf[T comparable](slice []T, elem T) int {
|
|
||||||
for i, v := range slice {
|
|
||||||
if v == elem {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user