/* NAME test-audio/main.go AUTHORS Ella Pietraroia LICENSE revid is Copyright (C) 2017-2020 the Australian Ocean Lab (AusOcean) It is free software: you can redistribute it and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in gpl.txt. If not, see http://www.gnu.org/licenses. */ //testing for underwater speaker audio playing on pi /* Pi Setup: pull master $sudo nano main.go chage file variable at top of function to be wav file that you have put onto the pi (hint: spc command) navigate to /go/src/bitbucket.org/ausocean/av/cmd/audio-player/looper and build edit rc.local to run looper at boot $sudo nano /etc/rc.local paste this in after comments but before 'exit 0': exec 2> /tmp/rc.local.log # send stderr from rc.local to a log file exec 1>&2 # send stdout to the same log file printf "rc.local started" # show start of execution set -x # tell sh to display commands before execution AUDIOPATH=/home/pi/go/src/bitbucket.org/ausocean/av/cmd/audio-player/looper cd $AUDIOPATH ./looper & $systemctl enable rc-local $sudo systemctl start rc-local.service */ package main import ( "bytes" "io" "log" "os" "os/exec" "sync" "time" ) func main() { file := "48khz.wav" //"5mStartToEndOfTrials.wav" //making log file _, err := os.Stat("audio.log") if !os.IsNotExist(err) { err := os.Remove("audio.log") if err != nil { log.Fatalf("fatal: error clearing file: %v", err) } } f, err := os.OpenFile("audio.log", os.O_RDWR|os.O_CREATE, 0666) //chage to empty each time if err != nil { log.Fatalf("fatal: error opening file: %v", err) } defer f.Close() log.SetOutput(f) path, err := exec.LookPath("alsactl") if err != nil { log.Fatalf("fatal: didn't find 'alsactl' executable\n") } else { log.Printf("'alsactl' executable is in '%s'\n", path) } for { cmdInit := exec.Command("alsactl", "-f", "/usr/share/doc/audioInjector/asound.state.RCA.thru.test", "restore") err := cmdInit.Run() if err == nil { break } log.Printf("fatal(ish): cmd.Run() for alsactl failed with '%s'\n", err) time.Sleep(1 * time.Second) } //making sure that play is on pi path, err = exec.LookPath("play") if err != nil { log.Fatalf("fatal: didn't find 'play' executable\n") } else { log.Printf("'play' executable is in '%s'\n", path) } numPlays := 0 for { numPlays++ log.Printf(" Number of times played: %d\n", numPlays) cmd := exec.Command("play", file) var stdoutBuf, stderrBuf bytes.Buffer stdoutIn, _ := cmd.StdoutPipe() stderrIn, _ := cmd.StderrPipe() var errStdout, errStderr error stdout := io.MultiWriter(os.Stdout, &stdoutBuf) stderr := io.MultiWriter(os.Stderr, &stderrBuf) err := cmd.Start() if err != nil { log.Fatalf("fatal: cmd.Start() failed with '%s'\n", err) } var wg sync.WaitGroup wg.Add(1) go func() { _, errStdout = io.Copy(stdout, stdoutIn) wg.Done() }() _, errStderr = io.Copy(stderr, stderrIn) wg.Wait() err = cmd.Wait() if err != nil { log.Fatalf("fatal: cmd.Run() failed with %s\n", err) } if errStdout != nil || errStderr != nil { log.Fatal("fatal: failed to capture stdout or stderr\n") } outStr, errStr := string(stdoutBuf.Bytes()), string(stderrBuf.Bytes()) log.Printf("\nout:\n%s\nerr:\n%s\n____________________________________________________\n\n", outStr, errStr) } }