Skip to main content
Associate III
May 21, 2024
Solved

Slow down SAI Audio output

  • May 21, 2024
  • 4 replies
  • 4208 views

 

Hello,

I am currently programming an STM32F469I in STM32CubeIDE (I am a beginner with STM) and I am facing some issues.

  1. What I want: I want to read WAV file data from an SD card and send it to the AUX output so I can hear it on my headset/speaker. Currently, I am reading the data from a buffer, but I will change that afterwards once I know that everything works.

  2. What is the issue?: The issue is that the sound plays way too fast and I don't know why. I am attaching my project so you can download it and look at it.

My main files are saved under /Core/Src

 

Thank you for your help!

    Best answer by DerFreaker

    Hey, after reviewing the code I'm using, I discovered that I'm modifying the SAI data size within the code.

    So, that was the issue.

     

     

    // From
    haudio_out_sai.Init.DataSize = SAI_DATASIZE_16;
    
    // To
    haudio_out_sai.Init.DataSize = SAI_DATASIZE_32;
    

     

     

     

    If you encounter any errors because it's too fast, simply change the data size to 32.

     

    Thanks for the help ;) 

    4 replies

    AScha.3
    Super User
    May 21, 2024

    Hi,

    so you got it working...right ?

    But you use the BSP functions - i never did.

    >The issue is that the sound plays way too fast 

    from source:

     

    /**
     * @brief Updates the audio frequency.
     * AudioFreq: Audio frequency used to play the audio stream.
     * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
     * audio frequency.
     */
    void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq)

     

     and you use:

     

     BSP_AUDIO_OUT_Init(2, 60, 44100);
     AUDIO_Play_Start((uint32_t *)0x08080000, (uint32_t)0x143046);
     HAL_Delay(500);
     BSP_AUDIO_OUT_Pause();
     BSP_AUDIO_OUT_SetFrequency(8000);
     BSP_AUDIO_OUT_Resume();

     

    So start with 44k1 , then switch to 8k ? why ?

    Did you check, whats written to CSxxx codec ? And whats set in SAIx_Init(..) to the SAI ?

    "If you feel a post has answered your question, please click ""Accept as Solution""."
    Associate III
    May 21, 2024

    so you got it working...right ?

    Yeah, but just way to fast.

     


    So start with 44k1 , then switch to 8k ? why ?


    It was just to test if it would run slower with it, because in the BSP file, it was much slower with 8k. Unfortunately, it sounds nearly the same with 8k or 44k1.

     


    Did you check, whats written to CSxxx codec ? And whats set in SAIx_Init(..) to the SAI ?


    Yes but I don't understand where I could "slow" the code down

     

    "I also tried to copy the SAI initialization from the BSP to my SAI initialization (in main.c line 675), but it resulted in the same issue."

    AScha.3
    Super User
    May 21, 2024

    >Yes but I don't understand where I could "slow" the code down

    The audio speed (= sample rate) is set by the SAI master and what you set it to.

    in Cube:

    AScha3_0-1716285411158.png

    then start it, from now its continuously running... (Check with scope the signal, word clk...to prove your setting.)

     

     

     fresult = HAL_DMA_Init(&hdma_sai1_a); 
    
    fresult = HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *)playbuf , (sizeof(playbuf))/4);// SAI start

     

     

    (playbuf is int32_t here, because i use 32b sample format, so you might adjust for int16 )

    Then just feed it in half/full callbacks - thats it, to get it running. :)

     

    "If you feel a post has answered your question, please click ""Accept as Solution""."
    Associate III
    May 28, 2024

    Unfortunately, after implementing the SD card, it no longer works as it should. If the data size increases, more problems occur. I have WAV files that are 60 seconds in length, and the speed issue persists, but this time changing the size variable doesn't work anymore (It just gets worse and worse)

     

     

    uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size)
    {
     uint8_t ret = AUDIO_OK;
    
     /*Call the audio Codec Play function */
     if(audio_drv->Play(AUDIO_I2C_ADDRESS, pBuffer, Size) != 0)
     {
     ret = AUDIO_ERROR;
     }
    
     /* Initiate a DMA transfer of PCM samples towards the serial audio interface */
     if(ret == AUDIO_OK)
     {
    	 	 	 	 	 	 	 	 	 	 	 	 	 		// Speed variable = 4000
     if (HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t *)pBuffer , 4000) != HAL_OK)
     {
     ret = AUDIO_ERROR;
     }
    
     }
    
     return ret;
    }

     

     

    Ive also made some changes to main.c so im just gonna attach it here 

    DerFreakerAuthorBest answer
    Associate III
    June 10, 2024

    Hey, after reviewing the code I'm using, I discovered that I'm modifying the SAI data size within the code.

    So, that was the issue.

     

     

    // From
    haudio_out_sai.Init.DataSize = SAI_DATASIZE_16;
    
    // To
    haudio_out_sai.Init.DataSize = SAI_DATASIZE_32;
    

     

     

     

    If you encounter any errors because it's too fast, simply change the data size to 32.

     

    Thanks for the help ;) 

    Visitor II
    November 17, 2024

    Hello, I want to play wav files. Can you walk me through the CubeMX configuration and other steps. There are very few articles or tutorials, I can't find