STM32 I2S with DMA playing slow

1.2k views Asked by At

I want to implement a WAV/MP3 player(now let's just say WAV) with an STM32, it reads it from the SD with FATFS, then transfer it to the I2S buffer with DMA.

The problem is that when I plug my speakers, it plays the song at the correct pitch(tone) but very slowly, and it also does an strange repetitive tick, is like the buffer is filled slowly, or played slowly, but with the correct frequencies.

I use an STM32_F4VE(STM32F407VET6) with a PCM5102(only needs DATA, BCK at 32xfs for 16bits, and LRCK at fs)

Here I attach a few code parts: main.c

    if(res = f_mount(&SDFatFS, SDPath, 1) == FR_OK){                        //If SD card is correctly mounted
      HAL_UART_Transmit_IT(&huart1, "SD montada correctamente\n\r", strlen("SD montada correctamente\n\r"));
      if(wavPlayer_fileSelect("test.wav")  == 0){                   //If the wav file wasn't correstly opened
          HAL_UART_Transmit_IT(&huart1, "Error al abrir el WAV\n\r", strlen("Error al abrir el WAV\n\r"));
      }
      else
      {
          HAL_UART_Transmit_IT(&huart1, "WAV abierto\n\r", strlen("WAV abierto\n\r"));
          wavPlayer_play();
          HAL_UART_Transmit_IT(&huart1, "WAV PLAY\n\r", strlen("WAV PLAY\n\r"));
          isPlaying = true;
      }
  }
  else
  {
      HAL_UART_Transmit_IT(&huart1, "Error al montar la SD\n\r", strlen("Error al montar la SD\n\r"));
  }

wavplayer.c

    /**
 * @brief Select WAV file to play
 * @retval returns true when file is found in USB Drive
 */
bool wavPlayer_fileSelect(const char* filePath)
{
  UINT readBytes = 0;
  //Open WAV file
  if(f_open(&wavFile, filePath, FA_READ) != FR_OK)
  {
    return false;
  }
  //Read WAV file Header
  f_read(&wavFile, &wavHeader, sizeof(wavHeader), &readBytes);
  sprintf(UART_buff, "TamaƱo del archivo: %d\n\rFrecuencia de muestreo: %d\n\r", wavHeader.FileSize, wavHeader.SampleRate);
  HAL_UART_Transmit_IT(&huart1, UART_buff, strlen(UART_buff));//TX Function
  end_of_file_reached = false;
  return true;
}

/**
 * @brief WAV File Play
 */
void wavPlayer_play(void)
{
  isFinished = false;
  //Read Audio data from USB Disk
  f_lseek(&wavFile, 0);
  f_read (&wavFile, &audioBuffer[0], AUDIO_BUFFER_SIZE, &playerReadBytes);
  audioRemainSize = wavHeader.FileSize - playerReadBytes;
  //Start playing the WAV
  HAL_I2S_Transmit_DMA(&hi2s2, (uint16_t *)&audioBuffer[0], AUDIO_BUFFER_SIZE);
}

    
/**
 * @brief Half/Full transfer Audio callback for buffer management
 */
void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
{
  if(hi2s->Instance == SPI2)
  {
      if(end_of_file_reached){
                return;
        }

        res = f_read (&wavFile, &audioBuffer[AUDIO_BUFFER_SIZE/2], AUDIO_BUFFER_SIZE/2, &playerReadBytes);

        if(audioRemainSize > (AUDIO_BUFFER_SIZE / 2))
        {
          audioRemainSize -= playerReadBytes;
        }
        else
        {
          audioRemainSize = 0;
          end_of_file_reached = true;
        }
  }
}

void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
{
  if(hi2s->Instance == SPI2)
  {
      if(end_of_file_reached){
          return;
      }

      res = f_read (&wavFile, &audioBuffer[0], AUDIO_BUFFER_SIZE/2, &playerReadBytes);

      if(audioRemainSize > (AUDIO_BUFFER_SIZE / 2))
      {
          audioRemainSize -= playerReadBytes;
      }
      else
      {
          audioRemainSize = 0;
          end_of_file_reached = true;
      }
  }
}
0

There are 0 answers