1 /*
2 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/ioctl.h>
23 #include <fcntl.h>
24 #include <pthread.h>
25 #include <errno.h>
26 #include <signal.h>
27 #include <sys/eventfd.h>
28
29 #include "hi_resampler_api.h"
30 #include "sample_comm.h"
31 #include "acodec.h"
32 #include "audio_aac_adp.h"
33 #include "audio_dl_adp.h"
34 #include "audio_mp3_adp.h"
35 #include "sample_comm_ive.h"
36 #include "sample_media_ai.h"
37
38 static PAYLOAD_TYPE_E gs_enPayloadType = PT_AAC;
39 static HI_BOOL gs_bAioReSample = HI_FALSE;
40 static HI_BOOL gs_bUserGetMode = HI_FALSE;
41 static HI_BOOL gs_bAoVolumeCtrl = HI_FALSE;
42 static AUDIO_SAMPLE_RATE_E g_in_sample_rate = AUDIO_SAMPLE_RATE_BUTT;
43 static AUDIO_SAMPLE_RATE_E g_out_sample_rate = AUDIO_SAMPLE_RATE_BUTT;
44 /* 0: close, 1: record, 2:reserved, 3:talkv2 */
45 static HI_U32 g_ai_vqe_type = 1;
46 static HI_BOOL g_sample_audio_exit = HI_FALSE;
47
48 static AI_RECORDVQE_CONFIG_S g_ai_record_vqe_attr;
49 static AI_TALKVQEV2_CONFIG_S g_ai_talkv2_vqe_attr;
50
audio_wait_quit(int quitFd)51 static int audio_wait_quit(int quitFd)
52 {
53 eventfd_t eval;
54 int ret = eventfd_read(quitFd, &eval);
55 assert(ret == 0);
56
57 return 0;
58 }
59
60 /* function : PT Number to String */
SAMPLE_AUDIO_Pt2Str(PAYLOAD_TYPE_E enType)61 static char *SAMPLE_AUDIO_Pt2Str(PAYLOAD_TYPE_E enType)
62 {
63 if (enType == PT_G711A) {
64 return "g711a";
65 } else if (enType == PT_G711U) {
66 return "g711u";
67 } else if (enType == PT_ADPCMA) {
68 return "adpcm";
69 } else if (enType == PT_G726) {
70 return "g726";
71 } else if (enType == PT_LPCM) {
72 return "pcm";
73 } else if (enType == PT_AAC) {
74 return "aac";
75 } else if (enType == PT_MP3) {
76 return "mp3";
77 } else {
78 return "data";
79 }
80 }
81
82 /* function : Add dynamic load path */
83 #ifndef HI_VQE_USE_STATIC_MODULE_REGISTER
SAMPLE_AUDIO_AddLibPath(HI_VOID)84 static HI_VOID SAMPLE_AUDIO_AddLibPath(HI_VOID)
85 {
86 HI_S32 s32Ret;
87 HI_CHAR aszLibPath[FILE_NAME_LEN] = {0};
88 #if defined(__HuaweiLite__) && (!defined(__OHOS__))
89 s32Ret = snprintf_s(aszLibPath, FILE_NAME_LEN, FILE_NAME_LEN - 1, "/sharefs/");
90 if (s32Ret <= EOK) {
91 SAMPLE_PRT("\n snprintf_s fail! ret = 0x%x", s32Ret);
92 return;
93 }
94 #else
95 #endif
96 s32Ret = Audio_Dlpath(aszLibPath);
97 if (s32Ret != HI_SUCCESS) {
98 SAMPLE_PRT("%s: add lib path %s failed\n", __FUNCTION__, aszLibPath);
99 }
100 return;
101 }
102 #endif
103
104 /* function : Open Adec File */
SAMPLE_AUDIO_OpenAdecFile_AAC(int num,ADEC_CHN AdChn,PAYLOAD_TYPE_E enType)105 static FILE* SAMPLE_AUDIO_OpenAdecFile_AAC(int num, ADEC_CHN AdChn, PAYLOAD_TYPE_E enType)
106 {
107 FILE* pfd;
108 HI_CHAR aszFileName[FILE_NAME_LEN] = {0};
109
110 /* create file for save stream */
111 #ifdef __HuaweiLite__
112 if (snprintf_s(aszFileName, FILE_NAME_LEN, FILE_NAME_LEN - 1, "/sharefs/audio_chn%d.%s",
113 AdChn, SAMPLE_AUDIO_Pt2Str(enType)) < 0) {
114 HI_ASSERT(0);
115 }
116 #else
117 if (num == -1) {
118 if (snprintf_s(aszFileName, FILE_NAME_LEN, FILE_NAME_LEN - 1,
119 "audio_chn%d.%s", AdChn, SAMPLE_AUDIO_Pt2Str(enType)) < 0) {
120 HI_ASSERT(0);
121 }
122 } else {
123 SAMPLE_PRT("SAMPLE_AUDIO_OpenAdecFile_AAC\n");
124 SAMPLE_PRT("filename:%d.%s\n", num, SAMPLE_AUDIO_Pt2Str(enType));
125 if (snprintf_s(aszFileName, FILE_NAME_LEN, FILE_NAME_LEN - 1,
126 "/userdata/aac_file/%d.%s", num, SAMPLE_AUDIO_Pt2Str(enType)) < 0) {
127 HI_ASSERT(0);
128 }
129 }
130 #endif
131
132 pfd = fopen(aszFileName, "rb");
133 if (pfd == NULL) {
134 SAMPLE_PRT("%s: open file %s failed\n", __FUNCTION__, aszFileName);
135 return NULL;
136 }
137 SAMPLE_PRT("open stream file:\"%s\" for adec ok\n", aszFileName);
138 return pfd;
139 }
140
sample_audio_adec_ao_init_param(AIO_ATTR_S * attr)141 static hi_void sample_audio_adec_ao_init_param(AIO_ATTR_S *attr)
142 {
143 attr->enSamplerate = AUDIO_SAMPLE_RATE_48000;
144 attr->u32FrmNum = FPS_30;
145 attr->enBitwidth = AUDIO_BIT_WIDTH_16;
146 attr->enWorkmode = AIO_MODE_I2S_MASTER;
147 attr->enSoundmode = AUDIO_SOUND_MODE_STEREO;
148 attr->u32ChnCnt = 2; /* 2: chn num */
149 attr->u32ClkSel = 1;
150 attr->enI2sType = AIO_I2STYPE_INNERCODEC;
151 attr->u32PtNumPerFrm = AACLC_SAMPLES_PER_FRAME;
152 attr->u32EXFlag = 0;
153
154 gs_bAioReSample = HI_FALSE;
155 g_in_sample_rate = AUDIO_SAMPLE_RATE_BUTT;
156 g_out_sample_rate = AUDIO_SAMPLE_RATE_BUTT;
157 }
158
SAMPLE_AUDIO_AdecAoInner(HI_S32 num,HI_S32 fd,AUDIO_DEV AoDev,AO_CHN AoChn,ADEC_CHN AdChn)159 static HI_VOID SAMPLE_AUDIO_AdecAoInner(HI_S32 num, HI_S32 fd, AUDIO_DEV AoDev, AO_CHN AoChn, ADEC_CHN AdChn)
160 {
161 HI_S32 s32Ret;
162 FILE *pfd = NULL;
163
164 s32Ret = SAMPLE_COMM_AUDIO_AoBindAdec(AoDev, AoChn, AdChn);
165 if (s32Ret != HI_SUCCESS) {
166 SAMPLE_PRT(s32Ret);
167 return;
168 }
169
170 pfd = SAMPLE_AUDIO_OpenAdecFile_AAC(num, AdChn, gs_enPayloadType);
171 if (pfd == NULL) {
172 SAMPLE_PRT(HI_FAILURE);
173 SAMPLE_CHECK_EXPR_GOTO(pfd == NULL, ADECAO_ERR0,
174 "SAMPLE_AUDIO_OpenAdecFile_AAC FAIL, ret=%#x\n", s32Ret);
175 }
176
177 s32Ret = SAMPLE_COMM_AUDIO_CreateTrdFileAdec(AdChn, pfd);
178 if (s32Ret != HI_SUCCESS) {
179 fclose(pfd);
180 pfd = HI_NULL;
181 SAMPLE_PRT(s32Ret);
182 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, ADECAO_ERR0,
183 "SAMPLE_COMM_AUDIO_CreateTrdFileAdec FAIL, ret=%#x\n", s32Ret);
184 }
185
186 printf("bind adec:%d to ao(%d,%d) ok \n", AdChn, AoDev, AoChn);
187
188 if (num == -1) {
189 audio_wait_quit(fd);
190 } else {
191 sleep(3); // 3: sleep time
192 }
193
194 s32Ret = SAMPLE_COMM_AUDIO_DestroyTrdFileAdec(AdChn);
195 if (s32Ret != HI_SUCCESS) {
196 SAMPLE_PRT(s32Ret);
197 return;
198 }
199
200 ADECAO_ERR0:
201 s32Ret = SAMPLE_COMM_AUDIO_AoUnbindAdec(AoDev, AoChn, AdChn);
202 if (s32Ret != HI_SUCCESS) {
203 SAMPLE_PRT(s32Ret);
204 }
205
206 return;
207 }
208
209 /* function : file -> Adec -> Ao */
SAMPLE_AUDIO_AdecAo(HI_S32 num,HI_S32 quitFd)210 static HI_S32 SAMPLE_AUDIO_AdecAo(HI_S32 num, HI_S32 quitFd)
211 {
212 HI_S32 s32Ret, s32AoChnCnt;
213 const AO_CHN AoChn = 0;
214 const ADEC_CHN AdChn = 0;
215 AIO_ATTR_S stAioAttr;
216 AUDIO_DEV AoDev = SAMPLE_AUDIO_INNER_AO_DEV;
217
218 sample_audio_adec_ao_init_param(&stAioAttr);
219
220 s32Ret = SAMPLE_COMM_AUDIO_StartAdec(AdChn, gs_enPayloadType);
221 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, ADECAO_ERR3,
222 "SAMPLE_COMM_AUDIO_StartAdec FAIL, ret=%#x\n", s32Ret);
223
224 s32AoChnCnt = stAioAttr.u32ChnCnt;
225 s32Ret = SAMPLE_COMM_AUDIO_StartAo(AoDev, s32AoChnCnt, &stAioAttr, g_in_sample_rate, gs_bAioReSample);
226 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, ADECAO_ERR2,
227 "SAMPLE_COMM_AUDIO_StartAo FAIL, ret=%#x\n", s32Ret);
228
229 s32Ret = SAMPLE_COMM_AUDIO_CfgAcodec(&stAioAttr);
230 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, ADECAO_ERR1,
231 "SAMPLE_COMM_AUDIO_CfgAcodec FAIL, ret=%#x\n", s32Ret);
232
233 SAMPLE_AUDIO_AdecAoInner(num, quitFd, AoDev, AoChn, AdChn);
234
235 ADECAO_ERR1:
236 s32Ret = SAMPLE_COMM_AUDIO_StopAo(AoDev, s32AoChnCnt, gs_bAioReSample);
237 if (s32Ret != HI_SUCCESS) {
238 SAMPLE_PRT(s32Ret);
239 }
240 ADECAO_ERR2:
241 s32Ret = SAMPLE_COMM_AUDIO_StopAdec(AdChn);
242 if (s32Ret != HI_SUCCESS) {
243 SAMPLE_PRT(s32Ret);
244 }
245
246 ADECAO_ERR3:
247 return s32Ret;
248 }
249
SAMPLE_AUDIO_StartAdecAo(HI_BOOL bSendAdec,AUDIO_DEV AoDev,AENC_CHN AeChn,AIO_ATTR_S * pstAioAttr)250 static HI_VOID SAMPLE_AUDIO_StartAdecAo(HI_BOOL bSendAdec, AUDIO_DEV AoDev, AENC_CHN AeChn, AIO_ATTR_S *pstAioAttr)
251 {
252 HI_S32 s32Ret, s32AoChnCnt;
253 const AO_CHN AoChn = 0;
254 const ADEC_CHN AdChn = 0;
255 FILE *pfd = NULL;
256
257 if (bSendAdec == HI_TRUE) {
258 s32Ret = SAMPLE_COMM_AUDIO_StartAdec(AdChn, gs_enPayloadType);
259 if (s32Ret != HI_SUCCESS) {
260 return;
261 }
262
263 s32AoChnCnt = pstAioAttr->u32ChnCnt;
264 s32Ret = SAMPLE_COMM_AUDIO_StartAo(AoDev, s32AoChnCnt, pstAioAttr, g_in_sample_rate, gs_bAioReSample);
265 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, STOP_ADEC,
266 "SAMPLE_COMM_AUDIO_StartAo FAIL. s32Ret: 0x%x\n", s32Ret);
267
268 pfd = SAMPLE_AUDIO_OpenAencFile(AdChn, gs_enPayloadType);
269 SAMPLE_CHECK_EXPR_GOTO(pfd == NULL, STOP_AO, "SAMPLE_AUDIO_OpenAencFile FAIL. s32Ret: 0x%x\n", s32Ret);
270
271 s32Ret = SAMPLE_COMM_AUDIO_CreateTrdAencAdec(AeChn, AdChn, pfd);
272 if (s32Ret != HI_SUCCESS) {
273 fclose(pfd);
274 pfd = HI_NULL;
275 SAMPLE_PRT(s32Ret);
276 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, STOP_AO,
277 "SAMPLE_COMM_AUDIO_CreateTrdAencAdec FAIL. s32Ret: 0x%x\n", s32Ret);
278 }
279
280 s32Ret = SAMPLE_COMM_AUDIO_AoBindAdec(AoDev, AoChn, AdChn);
281 if (s32Ret != HI_SUCCESS) {
282 SAMPLE_PRT(s32Ret);
283 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, DESTORY_AENC_THREAD,
284 "SAMPLE_COMM_AUDIO_AoBindAdec FAIL. s32Ret: 0x%x\n", s32Ret);
285 }
286
287 SAMPLE_PRT("bind adec:%d to ao(%d,%d) ok \n", AdChn, AoDev, AoChn);
288 }
289
290 if (bSendAdec == HI_TRUE) {
291 s32Ret = SAMPLE_COMM_AUDIO_AoUnbindAdec(AoDev, AoChn, AdChn);
292 if (s32Ret != HI_SUCCESS) {
293 SAMPLE_PRT(s32Ret);
294 }
295
296 DESTORY_AENC_THREAD:
297 (HI_VOID)SAMPLE_COMM_AUDIO_DestroyTrdAencAdec(AdChn);
298
299 STOP_AO:
300 (HI_VOID)SAMPLE_COMM_AUDIO_StopAo(AoDev, s32AoChnCnt, gs_bAioReSample);
301
302 STOP_ADEC:
303 (HI_VOID)SAMPLE_COMM_AUDIO_StopAdec(AdChn);
304 }
305 }
306
sample_audio_ai_ao_init_param(AIO_ATTR_S * attr)307 static hi_void sample_audio_ai_ao_init_param(AIO_ATTR_S *attr)
308 {
309 attr->enSamplerate = AUDIO_SAMPLE_RATE_48000;
310 attr->enBitwidth = AUDIO_BIT_WIDTH_16;
311 attr->enWorkmode = AIO_MODE_I2S_MASTER;
312 attr->enSoundmode = AUDIO_SOUND_MODE_STEREO;
313 attr->u32EXFlag = 0;
314 attr->u32FrmNum = FPS_30;
315 attr->u32PtNumPerFrm = AACLC_SAMPLES_PER_FRAME;
316 attr->u32ChnCnt = 2; /* 2: chn num */
317 attr->u32ClkSel = 1;
318 attr->enI2sType = AIO_I2STYPE_INNERCODEC;
319
320 gs_bAioReSample = HI_FALSE;
321 /* config ao resample attr if needed */
322 if (gs_bAioReSample == HI_TRUE) {
323 /* ai 48k -> 32k */
324 g_out_sample_rate = AUDIO_SAMPLE_RATE_32000;
325
326 /* ao 32k -> 48k */
327 g_in_sample_rate = AUDIO_SAMPLE_RATE_32000;
328 } else {
329 g_in_sample_rate = AUDIO_SAMPLE_RATE_BUTT;
330 g_out_sample_rate = AUDIO_SAMPLE_RATE_BUTT;
331 }
332
333 gs_bUserGetMode = (gs_bAioReSample == HI_TRUE) ? HI_TRUE : HI_FALSE;
334 }
335
SAMPLE_AUDIO_AiAoInner(AUDIO_DEV AiDev,AI_CHN AiChn,AUDIO_DEV AoDev,AO_CHN AoChn)336 static HI_VOID SAMPLE_AUDIO_AiAoInner(AUDIO_DEV AiDev, AI_CHN AiChn, AUDIO_DEV AoDev, AO_CHN AoChn)
337 {
338 HI_S32 s32Ret;
339
340 /* bind AI to AO channel */
341 if (gs_bUserGetMode == HI_TRUE) {
342 s32Ret = SAMPLE_COMM_AUDIO_CreateTrdAiAo(AiDev, AiChn, AoDev, AoChn);
343 if (s32Ret != HI_SUCCESS) {
344 SAMPLE_PRT(s32Ret);
345 return;
346 }
347 } else {
348 s32Ret = SAMPLE_COMM_AUDIO_AoBindAi(AiDev, AiChn, AoDev, AoChn);
349 if (s32Ret != HI_SUCCESS) {
350 SAMPLE_PRT(s32Ret);
351 return;
352 }
353 }
354 SAMPLE_PRT("ai(%d,%d) bind to ao(%d,%d) ok\n", AiDev, AiChn, AoDev, AoChn);
355
356 if (gs_bAoVolumeCtrl == HI_TRUE) {
357 s32Ret = SAMPLE_COMM_AUDIO_CreateTrdAoVolCtrl(AoDev);
358 if (s32Ret != HI_SUCCESS) {
359 SAMPLE_PRT(s32Ret);
360 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, AIAO_ERR0,
361 "SAMPLE_COMM_AUDIO_CreateTrdAoVolCtrl FAIL. s32Ret: 0x%x\n", s32Ret);
362 }
363 }
364
365 if (gs_bAoVolumeCtrl == HI_TRUE) {
366 s32Ret = SAMPLE_COMM_AUDIO_DestroyTrdAoVolCtrl(AoDev);
367 if (s32Ret != HI_SUCCESS) {
368 SAMPLE_PRT(s32Ret);
369 return;
370 }
371 }
372
373 AIAO_ERR0:
374 if (gs_bUserGetMode == HI_TRUE) {
375 s32Ret = SAMPLE_COMM_AUDIO_DestroyTrdAi(AiDev, AiChn);
376 if (s32Ret != HI_SUCCESS) {
377 SAMPLE_PRT(s32Ret);
378 }
379 } else {
380 s32Ret = SAMPLE_COMM_AUDIO_AoUnbindAi(AiDev, AiChn, AoDev, AoChn);
381 if (s32Ret != HI_SUCCESS) {
382 SAMPLE_PRT(s32Ret);
383 }
384 }
385
386 return;
387 }
388
389 /* function : Ai -> Ao(with fade in/out and volume adjust) */
SAMPLE_AUDIO_AiAo(HI_VOID)390 static HI_S32 SAMPLE_AUDIO_AiAo(HI_VOID)
391 {
392 HI_S32 s32Ret;
393 HI_S32 s32AiChnCnt;
394 HI_S32 s32AoChnCnt;
395 const AI_CHN AiChn = 0;
396 const AO_CHN AoChn = 0;
397 AIO_ATTR_S stAioAttr;
398 AUDIO_DEV AiDev = SAMPLE_AUDIO_INNER_AI_DEV;
399 AUDIO_DEV AoDev = SAMPLE_AUDIO_INNER_AO_DEV;
400
401 sample_audio_ai_ao_init_param(&stAioAttr);
402
403 /* enable AI channel */
404 s32AiChnCnt = stAioAttr.u32ChnCnt;
405 s32Ret = SAMPLE_COMM_AUDIO_StartAi(AiDev, s32AiChnCnt, &stAioAttr, g_out_sample_rate, gs_bAioReSample, NULL, 0);
406 if (s32Ret != HI_SUCCESS) {
407 SAMPLE_PRT(s32Ret);
408 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, AIAO_ERR3,
409 "SAMPLE_COMM_AUDIO_StartAi FAIL. s32Ret: 0x%x\n", s32Ret);
410 }
411
412 /* enable AO channel */
413 s32AoChnCnt = stAioAttr.u32ChnCnt;
414 s32Ret = SAMPLE_COMM_AUDIO_StartAo(AoDev, s32AoChnCnt, &stAioAttr, g_in_sample_rate, gs_bAioReSample);
415 if (s32Ret != HI_SUCCESS) {
416 SAMPLE_PRT(s32Ret);
417 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, AIAO_ERR2,
418 "SAMPLE_COMM_AUDIO_StartAo FAIL. s32Ret: 0x%x\n", s32Ret);
419 }
420
421 /* config internal audio codec */
422 s32Ret = SAMPLE_COMM_AUDIO_CfgAcodec(&stAioAttr);
423 SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, AIAO_ERR1,
424 "SAMPLE_COMM_AUDIO_CfgAcodec FAIL. s32Ret: 0x%x\n", s32Ret);
425
426 SAMPLE_AUDIO_AiAoInner(AiDev, AiChn, AoDev, AoChn);
427
428 AIAO_ERR1:
429 s32Ret = SAMPLE_COMM_AUDIO_StopAo(AoDev, s32AoChnCnt, gs_bAioReSample);
430 if (s32Ret != HI_SUCCESS) {
431 SAMPLE_PRT(s32Ret);
432 }
433
434 AIAO_ERR2:
435 s32Ret = SAMPLE_COMM_AUDIO_StopAi(AiDev, s32AiChnCnt, gs_bAioReSample, HI_FALSE);
436 if (s32Ret != HI_SUCCESS) {
437 SAMPLE_PRT(s32Ret);
438 }
439
440 AIAO_ERR3:
441 return s32Ret;
442 }
443
444 /* function : main */
AudioTest(HI_U32 num,HI_S32 quitFd)445 HI_S32 AudioTest(HI_U32 num, HI_S32 quitFd)
446 {
447 HI_S32 s32Ret = HI_SUCCESS;
448 SAMPLE_AUDIO_AddLibPath();
449
450 HI_MPI_AENC_AacInit();
451 HI_MPI_ADEC_AacInit();
452 SAMPLE_AUDIO_AdecAo(num, quitFd);
453
454 HI_MPI_AENC_AacDeInit();
455 HI_MPI_ADEC_AacDeInit();
456
457 return s32Ret;
458 }