xref: /OK3568_Linux_fs/external/rockit/mpi/example/mod/test_mpi_ai.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2020 Rockchip Electronics Co. LTD
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Licensed under the Apache License, Version 2.0 (the "License");
5*4882a593Smuzhiyun  * you may not use this file except in compliance with the License.
6*4882a593Smuzhiyun  * You may obtain a copy of the License at
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *      http://www.apache.org/licenses/LICENSE-2.0
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * Unless required by applicable law or agreed to in writing, software
11*4882a593Smuzhiyun  * distributed under the License is distributed on an "AS IS" BASIS,
12*4882a593Smuzhiyun  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4882a593Smuzhiyun  * See the License for the specific language governing permissions and
14*4882a593Smuzhiyun  * limitations under the License.
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  */
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include <stdio.h>
19*4882a593Smuzhiyun #include <errno.h>
20*4882a593Smuzhiyun #include <cstring>
21*4882a593Smuzhiyun #include <cstdlib>
22*4882a593Smuzhiyun #include <unistd.h>
23*4882a593Smuzhiyun #include <pthread.h>
24*4882a593Smuzhiyun #include <sys/poll.h>
25*4882a593Smuzhiyun #include "rk_defines.h"
26*4882a593Smuzhiyun #include "rk_debug.h"
27*4882a593Smuzhiyun #include "rk_mpi_ai.h"
28*4882a593Smuzhiyun #include "rk_mpi_sys.h"
29*4882a593Smuzhiyun #include "rk_mpi_mb.h"
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #include "test_comm_argparse.h"
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun static RK_BOOL gAiExit = RK_FALSE;
34*4882a593Smuzhiyun #define TEST_AI_WITH_FD 0
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun typedef struct _rkMpiAICtx {
37*4882a593Smuzhiyun     const char *srcFilePath;
38*4882a593Smuzhiyun     const char *dstFilePath;
39*4882a593Smuzhiyun     RK_S32      s32LoopCount;
40*4882a593Smuzhiyun     RK_S32      s32ChnNum;
41*4882a593Smuzhiyun     RK_S32      s32DeviceSampleRate;
42*4882a593Smuzhiyun     RK_S32      s32SampleRate;
43*4882a593Smuzhiyun     RK_S32      s32DeviceChannel;
44*4882a593Smuzhiyun     RK_S32      s32Channel;
45*4882a593Smuzhiyun     RK_S32      s32BitWidth;
46*4882a593Smuzhiyun     RK_S32      s32DevId;
47*4882a593Smuzhiyun     RK_S32      s32PeriodCount;
48*4882a593Smuzhiyun     RK_S32      s32PeriodSize;
49*4882a593Smuzhiyun     char       *chCardName;
50*4882a593Smuzhiyun     RK_S32      s32ChnIndex;
51*4882a593Smuzhiyun     RK_S32      s32DevFd;
52*4882a593Smuzhiyun } TEST_AI_CTX_S;
53*4882a593Smuzhiyun 
ai_find_sound_mode(RK_S32 ch)54*4882a593Smuzhiyun static AUDIO_SOUND_MODE_E ai_find_sound_mode(RK_S32 ch) {
55*4882a593Smuzhiyun     AUDIO_SOUND_MODE_E channel = AUDIO_SOUND_MODE_BUTT;
56*4882a593Smuzhiyun     switch (ch) {
57*4882a593Smuzhiyun       case 1:
58*4882a593Smuzhiyun         channel = AUDIO_SOUND_MODE_MONO;
59*4882a593Smuzhiyun         break;
60*4882a593Smuzhiyun       case 2:
61*4882a593Smuzhiyun         channel = AUDIO_SOUND_MODE_STEREO;
62*4882a593Smuzhiyun         break;
63*4882a593Smuzhiyun       default:
64*4882a593Smuzhiyun         RK_LOGE("channel = %d not support", ch);
65*4882a593Smuzhiyun         return AUDIO_SOUND_MODE_BUTT;
66*4882a593Smuzhiyun     }
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun     return channel;
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
ai_find_bit_width(RK_S32 bit)71*4882a593Smuzhiyun static AUDIO_BIT_WIDTH_E ai_find_bit_width(RK_S32 bit) {
72*4882a593Smuzhiyun     AUDIO_BIT_WIDTH_E bitWidth = AUDIO_BIT_WIDTH_BUTT;
73*4882a593Smuzhiyun     switch (bit) {
74*4882a593Smuzhiyun       case 8:
75*4882a593Smuzhiyun         bitWidth = AUDIO_BIT_WIDTH_8;
76*4882a593Smuzhiyun         break;
77*4882a593Smuzhiyun       case 16:
78*4882a593Smuzhiyun         bitWidth = AUDIO_BIT_WIDTH_16;
79*4882a593Smuzhiyun         break;
80*4882a593Smuzhiyun       case 24:
81*4882a593Smuzhiyun         bitWidth = AUDIO_BIT_WIDTH_24;
82*4882a593Smuzhiyun         break;
83*4882a593Smuzhiyun       default:
84*4882a593Smuzhiyun         RK_LOGE("bitwidth(%d) not support", bit);
85*4882a593Smuzhiyun         return AUDIO_BIT_WIDTH_BUTT;
86*4882a593Smuzhiyun     }
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun     return bitWidth;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun 
test_ai_poll_event(RK_S32 timeoutMsec,RK_S32 fd)91*4882a593Smuzhiyun RK_S32 test_ai_poll_event(RK_S32 timeoutMsec, RK_S32 fd) {
92*4882a593Smuzhiyun     RK_S32 num_fds = 1;
93*4882a593Smuzhiyun     struct pollfd pollFds[num_fds];
94*4882a593Smuzhiyun     RK_S32 ret = 0;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun     RK_ASSERT(fd > 0);
97*4882a593Smuzhiyun     memset(pollFds, 0, sizeof(pollFds));
98*4882a593Smuzhiyun     pollFds[0].fd = fd;
99*4882a593Smuzhiyun     pollFds[0].events = (POLLPRI | POLLIN | POLLERR | POLLNVAL | POLLHUP);
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun     ret = poll(pollFds, num_fds, timeoutMsec);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun     if (ret > 0 && (pollFds[0].revents & (POLLERR | POLLNVAL | POLLHUP))) {
104*4882a593Smuzhiyun         RK_LOGE("fd:%d polled error", fd);
105*4882a593Smuzhiyun         return -1;
106*4882a593Smuzhiyun     }
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun     return ret;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun 
test_open_device_ai(TEST_AI_CTX_S * ctx)111*4882a593Smuzhiyun RK_S32 test_open_device_ai(TEST_AI_CTX_S *ctx) {
112*4882a593Smuzhiyun     AUDIO_DEV aiDevId = ctx->s32DevId;
113*4882a593Smuzhiyun     AUDIO_SOUND_MODE_E soundMode;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun     AIO_ATTR_S aiAttr;
116*4882a593Smuzhiyun     RK_S32 result;
117*4882a593Smuzhiyun     memset(&aiAttr, 0, sizeof(AIO_ATTR_S));
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun     if (ctx->chCardName) {
120*4882a593Smuzhiyun         snprintf(reinterpret_cast<char *>(aiAttr.u8CardName),
121*4882a593Smuzhiyun                  sizeof(aiAttr.u8CardName), "%s", ctx->chCardName);
122*4882a593Smuzhiyun     }
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun     aiAttr.soundCard.channels = ctx->s32DeviceChannel;
125*4882a593Smuzhiyun     aiAttr.soundCard.sampleRate = ctx->s32DeviceSampleRate;
126*4882a593Smuzhiyun     aiAttr.soundCard.bitWidth = AUDIO_BIT_WIDTH_16;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun     AUDIO_BIT_WIDTH_E bitWidth = ai_find_bit_width(ctx->s32BitWidth);
129*4882a593Smuzhiyun     if (bitWidth == AUDIO_BIT_WIDTH_BUTT) {
130*4882a593Smuzhiyun         goto __FAILED;
131*4882a593Smuzhiyun     }
132*4882a593Smuzhiyun     aiAttr.enBitwidth = bitWidth;
133*4882a593Smuzhiyun     aiAttr.enSamplerate = (AUDIO_SAMPLE_RATE_E)ctx->s32SampleRate;
134*4882a593Smuzhiyun     soundMode = ai_find_sound_mode(ctx->s32Channel);
135*4882a593Smuzhiyun     if (soundMode == AUDIO_SOUND_MODE_BUTT) {
136*4882a593Smuzhiyun         goto __FAILED;
137*4882a593Smuzhiyun     }
138*4882a593Smuzhiyun     aiAttr.enSoundmode = soundMode;
139*4882a593Smuzhiyun     aiAttr.u32FrmNum = ctx->s32PeriodCount;
140*4882a593Smuzhiyun     aiAttr.u32PtNumPerFrm = ctx->s32PeriodSize;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun     aiAttr.u32EXFlag = 0;
143*4882a593Smuzhiyun     aiAttr.u32ChnCnt = 2;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun     result = RK_MPI_AI_SetPubAttr(aiDevId, &aiAttr);
146*4882a593Smuzhiyun     if (result != 0) {
147*4882a593Smuzhiyun         RK_LOGE("ai set attr fail, reason = %d", result);
148*4882a593Smuzhiyun         goto __FAILED;
149*4882a593Smuzhiyun     }
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun     result = RK_MPI_AI_Enable(aiDevId);
152*4882a593Smuzhiyun     if (result != 0) {
153*4882a593Smuzhiyun         RK_LOGE("ai enable fail, reason = %d", result);
154*4882a593Smuzhiyun         goto __FAILED;
155*4882a593Smuzhiyun     }
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun     return RK_SUCCESS;
158*4882a593Smuzhiyun __FAILED:
159*4882a593Smuzhiyun     return RK_FAILURE;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun 
test_init_mpi_ai(TEST_AI_CTX_S * params)162*4882a593Smuzhiyun RK_S32 test_init_mpi_ai(TEST_AI_CTX_S *params) {
163*4882a593Smuzhiyun     RK_S32 result;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun     result =  RK_MPI_AI_EnableChn(params->s32DevId, params->s32ChnIndex);
166*4882a593Smuzhiyun     if (result != 0) {
167*4882a593Smuzhiyun         RK_LOGE("ai enable channel fail, aoChn = %d, reason = %x", params->s32ChnIndex, result);
168*4882a593Smuzhiyun         return RK_FAILURE;
169*4882a593Smuzhiyun     }
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun #if TEST_AI_WITH_FD
172*4882a593Smuzhiyun     // open fd immediate after enable chn will be better.
173*4882a593Smuzhiyun     params->s32DevFd = RK_MPI_AI_GetFd(params->s32DevId, params->s32ChnIndex);
174*4882a593Smuzhiyun     RK_LOGI("ai (devId: %d, chnId: %d), selectFd:%d", params->s32DevId, params->s32ChnIndex, params->s32DevFd);
175*4882a593Smuzhiyun #endif
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun     result = RK_MPI_AI_EnableReSmp(params->s32DevId, params->s32ChnIndex,
178*4882a593Smuzhiyun                                   (AUDIO_SAMPLE_RATE_E)params->s32SampleRate);
179*4882a593Smuzhiyun     if (result != 0) {
180*4882a593Smuzhiyun         RK_LOGE("ai enable channel fail, reason = %x, aoChn = %d", result, params->s32ChnIndex);
181*4882a593Smuzhiyun         return RK_FAILURE;
182*4882a593Smuzhiyun     }
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun     return RK_SUCCESS;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun 
test_deinit_mpi_ai(TEST_AI_CTX_S * params)187*4882a593Smuzhiyun RK_S32 test_deinit_mpi_ai(TEST_AI_CTX_S *params) {
188*4882a593Smuzhiyun     RK_MPI_AI_DisableReSmp(params->s32DevId, params->s32ChnIndex);
189*4882a593Smuzhiyun     RK_S32 result = RK_MPI_AI_DisableChn(params->s32DevId, params->s32ChnIndex);
190*4882a593Smuzhiyun     if (result != 0) {
191*4882a593Smuzhiyun         RK_LOGE("ai disable channel fail, reason = %d", result);
192*4882a593Smuzhiyun         return RK_FAILURE;
193*4882a593Smuzhiyun     }
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun     result =  RK_MPI_AI_Disable(params->s32DevId);
196*4882a593Smuzhiyun     if (result != 0) {
197*4882a593Smuzhiyun         RK_LOGE("ai disable fail, reason = %d", result);
198*4882a593Smuzhiyun         return RK_FAILURE;
199*4882a593Smuzhiyun     }
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun     return RK_SUCCESS;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun 
sendDataThread(void * ptr)204*4882a593Smuzhiyun void* sendDataThread(void * ptr) {
205*4882a593Smuzhiyun     TEST_AI_CTX_S *params = reinterpret_cast<TEST_AI_CTX_S *>(ptr);
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun     RK_S32 result = 0;
208*4882a593Smuzhiyun     RK_S32 s32MilliSec = -1;
209*4882a593Smuzhiyun     AUDIO_FRAME_S frame;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun     if (params->dstFilePath) {
212*4882a593Smuzhiyun         AUDIO_SAVE_FILE_INFO_S save;
213*4882a593Smuzhiyun         save.bCfg = RK_TRUE;
214*4882a593Smuzhiyun         save.u32FileSize = 1024;
215*4882a593Smuzhiyun         snprintf(save.aFilePath, sizeof(save.aFilePath), "%s", params->dstFilePath);
216*4882a593Smuzhiyun         snprintf(save.aFileName, sizeof(save.aFileName), "%s", "cap_out.pcm");
217*4882a593Smuzhiyun         RK_MPI_AI_SaveFile(params->s32DevId, params->s32ChnIndex, &save);
218*4882a593Smuzhiyun     }
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun     while (!gAiExit) {
221*4882a593Smuzhiyun #if TEST_AI_WITH_FD
222*4882a593Smuzhiyun         test_ai_poll_event(-1, params->s32DevFd);
223*4882a593Smuzhiyun #endif
224*4882a593Smuzhiyun         result = RK_MPI_AI_GetFrame(params->s32DevId, params->s32ChnIndex, &frame, RK_NULL, s32MilliSec);
225*4882a593Smuzhiyun         if (result == 0) {
226*4882a593Smuzhiyun             void* data = RK_MPI_MB_Handle2VirAddr(frame.pMbBlk);
227*4882a593Smuzhiyun             // get the length of valid data in this frame
228*4882a593Smuzhiyun             RK_U64 len = RK_MPI_MB_GetLength(frame.pMbBlk);
229*4882a593Smuzhiyun             RK_LOGV("data = %p, len = %lld", data, len);
230*4882a593Smuzhiyun             RK_MPI_AI_ReleaseFrame(params->s32DevId, params->s32ChnIndex, &frame, RK_NULL);
231*4882a593Smuzhiyun         }
232*4882a593Smuzhiyun     }
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun     return RK_NULL;
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun 
unit_test_mpi_ai(TEST_AI_CTX_S * ctx)237*4882a593Smuzhiyun RK_S32 unit_test_mpi_ai(TEST_AI_CTX_S *ctx) {
238*4882a593Smuzhiyun     RK_S32 i = 0;
239*4882a593Smuzhiyun     TEST_AI_CTX_S params[AI_MAX_CHN_NUM];
240*4882a593Smuzhiyun     pthread_t tidSend[AI_MAX_CHN_NUM];
241*4882a593Smuzhiyun     pthread_t tidComand[AI_MAX_CHN_NUM];
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun     if (test_open_device_ai(ctx) != RK_SUCCESS) {
244*4882a593Smuzhiyun         goto __FAILED;
245*4882a593Smuzhiyun     }
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun     for (i = 0; i < ctx->s32ChnNum; i++) {
248*4882a593Smuzhiyun         memcpy(&(params[i]), ctx, sizeof(TEST_AI_CTX_S));
249*4882a593Smuzhiyun         params[i].s32ChnIndex = i;
250*4882a593Smuzhiyun         params[i].s32DevFd = -1;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun         test_init_mpi_ai(&params[i]);
253*4882a593Smuzhiyun         pthread_create(&tidSend[i], RK_NULL, sendDataThread, reinterpret_cast<void *>(&params[i]));
254*4882a593Smuzhiyun     }
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun     for (i = 0; i < ctx->s32ChnNum; i++) {
257*4882a593Smuzhiyun         pthread_join(tidSend[i], RK_NULL);
258*4882a593Smuzhiyun         pthread_join(tidComand[i], RK_NULL);
259*4882a593Smuzhiyun         test_deinit_mpi_ai(&params[i]);
260*4882a593Smuzhiyun     }
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun     return RK_SUCCESS;
263*4882a593Smuzhiyun __FAILED:
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun     return RK_FAILURE;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun 
mpi_ai_test_show_options(const TEST_AI_CTX_S * ctx)268*4882a593Smuzhiyun static void mpi_ai_test_show_options(const TEST_AI_CTX_S *ctx) {
269*4882a593Smuzhiyun     RK_PRINT("cmd parse result:\n");
270*4882a593Smuzhiyun     RK_PRINT("input  file name      : %s\n", ctx->srcFilePath);
271*4882a593Smuzhiyun     RK_PRINT("output file name      : %s\n", ctx->dstFilePath);
272*4882a593Smuzhiyun     RK_PRINT("loop count            : %d\n", ctx->s32LoopCount);
273*4882a593Smuzhiyun     RK_PRINT("channel number        : %d\n", ctx->s32ChnNum);
274*4882a593Smuzhiyun     RK_PRINT("open sound rate       : %d\n", ctx->s32DeviceSampleRate);
275*4882a593Smuzhiyun     RK_PRINT("record data rate      : %d\n", ctx->s32SampleRate);
276*4882a593Smuzhiyun     RK_PRINT("sound card channel    : %d\n", ctx->s32DeviceChannel);
277*4882a593Smuzhiyun     RK_PRINT("output channel        : %d\n", ctx->s32Channel);
278*4882a593Smuzhiyun     RK_PRINT("bit_width             : %d\n", ctx->s32BitWidth);
279*4882a593Smuzhiyun     RK_PRINT("period_count          : %d\n", ctx->s32PeriodCount);
280*4882a593Smuzhiyun     RK_PRINT("period_size           : %d\n", ctx->s32PeriodSize);
281*4882a593Smuzhiyun     RK_PRINT("sound card name       : %s\n", ctx->chCardName);
282*4882a593Smuzhiyun     RK_PRINT("device id             : %d\n", ctx->s32DevId);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun static const char *const usages[] = {
286*4882a593Smuzhiyun     "./rk_mpi_ai_test [--device_rate rate] [--device_ch ch] [--out_rate rate] [--out_ch ch]...",
287*4882a593Smuzhiyun     NULL,
288*4882a593Smuzhiyun };
289*4882a593Smuzhiyun 
main(int argc,const char ** argv)290*4882a593Smuzhiyun int main(int argc, const char **argv) {
291*4882a593Smuzhiyun     RK_S32          i;
292*4882a593Smuzhiyun     RK_S32          s32Ret;
293*4882a593Smuzhiyun     TEST_AI_CTX_S  *ctx;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun     ctx = reinterpret_cast<TEST_AI_CTX_S *>(malloc(sizeof(TEST_AI_CTX_S)));
296*4882a593Smuzhiyun     memset(ctx, 0, sizeof(TEST_AI_CTX_S));
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun     ctx->srcFilePath        = RK_NULL;
299*4882a593Smuzhiyun     ctx->dstFilePath        = RK_NULL;
300*4882a593Smuzhiyun     ctx->s32LoopCount       = 1;
301*4882a593Smuzhiyun     ctx->s32ChnNum          = 1;
302*4882a593Smuzhiyun     ctx->s32BitWidth        = 16;
303*4882a593Smuzhiyun     ctx->s32PeriodCount     = 4;
304*4882a593Smuzhiyun     ctx->s32PeriodSize      = 1024;
305*4882a593Smuzhiyun     ctx->chCardName         = RK_NULL;
306*4882a593Smuzhiyun     ctx->s32DevId           = 0;
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun     struct argparse_option options[] = {
309*4882a593Smuzhiyun         OPT_HELP(),
310*4882a593Smuzhiyun         OPT_GROUP("basic options:"),
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun         OPT_INTEGER('\0', "device_rate", &(ctx->s32DeviceSampleRate),
313*4882a593Smuzhiyun                     "the sample rate of open sound card.  <required>", NULL, 0, 0),
314*4882a593Smuzhiyun         OPT_INTEGER('\0', "device_ch", &(ctx->s32DeviceChannel),
315*4882a593Smuzhiyun                     "the number of sound card channels. <required>.", NULL, 0, 0),
316*4882a593Smuzhiyun         OPT_INTEGER('\0', "out_ch", &(ctx->s32Channel),
317*4882a593Smuzhiyun                     "the channels of out data. <required>", NULL, 0, 0),
318*4882a593Smuzhiyun         OPT_INTEGER('\0', "out_rate", &(ctx->s32SampleRate),
319*4882a593Smuzhiyun                     "the sample rate of out data. <required>", NULL, 0, 0),
320*4882a593Smuzhiyun         OPT_STRING('o', "output", &(ctx->dstFilePath),
321*4882a593Smuzhiyun                     "output file name, e.g.(./ai). default(NULL).", NULL, 0, 0),
322*4882a593Smuzhiyun         OPT_INTEGER('n', "loop_count", &(ctx->s32LoopCount),
323*4882a593Smuzhiyun                     "loop running count. can be any count. default(1)", NULL, 0, 0),
324*4882a593Smuzhiyun         OPT_INTEGER('c', "channel_count", &(ctx->s32ChnNum),
325*4882a593Smuzhiyun                     "the count of adec channel. default(1).", NULL, 0, 0),
326*4882a593Smuzhiyun         OPT_INTEGER('\0', "bit", &(ctx->s32BitWidth),
327*4882a593Smuzhiyun                     "the bit width of open sound card, range(8, 16, 24), default(16)", NULL, 0, 0),
328*4882a593Smuzhiyun         OPT_INTEGER('\0', "period_size", &(ctx->s32PeriodSize),
329*4882a593Smuzhiyun                     "the period size for open sound card, default(1024)", NULL, 0, 0),
330*4882a593Smuzhiyun         OPT_INTEGER('\0', "period_count", &(ctx->s32PeriodCount),
331*4882a593Smuzhiyun                     "the period count for open sound card, default(4)", NULL, 0, 0),
332*4882a593Smuzhiyun         OPT_STRING('\0', "sound_card_name", &(ctx->chCardName),
333*4882a593Smuzhiyun                     "the sound name for open sound card, default(NULL)", NULL, 0, 0),
334*4882a593Smuzhiyun         OPT_END(),
335*4882a593Smuzhiyun     };
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun     struct argparse argparse;
338*4882a593Smuzhiyun     argparse_init(&argparse, options, usages, 0);
339*4882a593Smuzhiyun     argparse_describe(&argparse, "\nselect a test case to run.",
340*4882a593Smuzhiyun                                  "\nuse --help for details.");
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun     argc = argparse_parse(&argparse, argc, argv);
343*4882a593Smuzhiyun     mpi_ai_test_show_options(ctx);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun     if (ctx->s32Channel <= 0
346*4882a593Smuzhiyun         || ctx->s32SampleRate <= 0
347*4882a593Smuzhiyun         || ctx->s32DeviceSampleRate <= 0
348*4882a593Smuzhiyun         || ctx->s32DeviceChannel <= 0) {
349*4882a593Smuzhiyun         argparse_usage(&argparse);
350*4882a593Smuzhiyun         goto __FAILED;
351*4882a593Smuzhiyun     }
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun     RK_MPI_SYS_Init();
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun     for (i = 0; i < ctx->s32LoopCount; i++) {
356*4882a593Smuzhiyun         RK_LOGI("start running loop count  = %d", i);
357*4882a593Smuzhiyun         s32Ret = unit_test_mpi_ai(ctx);
358*4882a593Smuzhiyun         if (s32Ret != RK_SUCCESS) {
359*4882a593Smuzhiyun             goto __FAILED;
360*4882a593Smuzhiyun         }
361*4882a593Smuzhiyun         RK_LOGI("end running loop count  = %d", i);
362*4882a593Smuzhiyun     }
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun __FAILED:
365*4882a593Smuzhiyun     if (ctx) {
366*4882a593Smuzhiyun         free(ctx);
367*4882a593Smuzhiyun         ctx = RK_NULL;
368*4882a593Smuzhiyun     }
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun     RK_MPI_SYS_Exit();
371*4882a593Smuzhiyun     return 0;
372*4882a593Smuzhiyun }
373