예제 #1
0
func main() {
	commands := []struct {
		Name        string
		Description string
		Action      func(p *drum.Pattern) int
	}{
		{"print", "print a textual representation of the pattern", func(p *drum.Pattern) int {
			fmt.Printf("%s", p)
			return 0
		}},
		{"play", "play the pattern (using libsdl2)", func(p *drum.Pattern) int {
			pl, err := drum.PlayerNew(p)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Failed to create player: "+err.Error())
				return 1
			}
			fmt.Println("Playing pattern (press <ENTER> to exit)")
			pl.Play()
			rd := bufio.NewReader(os.Stdin)
			rd.ReadString('\n')
			return 0
		}},
		{"edit", "open the pattern in the SPLICE editor", func(p *drum.Pattern) int {
			editor.Editor(p)
			return 0
		}},
	}

	printUsage := func() {
		fmt.Println("Usage: drum COMMAND FILE")
		fmt.Println("")
		fmt.Println("COMMANDS:")
		for _, c := range commands {
			fmt.Printf("\t%s\t\t%s\n", c.Name, c.Description)
		}
		fmt.Println("")
		fmt.Println("The FILE argument is a SPLICE file.")
	}

	if len(os.Args) < 3 {
		printUsage()
		os.Exit(1)
	}

	cmd := os.Args[1]
	path := os.Args[2]

	p, err := drum.DecodeFile(path)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open SPLICE file: "+err.Error())
		os.Exit(1)
	}

	for _, c := range commands {
		if cmd == c.Name {
			os.Exit(c.Action(p))
		}
	}
}
예제 #2
0
func setupPlayerWindow(p *drum.Pattern) *Window {
	var currStep int

	w := WindowNew(false)
	player, err := drum.PlayerNew(p)
	if err != nil {
		panic(err)
	}

	player.AddCallback(func(s int) {
		currStep = s
		w.Trigger("draw")
		termbox.Flush()
	})

	openFile := func() {
		player.Stop()
		path := Prompt("Open File", "Enter filename:", "fixtures/")
		if len(path) > 0 {
			p, err := drum.DecodeFile(path)
			if err != nil {
				MessageBox("File Open Failed!", err.Error(), CRed)
			} else {
				w.Close()
				w = setupPlayerWindow(p)
				w.Loop()
			}
		}
	}

	saveFile := func() {
		player.Stop()
		path := Prompt("Save File", "Enter filename:", "fixtures/")
		if len(path) > 0 {
			err := drum.EncodePattern(p, path)
			if err != nil {
				MessageBox("File Save Failed!", err.Error(), CRed)
			} else {
				MessageBox("File Save", "File saved!", CGreen)
			}
		}

	}

	changeTempo := func() {
		player.Stop()
		tempoString := Prompt("Change Tempo", "Enter new tempo:", strconv.FormatFloat(float64(p.Tempo), 'f', -1, 32))
		if len(tempoString) > 0 {
			tempo, err := strconv.ParseFloat(tempoString, 32)
			if err != nil {
				MessageBox("Invalid Tempo!", err.Error(), CRed)
			} else if tempo < 1 || tempo > 1000 {
				MessageBox("Invalid Tempo!", "Tempo must be between 1 and 1000", CRed)
			} else {
				p.Tempo = float32(tempo)
			}
		}
	}

	changeShuffle := func() {
		player.Stop()
		shuffleString := Prompt("Change Shuffle", "Enter new shuffle ratio (0.0 - 1.0):", strconv.FormatFloat(float64(player.Shuffle), 'f', -1, 32))
		if len(shuffleString) > 0 {
			shuffle, err := strconv.ParseFloat(shuffleString, 32)
			if err != nil {
				MessageBox("Invalid Shuffle Value!", err.Error(), CRed)
			} else if shuffle < 0.0 || shuffle > 1.0 {
				MessageBox("Invalid Shuffle Value!", "Must be between 0.0 and 1.0.", CRed)
			} else {
				player.Shuffle = shuffle
			}
		}

	}

	w.Listen("key", func(args ...interface{}) {
		key := args[0].(termbox.Key)
		ch := args[1].(rune)

		switch key {
		case termbox.KeyEsc:
			w.Close()
		case termbox.KeySpace:
			player.TogglePlay()
		default:
			switch ch {
			case 'c':
				p.ClearSteps()
			case 'o':
				openFile()
			case 's':
				saveFile()
			case 't':
				changeTempo()
			case 'u':
				changeShuffle()
			}
		}
	})

	LabelNew(w, ScrHW, 1, "SPLICE Editor v0.0")
	LabelNew(w, ScrHW, 2, "==================")
	LabelNew(w, ScrHW, ScrH-2, "Controls: <SPACE> to play/stop, <O> to open, <S> to save, <T> to change tempo, <U> to change shuffle, <C> to clear steps, <ESC> to exit")

	for j, t := range p.Tracks {
		y := 10 + (j * 4)
		x := ScrHW - 55

		LabelNew(w, x, y, t.Name)

		for i, _ := range t.Steps {
			x := (ScrHW - 45) + (i * 6) + int(i/4)

			if j == 0 {
				LabelNew(w, x, y-3, strconv.Itoa(i+1))
			}

			if j == len(p.Tracks)-1 {
				LedNew(w, x, y+3, i, &currStep)
			}

			StepButtonNew(w, x, y, &t.Steps[i])
		}
	}

	return w
}