I've implemented some codes in STM32F1 DAC to play some WAV audio files. Because the data is too big (for 44.1K 8Bit Sample rate) and the internal flash is not big enough to store it. My approach is to store it in an SPI external flash, read it buffer by buffer (usually 512 bytes at a time), and plug it into the DAC in normal mode. While this approach works, I'll have to be stuck in the buffer feeding loop and cannot do anything with the MCU (except I terminate the loop but the audio will also stop). I could go with another approach: I read all the audio data into an array and feed it with circular mode, but that will take too much RAM space, which is not practical with larger audio files. Is there another way to achieve both worlds?
while(0 < bytes_last) {
int blksize = (bitsPerSample == 8)? MIN(bytes_last, BUFSIZE / 2) : MIN(bytes_last, BUFSIZE);
uint32_t bytes_read = 0;
if (HAL_SPI_Receive(&SPI_FLASH_HANDLE, fileBuffer, blksize, 1000) != HAL_OK)
{
/* Transfer error in transmission process */
Error_Handler();
}
int i = 0;
while(i < BUFSIZE){
if(fileBuffer[i] != 0 && fileBuffer[i] != 0xFF){
bytes_read++;
i++;
}else{
break;
}
}
uint16_t numSamples = bytes_read / bytesPerSample / channels;
int16_t *pInput = (int16_t *)fileBuffer;
uint16_t *pOutput = (uint16_t *)dmaBuffer[dmaBank];
prepareData(channels, numSamples, pInput, pOutput);
// wait for DMA complete
while(flg_dma_done == 0) {
__NOP();
}
HAL_DAC_Stop_DMA(&hdac, DAC_CHANNEL_1);
flg_dma_done = 0;
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)dmaBuffer[dmaBank], numSamples, DAC_ALIGN_12B_R);
dmaBank = !dmaBank;
bytes_last -= blksize;
};
FLASH_CS_HIGH();
while(flg_dma_done == 0) {
__NOP();
}