xref: /OK3568_Linux_fs/external/rockit/mpi/example/mod/test_mpi_ao.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 "rk_defines.h"
25*4882a593Smuzhiyun #include "rk_debug.h"
26*4882a593Smuzhiyun #include "rk_mpi_adec.h"
27*4882a593Smuzhiyun #include "rk_mpi_ao.h"
28*4882a593Smuzhiyun #include "rk_mpi_mb.h"
29*4882a593Smuzhiyun #include "rk_mpi_sys.h"
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #include "test_comm_argparse.h"
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define USE_AO_MIXER 0
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun typedef struct _rkMpiAOCtx {
36*4882a593Smuzhiyun     const char *srcFilePath;
37*4882a593Smuzhiyun     const char *dstFilePath;
38*4882a593Smuzhiyun     RK_S32      s32LoopCount;
39*4882a593Smuzhiyun     RK_S32      s32ChnNum;
40*4882a593Smuzhiyun     RK_S32      s32SampleRate;
41*4882a593Smuzhiyun     RK_S32      s32ReSmpSampleRate;
42*4882a593Smuzhiyun     RK_S32      s32Channel;
43*4882a593Smuzhiyun     RK_S32      s32DeviceChannel;
44*4882a593Smuzhiyun     RK_S32      s32BitWidth;
45*4882a593Smuzhiyun     RK_S32      s32DevId;
46*4882a593Smuzhiyun     RK_S32      s32PeriodCount;
47*4882a593Smuzhiyun     RK_S32      s32PeriodSize;
48*4882a593Smuzhiyun     char       *chCardName;
49*4882a593Smuzhiyun     RK_S32      s32ChnIndex;
50*4882a593Smuzhiyun     RK_S32      s32SetVolume;
51*4882a593Smuzhiyun     RK_S32      s32SetMute;
52*4882a593Smuzhiyun     RK_S32      s32SetFadeRate;
53*4882a593Smuzhiyun     RK_S32      s32SetTrackMode;
54*4882a593Smuzhiyun     RK_S32      s32GetVolume;
55*4882a593Smuzhiyun     RK_S32      s32GetMute;
56*4882a593Smuzhiyun     RK_S32      s32GetTrackMode;
57*4882a593Smuzhiyun     RK_S32      s32QueryChnStat;
58*4882a593Smuzhiyun     RK_S32      s32PauseResumeChn;
59*4882a593Smuzhiyun     RK_S32      s32SaveFile;
60*4882a593Smuzhiyun     RK_S32      s32QueryFileStat;
61*4882a593Smuzhiyun     RK_S32      s32ClrChnBuf;
62*4882a593Smuzhiyun     RK_S32      s32ClrPubAttr;
63*4882a593Smuzhiyun     RK_S32      s32GetPubAttr;
64*4882a593Smuzhiyun } TEST_AO_CTX_S;
65*4882a593Smuzhiyun 
query_ao_flow_graph_stat(AUDIO_DEV aoDevId,AO_CHN aoChn)66*4882a593Smuzhiyun void query_ao_flow_graph_stat(AUDIO_DEV aoDevId, AO_CHN aoChn) {
67*4882a593Smuzhiyun     RK_S32 ret = 0;
68*4882a593Smuzhiyun     AO_CHN_STATE_S pstStat;
69*4882a593Smuzhiyun     memset(&pstStat, 0, sizeof(AO_CHN_STATE_S));
70*4882a593Smuzhiyun     ret = RK_MPI_AO_QueryChnStat(aoDevId, aoChn, &pstStat);
71*4882a593Smuzhiyun     if (ret == RK_SUCCESS) {
72*4882a593Smuzhiyun         RK_LOGI("query ao flow status:");
73*4882a593Smuzhiyun         RK_LOGI("total number of channel buffer : %d", pstStat.u32ChnTotalNum);
74*4882a593Smuzhiyun         RK_LOGI("free number of channel buffer : %d", pstStat.u32ChnFreeNum);
75*4882a593Smuzhiyun         RK_LOGI("busy number of channel buffer : %d", pstStat.u32ChnBusyNum);
76*4882a593Smuzhiyun     }
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun 
find_sound_mode(RK_S32 ch)79*4882a593Smuzhiyun static AUDIO_SOUND_MODE_E find_sound_mode(RK_S32 ch) {
80*4882a593Smuzhiyun     AUDIO_SOUND_MODE_E channel = AUDIO_SOUND_MODE_BUTT;
81*4882a593Smuzhiyun     switch (ch) {
82*4882a593Smuzhiyun       case 1:
83*4882a593Smuzhiyun         channel = AUDIO_SOUND_MODE_MONO;
84*4882a593Smuzhiyun         break;
85*4882a593Smuzhiyun       case 2:
86*4882a593Smuzhiyun         channel = AUDIO_SOUND_MODE_STEREO;
87*4882a593Smuzhiyun         break;
88*4882a593Smuzhiyun       default:
89*4882a593Smuzhiyun         RK_LOGE("channel = %d not support", ch);
90*4882a593Smuzhiyun         return AUDIO_SOUND_MODE_BUTT;
91*4882a593Smuzhiyun     }
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun     return channel;
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun 
find_bit_width(RK_S32 bit)96*4882a593Smuzhiyun static AUDIO_BIT_WIDTH_E find_bit_width(RK_S32 bit) {
97*4882a593Smuzhiyun     AUDIO_BIT_WIDTH_E bitWidth = AUDIO_BIT_WIDTH_BUTT;
98*4882a593Smuzhiyun     switch (bit) {
99*4882a593Smuzhiyun       case 8:
100*4882a593Smuzhiyun         bitWidth = AUDIO_BIT_WIDTH_8;
101*4882a593Smuzhiyun         break;
102*4882a593Smuzhiyun       case 16:
103*4882a593Smuzhiyun         bitWidth = AUDIO_BIT_WIDTH_16;
104*4882a593Smuzhiyun         break;
105*4882a593Smuzhiyun       case 24:
106*4882a593Smuzhiyun         bitWidth = AUDIO_BIT_WIDTH_24;
107*4882a593Smuzhiyun         break;
108*4882a593Smuzhiyun       default:
109*4882a593Smuzhiyun         RK_LOGE("bitwidth(%d) not support", bit);
110*4882a593Smuzhiyun         return AUDIO_BIT_WIDTH_BUTT;
111*4882a593Smuzhiyun     }
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun     return bitWidth;
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun 
test_open_device_ao(TEST_AO_CTX_S * ctx)116*4882a593Smuzhiyun RK_S32 test_open_device_ao(TEST_AO_CTX_S *ctx) {
117*4882a593Smuzhiyun     AUDIO_DEV aoDevId = ctx->s32DevId;
118*4882a593Smuzhiyun     AUDIO_SOUND_MODE_E soundMode;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun     AIO_ATTR_S aoAttr;
121*4882a593Smuzhiyun     memset(&aoAttr, 0, sizeof(AIO_ATTR_S));
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun     if (ctx->chCardName) {
124*4882a593Smuzhiyun         snprintf(reinterpret_cast<char *>(aoAttr.u8CardName),
125*4882a593Smuzhiyun                  sizeof(aoAttr.u8CardName), "%s", ctx->chCardName);
126*4882a593Smuzhiyun     }
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun     aoAttr.soundCard.channels = ctx->s32DeviceChannel;
129*4882a593Smuzhiyun     aoAttr.soundCard.sampleRate = ctx->s32SampleRate;
130*4882a593Smuzhiyun     aoAttr.soundCard.bitWidth = AUDIO_BIT_WIDTH_16;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun     AUDIO_BIT_WIDTH_E bitWidth = find_bit_width(ctx->s32BitWidth);
133*4882a593Smuzhiyun     if (bitWidth == AUDIO_BIT_WIDTH_BUTT) {
134*4882a593Smuzhiyun         goto __FAILED;
135*4882a593Smuzhiyun     }
136*4882a593Smuzhiyun     aoAttr.enBitwidth = bitWidth;
137*4882a593Smuzhiyun     aoAttr.enSamplerate = (AUDIO_SAMPLE_RATE_E)ctx->s32ReSmpSampleRate;
138*4882a593Smuzhiyun     soundMode = find_sound_mode(ctx->s32Channel);
139*4882a593Smuzhiyun     if (soundMode == AUDIO_SOUND_MODE_BUTT) {
140*4882a593Smuzhiyun         goto __FAILED;
141*4882a593Smuzhiyun     }
142*4882a593Smuzhiyun     aoAttr.enSoundmode = soundMode;
143*4882a593Smuzhiyun     aoAttr.u32FrmNum = ctx->s32PeriodCount;
144*4882a593Smuzhiyun     aoAttr.u32PtNumPerFrm = ctx->s32PeriodSize;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun     aoAttr.u32EXFlag = 0;
147*4882a593Smuzhiyun     aoAttr.u32ChnCnt = 2;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun     RK_MPI_AO_SetPubAttr(aoDevId, &aoAttr);
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun     RK_MPI_AO_Enable(aoDevId);
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun     return RK_SUCCESS;
154*4882a593Smuzhiyun __FAILED:
155*4882a593Smuzhiyun     return RK_FAILURE;
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun 
test_init_mpi_ao(TEST_AO_CTX_S * params)158*4882a593Smuzhiyun RK_S32 test_init_mpi_ao(TEST_AO_CTX_S *params) {
159*4882a593Smuzhiyun     RK_S32 result;
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun     result =  RK_MPI_AO_EnableChn(params->s32DevId, params->s32ChnIndex);
162*4882a593Smuzhiyun     if (result != 0) {
163*4882a593Smuzhiyun         RK_LOGE("ao enable channel fail, aoChn = %d, reason = %x", params->s32ChnIndex, result);
164*4882a593Smuzhiyun         return RK_FAILURE;
165*4882a593Smuzhiyun     }
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun     // set sample rate of input data
168*4882a593Smuzhiyun     result = RK_MPI_AO_EnableReSmp(params->s32DevId, params->s32ChnIndex,
169*4882a593Smuzhiyun                                   (AUDIO_SAMPLE_RATE_E)params->s32ReSmpSampleRate);
170*4882a593Smuzhiyun     if (result != 0) {
171*4882a593Smuzhiyun         RK_LOGE("ao enable channel fail, reason = %x, aoChn = %d", result, params->s32ChnIndex);
172*4882a593Smuzhiyun         return RK_FAILURE;
173*4882a593Smuzhiyun     }
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun     return RK_SUCCESS;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun 
deinit_mpi_ao(AUDIO_DEV aoDevId,AO_CHN aoChn)178*4882a593Smuzhiyun RK_S32 deinit_mpi_ao(AUDIO_DEV aoDevId, AO_CHN aoChn) {
179*4882a593Smuzhiyun     RK_S32 result = RK_MPI_AO_DisableReSmp(aoDevId, aoChn);
180*4882a593Smuzhiyun     if (result != 0) {
181*4882a593Smuzhiyun         RK_LOGE("ao disable resample fail, reason = %d", result);
182*4882a593Smuzhiyun         return RK_FAILURE;
183*4882a593Smuzhiyun     }
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun     result = RK_MPI_AO_DisableChn(aoDevId, aoChn);
186*4882a593Smuzhiyun     if (result != 0) {
187*4882a593Smuzhiyun         RK_LOGE("ao disable channel fail, reason = %d", result);
188*4882a593Smuzhiyun         return RK_FAILURE;
189*4882a593Smuzhiyun     }
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun     return RK_SUCCESS;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun 
test_close_device_ao(TEST_AO_CTX_S * ctx)194*4882a593Smuzhiyun RK_S32 test_close_device_ao(TEST_AO_CTX_S *ctx) {
195*4882a593Smuzhiyun     AUDIO_DEV aoDevId = ctx->s32DevId;
196*4882a593Smuzhiyun     RK_S32 result =  RK_MPI_AO_Disable(aoDevId);
197*4882a593Smuzhiyun     if (result != 0) {
198*4882a593Smuzhiyun         RK_LOGE("ao disable fail, reason = %d", result);
199*4882a593Smuzhiyun         return RK_FAILURE;
200*4882a593Smuzhiyun     }
201*4882a593Smuzhiyun     return RK_SUCCESS;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun 
test_set_ao_channel_mode(AUDIO_DEV aoDevId,AO_CHN aoChn)204*4882a593Smuzhiyun RK_S32 test_set_ao_channel_mode(AUDIO_DEV aoDevId, AO_CHN aoChn) {
205*4882a593Smuzhiyun     RK_S32 result = 0;
206*4882a593Smuzhiyun     AO_CHN_PARAM_S pstParams;
207*4882a593Smuzhiyun     memset(&pstParams, 0, sizeof(AO_CHN_PARAM_S));
208*4882a593Smuzhiyun     // for test : aoChn0 output left channel,  aoChn1 output right channel,
209*4882a593Smuzhiyun     if (aoChn == 0) {
210*4882a593Smuzhiyun         pstParams.enMode = AUDIO_CHN_MODE_LEFT;
211*4882a593Smuzhiyun     } else if (aoChn == 1) {
212*4882a593Smuzhiyun         pstParams.enMode = AUDIO_CHN_MODE_RIGHT;
213*4882a593Smuzhiyun     }
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun     result = RK_MPI_AO_SetChnParams(aoDevId, aoChn, &pstParams);
216*4882a593Smuzhiyun     if (result != RK_SUCCESS) {
217*4882a593Smuzhiyun         RK_LOGE("ao set channel params, aoChn = %d", aoChn);
218*4882a593Smuzhiyun         return RK_FAILURE;
219*4882a593Smuzhiyun     }
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun     return RK_SUCCESS;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun 
sendDataThread(void * ptr)224*4882a593Smuzhiyun void* sendDataThread(void * ptr) {
225*4882a593Smuzhiyun     TEST_AO_CTX_S *params = reinterpret_cast<TEST_AO_CTX_S *>(ptr);
226*4882a593Smuzhiyun     MB_POOL_CONFIG_S pool_config;
227*4882a593Smuzhiyun     // set default value for struct
228*4882a593Smuzhiyun     RK_U8 *srcData = RK_NULL;
229*4882a593Smuzhiyun     AUDIO_FRAME_S frame;
230*4882a593Smuzhiyun     RK_U64 timeStamp = 0;
231*4882a593Smuzhiyun     RK_S32 s32MilliSec = -1;
232*4882a593Smuzhiyun     RK_S32 size = 0;
233*4882a593Smuzhiyun     RK_S32 result = 0;
234*4882a593Smuzhiyun     FILE *file = RK_NULL;
235*4882a593Smuzhiyun     RK_LOGI("params->s32ChnIndex : %d", params->s32ChnIndex);
236*4882a593Smuzhiyun     if (USE_AO_MIXER) {
237*4882a593Smuzhiyun         if (params->s32ChnIndex == 0) {
238*4882a593Smuzhiyun             file = fopen("8000_1_ao0.pcm", "rb");
239*4882a593Smuzhiyun         } else if (params->s32ChnIndex == 1) {
240*4882a593Smuzhiyun             file = fopen("8000_1_ao1.pcm", "rb");
241*4882a593Smuzhiyun         }
242*4882a593Smuzhiyun     } else {
243*4882a593Smuzhiyun         file = fopen(params->srcFilePath, "rb");
244*4882a593Smuzhiyun     }
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun     if (file == RK_NULL) {
247*4882a593Smuzhiyun         RK_LOGE("open save file %s failed because %s.", params->srcFilePath, strerror(errno));
248*4882a593Smuzhiyun         goto __EXIT;
249*4882a593Smuzhiyun     }
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun     srcData = reinterpret_cast<RK_U8 *>(calloc(1024, sizeof(RK_U8)));
252*4882a593Smuzhiyun     memset(srcData, 0, 1024);
253*4882a593Smuzhiyun     while (1) {
254*4882a593Smuzhiyun         size = fread(srcData, 1, 1024, file);
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun         frame.u32Len = size;
257*4882a593Smuzhiyun         frame.u64TimeStamp = timeStamp++;
258*4882a593Smuzhiyun         frame.enBitWidth = find_bit_width(params->s32BitWidth);
259*4882a593Smuzhiyun         frame.enSoundMode = find_sound_mode(params->s32Channel);
260*4882a593Smuzhiyun         frame.bBypassMbBlk = RK_FALSE;
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun         MB_EXT_CONFIG_S extConfig;
263*4882a593Smuzhiyun         memset(&extConfig, 0, sizeof(extConfig));
264*4882a593Smuzhiyun         extConfig.pOpaque = srcData;
265*4882a593Smuzhiyun         extConfig.pu8VirAddr = srcData;
266*4882a593Smuzhiyun         extConfig.u64Size = size;
267*4882a593Smuzhiyun         RK_MPI_SYS_CreateMB(&(frame.pMbBlk), &extConfig);
268*4882a593Smuzhiyun __RETRY:
269*4882a593Smuzhiyun         result = RK_MPI_AO_SendFrame(params->s32DevId, params->s32ChnIndex, &frame, s32MilliSec);
270*4882a593Smuzhiyun         if (result < 0) {
271*4882a593Smuzhiyun             RK_LOGE("send frame fail, result = %d, TimeStamp = %lld, s32MilliSec = %d",
272*4882a593Smuzhiyun                 result, frame.u64TimeStamp, s32MilliSec);
273*4882a593Smuzhiyun             goto __RETRY;
274*4882a593Smuzhiyun         }
275*4882a593Smuzhiyun         RK_MPI_MB_ReleaseMB(frame.pMbBlk);
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun         if (size <= 0) {
278*4882a593Smuzhiyun             RK_LOGI("eof");
279*4882a593Smuzhiyun             break;
280*4882a593Smuzhiyun         }
281*4882a593Smuzhiyun     }
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun __EXIT:
284*4882a593Smuzhiyun     RK_MPI_AO_WaitEos(params->s32DevId, params->s32ChnIndex, s32MilliSec);
285*4882a593Smuzhiyun     if (file) {
286*4882a593Smuzhiyun         fclose(file);
287*4882a593Smuzhiyun         file = RK_NULL;
288*4882a593Smuzhiyun     }
289*4882a593Smuzhiyun     free(srcData);
290*4882a593Smuzhiyun     return RK_NULL;
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun 
commandThread(void * ptr)293*4882a593Smuzhiyun void* commandThread(void * ptr) {
294*4882a593Smuzhiyun     TEST_AO_CTX_S *params = reinterpret_cast<TEST_AO_CTX_S *>(ptr);
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun     {
297*4882a593Smuzhiyun         AUDIO_FADE_S aFade;
298*4882a593Smuzhiyun         aFade.bFade = RK_FALSE;
299*4882a593Smuzhiyun         aFade.enFadeOutRate = (AUDIO_FADE_RATE_E)params->s32SetFadeRate;
300*4882a593Smuzhiyun         aFade.enFadeInRate = (AUDIO_FADE_RATE_E)params->s32SetFadeRate;
301*4882a593Smuzhiyun         RK_BOOL mute = (params->s32SetMute == 0) ? RK_FALSE : RK_TRUE;
302*4882a593Smuzhiyun         RK_LOGI("test info : mute = %d, volume = %d", mute, params->s32SetVolume);
303*4882a593Smuzhiyun         RK_MPI_AO_SetMute(params->s32DevId, mute, &aFade);
304*4882a593Smuzhiyun         RK_MPI_AO_SetVolume(params->s32DevId, params->s32SetVolume);
305*4882a593Smuzhiyun     }
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun     if (params->s32SetTrackMode) {
308*4882a593Smuzhiyun         RK_LOGI("test info : set track mode = %d", params->s32SetTrackMode);
309*4882a593Smuzhiyun         RK_MPI_AO_SetTrackMode(params->s32DevId, (AUDIO_TRACK_MODE_E)params->s32SetTrackMode);
310*4882a593Smuzhiyun         params->s32SetTrackMode = 0;
311*4882a593Smuzhiyun     }
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun     if (params->s32GetVolume) {
314*4882a593Smuzhiyun         RK_S32 volume = 0;
315*4882a593Smuzhiyun         RK_MPI_AO_GetVolume(params->s32DevId, &volume);
316*4882a593Smuzhiyun         RK_LOGI("test info : get volume = %d", volume);
317*4882a593Smuzhiyun         params->s32GetVolume = 0;
318*4882a593Smuzhiyun     }
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun     if (params->s32GetMute) {
321*4882a593Smuzhiyun         RK_BOOL mute = RK_FALSE;
322*4882a593Smuzhiyun         AUDIO_FADE_S fade;
323*4882a593Smuzhiyun         RK_MPI_AO_GetMute(params->s32DevId, &mute, &fade);
324*4882a593Smuzhiyun         RK_LOGI("test info : is mute = %d", mute);
325*4882a593Smuzhiyun         params->s32GetMute = 0;
326*4882a593Smuzhiyun     }
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun     if (params->s32GetTrackMode) {
329*4882a593Smuzhiyun         AUDIO_TRACK_MODE_E trackMode;
330*4882a593Smuzhiyun         RK_MPI_AO_GetTrackMode(params->s32DevId, &trackMode);
331*4882a593Smuzhiyun         RK_LOGI("test info : get track mode = %d", trackMode);
332*4882a593Smuzhiyun         params->s32GetTrackMode = 0;
333*4882a593Smuzhiyun     }
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun     if (params->s32QueryChnStat) {
336*4882a593Smuzhiyun         query_ao_flow_graph_stat(params->s32DevId, params->s32ChnIndex);
337*4882a593Smuzhiyun         params->s32QueryChnStat = 0;
338*4882a593Smuzhiyun     }
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun     if (params->s32SaveFile) {
341*4882a593Smuzhiyun         AUDIO_SAVE_FILE_INFO_S saveFile;
342*4882a593Smuzhiyun         memset(&saveFile, 0, sizeof(AUDIO_SAVE_FILE_INFO_S));
343*4882a593Smuzhiyun         if (params->dstFilePath) {
344*4882a593Smuzhiyun             saveFile.bCfg = RK_TRUE;
345*4882a593Smuzhiyun             saveFile.u32FileSize = 1024 * 1024;
346*4882a593Smuzhiyun             snprintf(saveFile.aFileName, sizeof(saveFile.aFileName), "%s", "ao_save_file.bin");
347*4882a593Smuzhiyun             snprintf(saveFile.aFilePath, sizeof(saveFile.aFilePath), "%s", params->dstFilePath);
348*4882a593Smuzhiyun         }
349*4882a593Smuzhiyun         RK_MPI_AO_SaveFile(params->s32DevId, params->s32ChnIndex, &saveFile);
350*4882a593Smuzhiyun         params->s32SaveFile = 0;
351*4882a593Smuzhiyun     }
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun     if (params->s32QueryFileStat) {
354*4882a593Smuzhiyun         AUDIO_FILE_STATUS_S fileStat;
355*4882a593Smuzhiyun         RK_MPI_AO_QueryFileStatus(params->s32DevId, params->s32ChnIndex, &fileStat);
356*4882a593Smuzhiyun         RK_LOGI("test info : query save file status = %d", fileStat.bSaving);
357*4882a593Smuzhiyun         params->s32QueryFileStat = 0;
358*4882a593Smuzhiyun     }
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun     if (params->s32PauseResumeChn) {
361*4882a593Smuzhiyun         usleep(500 * 1000);
362*4882a593Smuzhiyun         RK_MPI_AO_PauseChn(params->s32DevId, params->s32ChnIndex);
363*4882a593Smuzhiyun         RK_LOGI("pause test");
364*4882a593Smuzhiyun         usleep(1000 * 1000);
365*4882a593Smuzhiyun         RK_MPI_AO_ResumeChn(params->s32DevId, params->s32ChnIndex);
366*4882a593Smuzhiyun         RK_LOGI("resume test");
367*4882a593Smuzhiyun         params->s32PauseResumeChn = 0;
368*4882a593Smuzhiyun     }
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun     if (params->s32ClrChnBuf) {
371*4882a593Smuzhiyun         RK_MPI_AO_ClearChnBuf(params->s32DevId, params->s32ChnIndex);
372*4882a593Smuzhiyun         params->s32ClrChnBuf = 0;
373*4882a593Smuzhiyun     }
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun     if (params->s32ClrPubAttr) {
376*4882a593Smuzhiyun         RK_MPI_AO_ClrPubAttr(params->s32DevId);
377*4882a593Smuzhiyun         params->s32ClrPubAttr = 0;
378*4882a593Smuzhiyun     }
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun     if (params->s32GetPubAttr) {
381*4882a593Smuzhiyun         AIO_ATTR_S pstAttr;
382*4882a593Smuzhiyun         RK_MPI_AO_GetPubAttr(params->s32DevId, &pstAttr);
383*4882a593Smuzhiyun         RK_LOGI("input stream rate = %d", pstAttr.enSamplerate);
384*4882a593Smuzhiyun         RK_LOGI("input stream sound mode = %d", pstAttr.enSoundmode);
385*4882a593Smuzhiyun         RK_LOGI("open sound card rate = %d", pstAttr.soundCard.sampleRate);
386*4882a593Smuzhiyun         RK_LOGI("open sound card channel = %d", pstAttr.soundCard.channels);
387*4882a593Smuzhiyun         params->s32GetPubAttr = 0;
388*4882a593Smuzhiyun     }
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun     return RK_NULL;
391*4882a593Smuzhiyun }
392*4882a593Smuzhiyun 
unit_test_mpi_ao(TEST_AO_CTX_S * ctx)393*4882a593Smuzhiyun RK_S32 unit_test_mpi_ao(TEST_AO_CTX_S *ctx) {
394*4882a593Smuzhiyun     RK_S32 i = 0;
395*4882a593Smuzhiyun     TEST_AO_CTX_S params[AO_MAX_CHN_NUM];
396*4882a593Smuzhiyun     pthread_t tidSend[AO_MAX_CHN_NUM];
397*4882a593Smuzhiyun     pthread_t tidReceive[AO_MAX_CHN_NUM];
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun     if (ctx->s32ChnNum > AO_MAX_CHN_NUM) {
400*4882a593Smuzhiyun         RK_LOGE("ao chn(%d) > max_chn(%d)", ctx->s32ChnNum, AO_MAX_CHN_NUM);
401*4882a593Smuzhiyun         goto __FAILED;
402*4882a593Smuzhiyun     }
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun     if (test_open_device_ao(ctx) != RK_SUCCESS) {
405*4882a593Smuzhiyun         goto __FAILED;
406*4882a593Smuzhiyun     }
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun     for (i = 0; i < ctx->s32ChnNum; i++) {
409*4882a593Smuzhiyun         memcpy(&(params[i]), ctx, sizeof(TEST_AO_CTX_S));
410*4882a593Smuzhiyun         params[i].s32ChnIndex = i;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun         if (USE_AO_MIXER) {
413*4882a593Smuzhiyun             test_set_ao_channel_mode(params[i].s32DevId, params[i].s32ChnIndex);
414*4882a593Smuzhiyun         }
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun         test_init_mpi_ao(&params[i]);
417*4882a593Smuzhiyun         pthread_create(&tidSend[i], RK_NULL, sendDataThread, reinterpret_cast<void *>(&params[i]));
418*4882a593Smuzhiyun         pthread_create(&tidReceive[i], RK_NULL, commandThread, reinterpret_cast<void *>(&params[i]));
419*4882a593Smuzhiyun     }
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun     for (i = 0; i < ctx->s32ChnNum; i++) {
422*4882a593Smuzhiyun         pthread_join(tidSend[i], RK_NULL);
423*4882a593Smuzhiyun         pthread_join(tidReceive[i], RK_NULL);
424*4882a593Smuzhiyun         deinit_mpi_ao(params[i].s32DevId, params[i].s32ChnIndex);
425*4882a593Smuzhiyun     }
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun     test_close_device_ao(ctx);
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun     return RK_SUCCESS;
430*4882a593Smuzhiyun __FAILED:
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun     return RK_FAILURE;
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun static const char *const usages[] = {
436*4882a593Smuzhiyun     "./rk_mpi_ao_test [-i src_path] [--device_rate rate] [--device_ch ch] [--input_rate rate] [--input_ch ch]...",
437*4882a593Smuzhiyun     NULL,
438*4882a593Smuzhiyun };
439*4882a593Smuzhiyun 
mpi_ao_test_show_options(const TEST_AO_CTX_S * ctx)440*4882a593Smuzhiyun static void mpi_ao_test_show_options(const TEST_AO_CTX_S *ctx) {
441*4882a593Smuzhiyun     RK_PRINT("cmd parse result:\n");
442*4882a593Smuzhiyun     RK_PRINT("input  file name      : %s\n", ctx->srcFilePath);
443*4882a593Smuzhiyun     RK_PRINT("output file name      : %s\n", ctx->dstFilePath);
444*4882a593Smuzhiyun     RK_PRINT("loop count            : %d\n", ctx->s32LoopCount);
445*4882a593Smuzhiyun     RK_PRINT("channel number        : %d\n", ctx->s32ChnNum);
446*4882a593Smuzhiyun     RK_PRINT("open sound rate       : %d\n", ctx->s32SampleRate);
447*4882a593Smuzhiyun     RK_PRINT("open sound channel    : %d\n", ctx->s32DeviceChannel);
448*4882a593Smuzhiyun     RK_PRINT("input stream rate     : %d\n", ctx->s32ReSmpSampleRate);
449*4882a593Smuzhiyun     RK_PRINT("input channel         : %d\n", ctx->s32Channel);
450*4882a593Smuzhiyun     RK_PRINT("bit_width             : %d\n", ctx->s32BitWidth);
451*4882a593Smuzhiyun     RK_PRINT("period_count          : %d\n", ctx->s32PeriodCount);
452*4882a593Smuzhiyun     RK_PRINT("period_size           : %d\n", ctx->s32PeriodSize);
453*4882a593Smuzhiyun     RK_PRINT("sound card name       : %s\n", ctx->chCardName);
454*4882a593Smuzhiyun     RK_PRINT("device id             : %d\n", ctx->s32DevId);
455*4882a593Smuzhiyun     RK_PRINT("set volume            : %d\n", ctx->s32SetVolume);
456*4882a593Smuzhiyun     RK_PRINT("set mute              : %d\n", ctx->s32SetMute);
457*4882a593Smuzhiyun     RK_PRINT("set track_mode        : %d\n", ctx->s32SetTrackMode);
458*4882a593Smuzhiyun     RK_PRINT("get volume            : %d\n", ctx->s32GetVolume);
459*4882a593Smuzhiyun     RK_PRINT("get mute              : %d\n", ctx->s32GetMute);
460*4882a593Smuzhiyun     RK_PRINT("get track_mode        : %d\n", ctx->s32GetTrackMode);
461*4882a593Smuzhiyun     RK_PRINT("query stat            : %d\n", ctx->s32QueryChnStat);
462*4882a593Smuzhiyun     RK_PRINT("pause and resume chn  : %d\n", ctx->s32PauseResumeChn);
463*4882a593Smuzhiyun     RK_PRINT("save file             : %d\n", ctx->s32SaveFile);
464*4882a593Smuzhiyun     RK_PRINT("query save file stat  : %d\n", ctx->s32QueryFileStat);
465*4882a593Smuzhiyun     RK_PRINT("clear buf             : %d\n", ctx->s32ClrChnBuf);
466*4882a593Smuzhiyun     RK_PRINT("get attribute         : %d\n", ctx->s32GetPubAttr);
467*4882a593Smuzhiyun     RK_PRINT("clear attribute       : %d\n", ctx->s32ClrPubAttr);
468*4882a593Smuzhiyun }
469*4882a593Smuzhiyun 
main(int argc,const char ** argv)470*4882a593Smuzhiyun int main(int argc, const char **argv) {
471*4882a593Smuzhiyun     RK_S32          i;
472*4882a593Smuzhiyun     RK_S32          s32Ret;
473*4882a593Smuzhiyun     TEST_AO_CTX_S  *ctx;
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun     ctx = reinterpret_cast<TEST_AO_CTX_S *>(malloc(sizeof(TEST_AO_CTX_S)));
476*4882a593Smuzhiyun     memset(ctx, 0, sizeof(TEST_AO_CTX_S));
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun     ctx->srcFilePath        = RK_NULL;
479*4882a593Smuzhiyun     ctx->dstFilePath        = RK_NULL;
480*4882a593Smuzhiyun     ctx->s32LoopCount       = 1;
481*4882a593Smuzhiyun     ctx->s32ChnNum          = 1;
482*4882a593Smuzhiyun     ctx->s32SampleRate      = 48000;
483*4882a593Smuzhiyun     ctx->s32ReSmpSampleRate = 0;
484*4882a593Smuzhiyun     ctx->s32DeviceChannel   = 2;
485*4882a593Smuzhiyun     ctx->s32Channel         = 0;
486*4882a593Smuzhiyun     ctx->s32BitWidth        = 16;
487*4882a593Smuzhiyun     ctx->s32PeriodCount     = 4;
488*4882a593Smuzhiyun     ctx->s32PeriodSize      = 1024;
489*4882a593Smuzhiyun     ctx->chCardName         = RK_NULL;
490*4882a593Smuzhiyun     ctx->s32DevId           = 0;
491*4882a593Smuzhiyun     ctx->s32SetVolume       = 100;
492*4882a593Smuzhiyun     ctx->s32SetMute         = 0;
493*4882a593Smuzhiyun     ctx->s32SetTrackMode    = 0;
494*4882a593Smuzhiyun     ctx->s32SetFadeRate     = 0;
495*4882a593Smuzhiyun     ctx->s32GetVolume       = 0;
496*4882a593Smuzhiyun     ctx->s32GetMute         = 0;
497*4882a593Smuzhiyun     ctx->s32GetTrackMode    = 0;
498*4882a593Smuzhiyun     ctx->s32QueryChnStat    = 0;
499*4882a593Smuzhiyun     ctx->s32PauseResumeChn  = 0;
500*4882a593Smuzhiyun     ctx->s32SaveFile        = 0;
501*4882a593Smuzhiyun     ctx->s32QueryFileStat   = 0;
502*4882a593Smuzhiyun     ctx->s32ClrChnBuf       = 0;
503*4882a593Smuzhiyun     ctx->s32ClrPubAttr      = 0;
504*4882a593Smuzhiyun     ctx->s32GetPubAttr      = 0;
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun     struct argparse_option options[] = {
507*4882a593Smuzhiyun         OPT_HELP(),
508*4882a593Smuzhiyun         OPT_GROUP("basic options:"),
509*4882a593Smuzhiyun         OPT_STRING('i', "input",  &(ctx->srcFilePath),
510*4882a593Smuzhiyun                    "input file name , e.g.(./*.pcm). <required>", NULL, 0, 0),
511*4882a593Smuzhiyun         OPT_INTEGER('\0', "input_ch", &(ctx->s32Channel),
512*4882a593Smuzhiyun                     "the sample rate of input data. <required>", NULL, 0, 0),
513*4882a593Smuzhiyun         OPT_INTEGER('\0', "input_rate", &(ctx->s32ReSmpSampleRate),
514*4882a593Smuzhiyun                     "the sample rate of input data. <required>", NULL, 0, 0),
515*4882a593Smuzhiyun         OPT_INTEGER('\0', "device_ch", &(ctx->s32DeviceChannel),
516*4882a593Smuzhiyun                     "the number of sound card channels. default(2).", NULL, 0, 0),
517*4882a593Smuzhiyun         OPT_INTEGER('\0', "device_rate", &(ctx->s32SampleRate),
518*4882a593Smuzhiyun                     "the sample rate of open sound card.  default(48000).", NULL, 0, 0),
519*4882a593Smuzhiyun         OPT_STRING('o', "output", &(ctx->dstFilePath),
520*4882a593Smuzhiyun                     "output file name, e.g.(./ao). default(NULL).", NULL, 0, 0),
521*4882a593Smuzhiyun         OPT_INTEGER('n', "loop_count", &(ctx->s32LoopCount),
522*4882a593Smuzhiyun                     "loop running count. can be any count. default(1)", NULL, 0, 0),
523*4882a593Smuzhiyun         OPT_INTEGER('c', "channel_count", &(ctx->s32ChnNum),
524*4882a593Smuzhiyun                     "the count of ao channel. default(1).", NULL, 0, 0),
525*4882a593Smuzhiyun         OPT_INTEGER('\0', "bit", &(ctx->s32BitWidth),
526*4882a593Smuzhiyun                     "the bit width of open sound card, range(8, 16, 24), default(16)", NULL, 0, 0),
527*4882a593Smuzhiyun         OPT_INTEGER('\0', "period_size", &(ctx->s32PeriodSize),
528*4882a593Smuzhiyun                     "the period size for open sound card, default(1024)", NULL, 0, 0),
529*4882a593Smuzhiyun         OPT_INTEGER('\0', "period_count", &(ctx->s32PeriodCount),
530*4882a593Smuzhiyun                     "the period count for open sound card, default(4)", NULL, 0, 0),
531*4882a593Smuzhiyun         OPT_STRING('\0', "sound_card_name", &(ctx->chCardName),
532*4882a593Smuzhiyun                     "the sound name for open sound card, default(NULL)", NULL, 0, 0),
533*4882a593Smuzhiyun         OPT_INTEGER('\0', "set_volume", &(ctx->s32SetVolume),
534*4882a593Smuzhiyun                     "set volume test, range(0, 100), default(100)", NULL, 0, 0),
535*4882a593Smuzhiyun         OPT_INTEGER('\0', "set_mute", &(ctx->s32SetMute),
536*4882a593Smuzhiyun                     "set mute test, range(0, 1), default(0)", NULL, 0, 0),
537*4882a593Smuzhiyun         OPT_INTEGER('\0', "set_fade", &(ctx->s32SetFadeRate),
538*4882a593Smuzhiyun                     "set fade rate, range(0, 7), default(0)", NULL, 0, 0),
539*4882a593Smuzhiyun         OPT_INTEGER('\0', "set_track_mode", &(ctx->s32SetTrackMode),
540*4882a593Smuzhiyun                     "set track mode test, range(0:normal, 1:both_left, 2:both_right, 3:exchange, 4:mix,"
541*4882a593Smuzhiyun                     "5:left_mute, 6:right_mute, 7:both_mute), default(0)", NULL, 0, 0),
542*4882a593Smuzhiyun         OPT_INTEGER('\0', "get_volume", &(ctx->s32GetVolume),
543*4882a593Smuzhiyun                     "get volume test, range(0, 1), default(0)", NULL, 0, 0),
544*4882a593Smuzhiyun         OPT_INTEGER('\0', "get_mute", &(ctx->s32GetMute),
545*4882a593Smuzhiyun                     "get mute test, range(0, 1), default(0)", NULL, 0, 0),
546*4882a593Smuzhiyun         OPT_INTEGER('\0', "get_track_mode", &(ctx->s32GetTrackMode),
547*4882a593Smuzhiyun                     "get track mode test, range(0, 1), default(0)", NULL, 0, 0),
548*4882a593Smuzhiyun         OPT_INTEGER('\0', "query_stat", &(ctx->s32QueryChnStat),
549*4882a593Smuzhiyun                     "query ao statistics info, range(0, 1), default(0)", NULL, 0, 0),
550*4882a593Smuzhiyun         OPT_INTEGER('\0', "pause_resume", &(ctx->s32PauseResumeChn),
551*4882a593Smuzhiyun                     "test ao chn pause and resume function, range(0, 1), default(0)", NULL, 0, 0),
552*4882a593Smuzhiyun         OPT_INTEGER('\0', "save_file", &(ctx->s32SaveFile),
553*4882a593Smuzhiyun                     "test ao save file, if enabled, must set output file, range(0, 1), default(0)", NULL, 0, 0),
554*4882a593Smuzhiyun         OPT_INTEGER('\0', "query_file_stat", &(ctx->s32QueryFileStat),
555*4882a593Smuzhiyun                     "query file status, range(0, 1), default(0)", NULL, 0, 0),
556*4882a593Smuzhiyun         OPT_INTEGER('\0', "clr_buf", &(ctx->s32ClrChnBuf),
557*4882a593Smuzhiyun                     "clear buffer of channel, range(0, 1), default(0)", NULL, 0, 0),
558*4882a593Smuzhiyun         OPT_INTEGER('\0', "clr_attr", &(ctx->s32ClrPubAttr),
559*4882a593Smuzhiyun                     "clear attribute of channel, range(0, 1), default(0)", NULL, 0, 0),
560*4882a593Smuzhiyun         OPT_INTEGER('\0', "get_attr", &(ctx->s32GetPubAttr),
561*4882a593Smuzhiyun                     "get attribute of device, range(0, 1), default(0)", NULL, 0, 0),
562*4882a593Smuzhiyun         OPT_END(),
563*4882a593Smuzhiyun     };
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun     struct argparse argparse;
566*4882a593Smuzhiyun     argparse_init(&argparse, options, usages, 0);
567*4882a593Smuzhiyun     argparse_describe(&argparse, "\nselect a test case to run.",
568*4882a593Smuzhiyun                                  "\nuse --help for details.");
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun     argc = argparse_parse(&argparse, argc, argv);
571*4882a593Smuzhiyun     mpi_ao_test_show_options(ctx);
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun     if (ctx->srcFilePath == RK_NULL
574*4882a593Smuzhiyun         || ctx->s32Channel <= 0
575*4882a593Smuzhiyun         || ctx->s32ReSmpSampleRate <= 0) {
576*4882a593Smuzhiyun         argparse_usage(&argparse);
577*4882a593Smuzhiyun         goto __FAILED;
578*4882a593Smuzhiyun     }
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun     RK_MPI_SYS_Init();
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun     for (i = 0; i < ctx->s32LoopCount; i++) {
583*4882a593Smuzhiyun         RK_LOGI("start running loop count  = %d", i);
584*4882a593Smuzhiyun         s32Ret = unit_test_mpi_ao(ctx);
585*4882a593Smuzhiyun         if (s32Ret != RK_SUCCESS) {
586*4882a593Smuzhiyun             goto __FAILED;
587*4882a593Smuzhiyun         }
588*4882a593Smuzhiyun         RK_LOGI("end running loop count  = %d", i);
589*4882a593Smuzhiyun     }
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun __FAILED:
592*4882a593Smuzhiyun     if (ctx) {
593*4882a593Smuzhiyun         free(ctx);
594*4882a593Smuzhiyun         ctx = RK_NULL;
595*4882a593Smuzhiyun     }
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun     RK_MPI_SYS_Exit();
598*4882a593Smuzhiyun     return 0;
599*4882a593Smuzhiyun }
600