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