Play an audio stream with a Cortex-M0+

I need to reproduce a short audio stream with a Cortex-M0+ MCU (it's SAM D21E from Atmel/Microchip). The audio bitstream will be stored in an external SPI Flash memory (I need to manage many short audio streams, so the internal Flash memory is not sufficient). SAMD21 features DAC, SPI and DMA.

The audio will not be high-fidelity. 8 bits at 8kHz sampling frequency is enough. I didn't make many tests, but I think I can use streams with lower bitrates.

Here the problem isn't the compress ratio, i.e. reducing the memory requirements to store all the streams, but to arrange an effective way to transfer samples from external Flash to DAC.

The simplest method I think is to configure the SPI transfer rate exactly at 8kHz, by calibrating the SPI clock (I think I can do): every

125us=8kHz a new sample is received, an interrupt is raised and the value is moved to the DAC register.

The only problem I see for this method is that the MCU must be interrupted every 125us. The MCU will run at 48MHz and should manage a serial RS485 38400bps (260us) too.

One solution to free the MCU is to use the DMA peripheral, but I never used it in the past. Will it be possible to use DMA to automatically move the byte received from SPI to DAC register, without interrupting the normal execution code?

Of course this "direct method" (from external memory to DAC output, without processing) can be done with uncompressed 8-bits samples audio streams. If I need to reduce the memory requirements, I need to use a compress (even simple) algorithm... there are many. Anyway in this case I can't move the samples from SPI to DAC, because I need to uncompress the samples.

Is it possible to use a normal (not DSP) Cortex-M0+ MCU to play a compressed audio stream? If yes, what is the best method to:

- arrange the load of compressed stream from external memory

- uncompress the input stream

- move the uncompressed samples to DAC Here the SPI input transfer rate is not perfectly syncronized with the DAC output transfer rate (fixed at 64kHz). I think I have to manage a FIFO buffer with two thresholds. When the FIFO is full over first threshold, the SPI transfer is stopped. When the FIFO is empty lower than the second threshold, the SPI transfer is started again.

Are there some examples to study?

Reply to
pozz
Loading thread data ...

s.

mbed.org has a mp3 player that works on M0+. Use DMA to fill the audio buffer from SPI. Maybe You may also use the DMA to feed the DAC.

Bye Jack

Reply to
Jack

Pumping audio from storage to speaker is a matter of keeping the pipeline full so the the output pointer is always ahead of the input pointer. You'll need some amount of buffer memory for that. Start by loading your buffer, and when it reaches some comfortable level of playable data, start outputting it. While you're waiting for the output mechanism to drain your buffer to some tolerably low level, you can be filling the pipe from SPI memory.

DMA varies among MCUs so only you will know about that. I suspect DMA will be the key to your success unless your MCU is extremely fast or unloaded, in whcih case you might not need it. I suggest you use it if you have it.

I've had good results using mu-law compression when fidelity expectations are low. You can find mu-law codec code on the web. You might find that compression is not needed. Large SPI memory devices are cheap and PCM wave files aren't that big so storage limitations should be ok for you (YMMV, of course).

JJS

Reply to
John Speth

I know the M3 supports peripheral to peripheral DMA but I'm not sure about the M0. It's not that hard to set up the channels once you kind of get your head around it. Transfer chaining makes it a lot easier. SPI read is a little of an issue as you have to keep the DMA controller issuing SCLKs. If the M0 will do p to p you should be able to setup the DMA descriptors, fire and forget until you get the final transfer complete interrupt.

--
Chisolm 
Republic of Texas
Reply to
Joe Chisolm

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.