添加flac解码器代码

This commit is contained in:
wangyz1997 2024-04-08 21:30:32 +08:00
parent 40c3323204
commit 16844ea4a6
6 changed files with 188 additions and 18 deletions

View File

@ -73,7 +73,7 @@ target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
freertos freertos
easylogger easylogger
fatfs fatfs
FLAC dr_lib
# lvgl # lvgl
# lvgl_demos # lvgl_demos
minimp3 minimp3

View File

@ -5,26 +5,27 @@ project(middlewares)
add_subdirectory(Third_Party/freertos) add_subdirectory(Third_Party/freertos)
add_subdirectory(Third_Party/easylogger) add_subdirectory(Third_Party/easylogger)
add_subdirectory(Third_Party/fatfs) add_subdirectory(Third_Party/fatfs)
add_subdirectory(Third_Party/flac) # add_subdirectory(Third_Party/flac)
add_subdirectory(Third_Party/lvgl) # add_subdirectory(Third_Party/lvgl)
add_subdirectory(Third_Party/dr_lib)
add_subdirectory(Third_Party/minimp3) add_subdirectory(Third_Party/minimp3)
add_subdirectory(Third_Party/tlsf) add_subdirectory(Third_Party/tlsf)
# #
target_compile_options(FLAC PRIVATE # target_compile_options(FLAC PRIVATE
-Wformat=0 # -Wformat=0
-Wno-incompatible-pointer-types # -Wno-incompatible-pointer-types
) # )
target_compile_options(grabbag PRIVATE # target_compile_options(grabbag PRIVATE
-Wformat=0 # -Wformat=0
) # )
target_compile_options(lvgl_demos PRIVATE # target_compile_options(lvgl_demos PRIVATE
-Wformat=0 # -Wformat=0
) # )
target_compile_options(lvgl_examples PRIVATE # target_compile_options(lvgl_examples PRIVATE
-Wformat=0 # -Wformat=0
-Wno-unused-variable # -Wno-unused-variable
) # )

159
User/audio/audio_flac.c Normal file
View File

@ -0,0 +1,159 @@
#include "audio_flac.h"
#include "main.h"
#include "ff.h"
#include "FreeRTOS.h"
#include "queue.h"
#include "elog.h"
#include "heap.h"
#define DR_FLAC_IMPLEMENTATION
#include "dr_flac.h"
const static char *TAG = "audio_flac";
static size_t flac_read(void* pUserData, void* pBufferOut, size_t bytesToRead)
{
HAL_GPIO_TogglePin(LED_Y_GPIO_Port, LED_Y_Pin);
UINT br;
FRESULT f_result = f_read(pUserData, pBufferOut, bytesToRead, &br); //从文件中读取新的内容
elog_verbose(TAG, "flac_read: reading %d bytes, %d bytes read", bytesToRead, br);
if (f_result != FR_OK) {
elog_error(TAG, "file read error");
return 0;
}
return br;
}
static drflac_bool32 flac_seek(void* pUserData, int offset, drflac_seek_origin origin)
{
FIL *file = (FIL*)pUserData;
HAL_GPIO_TogglePin(LED_G_GPIO_Port, LED_G_Pin);
if (origin == drflac_seek_origin_start) {
f_lseek(file, offset);
elog_debug(TAG, "flac_seek: drflac_seek_origin_start, offset=%d, fptr=%d", offset, f_tell(file));
} else {
uint32_t fptr = f_tell(file);
if (fptr + offset > f_size(file)) {
elog_warn(TAG, "flac_seek: seeking beyond the end of the file");
return false;
}
f_lseek(file, fptr + offset);
elog_debug(TAG, "flac_seek: drflac_seek_origin_current, offset=%d, fptr original=%d, fptr=%d", offset, fptr, f_tell((FIL*)pUserData));
}
return true;
}
void* flac_malloc(size_t sz, void* pUserData)
{
UNUSED(pUserData);
void *ptr = malloc(sz);
elog_warn(TAG, "flac_malloc: %d bytes", sz);
tlsf_pool_statistics *dtcm_heap_statistics = get_dtcm_heap_statistics();
tlsf_pool_statistics *ahb_heap_statistics = get_ahb_heap_statistics();
elog_verbose(TAG, "free heap: DTCM: %d, AXI: %d", dtcm_heap_statistics->free_size, ahb_heap_statistics->free_size);
return ptr;
}
void* flac_realloc(void* p, size_t sz, void* pUserData)
{
UNUSED(pUserData);
void *ptr = realloc(p, sz);
elog_warn(TAG, "flac_realloc: %d bytes", sz);
return ptr;
}
void flac_free(void* p, void* pUserData)
{
UNUSED(pUserData);
elog_warn(TAG, "flac_free");
free(p);
}
static const drflac_allocation_callbacks callbacks = {
.onMalloc = flac_malloc,
.onFree = flac_free,
.onRealloc = flac_realloc,
.pUserData = NULL
};
// static void flac_on_meta(void* pUserData, drflac_metadata* pMetadata)
// {
// elog_warn(TAG, "on metadata %d", pMetadata->type);
// }
void music_flac_play(const char *file_name)
{
FIL *file = malloc(sizeof(FIL));
if (file == NULL) {
elog_error(TAG, "error while allocating file object");
return;
}
FRESULT f_result = f_open(file, file_name, FA_READ);
if (f_result == FR_OK) {
elog_info(TAG, "successfully opened %s for playing", file_name);
} else {
elog_error(TAG, "error while opening %s, error code=%d", file_name, f_result);
free(file);
return;
}
/* 创建并初始化解码器 */
// drflac* pFlac = drflac_open_with_metadata(flac_read, flac_seek, flac_on_meta, file, NULL);
drflac* pFlac = drflac_open(flac_read, flac_seek, file, &callbacks);
if (pFlac == NULL) {
elog_error(TAG, "error while creating opening flac file");
goto exit;
}
/* 初始化SAI */
uint32_t frame_pcm_size = pFlac->maxBlockSizeInPCMFrames * pFlac->channels;
audio_hal_start(frame_pcm_size, pFlac->bitsPerSample / 8);
elog_info(TAG, "start playing");
while(1) {
/* 解码新一帧FLAC数据 */
drflac_int16 *sample = malloc(frame_pcm_size * (pFlac->bitsPerSample / 8));
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 */
if (frame_count != 0) {
// elog_verbose(TAG, "writing %d bytes of pcm data", frame_count * sizeof(drflac_int16));
audio_hal_write(sample, frame_count * pFlac->channels);
} else { //文件已经读取完毕
free(sample);
elog_info(TAG, "play done");
break; //结束播放
}
}
audio_hal_stop();
/* 关闭文件 */
f_close(file);
free(file);
exit:
if (pFlac) {
drflac_close(pFlac);
}
tlsf_pool_statistics *dtcm_heap_statistics = get_dtcm_heap_statistics();
tlsf_pool_statistics *ahb_heap_statistics = get_ahb_heap_statistics();
elog_verbose(TAG, "free heap: DTCM: %d, AXI: %d", dtcm_heap_statistics->free_size, ahb_heap_statistics->free_size);
}

8
User/audio/audio_flac.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef __AUDIO_FLAC_H
#define __AUDIO_FLAC_H
#include "audio_hal.h"
void music_flac_play(const char *file_name);
#endif

View File

@ -3,7 +3,7 @@
#include "main.h" #include "main.h"
#define AUDIO_HAL_SAMPLE_QUEUE_SIZE 5 #define AUDIO_HAL_SAMPLE_QUEUE_SIZE 3
void audio_hal_start(uint32_t sample_count, uint8_t sample_size); void audio_hal_start(uint32_t sample_count, uint8_t sample_size);
void audio_hal_stop(void); void audio_hal_stop(void);

View File

@ -8,6 +8,7 @@
#include "main.h" #include "main.h"
#include "ff.h" #include "ff.h"
#include "audio_player_mp3.h" #include "audio_player_mp3.h"
#include "audio_flac.h"
#include "bsp_aic3204.h" #include "bsp_aic3204.h"
// #include "lvgl.h" // #include "lvgl.h"
// #include "lv_demos.h" // #include "lv_demos.h"
@ -151,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_mp3_play("夏川椎菜 - No.1.mp3"); music_mp3_play("夏川椎菜 - No.1.mp3");
music_mp3_play("HoneyWorks,早見沙織 - 可愛くてごめん.mp3"); music_mp3_play("HoneyWorks,早見沙織 - 可愛くてごめん.mp3");
music_mp3_play("堀江由衣 - silky heart.mp3"); music_mp3_play("堀江由衣 - silky heart.mp3");