From 5f141dbd3e53362fee180fea512d600a4c4e2915 Mon Sep 17 00:00:00 2001 From: Drew Bednar Date: Sat, 21 Jun 2025 11:36:37 -0400 Subject: [PATCH] Working example of piping commands --- go.mod | 3 +++ main.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 go.mod create mode 100644 main.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7838314 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module gosay + +go 1.24.1 diff --git a/main.go b/main.go new file mode 100644 index 0000000..3260f90 --- /dev/null +++ b/main.go @@ -0,0 +1,59 @@ +// https://www.dolthub.com/blog/2022-11-28-go-os-exec-patterns/ + +package main + +import ( + "bufio" + "bytes" + "fmt" + "log/slog" + "os" + "os/exec" + "strings" +) + +var rawPiperCmd = strings.Split("piper --model /home/toor/piper_models/en_US-ryan-medium.onnx --output-raw", " ") +var rawAplayCmd = strings.Split("aplay -r 22050 -f S16_LE -t raw -", " ") + +func say(msg []byte) error { + buf := new(bytes.Buffer) + buf.Write(msg) + r, w, err := os.Pipe() + if err != nil { + return err + } + defer r.Close() + piperCmd := exec.Command(rawPiperCmd[0], rawPiperCmd[1:]...) + piperCmd.Stdin = buf + piperCmd.Stdout = w + err = piperCmd.Start() + if err != nil { + return err + } + w.Close() + defer piperCmd.Wait() + + aplayCmd := exec.Command(rawAplayCmd[0], rawAplayCmd[1:]...) + aplayCmd.Stdin = r + return aplayCmd.Run() +} + +func main() { + fmt.Println("Go say!") + reader := bufio.NewReader(os.Stdin) + + for { + fmt.Println("Give me something to say: ") + msg, err := reader.ReadString('\n') + if err != nil { + slog.Error("encoutered error reading from stdin", "error", err) + continue + } + contents := strings.TrimSpace(msg) + err = say([]byte(contents)) + if err != nil { + slog.Error("encountered error in say command", "error", err) + } + } + +}