AnsweredAssumed Answered

Unexpected audio artifact in dev_audio_speaker_freertos example

Question asked by Anton Glukhov on Jul 18, 2020
Latest reply on Aug 13, 2020 by Anton Glukhov

Hello,

I'm testing dev_audio_speaker_freertos example for RT1010 evk board and it seems there is one weird abnormal event that brings tiny artifact into the audio stream. If you add simple PRINTF or another _marker_ into txCallback function (audio_speaker.c) then you can see that the following condition occur regularly during the normal stream:

 

    if ((g_UsbDeviceAudioSpeaker.audioSendTimes >= g_UsbDeviceAudioSpeaker.usbRecvTimes) &&
        (g_UsbDeviceAudioSpeaker.startPlayHalfFull == 1))

 

So, there is a small drift or non-synchronization between usbRecvTimes counter and audioSendTimes. In my case, usbRecvTimes counter goes slightly faster and catching up the audioSendTimes counter, which leads to the condition when DMA switches to the audioPlayDAMTempBuffer.  Here is the full function with PRINTF marker that I added:

 

static void txCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData)
{
    sai_transfer_t xfer = {0};
    if ((g_UsbDeviceAudioSpeaker.audioSendTimes >= g_UsbDeviceAudioSpeaker.usbRecvTimes) &&
        (g_UsbDeviceAudioSpeaker.startPlayHalfFull == 1))
    {
         PRINTF("r\r\n");
        g_UsbDeviceAudioSpeaker.startPlayHalfFull      = 0;
        g_UsbDeviceAudioSpeaker.speakerDetachOrNoInput = 1;
    }
    if (g_UsbDeviceAudioSpeaker.startPlayHalfFull)
    {
        xfer.dataSize = FS_ISO_OUT_ENDP_PACKET_SIZE;
        xfer.data     = audioPlayDataBuff + g_UsbDeviceAudioSpeaker.tdWriteNumberPlay;
        g_UsbDeviceAudioSpeaker.audioSendCount += FS_ISO_OUT_ENDP_PACKET_SIZE;
        g_UsbDeviceAudioSpeaker.audioSendTimes++;
        g_UsbDeviceAudioSpeaker.tdWriteNumberPlay += FS_ISO_OUT_ENDP_PACKET_SIZE;
        if (g_UsbDeviceAudioSpeaker.tdWriteNumberPlay >=
            AUDIO_SPEAKER_DATA_WHOLE_BUFFER_LENGTH * FS_ISO_OUT_ENDP_PACKET_SIZE)
        {
            g_UsbDeviceAudioSpeaker.tdWriteNumberPlay = 0;
        }
    }
    else
    {
        xfer.dataSize = FS_ISO_OUT_ENDP_PACKET_SIZE;
        xfer.data     = audioPlayDMATempBuff;
    }
    SAI_TransferSendEDMA(base, handle, &xfer);
}

 

And here is the output from the serial terminal (audio stream was active all the time from the beginning):

 

[2020-07-19 01:07:58] Set Cur Mute : 0
[2020-07-19 01:07:59] Set Cur Volume : 1f00
[2020-07-19 01:07:59] Set Cur Mute : 0
[2020-07-19 01:07:59] Set Cur Volume : 2bc7
[2020-07-19 01:08:06] Set Cur Volume : 2bb8
[2020-07-19 01:08:06] Set Cur Volume : 2ba9
[2020-07-19 01:08:06] Set Cur Volume : 2b9a
[2020-07-19 01:08:06] Set Cur Volume : 2b7c
[2020-07-19 01:08:07] Set Cur Volume : 2b6d
[2020-07-19 01:08:07] Set Cur Volume : 2b5e
[2020-07-19 01:08:07] Set Cur Volume : 2b4f
[2020-07-19 01:08:07] Set Cur Volume : 2b40
[2020-07-19 01:08:07] Set Cur Volume : 2b30
[2020-07-19 01:08:07] Set Cur Volume : 2b21
[2020-07-19 01:10:49] r
[2020-07-19 01:13:32] r
[2020-07-19 01:16:16] r
[2020-07-19 01:19:00] r
[2020-07-19 01:21:44] r
[2020-07-19 01:24:27] r

The issue here, that every time this event occurs the buffer of frames (audioPlayDataBuff) switches to the _tmp_ buffer (audioPlayDMATempBuff) with zero-values and it hearable on synthetic data, e.g. sine wave.

 

I did these tests on the OSX OS with USB 3.0 connector and external USB 2.0 HUB. In both cases the same result. The audio stream was a single long-term sound from an audio player.

 

Could you please try to reproduce this issue on your side and provide any feedback?

 

Best regards,

Anton

Outcomes