2019-09-30 09:07 AM
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
Solved! Go to Solution.
2019-10-07 04:15 AM
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.
2019-09-30 01:52 PM
> 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
2019-10-01 09:37 AM
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
2019-10-02 10:29 AM
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
2019-10-02 10:39 AM
> 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
2019-10-02 12:01 PM
> Yes, I tried play simple waveforms,
With the upstream running, i.e. exactly the same setup as above except for the memcpy?
JW
2019-10-02 11:57 PM
Yes, except first memcpy from buff_in.
Regards,
Roman
2019-10-03 12:09 AM
Then it sounds like going through thousand registers. And checking the board design...
JW
2019-10-07 04:15 AM
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.
2020-12-18 12:22 PM
@RRumi would it be possible for you to share your project? I would find it very useful!