• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }