I have updated a few of my MIDI scripts to write directly to the state chunk, and they are now usable even when the take contains hundreds of thousands of events.
However, this approach is not yet perfect: 'deferred' scripts that track mouse movement and update MIDI in realtime are still somewhat jerky, unlike REAPER's smooth native functions.
In the state chunk string, the MIDI data of a take is hidden away between lots of non-MIDI information (and also MIDI data of other takes in the item), and is encoded in a complicated way that requires some awkward -- and slow -- parsing. (Some details of the encoding can be read here
.) For example, getting the PPQ position of en event requires adding the offsets of all prior events, and getting notation info requires base64 decoding.
The most time-consuming step seems to be that REAPER must process all the non-MIDI information in the state chunk -- as well as all the MIDI data of the non-active
takes in the item -- whenever the state chunk with edited MIDI of the active
take is uploaded via SetItemStateChunk.
(In my own scripts, for example, Lua can assemble and encode thousands of edited events during each cycle of reaper.defer(function) within a mere hundredth of a second, whereas reaper.SetItemStateChunk takes 0.2 seconds or more, making the movement of the MIDI events choppy and somewhat lagging behind mouse movement. The more takes in an item, the slower reaper.SetItemStateChunk gets.)
I am pretty sure that REAPER uses a more efficient representation of the MIDI data in its own internal processing: for example, arrays or tables with PPQ positions of each event.
It would be great if a new function MIDI_GetAllMIDI(take)
could return only
the MIDI data of one take, all
the useful info that REAPER has already pre-calculated (such as PPQ positions), in whatever straightforward format
is easiest for REAPER to encode and decode.
But even more importantly (since this function will be called multiple times, once during each defer cycle), a fast new function MIDI_SetAllMIDI(take)
that uploads only a single take's MIDI (again, in whatever format would be easiest for REAPER to parse), so that REAPER does not need to process all the other irrelevant information in the state chunk.