I have been struggling away for a good number of months now, with a polyphonic audio project using a microcontroller. (This was originally all done on an mbed but I had to switch over, for reasons given below). It consists of reading .wav files off of a micro sd-card, and then being able to output these to a wolfson audio codec via I2S.
A few requirements:
- There must be enough memory to open have up to 25 different .wav files open at once, so I can immediately switch or overlay any given sound immediately (this was my reason for moving over from mbed; there is an actual file limit somewhere that I could not change, and my estimates showed that there potentially wasn't enough memory on an LPC1768 board).
- I need to be able to play up to 6 .wav files at once.
- Sample rate and bit depth - 16 bit is ideal, as for sample rate, I can live with 11025Hz as it sounds fairly good. However anything less than this sounds terrible and so is not an option.
I have moved everything over to using the LPC55S69 EVK, part of the LPC5500 line from NXP which I gather is fairly new.
However I am running into some problems.
Despite the fact that on the mbed, I had enough latency to play 6 or 7 different 11025Hz sound files at once, I cannot do this on the LPC55S69. if I try to do this, the sound starts lagging and popping due to there not being enough time to read the .wav samples and add them together before the DMA triggers an interrupt. This is odd as the mbed lpc1768 can run up to 96MHz whereas my current LPC55S69 I am running the core at 150MHz. Moreover the sd card libraries appear to be using SDIO and, presumably, 4 bit SDIO, so the read times from the sd card should be pretty fast.
I have been using all of the MCUXpresso SDK APIs/libraries for this, including the I2S/DMA side of things. Looking at the files for this, there seems to be bazillions of different functions that get run once an interrupt is triggered, before the next transaction is even started, and before it finally comes back into the main code. I barely understand what half of them are even doing. (And of course, there is little to no documentation for any of these).
My (very) basic understanding of DMA was that it works nicely in the background to transfer data from your specified memory or peripheral location, and once all of this has been transferred, it interrupts, you tell it to start again, and off it goes. But it would appear that NXP's API is doing tons more than this.
The long and short of it is I have already been reading carefully through the "user manual" for this chip in the DMA and I2S sections and am wondering if it may be better to write this all from scratch. Although, the manual isn't incredibly clear about some things, however.
If anybody has any experience of using DMA and/or I2S on this range of processors, or just general advice, please let me know, I can provide more details as I go along.