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