修复flac播放

This commit is contained in:
wangyz1997 2024-04-08 23:51:58 +08:00
parent 6f0b87e6bb
commit b482b46e0b
4 changed files with 30 additions and 26 deletions

View File

@ -6,6 +6,8 @@
#include "elog.h" #include "elog.h"
#include "heap.h" #include "heap.h"
#define DR_FLAC_NO_STDIO
#define DR_FLAC_NO_OGG
#define DR_FLAC_IMPLEMENTATION #define DR_FLAC_IMPLEMENTATION
#include "dr_flac.h" #include "dr_flac.h"
@ -18,7 +20,7 @@ static size_t flac_read(void* pUserData, void* pBufferOut, size_t bytesToRead)
UINT br; UINT br;
FRESULT f_result = f_read(pUserData, pBufferOut, bytesToRead, &br); //从文件中读取新的内容 FRESULT f_result = f_read(pUserData, pBufferOut, bytesToRead, &br); //从文件中读取新的内容
elog_verbose(TAG, "flac_read: reading %d bytes, %d bytes read", bytesToRead, br); // elog_verbose(TAG, "flac_read: reading %d bytes, %d bytes read", bytesToRead, br);
if (f_result != FR_OK) { if (f_result != FR_OK) {
elog_error(TAG, "file read error"); elog_error(TAG, "file read error");
@ -122,19 +124,19 @@ void music_flac_play(const char *file_name)
audio_hal_start(frame_pcm_size, pFlac->bitsPerSample / 8); audio_hal_start(frame_pcm_size, pFlac->bitsPerSample / 8);
elog_info(TAG, "start playing"); elog_info(TAG, "start playing");
drflac_int16 *sample = malloc(frame_pcm_size * (pFlac->bitsPerSample / 8));
// if (sample == NULL) {
// elog_error(TAG, "%d bytes memory allocation failed", frame_pcm_size * (pFlac->bitsPerSample / 8));
// break;
// }
while(1) { while(1) {
/* 解码新一帧FLAC数据 */ /* 解码新一帧FLAC数据 */
drflac_int16 *sample = malloc(frame_pcm_size * (pFlac->bitsPerSample / 8)); uint32_t frame_count = drflac_read_pcm_frames_s16(pFlac, pFlac->maxBlockSizeInPCMFrames, sample);
if (sample == NULL) {
elog_error(TAG, "memory allocation failed");
goto exit;
}
uint32_t frame_count = drflac_read_pcm_frames_s16(pFlac, frame_pcm_size, sample);
/* 将解码后的PCM数据写入SAI */ /* 将解码后的PCM数据写入SAI */
if (frame_count != 0) { if (frame_count != 0) {
// elog_verbose(TAG, "writing %d bytes of pcm data", frame_count * sizeof(drflac_int16)); // elog_verbose(TAG, "writing %d bytes of pcm data", frame_count * sizeof(drflac_int16));
audio_hal_write(sample, frame_count * pFlac->channels); audio_hal_write(sample, frame_pcm_size * pFlac->channels);
} else { //文件已经读取完毕 } else { //文件已经读取完毕
free(sample); free(sample);
elog_info(TAG, "play done"); elog_info(TAG, "play done");
@ -142,13 +144,14 @@ void music_flac_play(const char *file_name)
} }
} }
audio_hal_stop();
/* 关闭文件 */ /* 关闭文件 */
f_close(file); f_close(file);
free(file); free(file);
exit: exit:
audio_hal_stop();
drflac_close(pFlac);
if (pFlac) { if (pFlac) {
drflac_close(pFlac); drflac_close(pFlac);
} }

View File

@ -20,11 +20,11 @@ static uint32_t audio_buffer_length = 0;
void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai) void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
{ {
BaseType_t need_yield = pdFALSE; BaseType_t need_yield = pdFALSE;
audio_sample_t sample; // audio_sample_t sample;
if (xQueueReceiveFromISR(audio_queue, &sample, &need_yield) == pdTRUE) { if (xQueueReceiveFromISR(audio_queue, &audio_buffer[0], &need_yield) == pdTRUE) {
memcpy(&audio_buffer[0], sample.buffer_ptr, sample.buffer_size); //复制到第一个缓冲区 // memcpy(&audio_buffer[0], sample.buffer_ptr, sample.buffer_size); //复制到第一个缓冲区
free(sample.buffer_ptr); //释放使用完的缓冲区 // free(sample.buffer_ptr); //释放使用完的缓冲区
} }
HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
@ -34,11 +34,11 @@ void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai) void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
{ {
BaseType_t need_yield = pdFALSE; BaseType_t need_yield = pdFALSE;
audio_sample_t sample; // audio_sample_t sample;
if (xQueueReceiveFromISR(audio_queue, &sample, &need_yield) == pdTRUE) { if (xQueueReceiveFromISR(audio_queue, &audio_buffer[audio_buffer_length / 2], &need_yield) == pdTRUE) {
memcpy(&audio_buffer[audio_buffer_length / 2], sample.buffer_ptr, sample.buffer_size); //复制到第二个缓冲区 // memcpy(&audio_buffer[audio_buffer_length / 2], sample.buffer_ptr, sample.buffer_size); //复制到第二个缓冲区
free(sample.buffer_ptr); //释放使用完的缓冲区 // free(sample.buffer_ptr); //释放使用完的缓冲区
} }
HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET);
@ -62,7 +62,7 @@ void audio_hal_start(uint32_t sample_count, uint8_t sample_size)
elog_warn(TAG, "audio_hal_start: audio_queue is not deleted"); elog_warn(TAG, "audio_hal_start: audio_queue is not deleted");
vQueueDelete(audio_queue); vQueueDelete(audio_queue);
} }
audio_queue = xQueueCreate(AUDIO_HAL_SAMPLE_QUEUE_SIZE, sizeof(audio_sample_t)); audio_queue = xQueueCreate(AUDIO_HAL_SAMPLE_QUEUE_SIZE, audio_buffer_length/2);
HAL_SAI_Transmit_DMA(&hsai_BlockB1, audio_buffer, sample_count * 2); //开始DMA循环发送 HAL_SAI_Transmit_DMA(&hsai_BlockB1, audio_buffer, sample_count * 2); //开始DMA循环发送
} }
@ -84,14 +84,14 @@ void audio_hal_write(void *buffer_ptr, uint32_t buffer_size)
return; return;
} }
audio_sample_t sample = { // audio_sample_t sample = {
.buffer_ptr = buffer_ptr, // .buffer_ptr = buffer_ptr,
.buffer_size = buffer_size // .buffer_size = buffer_size
}; // };
if (uxQueueSpacesAvailable(audio_queue) == AUDIO_HAL_SAMPLE_QUEUE_SIZE) { if (uxQueueSpacesAvailable(audio_queue) == AUDIO_HAL_SAMPLE_QUEUE_SIZE) {
elog_warn(TAG, "audio_hal_write: queue is empty before xQueueSend"); elog_warn(TAG, "audio_hal_write: queue is empty before xQueueSend");
} }
xQueueSend(audio_queue, &sample, portMAX_DELAY); //发送缓冲区到队列中 xQueueSend(audio_queue, buffer_ptr, portMAX_DELAY); //发送缓冲区到队列中
} }

View File

@ -152,6 +152,7 @@ void task_main_entry(void *param)
util_i2c_scan(&hi2c1); util_i2c_scan(&hi2c1);
while (1) { while (1) {
music_flac_play("唐九夏 - 一克拉月光.flac");
music_flac_play("四季音色 - 斑光.flac"); music_flac_play("四季音色 - 斑光.flac");
music_mp3_play("夏川椎菜 - No.1.mp3"); music_mp3_play("夏川椎菜 - No.1.mp3");
music_mp3_play("HoneyWorks,早見沙織 - 可愛くてごめん.mp3"); music_mp3_play("HoneyWorks,早見沙織 - 可愛くてごめん.mp3");

View File

@ -12,7 +12,7 @@ void *pvPortMalloc( size_t xWantedSize )
{ {
void *pvReturn; void *pvReturn;
pvReturn = malloc_dtcm( xWantedSize ); pvReturn = malloc( xWantedSize );
traceMALLOC( pvReturn, xWantedSize ); traceMALLOC( pvReturn, xWantedSize );
#if( configUSE_MALLOC_FAILED_HOOK == 1 ) #if( configUSE_MALLOC_FAILED_HOOK == 1 )
@ -30,7 +30,7 @@ void vPortFree( void *pv )
{ {
if( pv ) if( pv )
{ {
free_dtcm( pv ); free( pv );
traceFREE( pv, 0 ); traceFREE( pv, 0 );
} }
} }