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