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