2012-12-14 05:25 PM
On the discovery board, the digital MEMs mic data is accessed by providing a clock from i2s_2. In the Audio_playback_record example, i2s is set up to acquire data in 16b blocks, and an interrupt (AUDIO_REC_SPI_IRQHANDLER) is called when this data is ready to be filtered.
My question is, what is the ''correct'' way to set up a DAC to stream out this data? Is there a way to drive the DAC based on the i2s clock?2012-12-15 06:32 AM
I believe all you need to do is DAC each filtered result in the interrupt handler.
Cheers, Hal2012-12-15 03:18 PM
Thanks for the reply, I got it working. I'll leave some tips and code here for anyone that wants to stream data from the PDM Mic:
1. use WaveRecorderInit() and WaveRecorderStart() from the audio_playback_record example project to setup the MIC. 2. for DAC, setup GPIO clk, pins, and settings. For DAC triggering, use DAC_Trigger_None. 3. modify the IRQ handler in waverecorder.c:void AUDIO_REC_SPI_IRQHANDLER(void)
{
u16 volume;
u16 app;
u16 tmp;
/* Check if data are available in SPI Data register */
if (SPI_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)
{
app = SPI_I2S_ReceiveData(SPI2);
InternalBuffer[InternalBufferSize++] = HTONS(app);
outputcnt++;
if (outputcnt >= 4)
{
outputcnt = 0;
// convert data from 2sC to unsigned int
tmp = *(pAudioRecBuf+bufcntr);
tmp = (tmp>=32768) ? tmp - 32768 : tmp + 32768;
// load DAC. trigger is set to none, so data will immediately be transferred out
DAC_SetChannel2Data((uint32_t)DAC_Align_12b_L, tmp);
bufcntr++;
}
/* Check to prevent overflow condition */
if (InternalBufferSize >= INTERNAL_BUFF_SIZE)
{
// reset output-buffer counter
bufcntr = 0;
// reset internal-buffer counter
InternalBufferSize = 0;
volume = 50;
PDM_Filter_64_LSB((uint8_t *)InternalBuffer, (uint16_t *)pAudioRecBuf, volume, (PDMFilter_InitStruct *)&Filter);
Data_Status = 1;
}
}
}
In the code, outputcnt controls how often the DAC outputs data, which is depends on the PDM decimation factor and the fact that every time the interrupt is called, 16 bits are generated from the mic. In my case, I chose a decimation factor of 64, so we output to the DAC once every 64/16=4 calls to the interrupt.
Finally, it looks like the PDM filter output is in 2s complement format. The DAC requires unsigned int, so we make the conversion. If you don't, the DAC output sounds very noisy and clipped.
Cheers!
David
2013-08-16 07:28 AM
2013-08-16 07:28 AM
what did you connect after the DAC? Need a amp and a speaker?
How can I use the cs43l22 to implement the record and play at the same time? thanks2014-02-06 12:04 AM
Hi, i am new at embedded programming, and i am trying to learn but I couldn't find source which is appropriate for beginners.
Can you upload your project that you mentioned?2014-02-06 08:39 AM
Can you upload your project that you mentioned?
The code in question comes from the STM32F4-Discovery firmware librarySTM32F4-Discovery_FW_V1.1.0\Project\Audio_playback_and_record\src\waverecorder.c