Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sendSysEx from Program Space to save RAM #59

Open
franky47 opened this issue Oct 17, 2016 · 2 comments
Open

Add sendSysEx from Program Space to save RAM #59

franky47 opened this issue Oct 17, 2016 · 2 comments
Milestone

Comments

@franky47
Copy link
Member

Large static arrays need to be stored in RAM, at least temporarily, before being passed to sendSysEx.

Those could be declared as PROGMEM to be saved in Program Space, and it would be fairly easy to have another sendSysEx implementation that reads one byte at a time from Program Space instead of RAM, effectively saving lots of memory, at the cost of extra program size and execution time.

http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

@franky47 franky47 added this to the Backlog milestone Oct 17, 2016
@eclab
Copy link

eclab commented Oct 31, 2016

Let me make a different suggestion. The fundamental problem with the Sysex subsystem at the moment is that it requires transferring the entire data stream as one buffer. Which means you have to have that buffer allocated, sometimes twice. For example, if I want to read Sysex into a memory space I've allocated, The library at present allocates its own memory space, loads it, then sends it to me where I copy it into my space. If you have a memory constrained space (as I do) this is essentially impossible.

I suggest instead that that the Sysex library be written as:

-- input --
MIDI.sendSysex(unsigned inLength, const byte* inArray, int state, bool inArrayContainsBoundaries)

STATE is one of: (0) start of sysex message (1) continuing a sysex message (2) end of a sysex message (3) start and end of a sysex message

-- output --
void MidiInterface<SerialPort, Settings>::setHandleSystemExclusive (void()(byte *array, unsigned size, int state) fptr, byte sysexArray, int sysexArraylength)

STATE is one of: (0) start of sysex message (1) continuing a sysex message (2) end of a sysex message (3) start and end of a sysex message

SYSEXARRAY provides the sysex array to the system to use as its own internal buffer, and SYSEXARRAYLENGTH is its length. This way the library doesn't have to have a large static buffer allocated like it presently does (which is a serious memory issue). Instead it has exactly the size one we specified because we provided it.

@franky47
Copy link
Member Author

That's a very interesting approach indeed. It also works like the USB MIDI approach (where you receive data by packs of up to 3 bytes, and the SysEx has special status codes to indicate how much data is received), therefore I'll be giving this a look when I'm working on the next version of the lib, which will focus on USB compatibility.

Thanks for the suggestion !

@franky47 franky47 modified the milestones: v5.0, Backlog Nov 5, 2016
@franky47 franky47 mentioned this issue Mar 10, 2018
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants