linuxOS_AP05/device/rockchip/rk3308/rk3308_2mic_release-0.52-online/demo/music.c

349 lines
9.8 KiB
C
Raw Permalink Normal View History

2025-06-02 05:59:07 +00:00
/*================================================================
* Copyright (C) 2018 AISPEECH Ltd. All rights reserved.
*
* music.c
* chenjie.gu
* 20180524
*
*
================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "audio_player.h"
#include <time.h>
#include "cJSON.h"
#include <unistd.h>
#include <pthread.h>
audio_player_t *aplayer = NULL;
float vol_multiplier = 0.8;
int player_is_end = 0;
pthread_mutex_t music_mutex;
int play_judge_f(int index, int count, int mode);
void play_manager_f(const char *cmd, const char *data, char **user_data);
static int play_callback(void *userdata, int ev) {
if (ev == AUDIO_PLAYER_EV_END) {
player_is_end = 1;
}
return 0;
}
void *player_routine(void *user) {
while (1) {
if (player_is_end) {
player_is_end = 0;
play_manager_f("player.end", NULL, NULL);
}
usleep(100 * 1000);
}
return (void *)0;
}
int music_player_init(char *dev) {
aplayer = audio_player_new(play_callback, NULL);
audio_player_set_device(aplayer, dev);
audio_player_set_channel_volume(aplayer, vol_multiplier);
pthread_mutex_init(&music_mutex, NULL);
return 0;
}
int music_player_play(char *path) {
audio_player_play(aplayer, path);
}
int music_player_start() {
int ret;
pthread_t tid;
pthread_create(&tid, NULL, player_routine, NULL);
return 0;
}
void play_manager_f(const char *cmd, const char *data, char **user_data) {
/*
* 1. volume.set
* 2. play.list.update
* 3. play.list.clear
* 4. play.list.get
* 5. status.set
* 6. change.set
* 7. mode.set
* 8. play.choose.update
* 9. play.collect.choose
* 10. play.uncollect.choose
* 11. player.end
* 12. music.info
*/
enum PLAY_MODE {
sequence, random, single, loop
};
enum PLAY_STATUS {
idle, pause, playing
};
static enum PLAY_MODE mode = sequence;
static enum PLAY_STATUS status = idle;
static int count = 0;
static int index = 0;
static int old_index = 0;
static cJSON *root = NULL;
printf("play_manager_f cmd: %s\tdata: %s\n", cmd, data);
pthread_mutex_lock(&music_mutex);
if (!strcmp(cmd, "volume.set")) {
// 设置音量
if (!strcmp(data, "+")) {
vol_multiplier += 0.05;
if (vol_multiplier > 1.0) vol_multiplier = 0.99;
audio_player_set_channel_volume(aplayer, vol_multiplier);
printf("set vol_multiplier to %f\n", vol_multiplier);
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
}
else if (!strcmp(data, "-")) {
vol_multiplier -= 0.05;
if (vol_multiplier < 0.01) vol_multiplier = 0.01;
audio_player_set_channel_volume(aplayer, vol_multiplier);
printf("set vol_multiplier to %f\n", vol_multiplier);
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
}
else {
int vol = atoi(data);
vol_multiplier = vol / 100.0;
audio_player_set_channel_volume(aplayer, vol_multiplier);
printf("set vol_multiplier to %f\n", vol_multiplier);
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
}
}
else if (!strcmp(cmd, "play.list.clear")) {
// 清空播放列表
printf("clear the play list info\n");
audio_player_stop(aplayer);
cJSON_Delete(root);
root = NULL;
index = 0;
old_index = 0;
count = 0;
status = idle;
}
else if (!strcmp(cmd, "play.list.get")) {
}
else if (!strcmp(cmd, "music.info")) {
if (root) {
cJSON *temp, *music;
music = cJSON_GetObjectItem(root, "content");
temp = cJSON_GetArrayItem(music, index);
*user_data = cJSON_Print(temp);
}
else *user_data = NULL;
}
else if (!strcmp(cmd, "play.list.check")) {
// 开始真正播放
cJSON *temp, *music;
if (root) {
if (status == idle) {
temp = cJSON_GetObjectItem(root, "count");
count = temp->valueint;
if (count > 0) {
status = playing;
music = cJSON_GetObjectItem(root, "content");
temp = cJSON_GetArrayItem(music, index);
temp = cJSON_GetObjectItem(temp, "linkUrl");
printf("ready to play url is %s\n", temp->valuestring);
audio_player_play(aplayer, temp->valuestring);
}
}
else if (status == pause) {
status = playing;
audio_player_resume(aplayer);
}
}
}
else if (!strcmp(cmd, "play.list.update")) {
// 更新播放列表
// TODO: update
printf("update the play list info\n");
audio_player_stop(aplayer);
if (root) cJSON_Delete(root);
root = NULL;
index = 0;
old_index = 0;
count = 0;
status = idle;
root = cJSON_Parse(data);
}
else if (!strcmp(cmd, "status.set")) {
// 设置播放状态
printf("status.set data is %s status is %d\n", data, status);
if (!strcmp(data, "pause") && status == playing) {
status = pause;
audio_player_pause(aplayer);
}
else if (!strcmp(data, "resume") && status == pause) {
status = playing;
audio_player_resume(aplayer);
}
else if (!strcmp(data, "replay") && status == pause) {
status = idle;
}
else if (!strcmp(data, "step")) {
if (status == playing) {
status = pause;
audio_player_pause(aplayer);
}
else if (status == pause) {
status = playing;
audio_player_resume(aplayer);
}
}
}
else if (!strcmp(cmd, "mode.set")) {
// 播放模式
if (!strcmp(data, "sequence")) mode = sequence;
else if (!strcmp(data, "random")) mode = random;
else if (!strcmp(data, "single")) mode = single;
else if (!strcmp(data, "loop")) mode = loop;
}
else if (!strcmp(cmd, "change.set")) {
// 歌曲切换
// TODO: update
if (!strcmp(data, "prev")) {
// 上一首
index = old_index;
}
else if (!strcmp(data, "next")) {
// 下一首
old_index = index;
index = play_judge_f(index, count, mode);
}
else if (!strcmp(data, "change")) {
// 换一首
old_index = index;
index = play_judge_f(index, count, mode);
}
if (index == -1) {
// 播放结束
cJSON_Delete(root);
audio_player_stop(aplayer);
root = NULL;
index = 0;
old_index = 0;
count = 0;
status = idle;
}
else {
// 待播放指定的音频
status = idle;
}
}
else if (!strcmp(cmd, "play.choose.update")) {
// 播放特定歌曲
// TODO: update
int find = 0;
int i = 0;
cJSON *temp = cJSON_Parse(data);
temp = cJSON_GetObjectItem(temp, "linkUrl");
cJSON *music = cJSON_GetObjectItem(root, "content");
cJSON *xx;
for (i = 0; i < count; i++) {
xx = cJSON_GetArrayItem(music, i);
xx = cJSON_GetObjectItem(xx, "linkUrl");
if (!strcmp(xx->valuestring, temp->valuestring)) {
find = 1;
break;
}
}
if (find) {
old_index = index;
index = i;
printf("ready to play url is %s\n", temp->valuestring);
audio_player_stop(aplayer);
audio_player_play(aplayer, temp->valuestring);
}
else {
// 播放歌曲不在播放列表里面
printf("wwwwwwwwwwwwwwwwwwwwwwwwwww\n");
}
}
else if (!strcmp(cmd, "play.collect.choose")) {
// 收藏歌曲
}
else if (!strcmp(cmd, "play.uncollect.choose")) {
// 取消收藏
}
else if (!strcmp(cmd, "player.end") && root) {
// 播放器播放结束
// TODO: update
old_index = index;
index = play_judge_f(index, count, mode);
printf("play_judge_f index is %d\n", index);
if (index == -1) {
// 播放结束
audio_player_stop(aplayer);
cJSON_Delete(root);
root = NULL;
index = 0;
old_index = 0;
count = 0;
status = idle;
}
else {
// 播放指定的音频
cJSON *temp, *music;
music = cJSON_GetObjectItem(root, "content");
temp = cJSON_GetArrayItem(music, index);
temp = cJSON_GetObjectItem(temp, "linkUrl");
printf("ready to play url is %s\n", temp->valuestring);
audio_player_stop(aplayer);
audio_player_play(aplayer, temp->valuestring);
}
}
pthread_mutex_unlock(&music_mutex);
}
int play_judge_f(int index, int count, int mode) {
// sequence, random, single, loop
if (mode == 0) {
// 顺序播放
if (index + 1 == count) return -1;
else return index + 1;
}
else if (mode == 1) {
// 随机播放
srand(time(0));
return rand() % count;
}
else if (mode == 2) {
// 单曲循环
return index;
}
else if (mode == 3) {
// 循环播放
return (index + 1) % count;
}
else return -1;
}