• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
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 <dlfcn.h>
17 #include <limits.h>
18 #include <pthread.h>
19 #include <securec.h>
20 #include <signal.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/mman.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include "framework_common.h"
28 #include "hdf_base.h"
29 #include "hdf_remote_adapter_if.h"
30 #include "inttypes.h"
31 #include "osal_mem.h"
32 #include "v1_0/audio_types.h"
33 #include "v1_0/iaudio_manager.h"
34 
35 #define MAX_AUDIO_ADAPTER_DESC          5
36 #define BUFFER_LEN                      256
37 #define ID_RIFF                         0x46464952
38 #define ID_WAVE                         0x45564157
39 #define ID_FMT                          0x20746d66
40 #define ID_DATA                         0x61746164
41 #define MOVE_LEFT_NUM                   8
42 #define AUDIO_SAMPLE_RATE_8K            8000
43 #define AUDIO_CHANNELCOUNT              2
44 #define AUDIO_SAMPLE_RATE_48K           48000
45 #define PATH_LEN                        256
46 #define DEEP_BUFFER_RENDER_PERIOD_SIZE  4096
47 #define DEEP_BUFFER_RENDER_PERIOD_COUNT 8
48 #define INT_32_MAX                      0x7fffffff
49 #define EXT_PARAMS_MAXLEN               107
50 #define BITS_TO_FROMAT                  3
51 #define SERVICE_NAME                    "audio_manager_service"
52 
53 enum RenderSoundCardMode {
54     PRIMARY = 1,
55     PRIMARY_EXT = 2,
56     AUDIO_USB = 3,
57     AUDIO_A2DP = 4,
58 };
59 
60 struct StrPara {
61     struct IAudioRender *render;
62     FILE *file;
63     struct AudioSampleAttributes attrs;
64     uint64_t *replyBytes;
65     char *frame;
66     int32_t bufferSize;
67 };
68 
69 struct IAudioRender *g_render = NULL;
70 struct IAudioAdapter *g_adapter = NULL;
71 static struct IAudioManager *g_audioManager = NULL;
72 struct AudioDeviceDescriptor g_devDesc;
73 struct AudioSampleAttributes g_attrs;
74 struct AudioPort g_audioPort;
75 struct AudioHeadInfo g_wavHeadInfo;
76 static struct StrPara g_str;
77 
78 pthread_t g_tids;
79 char *g_frame = NULL;
80 FILE *g_file;
81 
82 char g_path[256];
83 char g_adapterName[PATH_LEN] = {0};
84 static int32_t g_closeEnd = 0;
85 pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
86 pthread_cond_t g_functionCond = PTHREAD_COND_INITIALIZER;
87 bool g_waitSleep = false;
88 bool g_isDirect = true;
89 
90 enum RenderMenuId {
91     RENDER_START = 1,
92     RENDER_STOP,
93     RENDER_RESUME,
94     RENDER_PAUSE,
95     SET_RENDER_VOLUME,
96     SET_RENDER_GAIN,
97     SET_RENDER_MUTE,
98     SET_RENDER_ATTRIBUTES,
99     SET_RENDER_SLECET_SCENE,
100     GET_RENDER_EXT_PARAMS,
101     GET_RENDER_POSITION,
102 };
103 
104 enum RenderInputType {
105     INPUT_INT = 0,
106     INPUT_FLOAT,
107     INPUT_UINT32,
108 };
109 
110 typedef int32_t (*AudioRenderOperation)(struct IAudioRender **);
111 
112 struct ProcessRenderMenuSwitchList {
113     enum RenderMenuId cmd;
114     AudioRenderOperation operation;
115 };
116 
CheckInputName(int type,void * val)117 static int32_t CheckInputName(int type, void *val)
118 {
119     if (val == NULL) {
120         return HDF_FAILURE;
121     }
122 
123     int ret;
124     int inputInt = 0;
125     float inputFloat = 0.0;
126     uint32_t inputUint = 0;
127 
128     printf("\n");
129     switch (type) {
130         case INPUT_INT:
131             ret = scanf_s("%d", &inputInt);
132             if (inputInt < 0 || inputInt > GET_RENDER_POSITION + 1) {
133                 AUDIO_FUNC_LOGE("Input failure");
134                 return HDF_FAILURE;
135             }
136 
137             *(int *)val = inputInt;
138             break;
139         case INPUT_FLOAT:
140             ret = scanf_s("%f", &inputFloat);
141 
142             *(float *)val = inputFloat;
143             break;
144         case INPUT_UINT32:
145             ret = scanf_s("%u", &inputUint);
146             if (inputUint > 0xFFFFFFFF) {
147                 return HDF_FAILURE;
148             }
149 
150             *(uint32_t *)val = inputUint;
151             break;
152         default:
153             ret = EOF;
154             break;
155     }
156 
157     if (ret == 0) {
158         CleanStdin();
159     } else if (ret == EOF) {
160         AUDIO_FUNC_LOGE("Input failure occurs!");
161         return HDF_FAILURE;
162     }
163     return HDF_SUCCESS;
164 }
165 
InitAttrs(struct AudioSampleAttributes * attrs)166 static int32_t InitAttrs(struct AudioSampleAttributes *attrs)
167 {
168     if (attrs == NULL) {
169         return HDF_FAILURE;
170     }
171     /* Initialization of audio parameters for playback */
172     attrs->format = AUDIO_FORMAT_PCM_16_BIT;
173     attrs->channelCount = AUDIO_CHANNELCOUNT;
174     attrs->sampleRate = AUDIO_SAMPLE_RATE_48K;
175     attrs->interleaved = 0;
176     attrs->type = AUDIO_IN_MEDIA;
177     attrs->period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
178     attrs->frameSize = PCM_16_BIT * attrs->channelCount / PCM_8_BIT;
179     attrs->isBigEndian = false;
180     attrs->isSignedData = true;
181     attrs->startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (attrs->frameSize);
182     attrs->stopThreshold = INT_32_MAX;
183     attrs->silenceThreshold = 0;
184     return HDF_SUCCESS;
185 }
186 
InitDevDesc(struct AudioDeviceDescriptor * devDesc,uint32_t portId)187 static int32_t InitDevDesc(struct AudioDeviceDescriptor *devDesc, uint32_t portId)
188 {
189     if (devDesc == NULL) {
190         return HDF_FAILURE;
191     }
192     /* Initialization of audio parameters for playback */
193     devDesc->portId = portId;
194     devDesc->pins = PIN_OUT_SPEAKER;
195     devDesc->desc = strdup("cardname");
196     return HDF_SUCCESS;
197 }
198 
WavHeadAnalysis(FILE * file,struct AudioSampleAttributes * attrs)199 static int32_t WavHeadAnalysis(FILE *file, struct AudioSampleAttributes *attrs)
200 {
201     if (file == NULL || attrs == NULL) {
202         return HDF_FAILURE;
203     }
204 
205     const char *audioRiffIdParam = "RIFF";
206     const char *audioFileFmtParam = "WAVE";
207     const char *aduioDataIdParam = "data";
208 
209     size_t ret = fread(&g_wavHeadInfo, sizeof(g_wavHeadInfo), 1, file);
210     if (ret != 1) {
211         return HDF_FAILURE;
212     }
213 
214     uint32_t audioRiffId = StringToInt(audioRiffIdParam);
215     uint32_t audioFileFmt = StringToInt(audioFileFmtParam);
216     uint32_t aduioDataId = StringToInt(aduioDataIdParam);
217     if (g_wavHeadInfo.riffId != audioRiffId || g_wavHeadInfo.waveType != audioFileFmt ||
218         g_wavHeadInfo.dataId != aduioDataId) {
219         return HDF_FAILURE;
220     }
221 
222     attrs->channelCount = g_wavHeadInfo.audioChannelNum;
223     attrs->sampleRate = g_wavHeadInfo.audioSampleRate;
224 
225     switch (g_wavHeadInfo.audioBitsPerSample) {
226         case PCM_8_BIT: {
227             attrs->format = AUDIO_FORMAT_PCM_8_BIT;
228             break;
229         }
230         case PCM_16_BIT: {
231             attrs->format = AUDIO_FORMAT_PCM_16_BIT;
232             break;
233         }
234         case PCM_24_BIT: {
235             attrs->format = AUDIO_FORMAT_PCM_24_BIT;
236             break;
237         }
238         case PCM_32_BIT: {
239             attrs->format = AUDIO_FORMAT_PCM_32_BIT;
240             break;
241         }
242         default:
243             return HDF_FAILURE;
244     }
245     return HDF_SUCCESS;
246 }
247 
SwitchAdapter(struct AudioAdapterDescriptor * descs,const char * adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort * renderPort,int32_t size)248 static int32_t SwitchAdapter(struct AudioAdapterDescriptor *descs, const char *adapterNameCase,
249     enum AudioPortDirection portFlag, struct AudioPort *renderPort, int32_t size)
250 {
251     struct AudioAdapterDescriptor *desc = NULL;
252     if (descs == NULL || adapterNameCase == NULL || renderPort == NULL) {
253         return HDF_FAILURE;
254     }
255 
256     for (int32_t index = 0; index < size; index++) {
257         desc = &descs[index];
258         if (desc == NULL) {
259             continue;
260         }
261         if (desc->adapterName == NULL) {
262             return HDF_FAILURE;
263         }
264         if (strcmp((const char *)desc->adapterName, adapterNameCase)) {
265             continue;
266         }
267         for (uint32_t port = 0; port < desc->portsLen; port++) {
268             // Only find out the port of out in the sound card
269             if (desc->ports[port].dir == portFlag) {
270                 *renderPort = desc->ports[port];
271                 return index;
272             }
273         }
274     }
275     return HDF_ERR_NOT_SUPPORT;
276 }
277 
StreamClose(int32_t sig)278 static void StreamClose(int32_t sig)
279 {
280     /* allow the stream to be closed gracefully */
281     (void)signal(sig, SIG_IGN);
282     g_closeEnd = 1;
283 }
284 
PcmFramesToBytes(const struct AudioSampleAttributes attrs)285 static uint32_t PcmFramesToBytes(const struct AudioSampleAttributes attrs)
286 {
287     return DEEP_BUFFER_RENDER_PERIOD_SIZE * attrs.channelCount * (PcmFormatToBits(attrs.format) >> BITS_TO_FROMAT);
288 }
289 
StopAudioFiles(struct IAudioRender ** renderS)290 static int32_t StopAudioFiles(struct IAudioRender **renderS)
291 {
292     if (renderS == NULL) {
293         return HDF_FAILURE;
294     }
295     if (g_waitSleep) {
296         pthread_mutex_lock(&g_mutex);
297         g_waitSleep = false;
298         pthread_cond_signal(&g_functionCond);
299         pthread_mutex_unlock(&g_mutex);
300     }
301     if (!g_closeEnd) {
302         g_closeEnd = true;
303         usleep(100000); // sleep 100000us
304     }
305 
306     struct IAudioRender *render = *renderS;
307     if (render == NULL) {
308         AUDIO_FUNC_LOGE("render is null");
309         return HDF_FAILURE;
310     }
311 
312     int32_t ret = render->Stop((void *)render);
313     if (ret < 0) {
314         AUDIO_FUNC_LOGE("Stop Render!");
315     }
316 
317     if (g_adapter == NULL || g_adapter->DestroyRender == NULL) {
318         return HDF_FAILURE;
319     }
320 
321     ret = g_adapter->DestroyRender(g_adapter, &g_devDesc);
322     if (ret < 0) {
323         AUDIO_FUNC_LOGE("Destroy Render!");
324     }
325 
326     IAudioRenderRelease(render, g_isDirect);
327 
328     *renderS = NULL;
329     g_render = NULL;
330     if (g_frame != NULL) {
331         OsalMemFree(g_frame);
332         g_frame = NULL;
333     }
334 
335     if (g_file != NULL) {
336         fclose(g_file);
337         g_file = NULL;
338     }
339     printf("Stop Successful\n");
340     return ret;
341 }
342 
FrameStartMmap(const struct StrPara * param)343 static int32_t FrameStartMmap(const struct StrPara *param)
344 {
345     if (param == NULL) {
346         return HDF_FAILURE;
347     }
348     const struct StrPara *strParam = param;
349     struct IAudioRender *render = strParam->render;
350     struct AudioMmapBufferDescripter mmapDesc;
351 
352     (void)signal(SIGINT, StreamClose);
353 
354     // get file length
355     char pathBuf[PATH_MAX] = {'\0'};
356     if (realpath(g_path, pathBuf) == NULL) {
357         return HDF_FAILURE;
358     }
359 
360     // get fileSize
361     FILE *fp = fopen(pathBuf, "rb+");
362     if (fp == NULL) {
363         printf("Open file failed!\n");
364         return HDF_FAILURE;
365     }
366 
367     int32_t ret = fseek(fp, 0, SEEK_END);
368     if (ret != 0) {
369         fclose(fp);
370         return HDF_FAILURE;
371     }
372 
373     int32_t reqSize = (int32_t)ftell(fp);
374     if (reqSize < 0) {
375         fclose(fp);
376         return HDF_FAILURE;
377     }
378     (void)fclose(fp);
379     // Init param
380     mmapDesc.memoryFd = 0; // default 0
381     mmapDesc.filePath = strdup(pathBuf);
382     mmapDesc.isShareable = 1;                                        // 1:Shareable ,0:Don't share
383     mmapDesc.transferFrameSize = DEEP_BUFFER_RENDER_PERIOD_SIZE / 4; // One frame size 4 bit
384     mmapDesc.offset = sizeof(g_wavHeadInfo);
385 
386     // start
387     if (render == NULL || render->ReqMmapBuffer == NULL) {
388         free(mmapDesc.filePath);
389         return HDF_FAILURE;
390     }
391 
392     ret = render->ReqMmapBuffer(render, reqSize, &mmapDesc);
393     if (ret < 0 || reqSize <= 0) {
394         free(mmapDesc.filePath);
395         printf("Request map fail,please check.\n");
396         return HDF_FAILURE;
397     }
398 
399     if (g_render != NULL) {
400         ret = StopAudioFiles(&render);
401         if (ret < 0) {
402             free(mmapDesc.filePath);
403             AUDIO_FUNC_LOGE("StopAudioFiles File!");
404         }
405     }
406     free(mmapDesc.filePath);
407     return HDF_SUCCESS;
408 }
409 
FrameStart(const struct StrPara * param)410 static int32_t FrameStart(const struct StrPara *param)
411 {
412     if (param == NULL) {
413         return HDF_FAILURE;
414     }
415 
416     size_t numRead;
417     char *frame = param->frame;
418     int32_t bufferSize = param->bufferSize;
419     struct IAudioRender *render = param->render;
420     size_t remainingDataSize = g_wavHeadInfo.riffSize;
421 
422     (void)signal(SIGINT, StreamClose);
423     if (g_file == NULL) {
424         return HDF_FAILURE;
425     }
426 
427     if (render == NULL || render->RenderFrame == NULL || frame == NULL) {
428         return HDF_FAILURE;
429     }
430 
431     do {
432         uint64_t replyBytes = 0;
433         size_t readSize = (remainingDataSize > bufferSize) ? (size_t)bufferSize : remainingDataSize;
434         numRead = fread(frame, 1, readSize, g_file);
435         if (numRead > 0) {
436             int32_t ret = render->RenderFrame(render, (int8_t *)frame, numRead, &replyBytes);
437             if (ret == HDF_ERR_INVALID_OBJECT) {
438                 AUDIO_FUNC_LOGE("Render already stop!");
439                 break;
440             }
441             remainingDataSize -= numRead;
442         }
443 
444         while (g_waitSleep) {
445             printf("music pause now.\n");
446             pthread_cond_wait(&g_functionCond, &g_mutex);
447             printf("music resume now.\n");
448         }
449     } while (!g_closeEnd && numRead > 0 && remainingDataSize > 0);
450 
451     if (!g_closeEnd) {
452         printf("\nPlay complete, please select input again\n");
453         (void)StopAudioFiles(&render);
454     }
455     return HDF_SUCCESS;
456 }
457 
InitPlayingAudioParam(struct IAudioRender * render)458 static int32_t InitPlayingAudioParam(struct IAudioRender *render)
459 {
460     if (render == NULL) {
461         return HDF_FAILURE;
462     }
463     uint32_t bufferSize = PcmFramesToBytes(g_attrs);
464 
465     g_frame = (char *)OsalMemCalloc(bufferSize);
466     if (g_frame == NULL) {
467         return HDF_FAILURE;
468     }
469 
470     (void)memset_s(&g_str, sizeof(struct StrPara), 0, sizeof(struct StrPara));
471 
472     g_str.render = render;
473     g_str.bufferSize = (int32_t)bufferSize;
474     g_str.frame = g_frame;
475     return HDF_SUCCESS;
476 }
477 
PrintPlayMode(void)478 static void PrintPlayMode(void)
479 {
480     printf(" ============= Play Render Mode ==========\n");
481     printf("| 1. Render non-mmap                     |\n");
482     printf("| 2. Render mmap                         |\n");
483     printf(" ======================================== \n");
484 }
485 
SelectPlayMode(int32_t * palyModeFlag)486 static int32_t SelectPlayMode(int32_t *palyModeFlag)
487 {
488     if (palyModeFlag == NULL) {
489         AUDIO_FUNC_LOGE("palyModeFlag is null");
490         return HDF_FAILURE;
491     }
492 
493     int choice = 0;
494 
495     system("clear");
496 
497     PrintPlayMode();
498 
499     printf("Please enter your choice:");
500 
501     int32_t ret = CheckInputName(INPUT_INT, (void *)&choice);
502     if (ret < 0) {
503         AUDIO_FUNC_LOGE("CheckInputName Fail");
504         return HDF_FAILURE;
505     } else {
506         *palyModeFlag = choice;
507     }
508     return HDF_SUCCESS;
509 }
510 
StartPlayThread(int32_t palyModeFlag)511 static int32_t StartPlayThread(int32_t palyModeFlag)
512 {
513     pthread_attr_t tidsAttr;
514     pthread_attr_init(&tidsAttr);
515     pthread_attr_setdetachstate(&tidsAttr, PTHREAD_CREATE_DETACHED);
516     switch (palyModeFlag) {
517         case 1: // 1. Stander Loading
518             if (pthread_create(&g_tids, &tidsAttr, (void *)(&FrameStart), &g_str) != 0) {
519                 AUDIO_FUNC_LOGE("Create Thread Fail");
520                 return HDF_FAILURE;
521             }
522             break;
523         case 2: // 2. Low latency Loading
524             if (pthread_create(&g_tids, &tidsAttr, (void *)(&FrameStartMmap), &g_str) != 0) {
525                 AUDIO_FUNC_LOGE("Create Thread Fail");
526                 return HDF_FAILURE;
527             }
528             break;
529         default:
530             printf("Input error,Switched to non-mmap Mode for you.\n");
531             SystemInputFail();
532 
533             if (pthread_create(&g_tids, &tidsAttr, (void *)(&FrameStart), &g_str) != 0) {
534                 AUDIO_FUNC_LOGE("Create Thread Fail");
535                 return HDF_FAILURE;
536             }
537             break;
538     }
539     return HDF_SUCCESS;
540 }
541 
PlayingAudioInitFile(void)542 static int32_t PlayingAudioInitFile(void)
543 {
544     if (g_file != NULL) {
545         AUDIO_FUNC_LOGE("the music is playing,please stop first");
546         return HDF_FAILURE;
547     }
548     g_closeEnd = false;
549 
550     char pathBuf[PATH_MAX] = {'\0'};
551     if (realpath(g_path, pathBuf) == NULL) {
552         return HDF_FAILURE;
553     }
554 
555     g_file = fopen(pathBuf, "rb");
556     if (g_file == NULL) {
557         printf("failed to open '%s'\n", g_path);
558         return HDF_FAILURE;
559     }
560 
561     if (WavHeadAnalysis(g_file, &g_attrs) < 0) {
562         AUDIO_FUNC_LOGE("Frame test is Fail");
563         FileClose(&g_file);
564         return HDF_FAILURE;
565     }
566 
567     (void)chmod(g_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
568 
569     return HDF_SUCCESS;
570 }
571 
PlayingAudioInitRender(struct IAudioRender ** renderTemp)572 static int32_t PlayingAudioInitRender(struct IAudioRender **renderTemp)
573 {
574     if (renderTemp == NULL) {
575         AUDIO_FUNC_LOGE("render is null");
576         return HDF_FAILURE;
577     }
578     struct IAudioRender *render = NULL;
579 
580     int32_t ret = g_adapter->CreateRender(g_adapter, &g_devDesc, &g_attrs, &render);
581     if (render == NULL || ret < 0 || render->RenderFrame == NULL) {
582         AUDIO_FUNC_LOGE("AudioDeviceCreateRender failed or RenderFrame is null");
583         return HDF_FAILURE;
584     }
585 
586     // Playing audio files
587     if (render->Start((void *)render)) {
588         AUDIO_FUNC_LOGE("Start Bind Fail!");
589         g_adapter->DestroyRender(g_adapter, &g_devDesc);
590         IAudioRenderRelease(render, g_isDirect);
591         return HDF_FAILURE;
592     }
593 
594     if (InitPlayingAudioParam(render) < 0) {
595         g_adapter->DestroyRender(g_adapter, &g_devDesc);
596         IAudioRenderRelease(render, g_isDirect);
597         return HDF_FAILURE;
598     }
599     *renderTemp = render;
600     return HDF_SUCCESS;
601 }
602 
PlayingAudioFiles(struct IAudioRender ** renderS)603 static int32_t PlayingAudioFiles(struct IAudioRender **renderS)
604 {
605     if (renderS == NULL || g_adapter == NULL || g_adapter->CreateRender == NULL) {
606         return HDF_FAILURE;
607     }
608 
609     if (PlayingAudioInitFile() < 0) {
610         AUDIO_FUNC_LOGE("PlayingAudioInitFile Fail");
611         return HDF_FAILURE;
612     }
613 
614     int32_t palyModeFlag = 0;
615     if (SelectPlayMode(&palyModeFlag) < 0) {
616         AUDIO_FUNC_LOGE("SelectPlayMode Fail");
617         FileClose(&g_file);
618         return HDF_FAILURE;
619     }
620 
621     struct IAudioRender *render = NULL;
622     if (PlayingAudioInitRender(&render) < 0) {
623         AUDIO_FUNC_LOGE("PlayingAudioInitRender fail");
624         FileClose(&g_file);
625         return HDF_FAILURE;
626     }
627 
628     if (StartPlayThread(palyModeFlag) < 0) {
629         FileClose(&g_file);
630         if (g_adapter != NULL && g_adapter->DestroyRender != NULL) {
631             g_adapter->DestroyRender(g_adapter, &g_devDesc);
632         }
633         IAudioRenderRelease(render, g_isDirect);
634         return HDF_FAILURE;
635     }
636 
637     *renderS = render;
638     printf("Start Successful,Music is playing\n");
639     return HDF_SUCCESS;
640 }
641 
PrintMenu0(void)642 static void PrintMenu0(void)
643 {
644     printf(" ============= Play Render Sound Card Mode ==========\n");
645     printf("| 1. Render Primary                                 |\n");
646     printf("| 2. Render Primary_Ext                             |\n");
647     printf("| 3. Render Usb                                     |\n");
648     printf("| 4. Render A2dp                                    |\n");
649     printf(" =================================================== \n");
650 }
651 
PrintMenu1(void)652 static void PrintMenu1(void)
653 {
654     printf(" ============== Play Render Loading Mode ===========\n");
655     printf("| 1. Render Direct Loading                         |\n");
656     printf("| 2. Render Service Loading                        |\n");
657     printf("| Note: switching is not supported in the MPI's    |\n");
658     printf("|       version.                                   |\n");
659     printf(" ================================================== \n");
660 }
661 
SwitchInternalOrExternal(char * adapterNameCase,int32_t nameLen)662 static int32_t SwitchInternalOrExternal(char *adapterNameCase, int32_t nameLen)
663 {
664     int choice = 0;
665 
666     system("clear");
667 
668     PrintMenu0();
669 
670     printf("Please enter your choice:");
671 
672     int32_t ret = CheckInputName(INPUT_INT, (void *)&choice);
673     if (ret < 0) {
674         return HDF_FAILURE;
675     }
676 
677     switch (choice) {
678         case PRIMARY:
679             snprintf_s(adapterNameCase, nameLen, nameLen - 1, "%s", "primary");
680             break;
681         case PRIMARY_EXT:
682             snprintf_s(adapterNameCase, nameLen, nameLen - 1, "%s", "primary_ext");
683             break;
684         case AUDIO_USB:
685             snprintf_s(adapterNameCase, nameLen, nameLen - 1, "%s", "usb");
686             break;
687         case AUDIO_A2DP:
688             snprintf_s(adapterNameCase, nameLen, nameLen - 1, "%s", "a2dp");
689             break;
690         default:
691             printf("Input error,Switched to primary in for you.\n");
692             SystemInputFail();
693             snprintf_s(adapterNameCase, nameLen, nameLen - 1, "%s", "primary");
694             break;
695     }
696     return HDF_SUCCESS;
697 }
698 
SelectLoadingMode(void)699 static int32_t SelectLoadingMode(void)
700 {
701     int choice = 0;
702 
703     system("clear");
704 
705     PrintMenu1();
706 
707     printf("Please enter your choice:");
708 
709     int32_t ret = CheckInputName(INPUT_INT, (void *)&choice);
710     if (ret < 0) {
711         return HDF_FAILURE;
712     }
713 
714     switch (choice) {
715         case DIRECT:
716             g_isDirect = true;
717             break;
718         case SERVICE:
719             g_isDirect = false;
720             break;
721         default:
722             printf("Input error,Switched to direct loading in for you.\n");
723             SystemInputFail();
724             g_isDirect = true;
725             break;
726     }
727 
728     return HDF_SUCCESS;
729 }
730 
AudioAdapterDescriptorFree(struct AudioAdapterDescriptor * dataBlock,bool freeSelf)731 void AudioAdapterDescriptorFree(struct AudioAdapterDescriptor *dataBlock, bool freeSelf)
732 {
733     if (dataBlock == NULL) {
734         return;
735     }
736 
737     if (dataBlock->adapterName != NULL) {
738         OsalMemFree(dataBlock->adapterName);
739         dataBlock->adapterName = NULL;
740     }
741 
742     if (dataBlock->ports != NULL) {
743         OsalMemFree(dataBlock->ports);
744     }
745 
746     if (freeSelf) {
747         OsalMemFree(dataBlock);
748     }
749 }
750 
ReleaseAdapterDescs(struct AudioAdapterDescriptor ** descs,uint32_t descsLen)751 static void ReleaseAdapterDescs(struct AudioAdapterDescriptor **descs, uint32_t descsLen)
752 {
753     if (descsLen > 0 && descs != NULL && (*descs) != NULL) {
754         for (uint32_t i = 0; i < descsLen; i++) {
755             AudioAdapterDescriptorFree(&(*descs)[i], false);
756         }
757         OsalMemFree(*descs);
758         *descs = NULL;
759     }
760 }
761 
GetManagerAndLoadAdapter(const char * adapterNameCase,struct AudioPort * renderPort)762 static int32_t GetManagerAndLoadAdapter(const char *adapterNameCase, struct AudioPort *renderPort)
763 {
764     if (adapterNameCase == NULL || renderPort == NULL) {
765         AUDIO_FUNC_LOGE("The Parameter is NULL");
766         return HDF_FAILURE;
767     }
768 
769     struct IAudioManager *audioManagerIns = IAudioManagerGetInstance(SERVICE_NAME, g_isDirect);
770     if (audioManagerIns == NULL) {
771         AUDIO_FUNC_LOGE("Get audio Manager Fail");
772         return HDF_FAILURE;
773     }
774 
775     g_audioManager = audioManagerIns;
776 
777     struct AudioAdapterDescriptor *descs = (struct AudioAdapterDescriptor *)OsalMemCalloc(
778         sizeof(struct AudioAdapterDescriptor) * (MAX_AUDIO_ADAPTER_DESC));
779     if (descs == NULL) {
780         AUDIO_FUNC_LOGE("OsalMemCalloc for descs failed");
781         return HDF_FAILURE;
782     }
783 
784     uint32_t adapterNum = MAX_AUDIO_ADAPTER_DESC;
785 
786     int32_t ret = audioManagerIns->GetAllAdapters(audioManagerIns, descs, &adapterNum);
787     if (ret < 0 || adapterNum == 0) {
788         AUDIO_FUNC_LOGE("Get All Adapters Fail");
789         ReleaseAdapterDescs(&descs, MAX_AUDIO_ADAPTER_DESC);
790         return HDF_ERR_NOT_SUPPORT;
791     }
792 
793     // Get qualified sound card and port
794     enum AudioPortDirection port = PORT_OUT; // Set port information
795     int32_t index = SwitchAdapter(descs, adapterNameCase, port, renderPort, adapterNum);
796     if (index < 0) {
797         AUDIO_FUNC_LOGE("Not Switch Adapter Fail");
798         ReleaseAdapterDescs(&descs, MAX_AUDIO_ADAPTER_DESC);
799         return HDF_ERR_NOT_SUPPORT;
800     }
801 
802     if (audioManagerIns->LoadAdapter(audioManagerIns, &descs[index], &g_adapter)) {
803         AUDIO_FUNC_LOGE("Load Adapter Fail");
804         ReleaseAdapterDescs(&descs, MAX_AUDIO_ADAPTER_DESC);
805         return HDF_ERR_NOT_SUPPORT;
806     }
807 
808     ReleaseAdapterDescs(&descs, MAX_AUDIO_ADAPTER_DESC);
809 
810     if (g_adapter == NULL) {
811         AUDIO_FUNC_LOGE("load audio device failed");
812         return HDF_FAILURE;
813     }
814     return HDF_SUCCESS;
815 }
816 
InitRenderParam(const char * adapterNameCase,uint32_t portId)817 static int32_t InitRenderParam(const char *adapterNameCase, uint32_t portId)
818 {
819     if (adapterNameCase == NULL || g_adapter == NULL) {
820         AUDIO_FUNC_LOGE("The Parameter is NULL");
821         return HDF_FAILURE;
822     }
823 
824     // Initialization port information, can fill through mode and other parameters
825     (void)g_adapter->InitAllPorts(g_adapter);
826 
827     // User needs to set
828     if (InitAttrs(&g_attrs) < 0) {
829         AUDIO_FUNC_LOGE("InitAttrs failed");
830         return HDF_FAILURE;
831     }
832 
833     // Specify a hardware device
834     if (InitDevDesc(&g_devDesc, portId) < 0) {
835         AUDIO_FUNC_LOGE("InitDevDesc failed");
836         return HDF_FAILURE;
837     }
838     return HDF_SUCCESS;
839 }
840 
RenderGetAdapterAndInitEnvParams(const char * adapterNameCase)841 static int32_t RenderGetAdapterAndInitEnvParams(const char *adapterNameCase)
842 {
843     struct AudioPort renderPort;
844 
845     int32_t ret = GetManagerAndLoadAdapter(adapterNameCase, &renderPort);
846     if (ret < 0) {
847         return ret;
848     }
849 
850     if (InitRenderParam(adapterNameCase, renderPort.portId) < 0) {
851         g_audioManager->UnloadAdapter(g_audioManager, adapterNameCase);
852         IAudioAdapterRelease(g_adapter, g_isDirect);
853         g_adapter = NULL;
854         return HDF_FAILURE;
855     }
856     return HDF_SUCCESS;
857 }
858 
InitParam(void)859 static int32_t InitParam(void)
860 {
861     /* Internal and external switch,begin */
862     if (SwitchInternalOrExternal(g_adapterName, PATH_LEN) < 0) {
863         return HDF_FAILURE;
864     }
865 
866     if (SelectLoadingMode() < 0) {
867         return HDF_FAILURE;
868     }
869 
870     /* Select loading mode,end */
871     g_audioPort.dir = PORT_OUT;
872     g_audioPort.portId = 0;
873     g_audioPort.portName = "AOP";
874 
875     if (RenderGetAdapterAndInitEnvParams(g_adapterName) < 0) {
876         AUDIO_FUNC_LOGE("GetProxyManagerFunc Fail");
877 
878         if (g_audioManager != NULL) {
879             IAudioManagerRelease(g_audioManager, g_isDirect);
880             g_audioManager = NULL;
881         }
882         return HDF_FAILURE;
883     }
884     return HDF_SUCCESS;
885 }
886 
SetRenderMute(struct IAudioRender ** render)887 static int32_t SetRenderMute(struct IAudioRender **render)
888 {
889     (void)render;
890     if (g_render == NULL || g_render->GetMute == NULL) {
891         return HDF_FAILURE;
892     }
893 
894     int32_t val;
895     bool isMute = false;
896 
897     int32_t ret = g_render->GetMute((void *)g_render, &isMute);
898     if (ret < 0) {
899         AUDIO_FUNC_LOGE("The current mute state was not obtained!");
900     }
901 
902     printf("Now %s ,Do you need to set mute status(1/0):", isMute ? "mute" : "not mute");
903 
904     ret = CheckInputName(INPUT_INT, (void *)&val);
905     if (ret < 0) {
906         return HDF_FAILURE;
907     }
908 
909     if (g_render == NULL || g_render->SetMute == NULL) {
910         AUDIO_FUNC_LOGE("Music already stop!");
911         SystemInputFail();
912         return HDF_FAILURE;
913     }
914     if (val == 1) {
915         ret = g_render->SetMute((void *)g_render, !isMute);
916     }
917     return ret;
918 }
919 
SetRenderVolume(struct IAudioRender ** render)920 static int32_t SetRenderVolume(struct IAudioRender **render)
921 {
922     (void)render;
923     if (g_render == NULL || g_render->GetVolume == NULL) {
924         return HDF_FAILURE;
925     }
926 
927     int32_t ret;
928     float val = 0.0;
929 
930     ret = g_render->GetVolume((void *)g_render, &val);
931     if (ret < 0) {
932         AUDIO_FUNC_LOGE("Get current volume failed!");
933         SystemInputFail();
934         return ret;
935     }
936 
937     printf("Now the volume is %f ,Please enter the volume value you want to set (0.0-1.0):", val);
938 
939     ret = CheckInputName(INPUT_FLOAT, (void *)&val);
940     if (ret < 0) {
941         return HDF_FAILURE;
942     }
943 
944     if (val < 0.0 || val > 1.0) {
945         AUDIO_FUNC_LOGE("Invalid volume value!");
946         SystemInputFail();
947         return HDF_FAILURE;
948     }
949 
950     if (g_render == NULL || g_render->SetVolume == NULL) {
951         AUDIO_FUNC_LOGE("Music already stop!");
952         SystemInputFail();
953         return HDF_FAILURE;
954     }
955 
956     ret = g_render->SetVolume((void *)g_render, val);
957     if (ret < 0) {
958         AUDIO_FUNC_LOGE("set volume fail!");
959         SystemInputFail();
960     }
961     return ret;
962 }
963 
GetRenderGain(struct IAudioRender ** render)964 static int32_t GetRenderGain(struct IAudioRender **render)
965 {
966     (void)render;
967     if (g_render == NULL || g_render->GetGain == NULL) {
968         return HDF_FAILURE;
969     }
970 
971     float val = 1.0;
972 
973     int32_t ret = g_render->GetGain((void *)g_render, &val);
974     if (ret < 0) {
975         AUDIO_FUNC_LOGE("Get current gain failed!");
976         SystemInputFail();
977         return HDF_FAILURE;
978     }
979     printf("Now the gain is %f,", val);
980     SystemInputFail();
981     return HDF_SUCCESS;
982 }
983 
SetRenderPause(struct IAudioRender ** render)984 static int32_t SetRenderPause(struct IAudioRender **render)
985 {
986     (void)render;
987 
988     if (g_waitSleep) {
989         AUDIO_FUNC_LOGE("Already pause,not need pause again!");
990         SystemInputFail();
991         return HDF_FAILURE;
992     }
993 
994     if (g_render == NULL || g_render->Pause == NULL) {
995         return HDF_FAILURE;
996     }
997 
998     int32_t ret = g_render->Pause((void *)g_render);
999     if (ret != 0) {
1000         return HDF_FAILURE;
1001     }
1002 
1003     printf("Pause success!\n");
1004     g_waitSleep = true;
1005     return HDF_SUCCESS;
1006 }
1007 
SetRenderResume(struct IAudioRender ** render)1008 static int32_t SetRenderResume(struct IAudioRender **render)
1009 {
1010     (void)render;
1011 
1012     if (!g_waitSleep) {
1013         AUDIO_FUNC_LOGE("Now is Playing,not need resume!");
1014         SystemInputFail();
1015         return HDF_FAILURE;
1016     }
1017 
1018     if (g_render == NULL || g_render->Resume == NULL) {
1019         return HDF_FAILURE;
1020     }
1021 
1022     int32_t ret = g_render->Resume((void *)g_render);
1023     if (ret != 0) {
1024         return HDF_FAILURE;
1025     }
1026     printf("resume success!\n");
1027 
1028     pthread_mutex_lock(&g_mutex);
1029     g_waitSleep = false;
1030     pthread_cond_signal(&g_functionCond);
1031     pthread_mutex_unlock(&g_mutex);
1032     return HDF_SUCCESS;
1033 }
PrintAttributesFromat(void)1034 static void PrintAttributesFromat(void)
1035 {
1036     printf(" ============= Render Sample Attributes Fromat =============== \n");
1037     printf("| 1. Render AUDIO_FORMAT_PCM_8_BIT                            |\n");
1038     printf("| 2. Render AUDIO_FORMAT_PCM_16_BIT                           |\n");
1039     printf("| 3. Render AUDIO_FORMAT_PCM_24_BIT                           |\n");
1040     printf("| 4. Render AUDIO_FORMAT_PCM_32_BIT                           |\n");
1041     printf(" ============================================================= \n");
1042 }
SelectAttributesFomat(uint32_t * pcmFomat)1043 static int32_t SelectAttributesFomat(uint32_t *pcmFomat)
1044 {
1045     if (pcmFomat == NULL) {
1046         AUDIO_FUNC_LOGE("fomat is null!");
1047         return HDF_FAILURE;
1048     }
1049 
1050     int val = 0;
1051 
1052     PrintAttributesFromat();
1053 
1054     printf("Please select audio format,If not selected, the default is 16bit:");
1055 
1056     int32_t ret = CheckInputName(INPUT_INT, (void *)&val);
1057     if (ret < 0) {
1058         AUDIO_FUNC_LOGE("CheckInputName failed.");
1059         return HDF_FAILURE;
1060     }
1061 
1062     switch (val) {
1063         case AUDIO_FORMAT_PCM_8_BIT:
1064             *pcmFomat = AUDIO_FORMAT_PCM_8_BIT;
1065             break;
1066         case AUDIO_FORMAT_PCM_16_BIT:
1067             *pcmFomat = AUDIO_FORMAT_PCM_16_BIT;
1068             break;
1069         case AUDIO_FORMAT_PCM_24_BIT:
1070             *pcmFomat = AUDIO_FORMAT_PCM_24_BIT;
1071             break;
1072         case AUDIO_FORMAT_PCM_32_BIT:
1073             *pcmFomat = AUDIO_FORMAT_PCM_32_BIT;
1074             break;
1075         default:
1076             *pcmFomat = AUDIO_FORMAT_PCM_16_BIT;
1077             break;
1078     }
1079     return HDF_SUCCESS;
1080 }
1081 
SetRenderAttributes(struct IAudioRender ** render)1082 static int32_t SetRenderAttributes(struct IAudioRender **render)
1083 {
1084     (void)render;
1085 
1086     struct AudioSampleAttributes attrs;
1087 
1088     if (g_render == NULL || g_render->GetSampleAttributes == NULL) {
1089         AUDIO_FUNC_LOGE("The pointer is null!");
1090         return HDF_FAILURE;
1091     }
1092 
1093     int32_t ret = g_render->GetSampleAttributes((void *)g_render, &attrs);
1094     if (ret < 0) {
1095         AUDIO_FUNC_LOGE("GetRenderAttributes failed!");
1096     } else {
1097         printf("Current sample attributes:\n");
1098         printf("audioType is %u\nfomat is %u\nsampleRate is %u\nchannalCount is"
1099                "%u\nperiod is %u\nframesize is %u\nbigEndian is %u\nSignedData is %u\n",
1100             attrs.type, attrs.format, attrs.sampleRate, attrs.channelCount, attrs.period, attrs.frameSize,
1101             attrs.isBigEndian, attrs.isSignedData);
1102     }
1103     printf("Set Sample Attributes,");
1104     SystemInputFail();
1105     system("clear");
1106     printf("The sample attributes you want to set,Step by step, please.\n");
1107 
1108     ret = SelectAttributesFomat((uint32_t *)(&attrs.format));
1109     if (ret < 0) {
1110         AUDIO_FUNC_LOGE("SetRenderAttributes format failed!");
1111         return HDF_FAILURE;
1112     }
1113 
1114     printf("\nPlease input sample rate(48000,44100,32000...):");
1115 
1116     ret = CheckInputName(INPUT_UINT32, (void *)(&attrs.sampleRate));
1117     if (ret < 0) {
1118         return HDF_FAILURE;
1119     }
1120 
1121     printf("\nPlease input bigEndian(false=0/true=1):");
1122 
1123     ret = CheckInputName(INPUT_UINT32, (void *)(&attrs.isBigEndian));
1124     if (ret < 0) {
1125         return HDF_FAILURE;
1126     }
1127     if (g_render == NULL || g_render->SetSampleAttributes == NULL) {
1128         AUDIO_FUNC_LOGE("Music already complete,Please replay and set the attrbutes!");
1129         SystemInputFail();
1130         return HDF_FAILURE;
1131     }
1132 
1133     ret = g_render->SetSampleAttributes((void *)g_render, &attrs);
1134     if (ret < 0) {
1135         AUDIO_FUNC_LOGE("Set render attributes failed!");
1136         SystemInputFail();
1137     }
1138     return ret;
1139 }
1140 
SelectRenderScene(struct IAudioRender ** render)1141 static int32_t SelectRenderScene(struct IAudioRender **render)
1142 {
1143     (void)render;
1144 
1145     int val = 0;
1146     struct AudioSceneDescriptor scene;
1147 
1148     system("clear");
1149     printf(" =================== Select Scene ===================== \n");
1150     printf("0 is Speaker.                                          |\n");
1151     printf("1 is HeadPhones.                                       |\n");
1152     printf(" ====================================================== \n");
1153     printf("Please input your choice:\n");
1154 
1155     int32_t ret = CheckInputName(INPUT_INT, (void *)&val);
1156     if (ret < 0 || (val != 0 && val != 1)) {
1157         AUDIO_FUNC_LOGE("Invalid value!");
1158         SystemInputFail();
1159         return HDF_FAILURE;
1160     }
1161 
1162     if (val == 1) {
1163         scene.scene.id = 0;
1164         scene.desc.pins = PIN_OUT_HEADSET;
1165     } else {
1166         scene.scene.id = 0;
1167         scene.desc.pins = PIN_OUT_SPEAKER;
1168     }
1169 
1170     scene.desc.desc = "mic";
1171 
1172     if (g_render == NULL || g_render->SelectScene == NULL) {
1173         AUDIO_FUNC_LOGE("Music already stop,");
1174         SystemInputFail();
1175         return HDF_FAILURE;
1176     }
1177 
1178     ret = g_render->SelectScene((void *)g_render, &scene);
1179     if (ret < 0) {
1180         AUDIO_FUNC_LOGE("Select scene fail\n");
1181     }
1182     return ret;
1183 }
1184 
GetExtParams(struct IAudioRender ** render)1185 static int32_t GetExtParams(struct IAudioRender **render)
1186 {
1187     (void)render;
1188     if (g_render == NULL || g_render->GetExtraParams == NULL) {
1189         return HDF_FAILURE;
1190     }
1191 
1192     char keyValueList[BUFFER_LEN] = {0};
1193 
1194     int32_t ret = g_render->GetExtraParams((void *)g_render, keyValueList, EXT_PARAMS_MAXLEN);
1195     if (ret < 0) {
1196         AUDIO_FUNC_LOGE("Get EXT params failed!");
1197         SystemInputFail();
1198         return HDF_FAILURE;
1199     }
1200     printf("keyValueList = %s\n", keyValueList);
1201     return HDF_SUCCESS;
1202 }
1203 
GetRenderMmapPosition(struct IAudioRender ** render)1204 static int32_t GetRenderMmapPosition(struct IAudioRender **render)
1205 {
1206     (void)render;
1207 
1208     if (g_render == NULL || g_render->GetMmapPosition == NULL) {
1209         return HDF_FAILURE;
1210     }
1211 
1212     uint64_t frames = 0;
1213     struct AudioTimeStamp time;
1214     time.tvNSec = 0;
1215     time.tvSec = 0;
1216 
1217     int32_t ret = g_render->GetMmapPosition((void *)g_render, &frames, &time);
1218     if (ret < 0) {
1219         AUDIO_FUNC_LOGE("Get current Mmap frames Position failed!");
1220         SystemInputFail();
1221         return HDF_FAILURE;
1222     }
1223     printf("Now the Position is %" PRIu64 "\n", frames);
1224     return HDF_SUCCESS;
1225 }
1226 
PrintMenu2(void)1227 static void PrintMenu2(void)
1228 {
1229     printf(" ================== Play Render Menu ================== \n");
1230     printf("| 1. Render Start                                      |\n");
1231     printf("| 2. Render Stop                                       |\n");
1232     printf("| 3. Render Resume                                     |\n");
1233     printf("| 4. Render Pause                                      |\n");
1234     printf("| 5. Render SetVolume                                  |\n");
1235     printf("| 6. Render GetGain                                    |\n");
1236     printf("| 7. Render SetMute                                    |\n");
1237     printf("| 8. Render SetAttributes                              |\n");
1238     printf("| 9. Render SelectScene                                |\n");
1239     printf("| 10. Render getEXtParams                              |\n");
1240     printf("| 11. Render getMmapPosition                           |\n");
1241     printf("| 12.Exit                                              |\n");
1242     printf(" ====================================================== \n");
1243 }
1244 
1245 static struct ProcessRenderMenuSwitchList g_processRenderMenuSwitchList[] = {
1246     {RENDER_START, PlayingAudioFiles},
1247     {RENDER_STOP, StopAudioFiles},
1248     {RENDER_RESUME, SetRenderResume},
1249     {RENDER_PAUSE, SetRenderPause},
1250     {SET_RENDER_VOLUME, SetRenderVolume},
1251     {SET_RENDER_GAIN, GetRenderGain},
1252     {SET_RENDER_MUTE, SetRenderMute},
1253     {SET_RENDER_ATTRIBUTES, SetRenderAttributes},
1254     {SET_RENDER_SLECET_SCENE, SelectRenderScene},
1255     {GET_RENDER_EXT_PARAMS, GetExtParams},
1256     {GET_RENDER_POSITION, GetRenderMmapPosition},
1257 };
1258 
ProcessMenu(int32_t choice)1259 static void ProcessMenu(int32_t choice)
1260 {
1261     if (choice == GET_RENDER_POSITION + 1) {
1262         return;
1263     }
1264 
1265     if (g_render == NULL && choice != 1) {
1266         AUDIO_FUNC_LOGE("This render already release!");
1267         SystemInputFail();
1268         return;
1269     }
1270 
1271     for (int32_t i = RENDER_START; i <= GET_RENDER_POSITION; ++i) {
1272         if ((choice == (int32_t)g_processRenderMenuSwitchList[i - 1].cmd) &&
1273             (g_processRenderMenuSwitchList[i - 1].operation != NULL)) {
1274             g_processRenderMenuSwitchList[i - 1].operation(&g_render);
1275         }
1276     }
1277 }
1278 
Choice(void)1279 static void Choice(void)
1280 {
1281     int32_t choice = 0;
1282 
1283     while (choice < GET_RENDER_POSITION + 1 && choice >= 0) {
1284         system("clear");
1285         PrintMenu2();
1286         printf("your choice is:\n");
1287 
1288         int32_t ret = CheckInputName(INPUT_INT, (void *)&choice);
1289         if (ret < 0) {
1290             continue;
1291         }
1292 
1293         if (choice < RENDER_START || choice > GET_RENDER_POSITION + 1) {
1294             AUDIO_FUNC_LOGE("You input is wrong!");
1295             choice = 0;
1296             SystemInputFail();
1297             continue;
1298         }
1299         ProcessMenu(choice);
1300     }
1301 }
1302 
main(int32_t argc,char const * argv[])1303 int32_t main(int32_t argc, char const *argv[])
1304 {
1305     if (argc < 2 || argv == NULL || argv[0] == NULL) { // The parameter number is not greater than 2
1306         printf("usage:[1]sample [2]/data/test.wav\n");
1307         return 0;
1308     }
1309 
1310     if (argv[1] == NULL || strlen(argv[1]) == 0) {
1311         return HDF_FAILURE;
1312     }
1313 
1314     int32_t ret = strncpy_s(g_path, PATH_LEN - 1, argv[1], strlen(argv[1]) + 1);
1315     if (ret != 0) {
1316         AUDIO_FUNC_LOGE("strncpy_s Fail!");
1317         return HDF_FAILURE;
1318     }
1319 
1320     char pathBuf[PATH_MAX] = {'\0'};
1321     if (realpath(g_path, pathBuf) == NULL) {
1322         AUDIO_FUNC_LOGE("realpath Fail!");
1323         return HDF_FAILURE;
1324     }
1325 
1326     if (InitParam() != HDF_SUCCESS) { // init
1327         AUDIO_FUNC_LOGE("InitParam Fail!");
1328         return HDF_FAILURE;
1329     }
1330 
1331     Choice();
1332 
1333     if (g_render != NULL && g_adapter != NULL) {
1334         StopAudioFiles(&g_render);
1335     }
1336 
1337     if (g_audioManager != NULL && g_audioManager->UnloadAdapter != NULL) {
1338         g_audioManager->UnloadAdapter(g_audioManager, g_adapterName);
1339         IAudioAdapterRelease(g_adapter, g_isDirect);
1340         g_adapter = NULL;
1341         IAudioManagerRelease(g_audioManager, g_isDirect);
1342         g_audioManager = NULL;
1343     }
1344     return 0;
1345 }
1346