cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F746-DISCO audio delay line implementation problem.

RRumi
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions
RRumi
Associate II

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.

View solution in original post

9 REPLIES 9

> 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

KnarfB
Principal III

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

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

> 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

> Yes, I tried play simple waveforms,

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

JW

Yes, except first memcpy from buff_in.

Regards,

Roman

Then it sounds like going through thousand registers. And checking the board design...

JW

RRumi
Associate II

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.

AZane.1
Associate II

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