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