Compare commits
	
		
			No commits in common. "ebb4d7102bb393d5185ce318524850609d4790c8" and "d59a2859b61c3a18c1bf5dc4016bcfedec421dcc" have entirely different histories.
		
	
	
		
			ebb4d7102b
			...
			d59a2859b6
		
	
		
							
								
								
									
										10
									
								
								README.md
								
								
								
								
							
							
						
						
									
										10
									
								
								README.md
								
								
								
								
							|  | @ -20,16 +20,16 @@ milkbucket reads a PCM stream from standard input to generate visualizations. | ||||||
| If you have an audio file and a preset in mind, you can use `ffmpeg` to | If you have an audio file and a preset in mind, you can use `ffmpeg` to | ||||||
| generate the PCM stream, then pipe to milkbucket, like so: | generate the PCM stream, then pipe to milkbucket, like so: | ||||||
| ``` | ``` | ||||||
| ffmpeg -i $audio -ar 44100 -f s16le - | ./milkbucket $preset | ffmpeg -i $audio -ar 44100 -f s16le - | ./milkbucket -p $preset | ||||||
| ``` | ``` | ||||||
| Note that you can pass in multiple presets, then use the arrow keys to cycle | Note that you can pass in multiple presets with multiple `-p` flags, then use | ||||||
| through the presets while running. | the arrow keys to cycle through the presets while running. | ||||||
| 
 | 
 | ||||||
| Note that neither of these commands (ffmpeg or milkbucket) will output any | Note that neither of these commands (ffmpeg or milkbucket) will output any | ||||||
| audio! If you want to hear the audio at the same time (and assuming your | audio! If you want to hear the audio at the same time (and assuming your | ||||||
| machine uses pipewire), run: | machine uses pipewire), run: | ||||||
| ``` | ``` | ||||||
| ffmpeg -i $audio -ar 44100 -f s16le - | tee >(pw-play --rate=44100 --format=s16 -) | ./milkbucket $preset | ffmpeg -i $audio -ar 44100 -f s16le - | tee >(pw-play --rate=44100 --format=s16 -) | ./milkbucket -p $preset | ||||||
| ``` | ``` | ||||||
| (If you don't use pipewire try using `aplay` instead of `pw-play`, or some | (If you don't use pipewire try using `aplay` instead of `pw-play`, or some | ||||||
| other command for playing PCM streams.) | other command for playing PCM streams.) | ||||||
|  | @ -37,5 +37,5 @@ other command for playing PCM streams.) | ||||||
| You can also generate a visualization from your system sound. Assuming pipewire | You can also generate a visualization from your system sound. Assuming pipewire | ||||||
| again, and that you have audio coming from Firefox, run: | again, and that you have audio coming from Firefox, run: | ||||||
| ``` | ``` | ||||||
| pw-record --target Firefox - | ./milkbucket $preset | pw-record --target Firefox - | ./milkbucket -p $preset | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
							
								
								
									
										47
									
								
								cmd/root.go
								
								
								
								
							
							
						
						
									
										47
									
								
								cmd/root.go
								
								
								
								
							|  | @ -20,12 +20,14 @@ import ( | ||||||
| 	"encoding/binary" | 	"encoding/binary" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"io" | 	"io" | ||||||
|  | 	"log" | ||||||
| 	"os" | 	"os" | ||||||
| 
 | 
 | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
| 	"github.com/veandco/go-sdl2/sdl" | 	"github.com/veandco/go-sdl2/sdl" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | var presets []string | ||||||
| var transition bool | var transition bool | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|  | @ -44,29 +46,16 @@ func checkStdin() error { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|  * validatePreset performs some basic checks on the preset passed in and |  * validatePresets performs some basic checks on the presets passed in and | ||||||
|  * returns an error if it finds a problem. |  * returns an error if it finds a problem. | ||||||
|  */ |  */ | ||||||
| func validatePreset(preset string) error { | func validatePresets() error { | ||||||
| 	info, err := os.Stat(preset) | 	for _, p := range presets { | ||||||
|  | 		info, err := os.Stat(p) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} else if info.IsDir() { | 		} else if info.IsDir() { | ||||||
| 		return errors.New("preset " + preset + " is a directory") | 			return errors.New("preset " + p + " is a directory") | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|  * validatePresets validates each preset passed in and returns an error if it |  | ||||||
|  * finds a problem. |  | ||||||
|  */ |  | ||||||
| func validatePresets(cmd *cobra.Command, args []string) error { |  | ||||||
| 	for _, p := range args { |  | ||||||
| 		err := validatePreset(p) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -147,43 +136,45 @@ func update(m *milkDropWindow) (bool, error) { | ||||||
| func milkbucket(cmd *cobra.Command, args []string) { | func milkbucket(cmd *cobra.Command, args []string) { | ||||||
| 	err := checkStdin() | 	err := checkStdin() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		cobra.CheckErr(err) | 		log.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = sdl.Init(sdl.INIT_VIDEO) | 	err = sdl.Init(sdl.INIT_VIDEO) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		cobra.CheckErr(err) | 		log.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	defer sdl.Quit() | 	defer sdl.Quit() | ||||||
| 
 | 
 | ||||||
| 	m, err := newMilkDropWindow(800, 600, args) | 	err = validatePresets() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		cobra.CheckErr(err) | 		log.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	m, err := newMilkDropWindow(800, 600, presets) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	defer m.destroy() | 	defer m.destroy() | ||||||
| 
 | 
 | ||||||
| 	if len(args) > 0 { |  | ||||||
| 	m.loadPreset(false) | 	m.loadPreset(false) | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	running := true | 	running := true | ||||||
| 	for running { | 	for running { | ||||||
| 		running, err = update(m) | 		running, err = update(m) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			cobra.CheckErr(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // rootCmd represents the base command when called without any subcommands
 | // rootCmd represents the base command when called without any subcommands
 | ||||||
| var rootCmd = &cobra.Command{ | var rootCmd = &cobra.Command{ | ||||||
| 	Use:   "milkbucket [presets]", | 	Use:   "milkbucket", | ||||||
| 	Short: "Audio visualizer", | 	Short: "Audio visualizer", | ||||||
| 	Long: `milkbucket is an audio visualizer. | 	Long: `milkbucket is an audio visualizer. | ||||||
| 
 | 
 | ||||||
| It uses Milkdrop preset files to generate visualizations from standard input.`, | It uses Milkdrop preset files to generate visualizations from standard input.`, | ||||||
| 	Run: milkbucket, | 	Run: milkbucket, | ||||||
| 	Args: validatePresets, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Execute adds all child commands to the root command and sets flags appropriately.
 | // Execute adds all child commands to the root command and sets flags appropriately.
 | ||||||
|  | @ -203,4 +194,6 @@ func init() { | ||||||
| 	// Cobra also supports local flags, which will only run
 | 	// Cobra also supports local flags, which will only run
 | ||||||
| 	// when this action is called directly.
 | 	// when this action is called directly.
 | ||||||
| 	rootCmd.Flags().BoolVarP(&transition, "transition", "t", false, "smoothly transition between presets") | 	rootCmd.Flags().BoolVarP(&transition, "transition", "t", false, "smoothly transition between presets") | ||||||
|  | 
 | ||||||
|  | 	rootCmd.Flags().StringArrayVarP(&presets, "presets", "p", []string{}, "preset files to use") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -67,10 +67,8 @@ func (m *milkDropWindow) setupPresets(presets []string) { | ||||||
|  * preset. |  * preset. | ||||||
|  */ |  */ | ||||||
| func (m *milkDropWindow) nextPreset(smooth bool) { | func (m *milkDropWindow) nextPreset(smooth bool) { | ||||||
| 	if m.preset.Len() > 0 { |  | ||||||
| 	m.preset = m.preset.Next() | 	m.preset = m.preset.Next() | ||||||
| 	m.loadPreset(smooth) | 	m.loadPreset(smooth) | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|  | @ -78,10 +76,8 @@ func (m *milkDropWindow) nextPreset(smooth bool) { | ||||||
|  * preset. |  * preset. | ||||||
|  */ |  */ | ||||||
| func (m *milkDropWindow) prevPreset(smooth bool) { | func (m *milkDropWindow) prevPreset(smooth bool) { | ||||||
| 	if m.preset.Len() > 0 { |  | ||||||
| 	m.preset = m.preset.Prev() | 	m.preset = m.preset.Prev() | ||||||
| 	m.loadPreset(smooth) | 	m.loadPreset(smooth) | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue