linuxOS_AP05/device/rockchip/rk3308/aispeech-2mic-64bit/dds_client/demo/music.c
2025-06-02 13:59:07 +08:00

385 lines
11 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*================================================================
* Copyright (C) 2018 AISPEECH Ltd. All rights reserved.
*
* 文件名称music.c
* 创 建 者chenjie.gu
* 创建日期2018年05月24日
* 描 述:
*
================================================================*/
#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>
#include <stdbool.h>
audio_player_t *aplayer = NULL;
float vol_multiplier = 0.5;
int vol_system = 70;
int player_is_end = 0;
pthread_mutex_t music_mutex;
int play_judge_f(int index, int count, int mode);
static int g_player_ev = AUDIO_PLAYER_EV_END;
void play_manager_f(const char *cmd, const char *data, char **user_data);
bool music_is_playing(void) {
if (g_player_ev == AUDIO_PLAYER_EV_END ||
g_player_ev == AUDIO_PLAYER_EV_ERROR ||
g_player_ev == AUDIO_PLAYER_EV_STOPPED)
return false;
else
return true;
}
static int play_callback(void *userdata, int ev) {
printf("++++++%s: ev %d\n", __func__, ev);
if (ev == AUDIO_PLAYER_EV_END) {
player_is_end = 1;
}
g_player_ev = ev;
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);
system("amixer cset name='Master Playback Volume' 70");
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;
}
static void send_vol_update_topic (int vol) {
printf("send_vol_update_topic vol is %d\n", vol);
char out[128] = {0};
sprintf(out, "{\"volume\":\"%d\"}", vol);
printf("send_vol_update_topic is %s\n", out);
busserver_send_msg("ui.control.topics.response", out);
}
static void send_music_update_topic(int change, int status, int mode, int index, cJSON *list) {
printf("send_music_update_topic %d %d %d %d %p\n", change, status, mode, index, list);
char *out;
cJSON *root, *root2;
char *music;
root = cJSON_CreateObject();
root2 = cJSON_CreateObject();
cJSON_AddNumberToObject(root, "change", change);
cJSON_AddNumberToObject(root, "status", status);
cJSON_AddNumberToObject(root, "mode", mode);
cJSON_AddNumberToObject(root, "currentIndex", index);
if (list) {
cJSON *tmp = cJSON_GetObjectItem(list, "content");
cJSON_AddItemReferenceToObject(root, "list", tmp);
}
music = cJSON_PrintUnformatted(root);
cJSON_Delete(root);
cJSON_AddStringToObject(root2, "music", music);
out = cJSON_PrintUnformatted(root2);
cJSON_Delete(root2);
printf("send_music_update_topic is %s\n", out);
busserver_send_msg("ui.control.topics.response", out);
free(music);
free(out);
}
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, playing, pause
};
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_system += 10;
if (vol_system > 100) vol_system = 100;
}
else if (!strcmp(data, "-")) {
vol_system -= 10;
if (vol_system < 0) vol_system = 0;
}
else {
vol_system = atoi(data);
}
char cmd[64] = {0};
sprintf(cmd, "amixer cset name='Master Playback Volume' %d", vol_system);
system(cmd);
printf("set vol to %d\n", vol_system);
send_vol_update_topic(vol_system);
}
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;
send_music_update_topic(0, status, mode, index, NULL);
}
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);
}
send_music_update_topic(0, status, mode, index, root);
}
else send_music_update_topic(0, status, mode, index, NULL);
}
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 = playing;
}
else if (!strcmp(data, "step")) {
if (status == playing) {
status = pause;
audio_player_pause(aplayer);
}
else if (status == pause) {
status = playing;
audio_player_resume(aplayer);
}
}
send_music_update_topic(0, status, mode, index, root);
}
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;
send_music_update_topic(0, status, mode, index, root);
}
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")) {
// 播放特定歌曲
old_index = index;
index = atoi(data);
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);
send_music_update_topic(0, status, mode, index, root);
}
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;
send_music_update_topic(0, status, mode, index, NULL);
}
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);
send_music_update_topic(0, status, mode, index, root);
}
}
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;
}