// start and connect timidity daemon to port.
start and connect timidity daemon to port.
// start and connect timidity daemon to port .
func startTimidity(port string, ready chan struct{}, quit <-chan struct{}) error {
	freepatsPath := "/usr/share/midi/freepats"
	if snapdir := os.Getenv("SNAP"); snapdir != "" {
		freepatsPath = path.Join(snapdir, freepatsPath)
	}
	cmd := exec.Command("timidity", "-Os", "-iA", "-c", path.Join(rootdir, "timidity-snap.cfg"),
		"-L", freepatsPath)
	var errbuf bytes.Buffer
	cmd.Stderr = &errbuf
	cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
	e := cmd.Start()
	if e != nil {
		return e
	}
	wg := sync.WaitGroup{}
	done := make(chan bool)
	defer close(done)
	go func() {
		select {
		case <-quit:
			Debug.Println("Forcing timidity to stop")
		case <-done:
		}
		cmd.Process.Kill()
		cmd = nil
	}()
	err := make(chan error, 1)
	defer close(err)
	wg.Add(1)
	go func() {
		defer wg.Done()
		Debug.Println("Starting timidity")
		e := cmd.Wait()
		err <- fmt.Errorf("%s: %v", errbuf.String(), e)
		Debug.Println("Timidity stopped")
	}()
	wg.Add(1)
	go func() {
		defer wg.Done()
		Debug.Println("Starting timidity connector")
		connectTimitidy(port, ready, done, err)
		Debug.Println("Timidity connector ended")
	}()
	e = <-err
	if cmd != nil {
		done <- true
	}
	wg.Wait()
	return e
}
func startTimidity ( port string , ready chan struct { } , quit <- chan struct { } ) error { freepatsPath := " " if snapdir := os . Getenv ( " " ) ; snapdir != " " { freepatsPath = path . Join ( snapdir , freepatsPath ) } cmd := exec . Command ( " " , " " , " " , " " , path . Join ( rootdir , " " ) , " " , freepatsPath ) var errbuf bytes . Buffer cmd . Stderr = & errbuf cmd . SysProcAttr = & syscall . SysProcAttr { Setpgid : true } e := cmd . Start ( ) if e != nil { return e } wg := sync . WaitGroup { } done := make ( chan bool ) defer close ( done ) go func ( ) { select { case <- quit : Debug . Println ( " " ) case <- done : } cmd . Process . Kill ( ) cmd = nil } ( ) err := make ( chan error , 1 ) defer close ( err ) wg . Add ( 1 ) go func ( ) { defer wg . Done ( ) Debug . Println ( " " ) e := cmd . Wait ( ) err <- fmt . Errorf ( " " , errbuf . String ( ) , e ) Debug . Println ( " " ) } ( ) wg . Add ( 1 ) go func ( ) { defer wg . Done ( ) Debug . Println ( " " ) connectTimitidy ( port , ready , done , err ) Debug . Println ( " " ) } ( ) e = <- err if cmd != nil { done <- true } wg . Wait ( ) return e }
start and connect timidity daemon to port.
start and connect timidity daemon to port .
// prevent Ctrl + C and other signals to get sent // killer goroutine // we have 2 goroutines which can send to err // if we stop the connect goroutine, the timidity .Wait() will try to send there // Timitidy process // connector goroutine // signal to kill timidity if still running