Files
tinygo/src/examples/usb-midi/main.go
T
deadprogram 9d6eb1ff06 machine/usb/adc/midi: improve implementation to include several new messages
such as program changes and pitch bend. Also add error handling for invalid
parameter values such as MIDI channel. This however makes a somewhat breaking
change to the current implementation, in that we now use the typical MIDI user
system of counting MIDI channels from 1-16 instead of from 0-15 as the lower
level USB-MIDI API itself expects.

Also add constant values for continuous controller messages, rename SendCC
function, and add SysEx function.

Signed-off-by: deadprogram <ron@hybridgroup.com>
2023-09-07 08:41:57 +02:00

67 lines
1.3 KiB
Go

package main
import (
"machine"
"machine/usb/adc/midi"
"time"
)
// Try it easily by opening the following site in Chrome.
// https://www.onlinemusictools.com/kb/
const (
cable = 0
channel = 1
velocity = 0x40
)
func main() {
led := machine.LED
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
button := machine.BUTTON
button.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
m := midi.Port()
m.SetRxHandler(func(b []byte) {
// blink when we receive a MIDI message
led.Set(!led.Get())
})
m.SetTxHandler(func() {
// blink when we send a MIDI message
led.Set(!led.Get())
})
prev := true
chords := []struct {
name string
notes []midi.Note
}{
{name: "C ", notes: []midi.Note{midi.C4, midi.E4, midi.G4}},
{name: "G ", notes: []midi.Note{midi.G3, midi.B3, midi.D4}},
{name: "Am", notes: []midi.Note{midi.A3, midi.C4, midi.E4}},
{name: "F ", notes: []midi.Note{midi.F3, midi.A3, midi.C4}},
}
index := 0
for {
current := button.Get()
if prev != current {
if current {
for _, note := range chords[index].notes {
m.NoteOff(cable, channel, note, velocity)
}
index = (index + 1) % len(chords)
} else {
for _, note := range chords[index].notes {
m.NoteOn(cable, channel, note, velocity)
}
}
prev = current
}
time.Sleep(100 * time.Millisecond)
}
}