From 95e82fcbfd386c81040006d0c088d0df13d4faf9 Mon Sep 17 00:00:00 2001 From: lawl Date: Mon, 5 Apr 2021 15:24:12 +0200 Subject: [PATCH] CLI: Factor CLI out of main Our CLI shared some data structures, like the pulseaudio connection with the GUI. This could lead to issues where the UI would break when code on the CLI was changed because the the GUI must handle things differently, by nature of working differently. Add more separation between those, so changes on the CLI are less likely to break the GUI. --- cli.go | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 125 +------------------------------------------------- 2 files changed, 139 insertions(+), 124 deletions(-) create mode 100644 cli.go diff --git a/cli.go b/cli.go new file mode 100644 index 0000000..716678b --- /dev/null +++ b/cli.go @@ -0,0 +1,138 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + + "github.com/lawl/pulseaudio" +) + +func doCLI(config *config, librnnoise string) { + var setcap bool + var sinkName string + var unload bool + var loadInput bool + var loadOutput bool + var threshold int + var list bool + + flag.BoolVar(&setcap, "setcap", false, "for internal use only") + flag.StringVar(&sinkName, "s", "", "Use the specified source/sink device ID") + flag.BoolVar(&loadInput, "i", false, "Load supressor for input. If no source device ID is specified the default pulse audio source is used.") + flag.BoolVar(&loadOutput, "o", false, "Load supressor for output. If no source device ID is specified the default pulse audio source is used.") + flag.BoolVar(&unload, "u", false, "Unload supressor") + flag.IntVar(&threshold, "t", -1, "Voice activation threshold") + flag.BoolVar(&list, "l", false, "List available PulseAudio devices") + flag.Parse() + + paClient, err := pulseaudio.NewClient() + + if err != nil { + log.Printf("Couldn't create pulseaudio client: %v\n", err) + os.Exit(1) + } + defer paClient.Close() + + ctx := ntcontext{} + ctx.config = config + ctx.librnnoise = librnnoise + + ctx.paClient = paClient + + if setcap { + err := makeBinarySetcapped() + if err != nil { + os.Exit(1) + } + os.Exit(0) + } + + if list { + fmt.Println("Sources:") + sources := getSources(paClient) + for i := range sources { + fmt.Printf("\tDevice Name: %s\n\tDevice ID: %s\n\n", sources[i].Name, sources[i].ID) + } + + fmt.Println("Sinks:") + sinks := getSinks(paClient) + for i := range sinks { + fmt.Printf("\tDevice Name: %s\n\tDevice ID: %s\n\n", sinks[i].Name, sinks[i].ID) + } + + os.Exit(0) + } + + if threshold > 0 { + if threshold > 95 { + fmt.Fprintf(os.Stderr, "Threshold of '%d' too high, setting to maximum of 95.\n", threshold) + ctx.config.Threshold = 95 + } else { + ctx.config.Threshold = threshold + } + } + + if unload { + err := unloadSupressor(&ctx) + if err != nil { + fmt.Fprintf(os.Stderr, "Error unloading PulseAudio Module: %+v\n", err) + os.Exit(1) + } + os.Exit(0) + } + + if loadInput { + sources := getSources(paClient) + + if sinkName == "" { + defaultSource, err := getDefaultSourceID(paClient) + if err != nil { + fmt.Fprintf(os.Stderr, "No source specified to load and failed to load default source: %+v\n", err) + os.Exit(1) + } + sinkName = defaultSource + } + for i := range sources { + if sources[i].ID == sinkName { + sources[i].checked = true + err := loadSupressor(&ctx, &sources[i], &device{}) + if err != nil { + fmt.Fprintf(os.Stderr, "Error loading PulseAudio Module: %+v\n", err) + os.Exit(1) + } + os.Exit(0) + } + } + fmt.Fprintf(os.Stderr, "PulseAudio source not found: %s\n", sinkName) + os.Exit(1) + + } + if loadOutput { + sinks := getSinks(paClient) + + if sinkName == "" { + defaultSink, err := getDefaultSinkID(paClient) + if err != nil { + fmt.Fprintf(os.Stderr, "No sink specified to load and failed to load default sink: %+v\n", err) + os.Exit(1) + } + sinkName = defaultSink + } + for i := range sinks { + if sinks[i].ID == sinkName { + sinks[i].checked = true + err := loadSupressor(&ctx, &device{}, &sinks[i]) + if err != nil { + fmt.Fprintf(os.Stderr, "Error loading PulseAudio Module: %+v\n", err) + os.Exit(1) + } + os.Exit(0) + } + } + fmt.Fprintf(os.Stderr, "PulseAudio sink not found: %s\n", sinkName) + os.Exit(1) + + } +} diff --git a/main.go b/main.go index 7aed3cf..a4fdc72 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,6 @@ package main import ( - "flag" "fmt" "image" "io/ioutil" @@ -46,31 +45,6 @@ const appName = "NoiseTorch" func main() { - var setcap bool - var sinkName string - var unload bool - var loadInput bool - var loadOutput bool - var threshold int - var list bool - - flag.BoolVar(&setcap, "setcap", false, "for internal use only") - flag.StringVar(&sinkName, "s", "", "Use the specified source/sink device ID") - flag.BoolVar(&loadInput, "i", false, "Load supressor for input. If no source device ID is specified the default pulse audio source is used.") - flag.BoolVar(&loadOutput, "o", false, "Load supressor for output. If no source device ID is specified the default pulse audio source is used.") - flag.BoolVar(&unload, "u", false, "Unload supressor") - flag.IntVar(&threshold, "t", -1, "Voice activation threshold") - flag.BoolVar(&list, "l", false, "List available PulseAudio devices") - flag.Parse() - - if setcap { - err := makeBinarySetcapped() - if err != nil { - os.Exit(1) - } - os.Exit(0) - } - date := time.Now().Format("2006_01_02_15_04_05") tmpdir := os.TempDir() f, err := os.OpenFile(filepath.Join(tmpdir, fmt.Sprintf("noisetorch-%s.log", date)), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) @@ -91,104 +65,7 @@ func main() { ctx.config = readConfig() ctx.librnnoise = rnnoisefile - paClient, err := pulseaudio.NewClient() - - if err != nil { - log.Printf("Couldn't create pulseaudio client: %v\n", err) - os.Exit(1) - } - - ctx.paClient = paClient - - if list { - fmt.Println("Sources:") - sources := getSources(paClient) - for i := range sources { - fmt.Printf("\tDevice Name: %s\n\tDevice ID: %s\n\n", sources[i].Name, sources[i].ID) - } - - fmt.Println("Sinks:") - sinks := getSinks(paClient) - for i := range sinks { - fmt.Printf("\tDevice Name: %s\n\tDevice ID: %s\n\n", sinks[i].Name, sinks[i].ID) - } - - os.Exit(0) - } - - if threshold > 0 { - if threshold > 95 { - fmt.Fprintf(os.Stderr, "Threshold of '%d' too high, setting to maximum of 95.\n", threshold) - ctx.config.Threshold = 95 - } else { - ctx.config.Threshold = threshold - } - } - - if unload { - err := unloadSupressor(&ctx) - if err != nil { - fmt.Fprintf(os.Stderr, "Error unloading PulseAudio Module: %+v\n", err) - os.Exit(1) - } - os.Exit(0) - } - - if loadInput { - sources := getSources(paClient) - - if sinkName == "" { - defaultSource, err := getDefaultSourceID(paClient) - if err != nil { - fmt.Fprintf(os.Stderr, "No source specified to load and failed to load default source: %+v\n", err) - os.Exit(1) - } - sinkName = defaultSource - } - for i := range sources { - if sources[i].ID == sinkName { - sources[i].checked = true - err := loadSupressor(&ctx, &sources[i], &device{}) - if err != nil { - fmt.Fprintf(os.Stderr, "Error loading PulseAudio Module: %+v\n", err) - os.Exit(1) - } - os.Exit(0) - } - } - fmt.Fprintf(os.Stderr, "PulseAudio source not found: %s\n", sinkName) - os.Exit(1) - - } - if loadOutput { - sinks := getSinks(paClient) - - if sinkName == "" { - defaultSink, err := getDefaultSinkID(paClient) - if err != nil { - fmt.Fprintf(os.Stderr, "No sink specified to load and failed to load default sink: %+v\n", err) - os.Exit(1) - } - sinkName = defaultSink - } - for i := range sinks { - if sinks[i].ID == sinkName { - sinks[i].checked = true - err := loadSupressor(&ctx, &device{}, &sinks[i]) - if err != nil { - fmt.Fprintf(os.Stderr, "Error loading PulseAudio Module: %+v\n", err) - os.Exit(1) - } - os.Exit(0) - } - } - fmt.Fprintf(os.Stderr, "PulseAudio sink not found: %s\n", sinkName) - os.Exit(1) - - } - - ctx.paClient.Close() - ctx.paClient = nil + doCLI(ctx.config, ctx.librnnoise) if ctx.config.EnableUpdates { go updateCheck(&ctx)