How to store and access generated data in a project?
Keyframes

Suggest using your midi file reader to keyframe the animation. I have done this using the very basic pysmf reader to make an action of custom properties for each track. For example in image below "AE" for electric guitar track, and "AB" for muted trumpet track.

For each of the midi notes in the track, if there is an ON event, keyframe that to a custom property, eg middle C on electric guitar "AE" would be assigned custom property AE60.  The smf decoder gives middle C as C4, I get it's midi position 60 by finding its index in midi_notes list below. Your reader may handle this differently. 

notes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
octaves = range(-1, 10)

midi_notes = ["%s%d" % (n, o) for o in octaves for n in notes]
#pop off the last 4

for i in range(4):
midi_notes.pop()


Rather than using custom properties, ob["AE60"], another method would be to create collection property for the tracks and channels.

The velocity and event time in seconds, converted to frame, of each on / off note event in the track, are keyframed as a (frame, value) pair.  Constant interpolation will make the note stay on until an off event.   

To find the value of AE60 in an action named "MidiAction" at frame 44

bpy.data.actions["MidiAction"].fcurves.find('["AE60"]').evaluate(44)




The very much WIP code to produce action above is here