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