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