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