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.
pull/110/head
lawl 3 years ago
parent 6ea788a0c0
commit 95e82fcbfd

138
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)
}
}

@ -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)

Loading…
Cancel
Save