What’s the problem with memory ?
That’s a good question… The ATmega328p offer 2k bytes of SRAM which is… not a lot…So knowing that, i tried to estimate how many MIDI command i can store inside this SRAM, and the result is problematic:
After reading the MIDI specification, i can estimate that most of the MIDI messages i’m going to store during the recording of a sequence are 3 bytes long: For exemple, when a note is played, the corresponding message contain the follwing bytes:
- 1 byte of status: containing an ID representing the king of message, plus the MIDI channel ID
- 2 bytes of data: containing the number the note (if it’s a C, a D or whatever) plus the velocity of the played note
2k bytes / 3 bytes = 682 messages
2k bytes / 3 bytes / 2 = 341 messages
But the estimation does not stop here… a MIDI message does not contain any timing informations (because they are supposed to be played in real time). If i want to playback those notes, i need to know WHEN to play them back, so i need to store an extra timing informations. To do that i’m going to follow what was already done in the MIDI file format.
A MIDI file contain a sequence of MIDI message and can be used to playback those messages/notes. In order to do that, extra data are added to each MIDI messages. These extra data are between 1 and 4 bytes long and store timing informations.
So if i assume this extra informations is always 4 bytes long, each MIDI message consume now: 3 bytes +4 bytes = 7 bytes. I will round it up to 8 bytes in case my application need to store some more extra data.
2k bytes / 8 Bytes / 2 = 128 messages
An other thing to take care of, is that among those 2k SRAM available, the Arduino System itself will already use some memory. And the application itself will also use memory. Here are differents estimations:
System take 128 bytes:
(2048 bytes – 128 bytes ) / 8 bytes / 2 = 120 messages
System take 256 bytes:
(2048 bytes – 256 bytes ) / 8 bytes / 2 = 112 messages
System take 512 bytes:
(2048 bytes – 512 bytes ) / 8 bytes / 2 = 96 messages
System take 1024 bytes:
(2048 bytes – 1024 bytes ) / 8 bytes / 2 = 64 messages
So i can reasonably think that i can store between 120 and 64 messages.
One last thing to note, is that when playing, not just MIDI note start and stop are send, other messages including “pitch variation“, or “note preassure” are also send. I can’t know in advance how many of this kind of messages are send because it of course depend on the way you are playing… But let’s say that for each note played, one of this commands is send this reduce the global estimation of total note that can be played to 32… This is not a lot and this is just an approximation…
So in order to avoid any memory related problems, additional memory is required !
Once again, thanks to the Arduino and it’s community, solutions exists:
The microchip 23k256 SPI SRAM:
The 23k256 is a small chip that provide 32k bytes of extra SRAM and can be easily connected to the Arduino:
Communication between this chip and the Arduino is done using SPI which is a serial communication protocol. (I will probably talk about the SPI protocol in an other post, but for now i will just talk about how to physicaly connect the chip and the Arduino ).
The tricky part here is that the 23k256 chip operate at 3.3V and the Arduino at 5V, so if i want to connect them safely, i must integrate some kind of voltage converter between the two devices…
The logic level voltage converter:
This kind of voltage converter can be done in very different ways, but, as i’m not an electronic specialist, i will use something that already exist: A 4 channel Bi-directional Logic Level Converter.
After reading the various specification for each devices, here is a first draft of how the wiring between the Arduino, the level converter and the 23k256, is going to be done…
I haven’t test it yet, but i think it should be ok 🙂