STM32 I2S с медленным воспроизведением DMA
Я хочу реализовать WAV/MP3-плеер (теперь просто скажем WAV) с STM32, он читает его с SD с помощью FATFS, а затем передает его в буфер I2S с помощью DMA.
Проблема в том, что когда я подключаю свои динамики, песня воспроизводится с правильным тоном (тоном), но очень медленно, а также издает странный повторяющийся тик, как будто буфер заполняется медленно или играет медленно, но с правильным частоты.
Я использую STM32_F4VE(STM32F407VET6) с PCM5102(нужны только DATA, BCK при 32xfs для 16 бит и LRCK на fs)
Здесь я прикрепляю несколько частей кода: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;
}
}
}