Go Down

Topic: Distortion when reading *.wav files with VS1053B (Read 298 times) previous topic - next topic

Muhmmbles

Oct 22, 2018, 08:46 pm Last Edit: Oct 23, 2018, 03:05 pm by Muhmmbles
My setup is currently an Arduino MEGA2560 with a VS1053B. I am using the <Adafruit_VS1053.h> library.

When running their basic examples, MP3 files work great, but WAV files are distorted.
I am not sure why this happens and was hoping someone can provide more insight.

Lucario448

I see this chip doesn't get the data directly from the SD card, it has to be streamed by another device.

Since the SPI bus is shared between card and decoder, the maximum "bandwidth" achievable for an AVR at 16 MHz, is around 37 KB/s (303 Kbit/s).

Obiously works fine for MP3 files with a bitrate lower than 300 kbit/s.
However, on a WAV file, bitrate is usually way higher; so my guess of your distortion is a buffer underrun on the decoder, due to a slow data transfer.

If you are trying to stream CD-quality WAV files, is basically impossible on an AVR.
CD audio is encoded as LPCM samples, 16 bits (2 bytes) per sample, it's stereo so 32 bits (4 bytes) for both channels, and there are 44100 samples per second.
If you do the math, you'll need a data transfer rate of at least 2 * 2 * 44100 = 176400 bytes per second (172 KB/s or 1.4 Mbit/s). On an AVR, such speed isn't achievable even with the SD card alone.

For uncompressed LPCM WAV files, your only options are:
  • mono 8 bits @ 22050 Hz
  • stereo 8 bits @ 11025 Hz
  • mono 16 bits @ 11025 Hz
  • stereo 16 bits @ 5000 Hz

Remember that lower sample rates makes the audio sound more "muffled".

Muhmmbles

#2
Oct 24, 2018, 02:40 pm Last Edit: Oct 24, 2018, 02:43 pm by Muhmmbles
I see this chip doesn't get the data directly from the SD card, it has to be streamed by another device.
Yes, I believe the MCU takes the file from the SD card, saves it in local memory, then sends it to the chip to be decoded.

Since the SPI bus is shared between card and decoder, the maximum "bandwidth" achievable for an AVR at 16 MHz, is around 37 KB/s (303 Kbit/s).
How did you yield the max bandwidth for an AVR? I am not sure which datasheet to look at; is this the max bandwidth of the MCU or the SD card?

Obiously works fine for MP3 files with a bitrate lower than 300 kbit/s.
However, on a WAV file, bitrate is usually way higher; so my guess of your distortion is a buffer underrun on the decoder, due to a slow data transfer.

If you are trying to stream CD-quality WAV files, is basically impossible on an AVR.
CD audio is encoded as LPCM samples, 16 bits (2 bytes) per sample, it's stereo so 32 bits (4 bytes) for both channels, and there are 44100 samples per second.
If you do the math, you'll need a data transfer rate of at least 2 * 2 * 44100 = 176400 bytes per second (172 KB/s or 1.4 Mbit/s). On an AVR, such speed isn't achievable even with the SD card alone.

For uncompressed LPCM WAV files, your only options are:
  • mono 8 bits @ 22050 Hz
  • stereo 8 bits @ 11025 Hz
  • mono 16 bits @ 11025 Hz
  • stereo 16 bits @ 5000 Hz

Remember that lower sample rates makes the audio sound more "muffled".
Thanks for the other information, I did not know wav files required such a high sample rate.

Lucario448

Yes, I believe the MCU takes the file from the SD card, saves it in local memory, then sends it to the chip to be decoded.
I know because the SPI interface works as a slave only; and also because the library makes use of the SD library (aka the Arduino has to retrieve and stream the data).


How did you yield the max bandwidth for an AVR?
Well, in SPI, the maximum "raw" (without execution or protocol overhead) data rate is half of the CPU's clock frequency. So at 16 MHz clock frequency, the maximum "raw" or theoretical speed is about 8 Mbit/s or 1 MB/s (almost 8 times the required rate for CD-quality audio streaming).

However, in a more realistic application, the effective speed is way lower.
For example: a single read operation from a file can take around 64 microseconds when the library has to load another block of data (512 bytes to be exact); but if the file is fragmented, more filesystem overhead comes into place and the operation gets stuck for up to half a millisecond.


Based on a test I've made long ago, the read speed of a file on a SD card with the IDE's library, topped up to somewhere around 70 KB/s (without sharing the bus); and not 1 MB/s.
As you can see, there's a lot going on that theoretical speeds are practically impossible.

By sharing the same bus gets even worse; because of its nature, you can only access one device at a given moment; so the access time has to be "sliced" for both of them.
Having two hardware SPI ports won't help either, not without DMA capabilities from the CPU.



is this the max bandwidth of the MCU or the SD card?
Mostly the MCU. So much so that the maximum serial clock frequency supported by the card is 20 MHz, while the micro just can offer up to 8 MHz.

The other limiting factor could be the decoder ifself, which is very unlikely considering that it needs to receive data from another (master) source; sort of like an I2S DAC.


I did not know wav files required such a high sample rate.
That's the disadvantage; the advantage is that it requires minimal processing to actually play it back. So minimal that an Arduino can play WAV files on its own (besides the fact it needs an SD card due to the already mentioned big data volume).

Although the sampling rate doesn't matter that much unless you are an audiophile. 22050 Hz still sounds fine for most people; lower than that is more accepted for things like speeches.

Go Up