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) }
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) } }