设计说明
5 Dec 2024
Read time: 9 minute(s)
源码说明
本模块源码位于 packages/artinchip/mpp/middle_media/mini_audio_player 下,目录结构如下
packages
|-artinchip
|-mpp
|-middle-media
|-mini_audio_player
|-mini_audio_player.h //接口
|-mini_audio_player.c //接口具体实现
|-mini_audio_player_demo //demo
数据结构设计
struct mini_audio_player;
enum MINI_AUDIO_PLAYER_STATE {
MINI_AUDIO_PLAYER_STATE_STOPED = 0,
MINI_AUDIO_PLAYER_STATE_PLAYING = 1,
MINI_AUDIO_PLAYER_STATE_PAUSED = 2,
};
struct mini_player_audio_info {
s64 file_size;
s64 duration;
s32 nb_channel;
s32 bits_per_sample;
s32 sample_rate;
};
接口设计
struct mini_audio_player* mini_audio_player_create(void);
int mini_audio_player_destroy(struct mini_audio_player *player);
int mini_audio_player_play(struct mini_audio_player *player,char *uri);
int mini_audio_player_stop(struct mini_audio_player *player);
int mini_audio_player_pause(struct mini_audio_player *player);
int mini_audio_player_resume(struct mini_audio_player *player);
int mini_audio_player_get_media_info(struct mini_audio_player *player,struct mini_player_audio_info *audio_info);
int mini_audio_player_set_volume(struct mini_audio_player *player,int vol);
int mini_audio_player_get_volume(struct mini_audio_player *player,int *vol);
int mini_audio_player_get_state(struct mini_audio_player *player);
函数原型 | struct mini_audio_player *mini_audio_player_create(void) |
---|---|
功能说明 | 创建 audio_player 对象 |
参数定义 |
无
|
返回值 | audio_player 对象 |
注意事项 | - |
函数原型 | int mini_audio_player_destroy(struct mini_audio_player *audio_player) |
---|---|
功能说明 | 销毁 audio_player 对象 |
参数定义 |
audio_player 对象
|
返回值 |
0:成功,其他:失败
|
函数原型 | int mini_audio_player_play(struct mini_audio_player *audio_player,char *uri) |
---|---|
功能说明 | 启动线程播放音频,非阻塞。 |
参数定义 |
audio_player 对象,uri ,文件路径
|
返回值 |
0:成功,其他:失败
|
函数原型 | s32 mini_audio_player_stop(struct mini_audio_player *audio_player) |
---|---|
功能说明 | 结束当前音频文件播放,非阻塞 |
参数定义 |
audio_player 对象
|
返回值 |
0:成功,其他:失败。
|
函数原型 | s32 mini_audio_player_pause(struct mini_audio_player *audio_player) |
---|---|
功能说明 | 暂停当前音频文件播放,非阻塞 |
参数定义 |
audio_player 对象
|
返回值 |
0:成功,其他:失败。
|
函数原型 | s32 mini_audio_player_get_media_info(struct mini_audio_player *audio_player) |
---|---|
功能说明 | 获取当前音频参数,非阻塞 |
参数定义 |
audio_player 对象
|
返回值 |
0:成功,其他:失败。
|
函数原型 | int mini_audio_player_set_volume(struct mini_audio_player *audio_player,int vol) |
---|---|
功能说明 | 设置音量,非阻塞 |
参数定义 |
audio_player 对象,vol 音量值,0-100
|
返回值 |
0:成功,其他:失败
|
函数原型 | int mini_audio_player_get_volume(struct mini_audio_player *audio_player,int *vol) |
---|---|
功能说明 | 获取音量,非阻塞 |
参数定义 |
audio_player 对象,vol ,音量值
|
返回值 |
0:成功,其他:失败
|
函数原型 | int mini_audio_player_get_state(struct mini_audio_player *audio_player) |
---|---|
功能说明 | 获取当前播放状态,非阻塞。 |
参数定义 |
audio_player 对象
|
返回值 |
返回当前状态,3 种状态,停止,播放中,暂停中
|
APP Demo
源码位于
packages/artinchip/mpp/middle_media/mini_audio_player/mini_audio_player_demo.c
/*
* Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd
*
* author: <jun.ma@artinchip.com>
* Desc: audio_player_demo
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <unistd.h>
#include <inttypes.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <getopt.h>
#include <shell.h>
#include <artinchip_fb.h>
#include "mini_audio_player.h"
#ifdef LPKG_USING_CPU_USAGE
#include "cpu_usage.h"
#endif
#define AUDIO_PLAYER_DEMO_FILE_MAX_NUM 128
#define AUDIO_PLAYER_DEMO_FILE_PATH_MAX_LEN 256
struct audio_file_list {
char *file_path[AUDIO_PLAYER_DEMO_FILE_MAX_NUM];
int file_num;
};
static void print_help(const char* prog)
{
printf("name: %s\n", prog);
printf("Compile time: %s\n", __TIME__);
printf("Usage: player_demo [options]:\n"
"\t-i input stream file name\n"
"\t-t directory of test files\n"
"\t-l loop time\n"
"\t-h help\n\n"
"---------------------------------------------------------------------------------------\n"
"-------------------------------control key while playing-------------------------------\n"
"---------------------------------------------------------------------------------------\n"
"('s'): stop current \n"
"('p'): pause \n"
"('r'): resume \n"
"('+'): volum+5 \n"
"('-'): volum-5 \n"
"('e'): eixt app \n");
}
static int read_dir(char* path, struct audio_file_list *files)
{
char* ptr = NULL;
int file_path_len = 0;
struct dirent* dir_file;
DIR* dir = opendir(path);
if (dir == NULL) {
printf("read dir failed");
return -1;
}
while((dir_file = readdir(dir))) {
if (strcmp(dir_file->d_name, ".") == 0 || strcmp(dir_file->d_name, "..") == 0)
continue;
ptr = strrchr(dir_file->d_name, '.');
if (ptr == NULL)
continue;
if (strcmp(ptr, ".mp3") && strcmp(ptr, ".wav"))
continue;
printf("name: %s\n", dir_file->d_name);
file_path_len = 0;
file_path_len += strlen(path);
file_path_len += 1; // '/'
file_path_len += strlen(dir_file->d_name);
printf("file_path_len:%d\n",file_path_len);
if (file_path_len > AUDIO_PLAYER_DEMO_FILE_PATH_MAX_LEN-1) {
printf("%s too long \n",dir_file->d_name);
continue;
}
files->file_path[files->file_num] = (char *)aicos_malloc(MEM_DEFAULT,file_path_len+1);
files->file_path[files->file_num][file_path_len] = '\0';
strcpy(files->file_path[files->file_num], path);
strcat(files->file_path[files->file_num], "/");
strcat(files->file_path[files->file_num], dir_file->d_name);
printf("i: %d, filename: %s\n", files->file_num, files->file_path[files->file_num]);
files->file_num ++;
if (files->file_num ≥ AUDIO_PLAYER_DEMO_FILE_MAX_NUM)
break;
}
closedir(dir);
return 0;
}
static int read_file(char* path, struct audio_file_list *files)
{
int file_path_len;
file_path_len = strlen(path);
printf("file_path_len:%d\n",file_path_len);
if (file_path_len > AUDIO_PLAYER_DEMO_FILE_PATH_MAX_LEN-1) {
printf("file_path_len too long \n");
return -1;
}
files->file_path[0] = (char *)aicos_malloc(MEM_DEFAULT,file_path_len+1);
files->file_path[0][file_path_len] = '\0';
strcpy(files->file_path[0], path);
files->file_num = 1;
printf("file path: %s\n", files->file_path[0]);
return 0;
}
static int volume(int* vol,char ch)
{
int volume = *vol;
if (ch == '+') {
volume += 5;
} else {
volume -= 5;
}
if (volume < 0) {
volume = 0;
} else if (volume > 100) {
volume = 100;
}
*vol = volume;
printf("volum:%d\n",volume);
return volume;
}
static void show_cpu_usage()
{
#ifdef LPKG_USING_CPU_USAGE
static int index = 0;
char data_str[64];
float value = 0.0;
if (index++ % 30 == 0) {
value = cpu_load_average();
#ifdef AIC_PRINT_FLOAT_CUSTOM
int cpu_i;
int cpu_frac;
cpu_i = (int)value;
cpu_frac = (value - cpu_i) * 100;
snprintf(data_str, sizeof(data_str), "%d.%02d\n", cpu_i, cpu_frac);
#else
snprintf(data_str, sizeof(data_str), "%.2f\n", value);
#endif
printf("cpu_loading:%s\n",data_str);
}
#endif
}
static void audio_player_demo(int argc, char **argv)
{
int i,j;
char ch;
int vol = 80;
int opt;
int loop_time = 1;
rt_device_t uart_dev = RT_NULL;
struct mini_audio_player *player = NULL;
struct audio_file_list files = {0};
uart_dev = rt_device_find(RT_CONSOLE_DEVICE_NAME);
if (uart_dev == NULL) {
printf("Failed to open %s\n", RT_CONSOLE_DEVICE_NAME);
return;
}
optind = 0;
while (1) {
opt = getopt(argc, argv, "i:t:l:h");
if (opt == -1) {
break;
}
switch (opt) {
case 'i':
read_file(optarg,&files);
break;
case 'l':
loop_time = atoi(optarg);
break;
case 't':
read_dir(optarg, &files);
break;
case 'h':
print_help(argv[0]);
default:
goto _exit;
break;
}
}
if (files.file_num == 0) {
print_help(argv[0]);
printf("files.file_num ==0 !!!\n");
goto _exit;
}
player = mini_audio_player_create();
if (player == NULL) {
printf("mini_audio_player_create fail!!!\n");
goto _exit;
}
mini_audio_player_set_volume(player,vol);
for(i = 0;i < loop_time; i++) {
for(j = 0; j < files.file_num; j++) {
mini_audio_player_play(player,files.file_path[j]);
printf("loop:%d,index:%d,path:%s\n",i,j,files.file_path[j]);
while(1) {
if (rt_device_read(uart_dev, -1, &ch, 1) == 1) {
if (ch == 's') {// stop cur
mini_audio_player_stop(player);
printf("force stop\n");
break;
} else if (ch == '+') {// volume++
mini_audio_player_set_volume(player,volume(&vol,ch));
} else if (ch == '-') {// volume--
mini_audio_player_set_volume(player,volume(&vol,ch));
} else if (ch == 'p') {// pause
mini_audio_player_pause(player);
printf("enter pause\n");
} else if (ch == 'r') {// resume
mini_audio_player_resume(player);
printf("resume \n");
} else if (ch == 'e') {// exit app
printf("exit app \n");
goto _exit;
}
}
if (mini_audio_player_get_state(player) == MINI_AUDIO_PLAYER_STATE_STOPED) {
printf("[%s:%d]\n",__FUNCTION__,__LINE__);
break;
}
usleep(100*1000);
show_cpu_usage();
}
}
}
_exit:
if (player) {
mini_audio_player_destroy(player);
player = NULL;
}
for(i = 0; i <files.file_num ;i++) {
if (files.file_path[i]) {
aicos_free(MEM_DEFAULT,files.file_path[i]);
}
}
}
MSH_CMD_EXPORT_ALIAS(audio_player_demo, audio_player_demo, audio player demo);