Skip to main content
Visitor II
February 16, 2021
Question

I2S audio crackly noise on STM32L05x

  • February 16, 2021
  • 4 replies
  • 4055 views

Hello everyone!

I am struggling with playback via I2S to external DAC on STM32L051/53.

Audio:

file in external SPI flash,

WAV format

16KHz sampling rate

16bit depth

I run the core on internal oscillator.

My 'real' I2S clock (WS frequency) is 15,957kHz, which is -0.26% off the target sampling frequency.

This is pretty accurate with my read from oscilloscope.

I send 16 bits of data on 16-bit frame.

External DAC:

UDA1334

min. 16KHz sampling rate

16bit I2S Phillips compatible

I cannot fit even 1s audio to MCUs memory, so I am reading from external flash using DMA.

My algorithm:

2x 512byte uint8_t array (let's say bufferA and bufferB)

2x 256 byte uint16_t array (let's say bufferC and bufferD)

read 512byte chunk of audio to bufferA

read 512 byte chunk of audio to bufferB

convert bufferA to bufferC

transmit bufferC to I2S

on i2sHalfCpltCallback update bufferA or bufferB

on spiRxTxCpltCallback convert bufferA to bufferC or bufferB to bufferD

while (!endOfFile)

i2sTransmit (bufferC or bufferD)

The actual questions:

Can 0.26% devation on I2S clock cause crackly noises during playback?

Is it possible to calculate/esitmate the THD based on I2S clock devation?

If I was handling big-endian/little-endian wrong I would not hear the audio at all, right?

What can I look into further to investigate the issue?

    This topic has been closed for replies.

    4 replies

    Super User
    February 16, 2021

    > Can 0.26% devation on I2S clock cause crackly noises during playback?

    If you read data synchronously with playback (i.e. you read exactly the amount of data you play back, for example if reading N bytes is triggered by spending N previously read bytes, and not by some other independently timed event), then no.

    > What can I look into further to investigate the issue?

    This depends on the details of application. Make sure you ALWAYS have ready next chunk of data to play back. One way to visualize this is to toggle one GPIO Out pin in the process which prepares the data, each time data are ready; and toggle other GPIO Out pin when the playback routine starts to play back the next chunk of data; and observe on LA whether these signals are regular and their mutual relationship is as expected.

    JW

    MBank.1Author
    Visitor II
    April 12, 2021

    Hello Jan,

    thank you for your reply very much.

    It took me while since I was reassigned somewhere else - obviously.

    I did check it how you advised though. I toggle some pin (ch4) when I finish reading and converting data from the external flash, and togggle another pin (ch3) when I finish transmission of previous chunk of data.

    The chunks read from flash and sent through I2S are the same of size:

    256, 8-bit read from the flash, converted to 128, 16-bit.

    128, 16-bit sent through I2S

    As you may see on the screen shot appended, 'normal sittuation' is when:

    ch4 rising edge is on high level ch3

    and

    falling edge of ch4 is on low level ch3.

    I was trying to trigger for following events:

    ch4 falling edge on high level ch3

    ch4 rising edge on low level ch3.

    These never happen, so I persume, that conversion of SPI Flash data is always finished before beginning of I2S transmission.

    0693W000008zJIwQAM.bmp 

    Should I provide some flow diagram or state machine to make it more clear?

    Privately I could also share some code I believe.

    With kind regards,

    Michal

    Graduate II
    April 12, 2021

    Not sure there are many here to provide testing resources. Try the support engineers for your account, or those at the distributors.

    Perhaps generate some pure sines and see if you get noise in them, or other repeating patterns you can store/generate without needing seconds of data, or reading via external memories.

    Determine if the noise is coming from the codec, or supplies.

    For short connections to SPI, etc, look carefully at just how aggressive a slew rate is used and the energy dumped into the pins. Drop the SPEEDR settings to the lower end. Consider if you need series resistors to stop ringing issues.

    Look for gaps in the data or clocking.

    MBank.1Author
    Visitor II
    April 12, 2021

    Thanks!| I've already ruled out any clock gaps. Will look into other aspects you mentioned, tomorrow.

    I do understand the rest, but I don't see how could I check the energy dumped to the pins. Do you mean energy from MCU to pins of external flash and codec? How should I measure that? With shunt resistors?

    MBank.1Author
    Visitor II
    April 12, 2021

    I just figured out another event, that might be alarming.

    in HAL_SPI_TxRxCpltCallback I trigger conversion of the buffer from 8-bit to 16-bit buffer.

    There I check the state of the buffers. Each run, after reste of MCU I get exactly 3 events, where the state is unexpected.

    It should mean that the buffer which was supposed to be updated, was not transmitted yet.

    Super User
    April 16, 2021

    > I think I will use some spare time to check if values sent via SPI I2S are the same and whether they create a nice clean sine wave at all. What do you think?

    It's easier to check something simpler, e.g. a sawtooth. It's also easy to generate - simply store an incrementing value to the output buffer.

    W