添加flac解码器代码
This commit is contained in:
parent
40c3323204
commit
16844ea4a6
@ -73,7 +73,7 @@ target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
freertos
|
||||
easylogger
|
||||
fatfs
|
||||
FLAC
|
||||
dr_lib
|
||||
# lvgl
|
||||
# lvgl_demos
|
||||
minimp3
|
||||
|
||||
@ -5,26 +5,27 @@ project(middlewares)
|
||||
add_subdirectory(Third_Party/freertos)
|
||||
add_subdirectory(Third_Party/easylogger)
|
||||
add_subdirectory(Third_Party/fatfs)
|
||||
add_subdirectory(Third_Party/flac)
|
||||
add_subdirectory(Third_Party/lvgl)
|
||||
# add_subdirectory(Third_Party/flac)
|
||||
# add_subdirectory(Third_Party/lvgl)
|
||||
add_subdirectory(Third_Party/dr_lib)
|
||||
add_subdirectory(Third_Party/minimp3)
|
||||
add_subdirectory(Third_Party/tlsf)
|
||||
|
||||
# 屏蔽第三方库中的警告
|
||||
target_compile_options(FLAC PRIVATE
|
||||
-Wformat=0
|
||||
-Wno-incompatible-pointer-types
|
||||
)
|
||||
# target_compile_options(FLAC PRIVATE
|
||||
# -Wformat=0
|
||||
# -Wno-incompatible-pointer-types
|
||||
# )
|
||||
|
||||
target_compile_options(grabbag PRIVATE
|
||||
-Wformat=0
|
||||
)
|
||||
# target_compile_options(grabbag PRIVATE
|
||||
# -Wformat=0
|
||||
# )
|
||||
|
||||
target_compile_options(lvgl_demos PRIVATE
|
||||
-Wformat=0
|
||||
)
|
||||
# target_compile_options(lvgl_demos PRIVATE
|
||||
# -Wformat=0
|
||||
# )
|
||||
|
||||
target_compile_options(lvgl_examples PRIVATE
|
||||
-Wformat=0
|
||||
-Wno-unused-variable
|
||||
)
|
||||
# target_compile_options(lvgl_examples PRIVATE
|
||||
# -Wformat=0
|
||||
# -Wno-unused-variable
|
||||
# )
|
||||
|
||||
159
User/audio/audio_flac.c
Normal file
159
User/audio/audio_flac.c
Normal 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
8
User/audio/audio_flac.h
Normal 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
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#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_stop(void);
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include "main.h"
|
||||
#include "ff.h"
|
||||
#include "audio_player_mp3.h"
|
||||
#include "audio_flac.h"
|
||||
#include "bsp_aic3204.h"
|
||||
// #include "lvgl.h"
|
||||
// #include "lv_demos.h"
|
||||
@ -151,6 +152,7 @@ void task_main_entry(void *param)
|
||||
util_i2c_scan(&hi2c1);
|
||||
|
||||
while (1) {
|
||||
music_flac_play("四季音色 - 斑光.flac");
|
||||
music_mp3_play("夏川椎菜 - No.1.mp3");
|
||||
music_mp3_play("HoneyWorks,早見沙織 - 可愛くてごめん.mp3");
|
||||
music_mp3_play("堀江由衣 - silky heart.mp3");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user