mirror of
https://github.com/onyx-and-iris/xair-cli.git
synced 2026-02-03 23:17:47 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2590a43c18 | |||
| 0559899666 | |||
|
|
20fed03c48 | ||
| fc36e9bf5c |
15
README.md
15
README.md
@ -46,9 +46,9 @@ 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 9 phantom on
|
||||
xair-cli headamp phantom 9 on
|
||||
|
||||
xair-cli headamp 9 gain 28.0 --duration 10s
|
||||
xair-cli headamp gain 9 28.0 --duration 10s
|
||||
```
|
||||
|
||||
*set strip 09 send level for bus 5 to -18.0dB*
|
||||
@ -56,15 +56,22 @@ xair-cli headamp 9 gain 28.0 --duration 10s
|
||||
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 1 name 'vocal mix'
|
||||
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
|
||||
|
||||
I've only implemented the parts I personally need, I don't know how much more I intend to add.
|
||||
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
|
||||
|
||||
227
cmd/bus.go
227
cmd/bus.go
@ -300,6 +300,228 @@ var busEqOnCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
// 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",
|
||||
@ -359,6 +581,11 @@ func init() {
|
||||
|
||||
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)
|
||||
|
||||
185
cmd/strip.go
185
cmd/strip.go
@ -475,6 +475,187 @@ If "false" or "0" is provided, the EQ is turned off.`,
|
||||
},
|
||||
}
|
||||
|
||||
// stripEqGainCmd represents the strip EQ Gain command.
|
||||
var stripEqGainCmd = &cobra.Command{
|
||||
Short: "Get or set the EQ band gain for a strip",
|
||||
Long: "Get or set the EQ band gain for a specific strip and band.",
|
||||
Use: "gain [strip 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 strip number and band number")
|
||||
}
|
||||
|
||||
stripIndex, bandIndex := func() (int, int) {
|
||||
return mustConvToInt(args[0]), mustConvToInt(args[1])
|
||||
}()
|
||||
|
||||
if len(args) == 2 {
|
||||
currentGain, err := client.Strip.Eq.Gain(stripIndex, bandIndex)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting strip EQ band gain: %w", err)
|
||||
}
|
||||
cmd.Printf("Strip %d EQ band %d gain: %.2f dB\n", stripIndex, bandIndex, currentGain)
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(args) < 3 {
|
||||
return fmt.Errorf("Please provide a gain in dB")
|
||||
}
|
||||
|
||||
gain := mustConvToFloat64(args[2])
|
||||
|
||||
err := client.Strip.Eq.SetGain(stripIndex, bandIndex, gain)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error setting strip EQ band gain: %w", err)
|
||||
}
|
||||
|
||||
cmd.Printf("Strip %d EQ band %d gain set to %.2f dB\n", stripIndex, bandIndex, gain)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
// stripEqFreqCmd represents the strip EQ Frequency command.
|
||||
var stripEqFreqCmd = &cobra.Command{
|
||||
Short: "Get or set the EQ band frequency for a strip",
|
||||
Long: "Get or set the EQ band frequency for a specific strip and band.",
|
||||
Use: "freq [strip 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 strip number and band number")
|
||||
}
|
||||
|
||||
stripIndex, bandIndex := func() (int, int) {
|
||||
return mustConvToInt(args[0]), mustConvToInt(args[1])
|
||||
}()
|
||||
|
||||
if len(args) == 2 {
|
||||
currentFreq, err := client.Strip.Eq.Frequency(stripIndex, bandIndex)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting strip EQ band frequency: %w", err)
|
||||
}
|
||||
cmd.Printf("Strip %d EQ band %d frequency: %.2f Hz\n", stripIndex, bandIndex, currentFreq)
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(args) < 3 {
|
||||
return fmt.Errorf("Please provide a frequency in Hz")
|
||||
}
|
||||
|
||||
freq := mustConvToFloat64(args[2])
|
||||
|
||||
err := client.Strip.Eq.SetFrequency(stripIndex, bandIndex, freq)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error setting strip EQ band frequency: %w", err)
|
||||
}
|
||||
|
||||
cmd.Printf("Strip %d EQ band %d frequency set to %.2f Hz\n", stripIndex, bandIndex, freq)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
// stripEqQCmd represents the strip EQ Q command.
|
||||
var stripEqQCmd = &cobra.Command{
|
||||
Short: "Get or set the EQ band Q factor for a strip",
|
||||
Long: "Get or set the EQ band Q factor for a specific strip and band.",
|
||||
Use: "q [strip 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 strip number and band number")
|
||||
}
|
||||
|
||||
stripIndex, bandIndex := func() (int, int) {
|
||||
return mustConvToInt(args[0]), mustConvToInt(args[1])
|
||||
}()
|
||||
|
||||
if len(args) == 2 {
|
||||
currentQ, err := client.Strip.Eq.Q(stripIndex, bandIndex)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting strip EQ band Q factor: %w", err)
|
||||
}
|
||||
cmd.Printf("Strip %d EQ band %d Q factor: %.2f\n", stripIndex, bandIndex, currentQ)
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(args) < 3 {
|
||||
return fmt.Errorf("Please provide a Q factor")
|
||||
}
|
||||
|
||||
q := mustConvToFloat64(args[2])
|
||||
|
||||
err := client.Strip.Eq.SetQ(stripIndex, bandIndex, q)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error setting strip EQ band Q factor: %w", err)
|
||||
}
|
||||
|
||||
cmd.Printf("Strip %d EQ band %d Q factor set to %.2f\n", stripIndex, bandIndex, q)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
// stripEqTypeCmd represents the strip EQ Type command.
|
||||
var stripEqTypeCmd = &cobra.Command{
|
||||
Short: "Get or set the EQ band type for a strip",
|
||||
Long: "Get or set the EQ band type for a specific strip and band.",
|
||||
Use: "type [strip 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 strip number and band number")
|
||||
}
|
||||
|
||||
stripIndex, 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.Strip.Eq.Type(stripIndex, bandIndex)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting strip EQ band type: %w", err)
|
||||
}
|
||||
cmd.Printf("Strip %d EQ band %d type: %s\n", stripIndex, bandIndex, eqTypeNames[currentType])
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(args) < 3 {
|
||||
return fmt.Errorf("Please provide a type")
|
||||
}
|
||||
|
||||
eqType := indexOf(eqTypeNames, args[2])
|
||||
if eqType == -1 {
|
||||
return fmt.Errorf("Invalid EQ band type. Valid types are: %v", eqTypeNames)
|
||||
}
|
||||
|
||||
err := client.Strip.Eq.SetType(stripIndex, bandIndex, eqType)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error setting strip EQ band type: %w", err)
|
||||
}
|
||||
|
||||
cmd.Printf("Strip %d EQ band %d type set to %s\n", stripIndex, bandIndex, eqTypeNames[eqType])
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
// stripCompCmd represents the strip Compressor command.
|
||||
var stripCompCmd = &cobra.Command{
|
||||
Short: "Commands to control the Compressor of individual strips.",
|
||||
@ -563,6 +744,10 @@ func init() {
|
||||
|
||||
stripCmd.AddCommand(stripEqCmd)
|
||||
stripEqCmd.AddCommand(stripEqOnCmd)
|
||||
stripEqCmd.AddCommand(stripEqGainCmd)
|
||||
stripEqCmd.AddCommand(stripEqFreqCmd)
|
||||
stripEqCmd.AddCommand(stripEqQCmd)
|
||||
stripEqCmd.AddCommand(stripEqTypeCmd)
|
||||
|
||||
stripCmd.AddCommand(stripCompCmd)
|
||||
stripCompCmd.AddCommand(stripCompOnCmd)
|
||||
|
||||
10
cmd/util.go
10
cmd/util.go
@ -21,3 +21,13 @@ func mustConvToInt(intStr string) int {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
24
go.mod
24
go.mod
@ -11,17 +11,17 @@ require (
|
||||
|
||||
require (
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/charmbracelet/colorprofile v0.3.3 // indirect
|
||||
github.com/charmbracelet/colorprofile v0.4.1 // indirect
|
||||
github.com/charmbracelet/lipgloss v1.1.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.10.3 // indirect
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
|
||||
github.com/charmbracelet/x/ansi v0.11.4 // indirect
|
||||
github.com/charmbracelet/x/cellbuf v0.0.14 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.2 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.4.1 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.9.0 // indirect
|
||||
github.com/clipperhouse/stringish v0.1.1 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.5.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.3.0 // 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/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/sagikazarmark/locafero v0.12.0 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect
|
||||
golang.org/x/sys v0.40.0 // indirect
|
||||
golang.org/x/text v0.33.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/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/charmbracelet/colorprofile v0.3.3 h1:DjJzJtLP6/NZ8p7Cgjno0CKGr7wwRJGxWUwh2IyhfAI=
|
||||
github.com/charmbracelet/colorprofile v0.3.3/go.mod h1:nB1FugsAbzq284eJcjfah2nhdSLppN2NqvfotkfRYP4=
|
||||
github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk=
|
||||
github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk=
|
||||
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/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig=
|
||||
github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw=
|
||||
github.com/charmbracelet/x/ansi v0.10.3 h1:3WoV9XN8uMEnFRZZ+vBPRy59TaIWa+gJodS4Vg5Fut0=
|
||||
github.com/charmbracelet/x/ansi v0.10.3/go.mod h1:uQt8bOrq/xgXjlGcFMc8U2WYbnxyjrKhnvTQluvfCaE=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
|
||||
github.com/charmbracelet/x/ansi v0.11.4 h1:6G65PLu6HjmE858CnTUQY1LXT3ZUWwfvqEROLF8vqHI=
|
||||
github.com/charmbracelet/x/ansi v0.11.4/go.mod h1:/5AZ+UfWExW3int5H5ugnsG/PWjNcSQcwYsHBlPFQN4=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA=
|
||||
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/clipperhouse/displaywidth v0.4.1 h1:uVw9V8UDfnggg3K2U84VWY1YLQ/x2aKSCtkRyYozfoU=
|
||||
github.com/clipperhouse/displaywidth v0.4.1/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
|
||||
github.com/clipperhouse/displaywidth v0.9.0 h1:Qb4KOhYwRiN3viMv1v/3cTBlz3AcAZX3+y9OLhMtAtA=
|
||||
github.com/clipperhouse/displaywidth v0.9.0/go.mod h1:aCAAqTlh4GIVkhQnJpbL0T/WfcrJXHcj8C0yjYcjOZA=
|
||||
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/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
|
||||
github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U=
|
||||
github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
|
||||
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/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/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/go-logfmt/logfmt v0.6.1 h1:4hvbpePJKnIzH1B+8OR/JPbTx37NktoI9LE2QZBBkvE=
|
||||
github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/z6CO0XAk=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
@ -56,10 +56,8 @@ 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/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
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/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4=
|
||||
github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
@ -79,13 +77,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=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU=
|
||||
golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||
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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@ -49,6 +49,26 @@ func (e *Eq) SetOn(index int, on bool) error {
|
||||
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)
|
||||
@ -62,11 +82,77 @@ func (e *Eq) Gain(index int, band int) (float64, error) {
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("unexpected argument type for EQ gain value")
|
||||
}
|
||||
return float64(val), nil
|
||||
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(gain))
|
||||
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))
|
||||
}
|
||||
|
||||
@ -10,6 +10,14 @@ 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 {
|
||||
switch {
|
||||
case db >= 10:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user