2013-08-11 07:06 PM
dear all. I hope this finds you well. I am trying to implement digital audio effects on a development board featuring a STM32F407ZG processor. I have never used it before but I managed to build the driver for the audio codec, the usb and 512KB SRAM looking at the firmware examples provided by ST. so far, so good ... and it gets better ... I can read a wave file from the usb and play the actual PCM raw data (2 channels, 48kHz sample rate, 16-bit per sample). the DMA controller transfers the data from the memory to the audio codec (just like the Audio playback and recording using the STM32F4DISCOVERY - AN3997): two buffer are read from the wave file so while the DMA controller transfer buffer1, I can work on buffer2 and vice versa. now, the PCM raw data from the wave file are 16-bit samples, 2's-complement signed integers, ranging from -32768 to 32767. I normalize this range between -1 and 1 as I wish to do some filtering but simply converting the samples and then converting them back to the 2's-complement signed integer range thus playing back the resulting audio data and I get a noisy signal. I can still hear the audio but it's noisy. Is there something I have missed? Thank you!
#wave-playback2013-08-12 06:02 PM
someone has suggested me that the issue I am having are related to the data-cache. Whenever sending out data via DMA that have been touched by the CPU a cache write-back on the region should be issued first, to makes sure that if the outcome of the CPU processing is still in the cache it will be written back to RAM so the DMA will access the latest results of the computation. how can I issue a write-back invalidate command? thank you
2013-08-12 06:13 PM
The Cortex M3/M4 doesn't have a data cache, it has some write buffers, but another read will cause them to flush as operations (read/write) must complete in program order.
2013-08-13 04:33 AM
hey clive. I trust you are well. therefore, processing (and overwriting) the data stored in the buffers read from the USB should work and the DMA should send to the audio codec the actual data, right?
2013-08-13 06:40 AM
Correct, whatever the problem you're having with the data processing, I don't think it's one of memory coherency.
2013-08-13 09:06 AM
this is really frustrating (I mean not knowing what is going on!) but I might have found something useful ... I have tried this on two different IDE, CoIDE and uVision, and this is what happens. I am using the STM32F4DISCOVERY and open the Audio_playback_and_record demo (AN3997) from the FW V1.1.0 (since the project I am trying to implement is based on that). I have removed the recording feature (in uVision) as I am limited to 32KB and I don't need that anyway.
... using FAT_FS the WAV file is read from the USB and a buffer is filled with 1024 bytes. before the address is passed to the DMA, I wish to modify such data. therefore I call a function and I pass the address and size of the buffer. Here's what happen in uVision ...using uVision I can mute one channel, i.e. assign the value 0x0000 every other couple of bytes, and it still sounds good. if, on the other hand, I try to convert PCM raw data to a floating number (normalized to the range -1 and 1) and then convert it back, the audio played back through the speakers/headphones starts getting noisy and when I do more stuff than just converting and to float and back to signed 16-bit integer, the audio played back gets really bad.in CoIDE instead ...within the function to modify the audio, simply going through the buffer with a for loop, doing nothing whatsoever to the data, I can hear a tick which almost suggest discontinuity. when I try to mute a channel using the same technique as in uVision, I can hear the same tick throughout both channel, obviously much clear from the muted channel.doesn't this sound like my issues could be related to how the priority of the tasks has been distributed?thank you!2013-08-13 09:37 AM
I try to convert PCM raw data to a floating number (normalized to the range -1 and 1) and then convert it back, the audio played back through the speakers/headphones starts getting noisy and when I do more stuff than just converting and to float and back to signed 16-bit integer, the audio played back gets really bad.
You might want to look at this conversion/casting more carefully. Make sure to use ''float'', and 32-bit float constants, as these can use the FPU. Do the integer conversion to signed 32-bit, and make sure the high order 16-bit word is only 0x0000 or 0xFFFF so there isn't any inadvertent overflow, before storing the low order 16-bit word.
2013-08-13 11:32 AM
/**
* @brief Convert and normalize PCM raw data to a processing sample.
* @param PCM: unsigned 16-bit integer raw data
* @retval Normalize single precision processing sample
*/
static
float
PCM2k(uint16_t PCM)
{
/* Convert unsigned 16-bit integer to single precision */
float
k = (int16_t)PCM*1.f;
/* Normalize */
return
k/327f;
}
/**
* @brief De-normalize and convert a processing sample to PCM raw data.
* @param k: single precision processing sample
* @retval Unsigned 16-bit integer PCM raw data
*/
static
uint16_t k2PCM(
float
k)
{
/* De-Normalize */
k = k*327f;
/* Saturate if overflow occurred */
k = k > 327f ? 327f : k;
k = k < -327f ? -327f : k;
/* Convert single precision to unsigned 16-bit integer */
return
(uint16_t)((int16_t)k);
}
here are the 2 functions I wrote to convert the samples. I do check for overflow and saturate if overflow occurred
2014-04-19 04:35 PM
Sorry to post in this old thread, however, I am having the same issues. I was wondering if anyone ever determined how to fix the issue?
2014-04-19 05:51 PM
I can't say I've used the CODEC on the STM32F4-DISCO, I've used others in the past. Sending PCM data to it, or using the internal DAC, honestly shouldn't be that complicated.