PcmAudioFile.c
7.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <dirent.h>
#include <sys/stat.h>
#include "JZsdkLib.h"
#include "Megaphone/AudioMange/AudioMange.h"
#define PCM_DIR "/root/sdcard/pcm"
//创建一个pcm节点
static struct AudioMange_Node *g_PcmList = NULL;
static struct AudioMange_Node *g_PcmListtail = NULL; // 用于跟踪链表的尾部
static int g_PcmListNum = 0; //用于记录链表中的节点数量
static int g_PcmList_CurrentNum = 0; //用于记录链表中当前节点位置
/*****************
*
* 获取pcm文件列表的歌曲数
*
* ************/
int PcmFile_GetListNum()
{
return g_PcmListNum;
}
/*********
*
* pcm文件链表注销
*
**********/
static T_JZsdkReturnCode PcmFile_FreeAudioList()
{
//清空尾部指针
g_PcmListtail = NULL;
//清空歌曲数量
g_PcmListNum = 0; //记录链表中一共有几首歌
g_PcmList_CurrentNum = 0; //记录播放当前第几首歌
//释放掉整个链表
Jzsdk_Free_AndioMange_Node(&g_PcmList);
g_PcmList = NULL;
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/*********
*
* pcm文件链表刷新
*
**********/
T_JZsdkReturnCode PcmFile_FlushList()
{
//读取audio文件夹,并将歌曲名放入音频列表
DIR *dir;
struct dirent *entry;
struct stat fileStat;
//创建一个临时pcm节点
struct AudioMange_audio_struct PcmInfo;
T_JZsdkReturnCode ret;
//检查是否存在pcm文件夹,没有则创建一个
if(JZsdk_check_directory_exists_posix(PCM_DIR) != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
JZSDK_LOG_ERROR("不存在pcm文件夹,创建一个");
JZsdk_Osal_Mkdir(PCM_DIR);
}
//确定音频文件夹存在
if ((dir = opendir(PCM_DIR)) == NULL)
{
JZSDK_LOG_ERROR("音频文件夹获取失败");
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
//查看歌曲存放链表是否有注册过
if (g_PcmList != NULL)
{
PcmFile_FreeAudioList();
}
while ((entry = readdir(dir)) != NULL)
{
const unsigned char *filename = entry->d_name;
unsigned int fileSize;
int len = strlen(filename);
// // 获取文件状态信息,包括大小
// if (stat(filename, &fileStat) == 0)
// {
// fileSize = (unsigned long long)fileStat.st_size;
// }
// else
// {
// JZSDK_LOG_ERROR("%s文件信息获取错误",filename);
// fileSize = 0;
// continue;
// }
// 跳过目录和隐藏文件,并检查文件扩展名
if (entry->d_type != DT_DIR && strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0)
{
//printf("获取到%s\n",filename);
// 检查后缀
if (JZsdk_strings_suffix_comparison_withLen((const unsigned char *)filename, len, (const unsigned char *)".pcm") == JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS
|| JZsdk_strings_suffix_comparison_withLen((const unsigned char *)filename, len, (const unsigned char *)".PCM") == JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS
)
{
// 处理文件
memset(&PcmInfo, 0, sizeof(PcmInfo)); // 清除audioInfo结构
//写入文件名
strncpy(PcmInfo.FileName, entry->d_name, JZSDK_FILE_NAME_SIZE_MAX);
unsigned char fileDir [256];
snprintf(fileDir, sizeof(fileDir), "%s/%s",PCM_DIR, filename);
//写入文件大小
JZsdk_Fs_ReadFileSize(fileDir, &(PcmInfo.FileSize));
//根据文件大小写入时长信息
int temp_time = (PcmInfo.FileSize * 8) / (16000 * 16 * 1); //这条是pcm算时长,超准确
//int temp_time = (PcmInfo.FileSize * 8) / (16000); //这条是opus算时长,超准确
PcmInfo.Time = temp_time;
//写入文件名长度
PcmInfo.FileNameLen = len;
// 创建新节点
struct AudioMange_Node *newNode = NULL;
ret = Jzsdk_Create_AndioMange_Node(&newNode, PcmInfo) ;
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
JZSDK_LOG_ERROR("存放pcm节点 %s 失败", entry->d_name);
continue;
}
// 将新节点添加到链表末尾
Jzsdk_AddAudioNodeToCircularList(&g_PcmList, &g_PcmListtail, &newNode);
// 歌曲计数+1
g_PcmListNum++;
}
}
}
closedir(dir);
//设置默认播放歌曲
g_PcmList_CurrentNum = 0;
//打印一遍已加载的音乐
JZsdk_PrintfAuidoNode_AudioList(g_PcmList);
JZSDK_LOG_INFO("刷新pcm列表已完成");
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/*********************************
*
*
* 获取某序号下的歌曲名字
*
*
* *********************************/
T_JZsdkReturnCode Megaphone_PcmFile_GetAudioNameByIndex(int index, unsigned char *name, int *name_len)
{
T_JZsdkReturnCode ret ;
//判断歌曲列表是否有歌
if (g_PcmListNum == 0)
{
JZSDK_LOG_INFO("pcm列表中没有歌");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//判断序号是否在数量内
if (index > g_PcmListNum)
{
JZSDK_LOG_INFO("pcm列表中没有第%d首歌",index);
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//根据当前的索引值,获取当前的歌曲节点
struct AudioMange_Node *Current = NULL;
ret = getAudioMange_NodeAtIndex(g_PcmList, &Current, index);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
return ret;
}
if (Current == NULL)
{
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
//获取名字,后期这里要改动以下,太危险了, 要限制长度
memcpy(name, Current->audioInfo.FileName, Current->audioInfo.FileNameLen);
*name_len = Current->audioInfo.FileNameLen;
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/***********
*
* 查询pcm是否存在于列表
*
* **********/
T_JZsdkReturnCode Megaphone_PcmFile_IsExistInList(unsigned char *str, unsigned int str_len)
{
T_JZsdkReturnCode ret;
//1、查询该名字是否存在于音乐列表中
struct AudioMange_audio_struct songToFind;
memset(&songToFind, 0, sizeof(struct AudioMange_audio_struct));
memset(songToFind.FileName, 0 ,sizeof(songToFind.FileName));
memcpy(songToFind.FileName, str, str_len);
ret = JZsdk_isSongInAudioList(g_PcmList, songToFind);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
JZSDK_LOG_ERROR("播放文件不存在于pcm列表 %s", songToFind.FileName);
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/*****************
*
* 查询pcm信息
*
*
* **************/
T_JZsdkReturnCode PcmFile_GetAudioInfo(unsigned char *str, unsigned int str_len, struct AudioMange_audio_struct *songToFind)
{
T_JZsdkReturnCode ret;
//1、查询该名字是否存在于音乐列表中
memset(songToFind->FileName, 0 ,sizeof(songToFind->FileName));
memcpy(songToFind->FileName, str, str_len);
ret = JZsdk_isSongInAudioList(g_PcmList, (*songToFind));
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
JZSDK_LOG_ERROR("播放文件不存在于pcm列表 %s", songToFind->FileName);
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//2、获取歌曲信息
JZsdk_GetSongInDudioList_AudioInfo(g_PcmList, songToFind);
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/*********
*
* pcm文件初始化
*
**********/
T_JZsdkReturnCode Megaphone_PcmFile_Init()
{
//刷新pcm列表(用于加载新的pcm文件)
PcmFile_FlushList();
JZSDK_LOG_DEBUG("pcmFile Init Complete");
}