@@ -107,9 +107,14 @@ type RtMidiMidinettePlatformImpl() as this =
107107 let error = new Event<_>()
108108 let channelMessage = new Event<_>()
109109 let sysex = new Event<_>()
110+ let invalidSysex = new Event<_>()
110111 let systemMessage = new Event<_>()
111112 let realtimeMessage = new Event<_>()
112- port.InputDevice.Message.Add( fun bytes ->
113+
114+ let sysexParts = ResizeArray()
115+
116+ let rec onBytes ( bytes : byte array ) =
117+
113118 let status : MidiMessageType = LanguagePrimitives.EnumOfValue ( bytes.[ 0 ])
114119 let inline toMidiEvent ( bytes : byte array ) ( watch : Stopwatch ) =
115120 let timestamp = watch.ElapsedTicks
@@ -120,21 +125,52 @@ type RtMidiMidinettePlatformImpl() as this =
120125 let event = toMidiEvent bytes watch
121126 event1.Trigger event
122127 platformNoticer ({ info = device}, event)
128+ let inline pushSysexBytes endSysexIndex =
129+ let sysexBytes =
130+ [|
131+ yield ! sysexParts.ToArray()
132+ yield bytes.[ 0 .. endSysexIndex]
133+ |] |> Array.concat
134+
135+ sysex.Trigger ( UMX.tag_ sysex_ data sysexBytes)
136+ platformEvents.NoticeSysex({ info = device }, sysexBytes)
137+ sysexParts.Clear()
138+
139+
140+ let inline getSysexEndIndex () = bytes |> Array.tryFindIndex ( fun i -> i = byte MidiMessageType.SysExEnd)
123141 if MidiMessageTypeIdentifaction.isChannelMessage status then
124142 triggerMessageEvent channelMessage platformEvents.NoticeChannelMessage
125143 elif MidiMessageTypeIdentifaction.isRealtimeMessage status then
126144 triggerMessageEvent realtimeMessage platformEvents.NoticeRealtimeMessage
127145 elif MidiMessageTypeIdentifaction.isSystemMessage status then
128- if MidiMessageTypeIdentifaction.isSysexBeginOrEnd status then
129- sysex.Trigger ( UMX.tag_ sysex_ data bytes)
130- platformEvents.NoticeSysex({ info = device }, bytes)
146+ if status = MidiMessageType.SysExEnd then
147+ sysexParts.Add ([| bytes.[ 0 ]|])
148+ pushSysexBytes 0
149+ elif status = MidiMessageType.SysEx then
150+ if sysexParts.Count > 0 then
151+ invalidSysex.Trigger( sysexParts.ToArray() |> Array.concat)
152+ sysexParts.Clear()
153+ else
154+ match getSysexEndIndex () with
155+ | Some endSysexIndex ->
156+ pushSysexBytes endSysexIndex
157+ if bytes.Length > endSysexIndex then
158+ onBytes bytes.[ endSysexIndex..]
159+ | None ->
160+ sysexParts.Add bytes
131161 else
132162 triggerMessageEvent systemMessage platformEvents.NoticeSystemMessage
163+ elif sysexParts.Count > 0 then
164+ match getSysexEndIndex() with
165+ | Some endIndex ->
166+ pushSysexBytes endIndex
167+ | None ->
168+ sysexParts.Add bytes
133169 else
134170 #if DEBUG
135171 failwithf " unable to parse what I received received %A " bytes
136172 #endif
137- )
173+ port.InputDevice.Message.Add ( onBytes )
138174 let inEvents = { error = error; channelMessage = channelMessage; sysex = sysex; systemMessage = systemMessage; realtimeMessage = realtimeMessage }
139175 Some ({ inPort = port; info = rtDevice; inEvents = inEvents } :> _)
140176 | _ -> None
0 commit comments