1 /**
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 /**
17 * @addtogroup Audio
18 * @{
19 *
20 * @brief Defines audio-related APIs, including custom data types and functions for loading drivers,
21 * accessing a driver adapter, and rendering and capturing audios.
22 *
23 * @since 1.0
24 * @version 1.0
25 */
26
27 /**
28 * @file audio_adapter.h
29 *
30 * @brief Declares APIs for operations related to the audio adapter.
31 *
32 * @since 1.0
33 * @version 1.0
34 */
35
36 #include "audio_hdi_common.h"
37
38 #ifdef FEATURE_SMALL_DEVICE
39 #else
40 #include "osal_mem.h"
41 #endif
42
43 #define SREREO_CHANNEL 2
44 #define MONO_CHANNEL 1
45 #define AUDIO_CHANNELCOUNT 2
46
47 using namespace std;
48
49 static int g_frameStatus = 1;
50 static int g_writeCompleted = 0;
51 static int g_renderFull = 0;
52 static int g_flushCompleted = 0;
53 static const int32_t AUDIO_CAPTURE_CHANNELCOUNT = 1;
54 static const int32_t SILENCE_THRESHOLD = 16 * 1024;
55 namespace OHOS {
56 namespace Audio {
57
InitAttrsCommon(struct AudioSampleAttributes & attrs)58 void InitAttrsCommon(struct AudioSampleAttributes &attrs)
59 {
60 /* Initialization of audio parameters for playback */
61 attrs.sampleRate = SAMPLE_RATE_48000;
62 }
63
InitAttrs(struct AudioSampleAttributes & attrs)64 void InitAttrs(struct AudioSampleAttributes &attrs)
65 {
66 attrs.sampleRate = SAMPLERATE;
67 attrs.format = AUDIO_FORMAT_TYPE_PCM_16_BIT;
68 attrs.channelCount = CHANNELCOUNT;
69 attrs.interleaved = 0;
70 attrs.type = AUDIO_IN_MEDIA;
71 attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
72 attrs.frameSize = PCM_16_BIT * CHANNELCOUNT / MOVE_LEFT_NUM;
73 attrs.isBigEndian = false;
74 attrs.isSignedData = true;
75 attrs.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (PCM_16_BIT * attrs.channelCount / MOVE_LEFT_NUM);
76 attrs.stopThreshold = INT_32_MAX;
77 attrs.silenceThreshold = BUFFER_LENTH;
78 }
79
InitAttrsRender(struct AudioSampleAttributes & attrs)80 void InitAttrsRender(struct AudioSampleAttributes &attrs)
81 {
82 InitAttrsCommon(attrs);
83 attrs.format = AUDIO_FORMAT_TYPE_PCM_32_BIT;
84 attrs.channelCount = AUDIO_CHANNELCOUNT;
85 attrs.interleaved = 1;
86 attrs.type = AUDIO_IN_MEDIA;
87 attrs.silenceThreshold = 0;
88 }
89
InitAttrsCapture(struct AudioSampleAttributes & attrs)90 void InitAttrsCapture(struct AudioSampleAttributes &attrs)
91 {
92 InitAttrsCommon(attrs);
93 attrs.format = AUDIO_FORMAT_TYPE_PCM_16_BIT;
94 attrs.channelCount = AUDIO_CAPTURE_CHANNELCOUNT;
95 attrs.silenceThreshold = SILENCE_THRESHOLD;
96 }
97
InitAttrsUpdate(struct AudioSampleAttributes & attrs,int format,uint32_t channelCount,uint32_t sampleRate,uint32_t silenceThreshold)98 void InitAttrsUpdate(struct AudioSampleAttributes &attrs, int format, uint32_t channelCount,
99 uint32_t sampleRate, uint32_t silenceThreshold)
100 {
101 #ifdef FEATURE_SMALL_DEVICE
102 InitAttrs(attrs);
103 #else
104 InitAttrsRender(attrs);
105 #endif
106 attrs.format = (enum AudioFormat)format;
107 attrs.sampleRate = sampleRate;
108 attrs.channelCount = channelCount;
109 attrs.silenceThreshold = silenceThreshold;
110 }
AudioRenderSetGetSampleAttributes(struct AudioSampleAttributes attrs,struct AudioSampleAttributes & attrsValue,struct AudioRender * render)111 int32_t AudioRenderSetGetSampleAttributes(struct AudioSampleAttributes attrs, struct AudioSampleAttributes &attrsValue,
112 struct AudioRender *render)
113 {
114 int32_t ret = -1;
115 if (render == nullptr) {
116 return HDF_ERR_INVALID_PARAM;
117 }
118 ret = render->attr.SetSampleAttributes(render, &attrs);
119 if (ret < 0) {
120 return ret;
121 }
122 ret = render->attr.GetSampleAttributes(render, &attrsValue);
123 if (ret < 0) {
124 return ret;
125 }
126 return HDF_SUCCESS;
127 }
AudioCaptureSetGetSampleAttributes(struct AudioSampleAttributes attrs,struct AudioSampleAttributes & attrsValue,struct AudioCapture * capture)128 int32_t AudioCaptureSetGetSampleAttributes(struct AudioSampleAttributes attrs, struct AudioSampleAttributes &attrsValue,
129 struct AudioCapture *capture)
130 {
131 int32_t ret = -1;
132 if (capture == nullptr) {
133 return HDF_ERR_INVALID_PARAM;
134 }
135 ret = capture->attr.SetSampleAttributes(capture, &attrs);
136 if (ret < 0) {
137 return ret;
138 }
139 ret = capture->attr.GetSampleAttributes(capture, &attrsValue);
140 if (ret < 0) {
141 return ret;
142 }
143 return HDF_SUCCESS;
144 }
145
StringToInt(std::string flag)146 uint32_t StringToInt(std::string flag)
147 {
148 uint32_t temp = flag[0];
149 for (int i = flag.size() - 1; i >= 0; i--) {
150 temp <<= MOVE_LEFT_NUM;
151 temp += flag[i];
152 }
153 return temp;
154 }
155
InitDevDesc(struct AudioDeviceDescriptor & devDesc,const uint32_t portId,int pins)156 int32_t InitDevDesc(struct AudioDeviceDescriptor &devDesc, const uint32_t portId, int pins)
157 {
158 devDesc.portId = portId;
159 devDesc.pins = (enum AudioPortPin)pins;
160 devDesc.desc = nullptr;
161 return HDF_SUCCESS;
162 }
163
SwitchAdapter(struct AudioAdapterDescriptor * descs,const std::string & adapterNameCase,int portFlag,struct AudioPort * & audioPort,int size)164 int32_t SwitchAdapter(struct AudioAdapterDescriptor *descs, const std::string &adapterNameCase,
165 int portFlag, struct AudioPort *&audioPort, int size)
166 {
167 if (descs == nullptr || size > ADAPTER_COUNT) {
168 return HDF_FAILURE;
169 }
170
171 for (int index = 0; index < size; index++) {
172 struct AudioAdapterDescriptor *desc = &descs[index];
173 if (desc == nullptr || desc->adapterName == nullptr) {
174 continue;
175 }
176 if (strcmp(desc->adapterName, adapterNameCase.c_str())) {
177 continue;
178 }
179 for (uint32_t port = 0; port < desc->portNum; port++) {
180 if (desc->ports[port].dir == portFlag) {
181 audioPort = &desc->ports[port];
182 return index;
183 }
184 }
185 }
186 return HDF_FAILURE;
187 }
188
PcmFormatToBits(int format)189 uint32_t PcmFormatToBits(int format)
190 {
191 switch (format) {
192 case AUDIO_FORMAT_TYPE_PCM_8_BIT:
193 return PCM_8_BIT;
194 case AUDIO_FORMAT_TYPE_PCM_16_BIT:
195 return PCM_16_BIT;
196 case AUDIO_FORMAT_TYPE_PCM_24_BIT:
197 return PCM_24_BIT;
198 case AUDIO_FORMAT_TYPE_PCM_32_BIT:
199 return PCM_32_BIT;
200 default:
201 return PCM_16_BIT;
202 }
203 }
204
PcmFramesToBytes(const struct AudioSampleAttributes attrs)205 uint32_t PcmFramesToBytes(const struct AudioSampleAttributes attrs)
206 {
207 if (attrs.channelCount < MONO_CHANNEL || attrs.channelCount > SREREO_CHANNEL) {
208 return 0;
209 }
210 uint32_t formatBits = PcmFormatToBits(attrs.format);
211 if (formatBits < PCM_8_BIT || formatBits > PCM_32_BIT) {
212 return 0;
213 }
214 uint32_t ret = FRAME_SIZE * (attrs.channelCount) * (formatBits >> MOVE_RIGHT_NUM);
215 return ret;
216 }
217
WavHeadAnalysis(struct AudioHeadInfo & wavHeadInfo,FILE * file,struct AudioSampleAttributes & attrs)218 int32_t WavHeadAnalysis(struct AudioHeadInfo &wavHeadInfo, FILE *file, struct AudioSampleAttributes &attrs)
219 {
220 size_t ret = 0;
221 if (file == nullptr) {
222 return HDF_FAILURE;
223 }
224 ret = fread(&wavHeadInfo, sizeof(wavHeadInfo), 1, file);
225 if (ret != 1) {
226 return HDF_FAILURE;
227 }
228 uint32_t audioRiffId = StringToInt(AUDIO_RIFF);
229 uint32_t audioFileFmt = StringToInt(AUDIO_WAVE);
230 uint32_t audioDataId = StringToInt(AUDIO_DATA);
231 if (wavHeadInfo.testFileRiffId != audioRiffId || wavHeadInfo.testFileFmt != audioFileFmt ||
232 wavHeadInfo.dataId != audioDataId) {
233 return HDF_FAILURE;
234 }
235 attrs.channelCount = wavHeadInfo.audioChannelNum;
236 attrs.sampleRate = wavHeadInfo.audioSampleRate;
237 switch (wavHeadInfo.audioBitsPerSample) {
238 case PCM_8_BIT: {
239 attrs.format = AUDIO_FORMAT_TYPE_PCM_8_BIT;
240 break;
241 }
242 case PCM_16_BIT: {
243 attrs.format = AUDIO_FORMAT_TYPE_PCM_16_BIT;
244 break;
245 }
246 case PCM_24_BIT: {
247 attrs.format = AUDIO_FORMAT_TYPE_PCM_24_BIT;
248 break;
249 }
250 case PCM_32_BIT: {
251 attrs.format = AUDIO_FORMAT_TYPE_PCM_32_BIT;
252 break;
253 }
254 default:
255 return HDF_FAILURE;
256 }
257 return HDF_SUCCESS;
258 }
GetAdapters(TestAudioManager * manager,struct AudioAdapterDescriptor ** descs,int & size)259 int32_t GetAdapters(TestAudioManager *manager, struct AudioAdapterDescriptor **descs, int &size)
260 {
261 if (descs == nullptr) {
262 return HDF_ERR_INVALID_PARAM;
263 }
264 #ifdef FEATURE_SMALL_DEVICE
265 int32_t ret = manager->GetAllAdapters(manager, descs, &size);
266 if (ret < 0) {
267 return ret;
268 }
269 if (*descs == nullptr) {
270 return HDF_FAILURE;
271 }
272 #else
273 size = 1;
274 uint32_t portNum = 2;
275 struct AudioPort *ports = reinterpret_cast<struct AudioPort*>(OsalMemCalloc(sizeof(struct AudioPort) *
276 (portNum)));
277 ports[0] = {
278 .dir = PORT_OUT,
279 .portId = 0,
280 };
281 ports[1] = {
282 .dir = PORT_IN,
283 .portId = 11,
284 };
285 *descs = reinterpret_cast<struct AudioAdapterDescriptor*>(OsalMemCalloc(sizeof(struct AudioAdapterDescriptor) *
286 (size)));
287 if (*descs == nullptr) {
288 return HDF_FAILURE;
289 }
290
291 **descs = {
292 .adapterName = "primary",
293 .portNum = portNum,
294 .ports = ports,
295 };
296 #endif
297 return HDF_SUCCESS;
298 }
299
GetLoadAdapter(TestAudioManager * manager,int portType,const std::string & adapterName,struct AudioAdapter ** adapter,struct AudioPort * & audioPort)300 int32_t GetLoadAdapter(TestAudioManager *manager, int portType,
301 const std::string &adapterName, struct AudioAdapter **adapter, struct AudioPort *&audioPort)
302 {
303 int32_t ret = -1;
304 int size = 0;
305 struct AudioAdapterDescriptor *desc = nullptr;
306 struct AudioAdapterDescriptor *descs = nullptr;
307 if (adapter == nullptr) {
308 return HDF_ERR_INVALID_PARAM;
309 }
310 ret = GetAdapters(manager, &descs, size);
311 if (ret < 0) {
312 return ret;
313 }
314 if (descs == nullptr) {
315 return HDF_FAILURE;
316 }
317
318 int index = SwitchAdapter(descs, adapterName, portType, audioPort, size);
319 if (index < 0) {
320 return HDF_FAILURE;
321 }
322 desc = &descs[index];
323 if (desc == nullptr) {
324 return HDF_ERR_INVALID_PARAM;
325 }
326 ret = manager->LoadAdapter(manager, desc, adapter);
327 if (ret < 0) {
328 return ret;
329 }
330 if (*adapter == nullptr) {
331 return HDF_FAILURE;
332 }
333 return HDF_SUCCESS;
334 }
335
AudioCreateRender(TestAudioManager * manager,int pins,const std::string & adapterName,struct AudioAdapter ** adapter,struct AudioRender ** render)336 int32_t AudioCreateRender(TestAudioManager *manager, int pins, const std::string &adapterName,
337 struct AudioAdapter **adapter, struct AudioRender **render)
338 {
339 int32_t ret = -1;
340 struct AudioSampleAttributes attrs = {};
341 struct AudioDeviceDescriptor devDesc = {};
342 struct AudioPort *renderPort = nullptr;
343 if (adapter == nullptr || render == nullptr) {
344 return HDF_ERR_INVALID_PARAM;
345 }
346 ret = GetLoadAdapter(manager, PORT_OUT, adapterName, adapter, renderPort);
347 if (ret < 0) {
348 return ret;
349 }
350 if (*adapter == nullptr || (*adapter)->CreateRender == nullptr) {
351 return HDF_FAILURE;
352 }
353 #ifdef FEATURE_SMALL_DEVICE
354 InitAttrs(attrs);
355 #else
356 InitAttrsRender(attrs);
357 #endif
358 InitDevDesc(devDesc, renderPort->portId, pins);
359 ret = (*adapter)->CreateRender(*adapter, &devDesc, &attrs, render);
360 if (ret < 0) {
361 manager->UnloadAdapter(manager, *adapter);
362 return ret;
363 }
364 if (*render == nullptr) {
365 manager->UnloadAdapter(manager, *adapter);
366 return HDF_FAILURE;
367 }
368 return HDF_SUCCESS;
369 }
370
AudioCreateStartRender(TestAudioManager * manager,struct AudioRender ** render,struct AudioAdapter ** adapter,const std::string & adapterName)371 int32_t AudioCreateStartRender(TestAudioManager *manager, struct AudioRender **render, struct AudioAdapter **adapter,
372 const std::string &adapterName)
373 {
374 int32_t ret = -1;
375
376 if (adapter == nullptr || render == nullptr) {
377 return HDF_ERR_INVALID_PARAM;
378 }
379 ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, adapterName, adapter, render);
380 if (ret < 0) {
381 return ret;
382 }
383 if (*render == nullptr || *adapter == nullptr) {
384 return HDF_FAILURE;
385 }
386 ret = AudioRenderStartAndOneFrame(*render);
387 if (ret < 0) {
388 (*adapter)->DestroyRender(*adapter, *render);
389 manager->UnloadAdapter(manager, *adapter);
390 return ret;
391 }
392 return HDF_SUCCESS;
393 }
394
AudioRenderStartAndOneFrame(struct AudioRender * render)395 int32_t AudioRenderStartAndOneFrame(struct AudioRender *render)
396 {
397 int32_t ret = -1;
398 char *frame = nullptr;
399 uint64_t numRead = 0;
400 uint64_t replyBytes = 0;
401 if (render == nullptr || render->control.Start == nullptr || render->RenderFrame == nullptr) {
402 return HDF_ERR_INVALID_PARAM;
403 }
404 ret = render->control.Start((AudioHandle)render);
405 if (ret) {
406 return ret;
407 }
408 ret = RenderFramePrepare(AUDIO_FILE, frame, numRead);
409 if (ret < 0) {
410 if (frame != nullptr) {
411 free(frame);
412 frame = nullptr;
413 }
414 return HDF_FAILURE;
415 }
416 ret = render->RenderFrame(render, frame, numRead, &replyBytes);
417 if (ret < 0) {
418 if (frame != nullptr) {
419 free(frame);
420 frame = nullptr;
421 }
422 return ret;
423 }
424 free(frame);
425 frame = nullptr;
426 return HDF_SUCCESS;
427 }
428
AudioCreateCapture(TestAudioManager * manager,int pins,const std::string & adapterName,struct AudioAdapter ** adapter,struct AudioCapture ** capture)429 int32_t AudioCreateCapture(TestAudioManager *manager, int pins, const std::string &adapterName,
430 struct AudioAdapter **adapter, struct AudioCapture **capture)
431 {
432 int32_t ret = -1;
433 struct AudioSampleAttributes attrs = {};
434 struct AudioDeviceDescriptor devDesc = {};
435 struct AudioPort *capturePort = nullptr;
436 if (adapter == nullptr || capture == nullptr) {
437 return HDF_ERR_INVALID_PARAM;
438 }
439 ret = GetLoadAdapter(manager, PORT_IN, adapterName, adapter, capturePort);
440 if (ret < 0) {
441 return ret;
442 }
443 if (*adapter == nullptr || (*adapter)->CreateCapture == nullptr) {
444 return HDF_FAILURE;
445 }
446 #ifdef FEATURE_SMALL_DEVICE
447 InitAttrs(attrs);
448 #else
449 InitAttrsCapture(attrs);
450 #endif
451 InitDevDesc(devDesc, capturePort->portId, pins);
452 ret = (*adapter)->CreateCapture(*adapter, &devDesc, &attrs, capture);
453 if (ret < 0) {
454 manager->UnloadAdapter(manager, *adapter);
455 return ret;
456 }
457 if (*capture == nullptr) {
458 manager->UnloadAdapter(manager, *adapter);
459 return HDF_FAILURE;
460 }
461 return HDF_SUCCESS;
462 }
463
AudioCreateStartCapture(TestAudioManager * manager,struct AudioCapture ** capture,struct AudioAdapter ** adapter,const std::string & adapterName)464 int32_t AudioCreateStartCapture(TestAudioManager *manager, struct AudioCapture **capture,
465 struct AudioAdapter **adapter, const std::string &adapterName)
466 {
467 int32_t ret = -1;
468 struct AudioSampleAttributes attrs = {};
469 if (adapter == nullptr || capture == nullptr) {
470 return HDF_ERR_INVALID_PARAM;
471 }
472 ret = AudioCreateCapture(manager, PIN_IN_MIC, adapterName, adapter, capture);
473 if (ret < 0) {
474 manager->UnloadAdapter(manager, *adapter);
475 return ret;
476 }
477 if (*capture == nullptr || *adapter == nullptr) {
478 manager->UnloadAdapter(manager, *adapter);
479 return HDF_FAILURE;
480 }
481 FILE *file = fopen(AUDIO_CAPTURE_FILE.c_str(), "wb+");
482 if (file == nullptr) {
483 (*adapter)->DestroyCapture(*adapter, *capture);
484 manager->UnloadAdapter(manager, *adapter);
485 return HDF_FAILURE;
486 }
487 #ifdef FEATURE_SMALL_DEVICE
488 InitAttrs(attrs);
489 #else
490 InitAttrsCapture(attrs);
491 #endif
492 ret = FrameStartCapture((*capture), file, attrs);
493 if (ret < 0) {
494 (*adapter)->DestroyCapture(*adapter, *capture);
495 manager->UnloadAdapter(manager, *adapter);
496 fclose(file);
497 return ret;
498 }
499 (void)fclose(file);
500 return HDF_SUCCESS;
501 }
502
AudioCaptureStartAndOneFrame(struct AudioCapture * capture)503 int32_t AudioCaptureStartAndOneFrame(struct AudioCapture *capture)
504 {
505 int32_t ret = -1;
506 struct AudioSampleAttributes attrs = {};
507 #ifdef FEATURE_SMALL_DEVICE
508 InitAttrs(attrs);
509 #else
510 InitAttrsCapture(attrs);
511 #endif
512 FILE *file = fopen(AUDIO_CAPTURE_FILE.c_str(), "wb+");
513 if (file == nullptr) {
514 return HDF_FAILURE;
515 }
516 ret = FrameStartCapture(capture, file, attrs);
517 if (ret < 0) {
518 fclose(file);
519 return ret;
520 }
521 (void)fclose(file);
522 return HDF_SUCCESS;
523 }
524
FrameStart(struct AudioHeadInfo wavHeadInfo,struct AudioRender * render,FILE * file,struct AudioSampleAttributes attrs)525 int32_t FrameStart(struct AudioHeadInfo wavHeadInfo, struct AudioRender *render, FILE *file,
526 struct AudioSampleAttributes attrs)
527 {
528 uint32_t readSize = 0;
529 size_t numRead = 0;
530 uint64_t replyBytes = 0;
531 int32_t tryNumFrame = 0;
532 if (render == nullptr || render->control.Start == nullptr || render->RenderFrame == nullptr || file == nullptr) {
533 return HDF_ERR_INVALID_PARAM;
534 }
535 int32_t ret = render->control.Start((AudioHandle)render);
536 if (ret) {
537 return ret;
538 }
539 uint32_t remainingDataSize = wavHeadInfo.dataSize;
540 uint32_t bufferSize = PcmFramesToBytes(attrs);
541 if (bufferSize == 0) {
542 return HDF_FAILURE;
543 }
544 char *frame = nullptr;
545 frame = reinterpret_cast<char *>(calloc(1, bufferSize));
546 if (frame == nullptr) {
547 return HDF_ERR_MALLOC_FAIL;
548 }
549 do {
550 if (g_frameStatus) {
551 readSize = (remainingDataSize) > (bufferSize) ? (bufferSize) : (remainingDataSize);
552 numRead = fread(frame, readSize, 1, file);
553 if (numRead > 0) {
554 ret = render->RenderFrame(render, frame, readSize, &replyBytes);
555 if (ret < 0) {
556 if (ret == -1) {
557 if (tryNumFrame > TRY_NUM_FRAME) {
558 free(frame);
559 return ret;
560 }
561 tryNumFrame++;
562 continue;
563 }
564 free(frame);
565 return ret;
566 }
567 tryNumFrame = 0;
568 }
569 remainingDataSize -= readSize;
570 }
571 } while (readSize > 0 && remainingDataSize > 0);
572 free(frame);
573 return HDF_SUCCESS;
574 }
575
FrameStartCapture(struct AudioCapture * capture,FILE * file,const struct AudioSampleAttributes attrs)576 int32_t FrameStartCapture(struct AudioCapture *capture, FILE *file, const struct AudioSampleAttributes attrs)
577 {
578 int32_t ret = 0;
579 uint32_t bufferSize = 0;
580 uint64_t replyBytes = 0;
581 uint64_t requestBytes = 0;
582 if (capture == nullptr || capture->control.Start == nullptr || capture->CaptureFrame == nullptr) {
583 return HDF_ERR_INVALID_PARAM;
584 }
585 ret = capture->control.Start((AudioHandle)capture);
586 if (ret < 0) {
587 return ret;
588 }
589 uint32_t pcmBytes = PcmFramesToBytes(attrs);
590 if (pcmBytes < PCM_BYTE_MIN || pcmBytes > PCM_BYTE_MAX) {
591 return HDF_FAILURE;
592 }
593 bufferSize = FRAME_COUNT * pcmBytes;
594 if (bufferSize == 0) {
595 return HDF_FAILURE;
596 }
597 char *frame = nullptr;
598 frame = reinterpret_cast<char *>(calloc(1, bufferSize));
599 if (frame == nullptr) {
600 return HDF_ERR_MALLOC_FAIL;
601 }
602 requestBytes = bufferSize;
603 ret = capture->CaptureFrame(capture, frame, requestBytes, &replyBytes);
604 if (ret < 0) {
605 ret = capture->CaptureFrame(capture, frame, requestBytes, &replyBytes);
606 if (ret < 0) {
607 free(frame);
608 return ret;
609 }
610 }
611 uint32_t requestByte = static_cast<uint32_t>(replyBytes);
612 (void)fwrite(frame, requestByte, 1, file);
613 free(frame);
614 return HDF_SUCCESS;
615 }
616
RenderFramePrepare(const std::string & path,char * & frame,uint64_t & readSize)617 int32_t RenderFramePrepare(const std::string &path, char *&frame, uint64_t &readSize)
618 {
619 int32_t ret = -1;
620 size_t numRead = 0;
621 uint32_t bufferSize = 4096;
622 uint32_t remainingDataSize = 0;
623 struct AudioSampleAttributes attrs = {};
624 struct AudioHeadInfo headInfo = {};
625 #ifdef FEATURE_SMALL_DEVICE
626 InitAttrs(attrs);
627 #else
628 InitAttrsRender(attrs);
629 #endif
630 char absPath[PATH_MAX] = {0};
631 if (realpath(path.c_str(), absPath) == nullptr) {
632 return HDF_FAILURE;
633 }
634 FILE *file = fopen(absPath, "rb");
635 if (file == nullptr) {
636 return HDF_FAILURE;
637 }
638 ret = WavHeadAnalysis(headInfo, file, attrs);
639 if (ret < 0) {
640 fclose(file);
641 return HDF_FAILURE;
642 }
643 frame = reinterpret_cast<char *>(calloc(1, bufferSize));
644 if (frame == nullptr) {
645 fclose(file);
646 return HDF_ERR_MALLOC_FAIL;
647 }
648 remainingDataSize = headInfo.dataSize;
649 readSize = (remainingDataSize) > (bufferSize) ? (bufferSize) : (remainingDataSize);
650 size_t readSizes = static_cast<size_t>(readSize);
651 numRead = fread(frame, readSizes, 1, file);
652 if (numRead < 1) {
653 free(frame);
654 frame = nullptr;
655 fclose(file);
656 return HDF_FAILURE;
657 }
658 (void)fclose(file);
659 return HDF_SUCCESS;
660 }
661
FrameStatus(int status)662 void FrameStatus(int status)
663 {
664 g_frameStatus = status;
665 return;
666 }
667
StartRecord(struct AudioCapture * capture,FILE * file,uint64_t filesize)668 int32_t StartRecord(struct AudioCapture *capture, FILE *file, uint64_t filesize)
669 {
670 uint64_t replyBytes = 0;
671 uint64_t requestBytes = BUFFER_LENTH;
672 uint64_t totalSize = 0;
673 int32_t tryNumFrame = 0;
674 if (capture == nullptr || capture->control.Start == nullptr ||
675 capture->CaptureFrame == nullptr || file == nullptr) {
676 return HDF_ERR_INVALID_PARAM;
677 }
678 int32_t ret = capture->control.Start((AudioHandle)capture);
679 if (ret < 0) {
680 return ret;
681 }
682 char *frame = reinterpret_cast<char *>(calloc(1, BUFFER_LENTH));
683 if (frame == nullptr) {
684 return HDF_ERR_MALLOC_FAIL;
685 }
686 do {
687 if (g_frameStatus) {
688 ret = capture->CaptureFrame(capture, frame, requestBytes, &replyBytes);
689 if (ret < 0) {
690 if (ret == -1) {
691 if (tryNumFrame++ > TRY_NUM_FRAME) {
692 free(frame);
693 frame = nullptr;
694 return ret;
695 }
696 continue;
697 }
698 free(frame);
699 frame = nullptr;
700 return ret;
701 }
702 tryNumFrame = 0;
703 uint32_t replyByte = static_cast<uint32_t>(replyBytes);
704 size_t writeRet = fwrite(frame, replyByte, 1, file);
705 if (writeRet == 0) {
706 free(frame);
707 frame = nullptr;
708 return HDF_FAILURE;
709 }
710 totalSize += replyBytes;
711 } else {
712 totalSize += 0;
713 }
714 } while (totalSize <= filesize * MEGABYTE);
715 free(frame);
716 frame = nullptr;
717 return HDF_SUCCESS;
718 }
719
WriteIdToBuf(struct HdfSBuf * sBuf,struct AudioCtlElemId id)720 int32_t WriteIdToBuf(struct HdfSBuf *sBuf, struct AudioCtlElemId id)
721 {
722 if (!HdfSbufWriteInt32(sBuf, id.iface)) {
723 return HDF_FAILURE;
724 }
725 if (!HdfSbufWriteString(sBuf, id.cardServiceName)) {
726 return HDF_FAILURE;
727 }
728 if (!HdfSbufWriteString(sBuf, id.itemName)) {
729 return HDF_FAILURE;
730 }
731 return HDF_SUCCESS;
732 }
733
WriteEleValueToBuf(struct HdfSBuf * sBuf,struct AudioCtlElemValue elemvalue)734 int32_t WriteEleValueToBuf(struct HdfSBuf *sBuf, struct AudioCtlElemValue elemvalue)
735 {
736 int32_t ret = -1;
737 if (sBuf == nullptr) {
738 return HDF_FAILURE;
739 }
740 if (!HdfSbufWriteInt32(sBuf, elemvalue.value[0])) {
741 return HDF_FAILURE;
742 }
743 ret = WriteIdToBuf(sBuf, elemvalue.id);
744 if (ret != HDF_SUCCESS) {
745 return HDF_FAILURE;
746 }
747 return HDF_SUCCESS;
748 }
749
ChangeRegisterStatus(struct AudioCtlElemValue elemValue)750 int32_t ChangeRegisterStatus(struct AudioCtlElemValue elemValue)
751 {
752 int32_t ret = -1;
753 struct HdfIoService *service = nullptr;
754 struct HdfSBuf *reply = nullptr;
755 struct HdfSBuf *sBuf = nullptr;
756 service = HdfIoServiceBind(HDF_CONTROL_SERVICE.c_str());
757 if (service == nullptr || service->dispatcher == nullptr) {
758 return HDF_FAILURE;
759 }
760 sBuf = HdfSbufObtainDefaultSize();
761 if (sBuf == nullptr) {
762 HdfIoServiceRecycle(service);
763 return HDF_FAILURE;
764 }
765 ret = WriteEleValueToBuf(sBuf, elemValue);
766 if (ret < 0) {
767 HdfSbufRecycle(sBuf);
768 HdfIoServiceRecycle(service);
769 return HDF_FAILURE;
770 }
771 ret = service->dispatcher->Dispatch(&service->object, AUDIODRV_CTRL_IOCTRL_ELEM_WRITE, sBuf, reply);
772 if (ret < 0) {
773 HdfSbufRecycle(sBuf);
774 HdfIoServiceRecycle(service);
775 return ret;
776 }
777 HdfSbufRecycle(sBuf);
778 HdfIoServiceRecycle(service);
779 return HDF_SUCCESS;
780 }
781
QueryRegisterStatus(struct AudioCtlElemId id,struct AudioCtlElemValue & elemValue)782 int32_t QueryRegisterStatus(struct AudioCtlElemId id, struct AudioCtlElemValue &elemValue)
783 {
784 struct HdfIoService *service = nullptr;
785 struct HdfSBuf *sBuf = nullptr;
786 struct HdfSBuf *reply = nullptr;
787 int32_t ret = -1;
788 service = HdfIoServiceBind(HDF_CONTROL_SERVICE.c_str());
789 if (service == nullptr || service->dispatcher == nullptr) {
790 return HDF_FAILURE;
791 }
792 sBuf = HdfSbufObtainDefaultSize();
793 if (sBuf == nullptr) {
794 HdfIoServiceRecycle(service);
795 return HDF_FAILURE;
796 }
797 ret = WriteIdToBuf(sBuf, id);
798 if (ret < 0) {
799 HdfSbufRecycle(sBuf);
800 HdfIoServiceRecycle(service);
801 return HDF_FAILURE;
802 }
803 reply = HdfSbufObtainDefaultSize();
804 if (reply == nullptr) {
805 HdfSbufRecycle(sBuf);
806 HdfIoServiceRecycle(service);
807 return HDF_FAILURE;
808 }
809 ret = service->dispatcher->Dispatch(&service->object, AUDIODRV_CTRL_IOCTRL_ELEM_READ, sBuf, reply);
810 if (ret < 0) {
811 HdfSbufRecycle(sBuf);
812 HdfSbufRecycle(reply);
813 HdfIoServiceRecycle(service);
814 return ret;
815 }
816 if (!HdfSbufReadInt32(reply, &elemValue.value[0])) {
817 HdfSbufRecycle(sBuf);
818 HdfSbufRecycle(reply);
819 HdfIoServiceRecycle(service);
820 return HDF_FAILURE;
821 }
822 HdfSbufRecycle(sBuf);
823 HdfSbufRecycle(reply);
824 HdfIoServiceRecycle(service);
825 return HDF_SUCCESS;
826 }
827
PowerOff(struct AudioCtlElemValue firstElemValue,struct AudioCtlElemValue secondElemValue)828 int32_t PowerOff(struct AudioCtlElemValue firstElemValue, struct AudioCtlElemValue secondElemValue)
829 {
830 int32_t ret = -1;
831 ret = ChangeRegisterStatus(firstElemValue);
832 if (ret < 0) {
833 return ret;
834 }
835 ret = ChangeRegisterStatus(secondElemValue);
836 if (ret < 0) {
837 return ret;
838 }
839 return HDF_SUCCESS;
840 }
841
CheckRegisterStatus(const struct AudioCtlElemId firstId,const struct AudioCtlElemId secondId,const int firstStatus,const int secondStatus)842 int32_t CheckRegisterStatus(const struct AudioCtlElemId firstId, const struct AudioCtlElemId secondId,
843 const int firstStatus, const int secondStatus)
844 {
845 int32_t ret = -1;
846 struct AudioCtlElemValue elemValue[2] = {{}, {}};
847 ret = QueryRegisterStatus(firstId, elemValue[0]);
848 if (ret < 0) {
849 return ret;
850 }
851 if (firstStatus != elemValue[0].value[0]) {
852 return HDF_FAILURE;
853 }
854 ret = QueryRegisterStatus(secondId, elemValue[1]);
855 if (ret < 0) {
856 return ret;
857 }
858 if (secondStatus != elemValue[1].value[0]) {
859 return HDF_FAILURE;
860 }
861 return HDF_SUCCESS;
862 }
863
StopAudio(struct PrepareAudioPara & audiopara)864 int32_t StopAudio(struct PrepareAudioPara &audiopara)
865 {
866 if (audiopara.manager == nullptr || audiopara.adapter == nullptr) {
867 return HDF_FAILURE;
868 }
869 int32_t ret = -1;
870 if (audiopara.capture != nullptr) {
871 ret = audiopara.capture->control.Stop((AudioHandle)(audiopara.capture));
872 if (ret < 0) {
873 audiopara.adapter->DestroyCapture(audiopara.adapter, audiopara.capture);
874 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
875 audiopara.capture = nullptr;
876 audiopara.adapter = nullptr;
877 return ret;
878 }
879 audiopara.adapter->DestroyCapture(audiopara.adapter, audiopara.capture);
880 audiopara.capture = nullptr;
881 }
882 if (audiopara.render != nullptr) {
883 ret = audiopara.render->control.Stop((AudioHandle)(audiopara.render));
884 if (ret < 0) {
885 audiopara.adapter->DestroyRender(audiopara.adapter, audiopara.render);
886 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
887 audiopara.render = nullptr;
888 audiopara.adapter = nullptr;
889 return ret;
890 }
891 audiopara.adapter->DestroyRender(audiopara.adapter, audiopara.render);
892 audiopara.render = nullptr;
893 }
894 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
895 audiopara.adapter = nullptr;
896 return HDF_SUCCESS;
897 }
898
ThreadRelease(struct PrepareAudioPara & audiopara)899 int32_t ThreadRelease(struct PrepareAudioPara &audiopara)
900 {
901 int32_t ret = -1;
902 pthread_join(audiopara.tids, &audiopara.result);
903 ret = (intptr_t)audiopara.result;
904 if (ret < 0) {
905 StopAudio(audiopara);
906 return ret;
907 }
908 ret = StopAudio(audiopara);
909 if (ret < 0) {
910 return ret;
911 }
912 return HDF_SUCCESS;
913 }
PlayAudioFile(struct PrepareAudioPara & audiopara)914 int32_t PlayAudioFile(struct PrepareAudioPara &audiopara)
915 {
916 int32_t ret = -1;
917 char absPath[PATH_MAX] = {0};
918 if (realpath(audiopara.path, absPath) == nullptr) {
919 return HDF_FAILURE;
920 }
921 if (audiopara.manager == nullptr) {
922 return HDF_ERR_INVALID_PARAM;
923 }
924 FILE *file = fopen(absPath, "rb");
925 if (file == nullptr) {
926 return HDF_FAILURE;
927 }
928 if (WavHeadAnalysis(audiopara.headInfo, file, audiopara.attrs) < 0) {
929 fclose(file);
930 return HDF_FAILURE;
931 }
932 ret = AudioCreateRender(audiopara.manager, audiopara.pins, audiopara.adapterName, &audiopara.adapter,
933 &audiopara.render);
934 if (ret < 0) {
935 fclose(file);
936 return ret;
937 }
938 if (audiopara.render == nullptr) {
939 fclose(file);
940 return HDF_ERR_INVALID_PARAM;
941 }
942 ret = FrameStart(audiopara.headInfo, audiopara.render, file, audiopara.attrs);
943 if (ret == HDF_SUCCESS) {
944 fclose(file);
945 } else {
946 audiopara.adapter->DestroyRender(audiopara.adapter, audiopara.render);
947 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
948 audiopara.render = nullptr;
949 audiopara.adapter = nullptr;
950 fclose(file);
951 return ret;
952 }
953 return HDF_SUCCESS;
954 }
955
RecordAudio(struct PrepareAudioPara & audiopara)956 int32_t RecordAudio(struct PrepareAudioPara &audiopara)
957 {
958 int32_t ret = -1;
959 if (audiopara.manager == nullptr) {
960 return HDF_ERR_INVALID_PARAM;
961 }
962 ret = AudioCreateCapture(audiopara.manager, audiopara.pins, audiopara.adapterName, &audiopara.adapter,
963 &audiopara.capture);
964 if (ret < 0) {
965 return ret;
966 }
967 if (audiopara.capture == nullptr) {
968 return HDF_ERR_INVALID_PARAM;
969 }
970
971 bool isMute = false;
972 ret = audiopara.capture->volume.SetMute(audiopara.capture, isMute);
973 if (ret < 0) {
974 audiopara.adapter->DestroyCapture(audiopara.adapter, audiopara.capture);
975 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
976 return ret;
977 }
978
979 FILE *file = fopen(audiopara.path, "wb+");
980 if (file == nullptr) {
981 audiopara.adapter->DestroyCapture(audiopara.adapter, audiopara.capture);
982 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
983 return HDF_FAILURE;
984 }
985 ret = StartRecord(audiopara.capture, file, audiopara.fileSize);
986 if (ret < 0) {
987 audiopara.adapter->DestroyCapture(audiopara.adapter, audiopara.capture);
988 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
989 audiopara.capture = nullptr;
990 audiopara.adapter = nullptr;
991 fclose(file);
992 return ret;
993 }
994 (void)fclose(file);
995 return HDF_SUCCESS;
996 }
InitMmapDesc(FILE * fp,struct AudioMmapBufferDescriptor & desc,int32_t & reqSize,bool flag)997 int32_t InitMmapDesc(FILE *fp, struct AudioMmapBufferDescriptor &desc, int32_t &reqSize, bool flag)
998 {
999 if (fp == NULL) {
1000 return HDF_FAILURE;
1001 }
1002 int fd = fileno(fp);
1003 if (fd == -1) {
1004 return HDF_FAILURE;
1005 }
1006 if (flag) {
1007 struct AudioHeadInfo wavHeadInfo = {};
1008 fseek(fp, 0, SEEK_END);
1009 reqSize = ftell(fp);
1010 desc.offset = sizeof(wavHeadInfo);
1011 } else {
1012 reqSize = FILE_CAPTURE_SIZE;
1013 ftruncate(fd, FILE_CAPTURE_SIZE);
1014 desc.offset = 0;
1015 }
1016 desc.memoryFd = fd;
1017 desc.isShareable = 1;
1018 desc.transferFrameSize = DEEP_BUFFER_RENDER_PERIOD_SIZE / FRAME_COUNT;
1019 return HDF_SUCCESS;
1020 }
1021
PlayMapAudioFile(struct PrepareAudioPara & audiopara)1022 int32_t PlayMapAudioFile(struct PrepareAudioPara &audiopara)
1023 {
1024 int32_t ret = -1;
1025 int32_t reqSize = 0;
1026 bool isRender = true;
1027 FrameStatus(1);
1028 struct AudioMmapBufferDescriptor desc = {};
1029 if (audiopara.render == nullptr) {
1030 return HDF_FAILURE;
1031 }
1032 char absPath[PATH_MAX] = {0};
1033 if (realpath(audiopara.path, absPath) == nullptr) {
1034 return HDF_FAILURE;
1035 }
1036 FILE *fp = fopen(absPath, "rb+");
1037 if (fp == nullptr) {
1038 return HDF_FAILURE;
1039 }
1040 ret = InitMmapDesc(fp, desc, reqSize, isRender);
1041 if (ret < 0) {
1042 fclose(fp);
1043 return HDF_FAILURE;
1044 }
1045 ret = audiopara.render->control.Start((AudioHandle)(audiopara.render));
1046 if (ret < 0) {
1047 fclose(fp);
1048 return ret;
1049 }
1050 ret = audiopara.render->attr.ReqMmapBuffer((AudioHandle)(audiopara.render), reqSize, &desc);
1051 if (ret == 0) {
1052 munmap(desc.memoryAddress, reqSize);
1053 }
1054 (void)fclose(fp);
1055 return ret;
1056 }
RecordMapAudio(struct PrepareAudioPara & audiopara)1057 int32_t RecordMapAudio(struct PrepareAudioPara &audiopara)
1058 {
1059 int32_t ret = -1;
1060 int32_t reqSize = 0;
1061 bool isRender = false;
1062 struct AudioMmapBufferDescriptor desc = {};
1063 if (audiopara.capture == nullptr) {
1064 return HDF_FAILURE;
1065 }
1066 FILE *fp = fopen(audiopara.path, "wb+");
1067 if (fp == NULL) {
1068 return HDF_FAILURE;
1069 }
1070 ret = InitMmapDesc(fp, desc, reqSize, isRender);
1071 if (ret < 0) {
1072 fclose(fp);
1073 return HDF_FAILURE;
1074 }
1075 ret = audiopara.capture->control.Start((AudioHandle)(audiopara.capture));
1076 if (ret < 0) {
1077 fclose(fp);
1078 return ret;
1079 }
1080 ret = audiopara.capture->attr.ReqMmapBuffer((AudioHandle)(audiopara.capture), reqSize, &desc);
1081 (void)fclose(fp);
1082 if (ret == 0) {
1083 munmap(desc.memoryAddress, reqSize);
1084 }
1085 return ret;
1086 }
AudioRenderCallback(enum AudioCallbackType type,void * reserved,void * cookie)1087 int32_t AudioRenderCallback(enum AudioCallbackType type, void *reserved, void *cookie)
1088 {
1089 switch (type) {
1090 case AUDIO_NONBLOCK_WRITE_COMPLETED:
1091 g_writeCompleted = AUDIO_WRITE_COMPLETED_VALUE;
1092 return HDF_SUCCESS;
1093 case AUDIO_RENDER_FULL:
1094 g_renderFull = AUDIO_RENDER_FULL_VALUE;
1095 return HDF_SUCCESS;
1096 case AUDIO_FLUSH_COMPLETED:
1097 g_flushCompleted = AUDIO_FLUSH_COMPLETED_VALUE;
1098 return HDF_SUCCESS;
1099 case AUDIO_ERROR_OCCUR:
1100 return HDF_FAILURE;
1101 case AUDIO_DRAIN_COMPLETED:
1102 return HDF_FAILURE;
1103 default:
1104 return HDF_FAILURE;
1105 }
1106 }
CheckWriteCompleteValue()1107 int32_t CheckWriteCompleteValue()
1108 {
1109 if (g_writeCompleted == AUDIO_WRITE_COMPLETED_VALUE)
1110 return HDF_SUCCESS;
1111 else
1112 return HDF_FAILURE;
1113 }
CheckRenderFullValue()1114 int32_t CheckRenderFullValue()
1115 {
1116 if (g_renderFull == AUDIO_RENDER_FULL_VALUE)
1117 return HDF_SUCCESS;
1118 else
1119 return HDF_FAILURE;
1120 }
CheckFlushValue()1121 int32_t CheckFlushValue()
1122 {
1123 if (g_flushCompleted == AUDIO_FLUSH_COMPLETED_VALUE)
1124 return HDF_SUCCESS;
1125 else
1126 return HDF_FAILURE;
1127 }
ReleaseCaptureSource(struct AudioManager * manager,struct AudioAdapter * & adapter,struct AudioCapture * & capture)1128 int32_t ReleaseCaptureSource(struct AudioManager *manager, struct AudioAdapter *&adapter,
1129 struct AudioCapture *&capture)
1130 {
1131 if (manager == nullptr || adapter == nullptr || capture == nullptr ||
1132 adapter->DestroyCapture == nullptr || manager->UnloadAdapter == nullptr) {
1133 return HDF_FAILURE;
1134 }
1135 int32_t ret = adapter->DestroyCapture(adapter, capture);
1136 if (ret != HDF_SUCCESS) {
1137 return ret;
1138 }
1139 capture = nullptr;
1140 manager->UnloadAdapter(manager, adapter);
1141 adapter = nullptr;
1142 return HDF_SUCCESS;
1143 }
ReleaseRenderSource(struct AudioManager * manager,struct AudioAdapter * & adapter,struct AudioRender * & render)1144 int32_t ReleaseRenderSource(struct AudioManager *manager, struct AudioAdapter *&adapter,
1145 struct AudioRender *&render)
1146 {
1147 if (manager == nullptr || adapter == nullptr || render == nullptr ||
1148 adapter->DestroyRender == nullptr || manager->UnloadAdapter == nullptr) {
1149 return HDF_FAILURE;
1150 }
1151 int32_t ret = adapter->DestroyRender(adapter, render);
1152 if (ret != HDF_SUCCESS) {
1153 return ret;
1154 }
1155 render = nullptr;
1156 manager->UnloadAdapter(manager, adapter);
1157 adapter = nullptr;
1158 return HDF_SUCCESS;
1159 }
1160 }
1161 }
1162