Exemple #1
0
func main() {
	var (
		id  = flag.Int("id", -1, "MIDI output device ID (-1 = default)")
		bpm = flag.Int("bpm", 120, "default BPM")
	)
	flag.Parse()
	log.SetFlags(0)

	portmidi.Initialize()
	defer portmidi.Terminate()

	deviceID := *id
	if deviceID < 0 {
		deviceID = portmidi.GetDefaultOutputDeviceID()
	}

	stream, err := portmidi.NewOutputStream(deviceID, bufferSize, latency)
	if err != nil {
		log.Fatalf("NewOutputStream(device ID %d, buffer size %d, latency %v): %v", deviceID, bufferSize, latency, err)
	}

	defer stream.Close()

	var (
		pulsePerSec = (float64(*bpm) / 60.) * 24.
		interval    = (1. / pulsePerSec) * float64(time.Second)
		quitc       = make(chan struct{})
	)

	defer close(quitc)

	go func() {
		log.Printf("%d BPM = %.2f PPS", *bpm, pulsePerSec)
		defer log.Printf("done")

		tick := time.Tick(time.Duration(interval))

		for {
			select {
			case <-quitc:
				return
			case <-tick:
				stream.Write([]portmidi.Event{{Timestamp: portmidi.Time(), Status: 0xF8}})
			}
		}
	}()

	sigc := make(chan os.Signal)
	signal.Notify(sigc, syscall.SIGINT)
	log.Print(<-sigc)
}
Exemple #2
0
func main() {
	var (
		inID  = flag.Int("in", -1, "MIDI input device ID (-1 = default)")
		outID = flag.Int("out", -1, "MIDI output device ID (-1 = default)")
	)
	flag.Parse()
	log.SetFlags(0)

	portmidi.Initialize()
	defer portmidi.Terminate()

	if *inID < 0 {
		(*inID) = portmidi.GetDefaultInputDeviceID()
	}

	if *outID < 0 {
		(*outID) = portmidi.GetDefaultOutputDeviceID()
	}

	in, err := portmidi.NewInputStream(*inID, bufferSize)
	if err != nil {
		log.Fatalf("input stream (device ID %d, buffer size %d): %v", *inID, bufferSize, err)
	}

	out, err := portmidi.NewOutputStream(*outID, bufferSize, latency)
	if err != nil {
		log.Fatalf("output stream (device ID %d, buffer size %d, latency %v): %v", *outID, bufferSize, latency, err)
	}

	chain := markov.Chain{}
	board := keyboard.Keyboard{}
	first := true
	prev := keyboard.Keyboard{}

	log.Printf("listening for events...")
	for inEvent := range in.Listen() {
		log.Printf("-> %#+v", inEvent)

		board.Receive(inEvent)
		log.Printf("== %#+v", board.Keys())

		if first {
			prev = board
			first = false
			continue
		}

		chain.Observe(prev, board)
		output := chain.Emit(board).(keyboard.Keyboard)
		log.Printf("<- %#+v", output.Keys())

		prev = board
		outKeys := output.Keys()
		if len(outKeys) == 0 {
			// Can't send, will crash
			// TODO needs attention
			continue
		}

		if inEvent.Data2 == 0 {
			// don't play notes on key up
			continue
		}

		events := make([]portmidi.Event, len(outKeys))
		for i, key := range outKeys {
			events[i] = portmidi.Event{
				Timestamp: inEvent.Timestamp,
				Status:    inEvent.Status,
				Data1:     int64(key),
				Data2:     inEvent.Data2,
			}
		}
		out.Write(events)
	}
}