Skip to main content
Visitor II
September 30, 2019
Solved

STM32F746-DISCO audio delay line implementation problem.

  • September 30, 2019
  • 4 replies
  • 2429 views

I have audio pass-through working project for STM32F746/769 DISCO module, where block of 4 samples (2 left and 2 right channel ones) from input are passed to output chanell DMA buffer.

My delay line implementation is as follows:

#define BUFF_SIZE 4

#define DBUF_SIZE 8192

int32_t buff_in[BUFF_SIZE];

int32_t buff_out[BUFF_SIZE];

int32_t dbuf[DBUF_SIZE];

int    i=0,j=0,k;

...

void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai){

   memcpy(&dbuf[i], buff_in, BUFF_SIZE*sizeof(uint32_t));

   i += BUFF_SIZE;

   if(i>=DBUF_SIZE) i=0;

   memcpy(buff_out, &dbuf[i], BUFF_SIZE*sizeof(uint32_t));

}

The effect should be a DBUF_SIZE/2 samples delay but instead of this i observe additionally echo, where subsequent repetitions of input signal occur at DBUF_SIZE/2*sample_period intervals.

I suspect, that the source of this maybe some analog or digital loopback in WM8994 audio codec.

Please, help me find the bug.

Regards,

Roman

    This topic has been closed for replies.
    Best answer by RRumi

    Problem solved. Initialization in wm889.c file has an error.

     /* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
     counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0035);
     
     /* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
     counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0035);

    LS nibble equal 5 opens a loopback from output mixer to input mixer with the 0dB gain(MIXOUTL_MIXINL_VOL [2:0] = 5).

    Correct version should mute this signal path(MIXOUTL_MIXINL_VOL [2:0] = 0):

     /* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
     counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0030);
     
     /* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
     counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0030);

    Regards,

    Roman

    P.S. This error is present in wm8894.c files being a part of all STM32F7xx boards projects.

    4 replies

    Super User
    September 30, 2019

    > maybe some analog or digital loopback in WM8994 audio codec.

    What does the WM8994 DS say?

    If you try only play back some simple waveform - plain zeros, for example, or a sine wave - does it come out clean?

    Then maybe try to record as much the internal memory (or if there is external memory connected, that on) allows; and play back - is there any echo?

    JW

    RRumiAuthor
    Visitor II
    October 2, 2019

    WM8994 has over tousand control registers, so ... anyway, i'll check.

    Yes, I tried play simple waveforms, tone burst and they are clean - no echo.

    Repeated signal has 1/3 amplitude of oryginal signal in case of pass-through.

    Thanks for response,

    Roman

    Super User
    October 2, 2019

    > Yes, I tried play simple waveforms,

    With the upstream running, i.e. exactly the same setup as above except for the memcpy?

    JW

    Super User
    October 1, 2019

    I don't get the point why you are using a small buffer and a large one. The small buffer forces HAL_SAI_RxCpltCallback to be called very frequently. And, you copy the samples to buff_out asynchronously, i.e. independent of any HAL_SAI_TxCpltCallback.

    I would recommend using one larger buffer (maybe 8192 or less) and both, HAL_SAI_RxHalfCpltCallback and HAL_SAI_RxCpltCallback and another buffer and callbacks for the Tx part. An IRQ safe queue could be used for copying the data, maybe a volatile variable would do it as well.

    hth KnarfB

    RRumiAuthor
    Visitor II
    October 2, 2019

    > I don't get the point why you are using a small buffer and a large one. The small buffer forces HAL_SAI_RxCpltCallback to be called very frequently. And, you copy the samples to buff_out asynchronously, i.e. independent of any HAL_SAI_TxCpltCallback.

    It doesn't matter - HAL_SAI_TxCpltCallback is synchronous to HAL_SAI_RxCpltCallback, and two sample period give 42usec for copy operation, so this operation is sychnronous and correct. No artefacts on waveforms.

    I do the same way on signal processors like Analog Devices Blackfin and SHARC - it always works correctrly.

    > I would recommend using one larger buffer (maybe 8192 or less) and both, HAL_SAI_RxHalfCpltCallback and HAL_SAI_RxCpltCallback and another buffer and callbacks for the Tx part. An IRQ safe queue could be used for copying the data, maybe a volatile variable would do it as well.

    Yes, maybe this is a method of baypassing the problem, but it cost more memory, and, I want to understand this unwanted mechanism of echo generation, before I start more complicated DSP algorithms implementation.

    Thank you,

    Roman

    RRumiAuthorAnswer
    Visitor II
    October 7, 2019

    Problem solved. Initialization in wm889.c file has an error.

     /* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
     counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0035);
     
     /* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
     counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0035);

    LS nibble equal 5 opens a loopback from output mixer to input mixer with the 0dB gain(MIXOUTL_MIXINL_VOL [2:0] = 5).

    Correct version should mute this signal path(MIXOUTL_MIXINL_VOL [2:0] = 0):

     /* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
     counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0030);
     
     /* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
     counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0030);

    Regards,

    Roman

    P.S. This error is present in wm8894.c files being a part of all STM32F7xx boards projects.

    Visitor II
    December 18, 2020

    @RRumi would it be possible for you to share your project? I would find it very useful!