Zack Scholl

zack.scholl@gmail.com

sd cards

 / #software 

Not all sd cards are the same.

I am working on an embedded device which I call “_core”. One of the main features of this device is the ability to jump around in an audio sample. Jumping around in audio normally requires a computer to load in the entire audio data into RAM. However, 16-bit audio at 44.1 kHz quickly becomes megabytes of data, and I’m using the RP2040 which only has 264 kilobytes of internal RAM! So, instead of using RAM, I’m attempting to use an SD Card to quickly and randomly access memory.

SD card in the audio block

In many applications (mine included), audio is transferred in “blocks”, i.e. the audio DAC asks for a batch of samples all at once instead of one sample at a time. For real-time audio, this is a good strategy to buffer playback so that a sample isn’t lost in case another sample takes too long to compute. In my audio application, the audio block consists of 441 samples. This means, at a sampling rate of 44,100 samples/second (44.1 kHz), there is only 10 milliseconds to generate the next piece of audio.

If the audio data is in RAM, there is almost no latency to access the data. However, when the audio is coming from the SD card, there is some latency involved in sending messages to the SD card. To prevent dropouts (bad audio “pops”), the SD card must successfully retrieve data in less than 10 milliseconds.

So, my most basic question is “what is the best SD card to use,” which revolves around two questions:

  1. How fast can an SD card retrieve audio data in my application?
  2. How often does the SD card require more than 10 milliseconds to retrieve data?

Experiment

I bought 14 different SD cards and tested them using the same firmware, same hardware, and the same samples. My firmware uses the SDIO protocol; for this test, it is accessing 819 bytes after seeking to a position. I use the RP2040 time_us_64() to get the timing before and after the operations and add up the entire time to get the latency.

(click the image to enlarge). The box-plots show the median read duration (latency) in my application and the dots show the outliers. The red area at the top shows where latency exceeds the audio block time, causing dropouts. (code for making plot)

Experiment 2 (overclocking)

A few weeks later, I decided that I need to run my rp2040 at 250 Mhz instead of 125 Mhz to eek out much more CPU processing power. The SDIO does not run this fast, so I am increasing the clock divider from 1 to 2 so that the SDIO actually runs at the same speed.

(click the image to enlarge). In this case we see partially the same story - “Lexar” is fast but unreliable. But also now we can see that “Kootion” is fast and unreliable as well. However, interestingly, the “PNY” and the “SP Elite” chips which used to be unreliable are now more reliable and their speed matches most of the other cards. The slow card here is, again, the SanDisk Ultra 16GB, which is a bit old. Also the “Kingston 2GB” is apparently so old that the SDIO never worked on it at all.

Conclusion

I found that most SD cards are pretty fast. There are some that are much slower (an old Sandisk 16GB). Surprisingly, the fastest SD card (Lexar A1 32 GB) is not usable because it has periodic spikes of high latency which causes audio dropouts.

The best SD card, then, is somewhere in the middle - not too fast and mostly reliable!

not all SD cards are the same!

tinker / #software 

gno -> go      go and zig