github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/usb/adc/midi/midi.go (about) 1 package midi 2 3 import ( 4 "machine" 5 "machine/usb" 6 "machine/usb/descriptor" 7 ) 8 9 const ( 10 midiEndpointOut = usb.MIDI_ENDPOINT_OUT // from PC 11 midiEndpointIn = usb.MIDI_ENDPOINT_IN // to PC 12 ) 13 14 var Midi *midi 15 16 type midi struct { 17 msg [4]byte 18 buf *RingBuffer 19 rxHandler func([]byte) 20 txHandler func() 21 waitTxc bool 22 } 23 24 func init() { 25 if Midi == nil { 26 Midi = newMidi() 27 } 28 } 29 30 // New returns the USB MIDI port. 31 // Deprecated, better to just use Port() 32 func New() *midi { 33 return Port() 34 } 35 36 // Port returns the USB midi port. 37 func Port() *midi { 38 return Midi 39 } 40 41 func newMidi() *midi { 42 m := &midi{ 43 buf: NewRingBuffer(), 44 } 45 machine.ConfigureUSBEndpoint(descriptor.CDCMIDI, 46 []usb.EndpointConfig{ 47 { 48 Index: usb.MIDI_ENDPOINT_OUT, 49 IsIn: false, 50 Type: usb.ENDPOINT_TYPE_BULK, 51 RxHandler: m.RxHandler, 52 }, 53 { 54 Index: usb.MIDI_ENDPOINT_IN, 55 IsIn: true, 56 Type: usb.ENDPOINT_TYPE_BULK, 57 TxHandler: m.TxHandler, 58 }, 59 }, 60 []usb.SetupConfig{}, 61 ) 62 return m 63 } 64 65 // SetHandler is now deprecated, please use SetRxHandler(). 66 func (m *midi) SetHandler(rxHandler func([]byte)) { 67 m.SetRxHandler(rxHandler) 68 } 69 70 // SetRxHandler sets the handler function for incoming MIDI messages. 71 func (m *midi) SetRxHandler(rxHandler func([]byte)) { 72 m.rxHandler = rxHandler 73 } 74 75 // SetTxHandler sets the handler function for outgoing MIDI messages. 76 func (m *midi) SetTxHandler(txHandler func()) { 77 m.txHandler = txHandler 78 } 79 80 func (m *midi) Write(b []byte) (n int, err error) { 81 s, e := 0, 0 82 for s = 0; s < len(b); s += 4 { 83 e = s + 4 84 if e > len(b) { 85 e = len(b) 86 } 87 88 m.tx(b[s:e]) 89 } 90 return e, nil 91 } 92 93 // sendUSBPacket sends a MIDIPacket. 94 func (m *midi) sendUSBPacket(b []byte) { 95 machine.SendUSBInPacket(midiEndpointIn, b) 96 } 97 98 // from BulkIn 99 func (m *midi) TxHandler() { 100 if m.txHandler != nil { 101 m.txHandler() 102 } 103 104 m.waitTxc = false 105 if b, ok := m.buf.Get(); ok { 106 m.waitTxc = true 107 m.sendUSBPacket(b) 108 } 109 } 110 111 func (m *midi) tx(b []byte) { 112 if machine.USBDev.InitEndpointComplete { 113 if m.waitTxc { 114 m.buf.Put(b) 115 } else { 116 m.waitTxc = true 117 m.sendUSBPacket(b) 118 } 119 } 120 } 121 122 // from BulkOut 123 func (m *midi) RxHandler(b []byte) { 124 if m.rxHandler != nil { 125 m.rxHandler(b) 126 } 127 }