mirror of
				https://github.com/vsariola/sointu.git
				synced 2025-10-30 15:35:41 -04:00 
			
		
		
		
	feat(sointu-player): implement a basic commandline tool to play songs
This commit is contained in:
		
							
								
								
									
										91
									
								
								go4k/cmd/sointu-player/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								go4k/cmd/sointu-player/main.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,91 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"github.com/vsariola/sointu/go4k" | ||||
| 	"github.com/vsariola/sointu/go4k/audio" | ||||
| 	"github.com/vsariola/sointu/go4k/audio/oto" | ||||
| 	"github.com/vsariola/sointu/go4k/bridge" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	// parse flags | ||||
| 	quiet := flag.Bool("quiet", false, "no sound output") | ||||
| 	out := flag.String("out", "", "write output to file") | ||||
| 	help := flag.Bool("h", false, "show help") | ||||
| 	flag.Usage = printUsage | ||||
| 	flag.Parse() | ||||
| 	if flag.NArg() == 0 || *help { | ||||
| 		flag.Usage() | ||||
| 		os.Exit(0) | ||||
| 	} | ||||
|  | ||||
| 	// read input song | ||||
| 	var song go4k.Song | ||||
| 	if bytes, err := ioutil.ReadFile(flag.Arg(0)); err != nil { | ||||
| 		fmt.Printf("Cannot read song file: %v", err) | ||||
| 		os.Exit(1) | ||||
| 	} else if err := json.Unmarshal(bytes, &song); err != nil { | ||||
| 		fmt.Printf("Cannot unmarshal song file: %v", err) | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
|  | ||||
| 	// set up synth | ||||
| 	synth, err := bridge.Synth(song.Patch) | ||||
| 	if err != nil { | ||||
| 		fmt.Printf("Cannot create synth: %v", err) | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
|  | ||||
| 	// render the actual data for the entire song | ||||
| 	fmt.Print("Rendering.. ") | ||||
| 	buff, err := go4k.Play(synth, song) | ||||
| 	if err != nil { | ||||
| 		fmt.Printf("Error rendering with go4k: %v\n", err.Error()) | ||||
| 		os.Exit(1) | ||||
| 	} else { | ||||
| 		fmt.Printf("Rendered %v samples.\n", len(buff)) | ||||
| 	} | ||||
|  | ||||
| 	// play output if not in quiet mode | ||||
| 	if !*quiet { | ||||
| 		fmt.Print("Playing.. ") | ||||
| 		player, err := oto.NewPlayer() | ||||
| 		if err != nil { | ||||
| 			fmt.Printf("Error creating oto player: %v\n", err.Error()) | ||||
| 			os.Exit(1) | ||||
| 		} | ||||
| 		defer player.Close() | ||||
| 		if err := player.Play(buff); err != nil { | ||||
| 			fmt.Printf("Error playing: %v\n", err.Error()) | ||||
| 			os.Exit(1) | ||||
| 		} | ||||
| 		fmt.Println("Played.") | ||||
| 	} | ||||
|  | ||||
| 	// write output to file if output given | ||||
| 	if out != nil && *out != "" { | ||||
| 		fmt.Printf("Writing output to %v.. ", *out) | ||||
| 		if bbuffer, err := audio.FloatBufferTo16BitLE(buff); err != nil { | ||||
| 			fmt.Printf("Error converting buffer: %v\n", err.Error()) | ||||
| 			os.Exit(1) | ||||
| 		} else if err := ioutil.WriteFile(*out, bbuffer, os.ModePerm); err != nil { | ||||
| 			fmt.Printf("Error writing: %v\n", err.Error()) | ||||
| 			os.Exit(1) | ||||
| 		} else { | ||||
| 			fmt.Printf("Wrote %v bytes.\n", len(bbuffer)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	fmt.Println("All done.") | ||||
| 	os.Exit(0) | ||||
| } | ||||
|  | ||||
| func printUsage() { | ||||
| 	fmt.Fprintf(os.Stderr, "Usage: %s [OPTIONS] [SONG FILE] [OUTPUT FILE]\n", os.Args[0]) | ||||
| 	flag.PrintDefaults() | ||||
| } | ||||
		Reference in New Issue
	
	Block a user