cancel
Showing results for 
Search instead for 
Did you mean: 

How to sync ADC sampling at 192K to DAC output

Robmar
Senior III

On STM32F407V-Disc the divisions don't work out for an 192KHz Timer trigger for the ADC, so sampling runs a bit slower or faster, the problem is that the Cirrus DAC audio chip cannot be set to match the sample rate, so I get buffer sync drift, audio is clear but at the end of every second there is a "scrrrr, scrrr" noise as the DAC buffer end is overwritten while it should have reached the start, but the clock issue delays it... I think that's it at least.

I down-sample the 192.2KHz to 48.05KHz, but with no way apparently to sync the ADC and DAC streams I have tried to use HAL_I2S_Transmit_DMA() to send the samples at the required 48KHz rate, but when called from HAL_I2S_TxHalfCpltCallback it only works once!

I can get HAL_I2S_TxHalfCpltCallback to run continuous, but can't see how to reset the DMA reading to sync to the data rate coming in at 192.2K/4. I need to reset the I2S DMA read to the start of my audio samples buffer in continuous mode. This will lock the audio playback to the incoming sample rate.

There would be 5uS of audio missing every 666uS using sample buffer realignment but I don't think it would be detectable.

All ideas welcome, its been a stressy couple of days to say the least!

14 REPLIES 14

If you're talking about the on-board CS43L22 codec, according to its datasheet, it does not support 192kHz sampling rate.

JW

It doesn't work well at lower rates, but 192k is in the datasheet and simple playback at 192k works a treat​

LCE
Principal

Maybe you could be a little clearer on what you want to achieve.

ADC: the internal peripheral,or an external audio device?

At first glance it looks like you can use the DAC CS43L22 as an I2S slave, which means you can absolutely control its sampling rate.

So you could let it run on 48.05 kHz, or any other sampling rate <= 96 kHz.

But I actually don't know the F407, so maybe there are some clock source limitations for I2S/SAI/ADC?

Internal ADC, cannot be clocked at exactly 192 KHz can it!

Code has to process and downsample to 48K packets.

I2S DMA transfers only seem to work in continuous mode for some reason!

I can't slave the Cirrus DAC off the ADC because of post processing of the ADC samples.

I sync dual buffer update off the NDTR register, but its still glitching the audio, maybe due to the small gap in samples caused by the ADC being 192,200, and the DAC at 48000.

Hope that is clear enough! 😉

LCE
Principal

I guess your final product will not be the discovery board, so get a HSE / crystal from which you can derive 192 kHz for the ADC and 48 kHz for I2S.

Or that not possible for F407?

Or for now, if you don't want to solder on the discovery board, just let the DAC run at 48.05 kHz.

Anyway, I'd try it this way:

ADC -> DMA to big SRAM AD_buffer

post-processing of AD_buffer into I2S_buffer

I2S buffer via DMA to I2S DAC

Depending on your input data and the post-processing, maybe throw away 1 per every 961 ADC samples ?

> 192k is in the datasheet

You must then have a very different datasheet of CS43L22 than what I've just downloaded from Cirrus


_legacyfs_online_stmicro_images_0693W00000biV7YQAU.png 

JW

I think the OP is using the DAC with 48 kHz (or 48.05 kHz...) anyway.

Ah that, I see, thanks.

JW

I down-sample. Thanks