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