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 HMOS {
45 namespace Audio {
InitAttrs(struct AudioSampleAttributes & attrs)46 int32_t InitAttrs(struct AudioSampleAttributes &attrs)
47 {
48 attrs.format = AUDIO_FORMAT_PCM_16_BIT;
49 attrs.channelCount = CHANNELCOUNT;
50 attrs.sampleRate = SAMPLERATE;
51 attrs.interleaved = 0;
52 attrs.type = AUDIO_IN_MEDIA;
53 attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
54 attrs.frameSize = PCM_16_BIT * CHANNELCOUNT / MOVE_LEFT_NUM;
55 attrs.isBigEndian = false;
56 attrs.isSignedData = true;
57 attrs.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (PCM_16_BIT * attrs.channelCount / MOVE_LEFT_NUM);
58 attrs.stopThreshold = INT_32_MAX;
59 attrs.silenceThreshold = BUFFER_LENTH;
60 return HDF_SUCCESS;
61 }
InitAttrsUpdate(struct AudioSampleAttributes & attrs,enum AudioFormat format,uint32_t channelCount,uint32_t sampleRate)62 int32_t InitAttrsUpdate(struct AudioSampleAttributes &attrs, enum AudioFormat format, uint32_t channelCount,
63 uint32_t sampleRate)
64 {
65 InitAttrs(attrs);
66 attrs.format = format;
67 attrs.sampleRate = sampleRate;
68 attrs.channelCount = channelCount;
69 return HDF_SUCCESS;
70 }
AudioRenderSetGetSampleAttributes(struct AudioSampleAttributes attrs,struct AudioSampleAttributes & attrsValue,struct AudioRender * render)71 int32_t AudioRenderSetGetSampleAttributes(struct AudioSampleAttributes attrs, struct AudioSampleAttributes &attrsValue,
72 struct AudioRender *render)
73 {
74 int32_t ret = -1;
75 if (render == nullptr) {
76 return AUDIO_HAL_ERR_INVALID_PARAM;
77 }
78 ret = render->attr.SetSampleAttributes(render, &attrs);
79 if (ret < 0) {
80 return ret;
81 }
82 ret = render->attr.GetSampleAttributes(render, &attrsValue);
83 if (ret < 0) {
84 return ret;
85 }
86 return AUDIO_HAL_SUCCESS;
87 }
AudioCaptureSetGetSampleAttributes(struct AudioSampleAttributes attrs,struct AudioSampleAttributes & attrsValue,struct AudioCapture * capture)88 int32_t AudioCaptureSetGetSampleAttributes(struct AudioSampleAttributes attrs, struct AudioSampleAttributes &attrsValue,
89 struct AudioCapture *capture)
90 {
91 int32_t ret = -1;
92 if (capture == nullptr) {
93 return AUDIO_HAL_ERR_INVALID_PARAM;
94 }
95 ret = capture->attr.SetSampleAttributes(capture, &attrs);
96 if (ret < 0) {
97 return ret;
98 }
99 ret = capture->attr.GetSampleAttributes(capture, &attrsValue);
100 if (ret < 0) {
101 return ret;
102 }
103 return AUDIO_HAL_SUCCESS;
104 }
StringToInt(std::string flag)105 uint32_t StringToInt(std::string flag)
106 {
107 uint32_t temp = flag[0];
108 for (int i = flag.size() - 1; i >= 0; i--) {
109 temp <<= MOVE_LEFT_NUM;
110 temp += flag[i];
111 }
112 return temp;
113 }
114
InitDevDesc(struct AudioDeviceDescriptor & devDesc,const uint32_t portId,enum AudioPortPin pins)115 int32_t InitDevDesc(struct AudioDeviceDescriptor &devDesc, const uint32_t portId, enum AudioPortPin pins)
116 {
117 devDesc.portId = portId;
118 devDesc.pins = pins;
119 devDesc.desc = nullptr;
120 return HDF_SUCCESS;
121 }
122
SwitchAdapter(struct AudioAdapterDescriptor * descs,const std::string & adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort * & audioPort,int size)123 int32_t SwitchAdapter(struct AudioAdapterDescriptor *descs, const std::string &adapterNameCase,
124 enum AudioPortDirection portFlag, struct AudioPort *&audioPort, int size)
125 {
126 if (descs == nullptr || size > ADAPTER_COUNT) {
127 return HDF_FAILURE;
128 }
129
130 for (int index = 0; index < size; index++) {
131 struct AudioAdapterDescriptor *desc = &descs[index];
132 if (desc == nullptr || desc->adapterName == nullptr) {
133 continue;
134 }
135 if (strcmp(desc->adapterName, adapterNameCase.c_str())) {
136 continue;
137 }
138 for (uint32_t port = 0; port < desc->portNum; port++) {
139 if (desc->ports[port].dir == portFlag) {
140 audioPort = &desc->ports[port];
141 return index;
142 }
143 }
144 }
145 return HDF_FAILURE;
146 }
147
PcmFormatToBits(enum AudioFormat format)148 uint32_t PcmFormatToBits(enum AudioFormat format)
149 {
150 switch (format) {
151 case AUDIO_FORMAT_PCM_8_BIT:
152 return PCM_8_BIT;
153 case AUDIO_FORMAT_PCM_16_BIT:
154 return PCM_16_BIT;
155 case AUDIO_FORMAT_PCM_24_BIT:
156 return PCM_24_BIT;
157 case AUDIO_FORMAT_PCM_32_BIT:
158 return PCM_32_BIT;
159 default:
160 return PCM_16_BIT;
161 };
162 }
163
PcmFramesToBytes(const struct AudioSampleAttributes attrs)164 uint32_t PcmFramesToBytes(const struct AudioSampleAttributes attrs)
165 {
166 if (attrs.channelCount < 1 || attrs.channelCount > 2) {
167 return 0;
168 }
169 uint32_t formatBits = PcmFormatToBits(attrs.format);
170 if (formatBits < PCM_8_BIT || formatBits > PCM_32_BIT) {
171 return 0;
172 }
173 uint32_t ret = FRAME_SIZE * (attrs.channelCount) * (formatBits >> MOVE_RIGHT_NUM);
174 return ret;
175 }
176
WavHeadAnalysis(struct AudioHeadInfo & wavHeadInfo,FILE * file,struct AudioSampleAttributes & attrs)177 int32_t WavHeadAnalysis(struct AudioHeadInfo &wavHeadInfo, FILE *file, struct AudioSampleAttributes &attrs)
178 {
179 size_t ret = 0;
180 if (file == nullptr) {
181 return HDF_FAILURE;
182 }
183 ret = fread(&wavHeadInfo, sizeof(wavHeadInfo), 1, file);
184 if (ret != 1) {
185 return HDF_FAILURE;
186 }
187 uint32_t audioRiffId = StringToInt(AUDIO_RIFF);
188 uint32_t audioFileFmt = StringToInt(AUDIO_WAVE);
189 uint32_t audioDataId = StringToInt(AUDIO_DATA);
190 if (wavHeadInfo.testFileRiffId != audioRiffId || wavHeadInfo.testFileFmt != audioFileFmt ||
191 wavHeadInfo.dataId != audioDataId) {
192 return HDF_FAILURE;
193 }
194 attrs.channelCount = wavHeadInfo.audioChannelNum;
195 attrs.sampleRate = wavHeadInfo.audioSampleRate;
196 switch (wavHeadInfo.audioBitsPerSample) {
197 case PCM_8_BIT: {
198 attrs.format = AUDIO_FORMAT_PCM_8_BIT;
199 break;
200 }
201 case PCM_16_BIT: {
202 attrs.format = AUDIO_FORMAT_PCM_16_BIT;
203 break;
204 }
205 case PCM_24_BIT: {
206 attrs.format = AUDIO_FORMAT_PCM_24_BIT;
207 break;
208 }
209 case PCM_32_BIT: {
210 attrs.format = AUDIO_FORMAT_PCM_32_BIT;
211 break;
212 }
213 default:
214 return HDF_FAILURE;
215 }
216 return HDF_SUCCESS;
217 }
GetAdapters(TestAudioManager * manager,struct AudioAdapterDescriptor ** descs,int & size)218 int32_t GetAdapters(TestAudioManager *manager, struct AudioAdapterDescriptor **descs, int &size)
219 {
220 int32_t ret = -1;
221 if (descs == nullptr) {
222 return AUDIO_HAL_ERR_INVALID_PARAM;
223 }
224 ret = manager->GetAllAdapters(manager, descs, &size);
225 if (ret < 0) {
226 return ret;
227 }
228 if (*descs == nullptr) {
229 return AUDIO_HAL_ERR_INTERNAL;
230 }
231 return AUDIO_HAL_SUCCESS;
232 }
233
GetLoadAdapter(TestAudioManager * manager,enum AudioPortDirection portType,const std::string & adapterName,struct AudioAdapter ** adapter,struct AudioPort * & audioPort)234 int32_t GetLoadAdapter(TestAudioManager *manager, enum AudioPortDirection portType,
235 const std::string &adapterName, struct AudioAdapter **adapter, struct AudioPort *&audioPort)
236 {
237 int32_t ret = -1;
238 int size = 0;
239 struct AudioAdapterDescriptor *desc = nullptr;
240 struct AudioAdapterDescriptor *descs = nullptr;
241 if (adapter == nullptr) {
242 return AUDIO_HAL_ERR_INVALID_PARAM;
243 }
244 ret = GetAdapters(manager, &descs, size);
245 if (ret < 0) {
246 return ret;
247 }
248 if (descs == nullptr) {
249 return AUDIO_HAL_ERR_INTERNAL;
250 }
251
252 int index = SwitchAdapter(descs, adapterName, portType, audioPort, size);
253 if (index < 0) {
254 return AUDIO_HAL_ERR_INTERNAL;
255 }
256 desc = &descs[index];
257 if (desc == nullptr) {
258 return AUDIO_HAL_ERR_INVALID_PARAM;
259 }
260 ret = manager->LoadAdapter(manager, desc, adapter);
261 if (ret < 0) {
262 return ret;
263 }
264 if (*adapter == nullptr) {
265 return AUDIO_HAL_ERR_INTERNAL;
266 }
267 return AUDIO_HAL_SUCCESS;
268 }
269
AudioCreateRender(TestAudioManager * manager,enum AudioPortPin pins,const std::string & adapterName,struct AudioAdapter ** adapter,struct AudioRender ** render)270 int32_t AudioCreateRender(TestAudioManager *manager, enum AudioPortPin pins, const std::string &adapterName,
271 struct AudioAdapter **adapter, struct AudioRender **render)
272 {
273 int32_t ret = -1;
274 struct AudioSampleAttributes attrs = {};
275 struct AudioDeviceDescriptor devDesc = {};
276 struct AudioPort *renderPort = nullptr;
277 if (adapter == nullptr || render == nullptr) {
278 return AUDIO_HAL_ERR_INVALID_PARAM;
279 }
280 ret = GetLoadAdapter(manager, PORT_OUT, adapterName, adapter, renderPort);
281 if (ret < 0) {
282 return ret;
283 }
284 if (*adapter == nullptr || (*adapter)->CreateRender == nullptr) {
285 return AUDIO_HAL_ERR_INTERNAL;
286 }
287 InitAttrs(attrs);
288 InitDevDesc(devDesc, renderPort->portId, pins);
289 ret = (*adapter)->CreateRender(*adapter, &devDesc, &attrs, render);
290 if (ret < 0) {
291 manager->UnloadAdapter(manager, *adapter);
292 return ret;
293 }
294 if (*render == nullptr) {
295 manager->UnloadAdapter(manager, *adapter);
296 return AUDIO_HAL_ERR_INTERNAL;
297 }
298 return AUDIO_HAL_SUCCESS;
299 }
300
AudioCreateStartRender(TestAudioManager * manager,struct AudioRender ** render,struct AudioAdapter ** adapter,const std::string & adapterName)301 int32_t AudioCreateStartRender(TestAudioManager *manager, struct AudioRender **render, struct AudioAdapter **adapter,
302 const std::string &adapterName)
303 {
304 int32_t ret = -1;
305 enum AudioPortPin pins = PIN_OUT_SPEAKER;
306
307 if (adapter == nullptr || render == nullptr) {
308 return AUDIO_HAL_ERR_INVALID_PARAM;
309 }
310 ret = AudioCreateRender(manager, pins, adapterName, adapter, render);
311 if (ret < 0) {
312 return ret;
313 }
314 if (*render == nullptr || *adapter == nullptr) {
315 return AUDIO_HAL_ERR_INTERNAL;
316 }
317 ret = AudioRenderStartAndOneFrame(*render);
318 if (ret < 0) {
319 (*adapter)->DestroyRender(*adapter, *render);
320 manager->UnloadAdapter(manager, *adapter);
321 return ret;
322 }
323 return AUDIO_HAL_SUCCESS;
324 }
325
AudioRenderStartAndOneFrame(struct AudioRender * render)326 int32_t AudioRenderStartAndOneFrame(struct AudioRender *render)
327 {
328 int32_t ret = -1;
329 char *frame = nullptr;
330 uint64_t numRead = 0;
331 uint64_t replyBytes = 0;
332 if (render == nullptr || render->control.Start == nullptr || render->RenderFrame == nullptr) {
333 return AUDIO_HAL_ERR_INVALID_PARAM;
334 }
335 ret = render->control.Start((AudioHandle)render);
336 if (ret) {
337 return ret;
338 }
339 ret = RenderFramePrepare(AUDIO_FILE, frame, numRead);
340 if (ret < 0) {
341 if (frame != nullptr) {
342 free(frame);
343 frame = nullptr;
344 }
345 return HDF_FAILURE;
346 }
347 ret = render->RenderFrame(render, frame, numRead, &replyBytes);
348 if (ret < 0) {
349 if (frame != nullptr) {
350 free(frame);
351 frame = nullptr;
352 }
353 return ret;
354 }
355 free(frame);
356 frame = nullptr;
357 return AUDIO_HAL_SUCCESS;
358 }
359
AudioCreateCapture(TestAudioManager * manager,enum AudioPortPin pins,const std::string & adapterName,struct AudioAdapter ** adapter,struct AudioCapture ** capture)360 int32_t AudioCreateCapture(TestAudioManager *manager, enum AudioPortPin pins, const std::string &adapterName,
361 struct AudioAdapter **adapter, struct AudioCapture **capture)
362 {
363 int32_t ret = -1;
364 struct AudioSampleAttributes attrs = {};
365 struct AudioDeviceDescriptor devDesc = {};
366 struct AudioPort *capturePort = nullptr;
367 if (adapter == nullptr || capture == nullptr) {
368 return AUDIO_HAL_ERR_INVALID_PARAM;
369 }
370 ret = GetLoadAdapter(manager, PORT_IN, adapterName, adapter, capturePort);
371 if (ret < 0) {
372 return ret;
373 }
374 if (*adapter == nullptr || (*adapter)->CreateCapture == nullptr) {
375 return AUDIO_HAL_ERR_INTERNAL;
376 }
377 InitAttrs(attrs);
378 InitDevDesc(devDesc, capturePort->portId, pins);
379 ret = (*adapter)->CreateCapture(*adapter, &devDesc, &attrs, capture);
380 if (ret < 0) {
381 manager->UnloadAdapter(manager, *adapter);
382 return ret;
383 }
384 if (*capture == nullptr) {
385 manager->UnloadAdapter(manager, *adapter);
386 return AUDIO_HAL_ERR_INTERNAL;
387 }
388 return AUDIO_HAL_SUCCESS;
389 }
390
AudioCreateStartCapture(TestAudioManager * manager,struct AudioCapture ** capture,struct AudioAdapter ** adapter,const std::string & adapterName)391 int32_t AudioCreateStartCapture(TestAudioManager *manager, struct AudioCapture **capture,
392 struct AudioAdapter **adapter, const std::string &adapterName)
393 {
394 int32_t ret = -1;
395 struct AudioSampleAttributes attrs = {};
396 enum AudioPortPin pins = PIN_IN_MIC;
397 if (adapter == nullptr || capture == nullptr) {
398 return AUDIO_HAL_ERR_INVALID_PARAM;
399 }
400 ret = AudioCreateCapture(manager, pins, adapterName, adapter, capture);
401 if (ret < 0) {
402 manager->UnloadAdapter(manager, *adapter);
403 return ret;
404 }
405 if (*capture == nullptr || *adapter == nullptr) {
406 manager->UnloadAdapter(manager, *adapter);
407 return AUDIO_HAL_ERR_INTERNAL;
408 }
409 FILE *file = fopen(AUDIO_CAPTURE_FILE.c_str(), "wb+");
410 if (file == nullptr) {
411 (*adapter)->DestroyCapture(*adapter, *capture);
412 manager->UnloadAdapter(manager, *adapter);
413 return HDF_FAILURE;
414 }
415 InitAttrs(attrs);
416 ret = FrameStartCapture((*capture), file, attrs);
417 if (ret < 0) {
418 (*adapter)->DestroyCapture(*adapter, *capture);
419 manager->UnloadAdapter(manager, *adapter);
420 (void)fclose(file);
421 return ret;
422 }
423 (void)fclose(file);
424 return AUDIO_HAL_SUCCESS;
425 }
426
AudioCaptureStartAndOneFrame(struct AudioCapture * capture)427 int32_t AudioCaptureStartAndOneFrame(struct AudioCapture *capture)
428 {
429 int32_t ret = -1;
430 struct AudioSampleAttributes attrs = {};
431 InitAttrs(attrs);
432 FILE *file = fopen(AUDIO_CAPTURE_FILE.c_str(), "wb+");
433 if (file == nullptr) {
434 return HDF_FAILURE;
435 }
436 ret = FrameStartCapture(capture, file, attrs);
437 if (ret < 0) {
438 (void)fclose(file);
439 return ret;
440 }
441 (void)fclose(file);
442 return AUDIO_HAL_SUCCESS;
443 }
444
FrameStart(struct AudioHeadInfo wavHeadInfo,struct AudioRender * render,FILE * file,struct AudioSampleAttributes attrs)445 int32_t FrameStart(struct AudioHeadInfo wavHeadInfo, struct AudioRender *render, FILE *file,
446 struct AudioSampleAttributes attrs)
447 {
448 uint32_t readSize = 0;
449 size_t numRead = 0;
450 uint64_t replyBytes = 0;
451 int32_t tryNumFrame = 0;
452 if (render == nullptr || render->control.Start == nullptr || render->RenderFrame == nullptr || file == nullptr) {
453 return AUDIO_HAL_ERR_INVALID_PARAM;
454 }
455 int32_t ret = render->control.Start((AudioHandle)render);
456 if (ret) {
457 return ret;
458 }
459 uint32_t remainingDataSize = wavHeadInfo.dataSize;
460 uint32_t bufferSize = PcmFramesToBytes(attrs);
461 if (bufferSize <= 0) {
462 return HDF_FAILURE;
463 }
464 char *frame = nullptr;
465 frame = (char *)calloc(1, bufferSize);
466 if (frame == nullptr) {
467 return HDF_ERR_MALLOC_FAIL;
468 }
469 do {
470 if (g_frameStatus) {
471 readSize = (remainingDataSize) > (bufferSize) ? (bufferSize) : (remainingDataSize);
472 numRead = fread(frame, readSize, 1, file);
473 if (numRead > 0) {
474 ret = render->RenderFrame(render, frame, readSize, &replyBytes);
475 if (ret < 0) {
476 if (ret == -1) {
477 if (tryNumFrame > TRY_NUM_FRAME) {
478 free(frame);
479 return ret;
480 }
481 tryNumFrame++;
482 continue;
483 }
484 free(frame);
485 return ret;
486 }
487 tryNumFrame = 0;
488 }
489 remainingDataSize -= readSize;
490 }
491 } while (readSize > 0 && remainingDataSize > 0);
492 free(frame);
493 return AUDIO_HAL_SUCCESS;
494 }
495
FrameStartCapture(struct AudioCapture * capture,FILE * file,const struct AudioSampleAttributes attrs)496 int32_t FrameStartCapture(struct AudioCapture *capture, FILE *file, const struct AudioSampleAttributes attrs)
497 {
498 int32_t ret = 0;
499 uint32_t bufferSize = 0;
500 uint64_t replyBytes = 0;
501 uint64_t requestBytes = 0;
502 if (capture == nullptr || capture->control.Start == nullptr || capture->CaptureFrame == nullptr) {
503 return AUDIO_HAL_ERR_INVALID_PARAM;
504 }
505 ret = capture->control.Start((AudioHandle)capture);
506 if (ret < 0) {
507 return ret;
508 }
509 uint32_t pcmBytes = PcmFramesToBytes(attrs);
510 if (pcmBytes < 1024 || pcmBytes > 8192) {
511 return HDF_FAILURE;
512 }
513 bufferSize = FRAME_COUNT * pcmBytes;
514 if (bufferSize <= 0) {
515 return HDF_FAILURE;
516 }
517 char *frame = nullptr;
518 frame = (char *)calloc(1, bufferSize);
519 if (frame == nullptr) {
520 return HDF_ERR_MALLOC_FAIL;
521 }
522 requestBytes = bufferSize;
523 ret = capture->CaptureFrame(capture, frame, requestBytes, &replyBytes);
524 if (ret < 0) {
525 ret = capture->CaptureFrame(capture, frame, requestBytes, &replyBytes);
526 if (ret < 0) {
527 free(frame);
528 return ret;
529 }
530 }
531 uint32_t requestByte = static_cast<uint32_t>(replyBytes);
532 (void)fwrite(frame, requestByte, 1, file);
533 free(frame);
534 return AUDIO_HAL_SUCCESS;
535 }
536
RenderFramePrepare(const std::string & path,char * & frame,uint64_t & readSize)537 int32_t RenderFramePrepare(const std::string &path, char *&frame, uint64_t &readSize)
538 {
539 int32_t ret = -1;
540 size_t numRead = 0;
541 uint32_t bufferSize = 4096;
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 (void)fclose(file);
557 return HDF_FAILURE;
558 }
559 frame = (char *)calloc(1, bufferSize);
560 if (frame == nullptr) {
561 (void)fclose(file);
562 return HDF_ERR_MALLOC_FAIL;
563 }
564 remainingDataSize = headInfo.dataSize;
565 readSize = (remainingDataSize) > (bufferSize) ? (bufferSize) : (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 (void)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 if (audiopara.adapter != nullptr) {
793 audiopara.adapter->DestroyCapture(audiopara.adapter, audiopara.capture);
794 }
795 audiopara.capture = nullptr;
796 }
797 if (audiopara.render != nullptr) {
798 ret = audiopara.render->control.Stop((AudioHandle)(audiopara.render));
799 if (ret < 0) {
800 audiopara.adapter->DestroyRender(audiopara.adapter, audiopara.render);
801 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
802 audiopara.render = nullptr;
803 audiopara.adapter = nullptr;
804 return ret;
805 }
806 audiopara.adapter->DestroyRender(audiopara.adapter, audiopara.render);
807 audiopara.render = nullptr;
808 }
809 if (audiopara.manager != nullptr && audiopara.adapter != nullptr) {
810 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
811 audiopara.adapter = nullptr;
812 }
813 return AUDIO_HAL_SUCCESS;
814 }
815
ThreadRelease(struct PrepareAudioPara & audiopara)816 int32_t ThreadRelease(struct PrepareAudioPara &audiopara)
817 {
818 int32_t ret = -1;
819 pthread_join(audiopara.tids, &audiopara.result);
820 ret = (intptr_t)audiopara.result;
821 if (ret < 0) {
822 StopAudio(audiopara);
823 return ret;
824 }
825 ret = StopAudio(audiopara);
826 if (ret < 0) {
827 return ret;
828 }
829 return AUDIO_HAL_SUCCESS;
830 }
PlayAudioFile(struct PrepareAudioPara & audiopara)831 int32_t PlayAudioFile(struct PrepareAudioPara &audiopara)
832 {
833 int32_t ret = -1;
834 char absPath[PATH_MAX] = {0};
835 if (realpath(audiopara.path, absPath) == nullptr) {
836 return HDF_FAILURE;
837 }
838 if (audiopara.manager == nullptr) {
839 return AUDIO_HAL_ERR_INVALID_PARAM;
840 }
841 FILE *file = fopen(absPath, "rb");
842 if (file == nullptr) {
843 return HDF_FAILURE;
844 }
845 if (WavHeadAnalysis(audiopara.headInfo, file, audiopara.attrs) < 0) {
846 (void)fclose(file);
847 return HDF_FAILURE;
848 }
849 ret = AudioCreateRender(audiopara.manager, audiopara.pins, audiopara.adapterName, &audiopara.adapter,
850 &audiopara.render);
851 if (ret < 0) {
852 (void)fclose(file);
853 return ret;
854 }
855 if (audiopara.render == nullptr) {
856 (void)fclose(file);
857 return AUDIO_HAL_ERR_INVALID_PARAM;
858 }
859 ret = FrameStart(audiopara.headInfo, audiopara.render, file, audiopara.attrs);
860 if (ret == AUDIO_HAL_SUCCESS) {
861 (void)fclose(file);
862 } else {
863 audiopara.adapter->DestroyRender(audiopara.adapter, audiopara.render);
864 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
865 audiopara.render = nullptr;
866 audiopara.adapter = nullptr;
867 (void)fclose(file);
868 return ret;
869 }
870 return AUDIO_HAL_SUCCESS;
871 }
872
RecordAudio(struct PrepareAudioPara & audiopara)873 int32_t RecordAudio(struct PrepareAudioPara &audiopara)
874 {
875 int32_t ret = -1;
876 if (audiopara.manager == nullptr) {
877 return AUDIO_HAL_ERR_INVALID_PARAM;
878 }
879 ret = AudioCreateCapture(audiopara.manager, audiopara.pins, audiopara.adapterName, &audiopara.adapter,
880 &audiopara.capture);
881 if (ret < 0) {
882 return ret;
883 }
884 if (audiopara.capture == nullptr) {
885 return AUDIO_HAL_ERR_INVALID_PARAM;
886 }
887
888 bool isMute = false;
889 ret = audiopara.capture->volume.SetMute(audiopara.capture, isMute);
890 if (ret < 0) {
891 audiopara.adapter->DestroyCapture(audiopara.adapter, audiopara.capture);
892 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
893 return ret;
894 }
895
896 FILE *file = fopen(audiopara.path, "wb+");
897 if (file == nullptr) {
898 audiopara.adapter->DestroyCapture(audiopara.adapter, audiopara.capture);
899 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
900 return AUDIO_HAL_ERR_INTERNAL;
901 }
902 ret = StartRecord(audiopara.capture, file, audiopara.fileSize);
903 if (ret < 0) {
904 audiopara.adapter->DestroyCapture(audiopara.adapter, audiopara.capture);
905 audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter);
906 audiopara.capture = nullptr;
907 audiopara.adapter = nullptr;
908 (void)fclose(file);
909 return ret;
910 }
911 (void)fclose(file);
912 return AUDIO_HAL_SUCCESS;
913 }
InitMmapDesc(FILE * fp,struct AudioMmapBufferDescripter & desc,int32_t & reqSize,bool flag)914 int32_t InitMmapDesc(FILE *fp, struct AudioMmapBufferDescripter &desc, int32_t &reqSize, bool flag)
915 {
916 if (fp == NULL) {
917 return HDF_FAILURE;
918 }
919 int fd = fileno(fp);
920 if (fd == -1) {
921 return HDF_FAILURE;
922 }
923 if (flag) {
924 struct AudioHeadInfo wavHeadInfo = {};
925 fseek(fp, 0, SEEK_END);
926 reqSize = ftell(fp);
927 desc.offset = sizeof(wavHeadInfo);
928 } else {
929 reqSize = FILE_CAPTURE_SIZE;
930 ftruncate(fd, FILE_CAPTURE_SIZE);
931 desc.offset = 0;
932 }
933 desc.memoryFd = fd;
934 desc.isShareable = 1;
935 desc.transferFrameSize = DEEP_BUFFER_RENDER_PERIOD_SIZE / FRAME_COUNT;
936 return HDF_SUCCESS;
937 }
938
PlayMapAudioFile(struct PrepareAudioPara & audiopara)939 int32_t PlayMapAudioFile(struct PrepareAudioPara &audiopara)
940 {
941 int32_t ret = -1;
942 int32_t reqSize = 0;
943 bool isRender = true;
944 FrameStatus(1);
945 struct AudioMmapBufferDescripter desc = {};
946 if (audiopara.render == nullptr) {
947 return HDF_FAILURE;
948 }
949 char absPath[PATH_MAX] = {0};
950 if (realpath(audiopara.path, absPath) == nullptr) {
951 return HDF_FAILURE;
952 }
953 FILE *fp = fopen(absPath, "rb+");
954 if (fp == nullptr) {
955 return HDF_FAILURE;
956 }
957 ret = InitMmapDesc(fp, desc, reqSize, isRender);
958 if (ret < 0) {
959 (void)fclose(fp);
960 return HDF_FAILURE;
961 }
962 ret = audiopara.render->control.Start((AudioHandle)(audiopara.render));
963 if (ret < 0) {
964 (void)fclose(fp);
965 return ret;
966 }
967 ret = audiopara.render->attr.ReqMmapBuffer((AudioHandle)(audiopara.render), reqSize, &desc);
968 if (ret == 0) {
969 munmap(desc.memoryAddress, reqSize);
970 }
971 (void)fclose(fp);
972 return ret;
973 }
RecordMapAudio(struct PrepareAudioPara & audiopara)974 int32_t RecordMapAudio(struct PrepareAudioPara &audiopara)
975 {
976 int32_t ret = -1;
977 int32_t reqSize = 0;
978 bool isRender = false;
979 struct AudioMmapBufferDescripter desc = {};
980 if (audiopara.capture == nullptr) {
981 return HDF_FAILURE;
982 }
983 FILE *fp = fopen(audiopara.path, "wb+");
984 if (fp == NULL) {
985 return HDF_FAILURE;
986 }
987 ret = InitMmapDesc(fp, desc, reqSize, isRender);
988 if (ret < 0) {
989 (void)fclose(fp);
990 return HDF_FAILURE;
991 }
992 ret = audiopara.capture->control.Start((AudioHandle)(audiopara.capture));
993 if (ret < 0) {
994 (void)fclose(fp);
995 return ret;
996 }
997 ret = audiopara.capture->attr.ReqMmapBuffer((AudioHandle)(audiopara.capture), reqSize, &desc);
998 (void)fclose(fp);
999 if (ret == 0) {
1000 munmap(desc.memoryAddress, reqSize);
1001 }
1002 return ret;
1003 }
AudioRenderCallback(enum AudioCallbackType type,void * reserved,void * cookie)1004 int32_t AudioRenderCallback(enum AudioCallbackType type, void *reserved, void *cookie)
1005 {
1006 switch (type) {
1007 case AUDIO_NONBLOCK_WRITE_COMPELETED:
1008 g_writeCompleted = AUDIO_WRITE_COMPELETED_VALUE;
1009 return HDF_SUCCESS;
1010 case AUDIO_RENDER_FULL:
1011 g_renderFull = AUDIO_RENDER_FULL_VALUE;
1012 return HDF_SUCCESS;
1013 case AUDIO_FLUSH_COMPLETED:
1014 g_flushCompleted = AUDIO_FLUSH_COMPLETED_VALUE;
1015 return HDF_SUCCESS;
1016 case AUDIO_ERROR_OCCUR:
1017 return HDF_FAILURE;
1018 case AUDIO_DRAIN_COMPELETED:
1019 return HDF_FAILURE;
1020 default:
1021 return HDF_FAILURE;
1022 }
1023 }
CheckWriteCompleteValue()1024 int32_t CheckWriteCompleteValue()
1025 {
1026 if (g_writeCompleted == AUDIO_WRITE_COMPELETED_VALUE)
1027 return HDF_SUCCESS;
1028 else
1029 return HDF_FAILURE;
1030 }
CheckRenderFullValue()1031 int32_t CheckRenderFullValue()
1032 {
1033 if (g_renderFull == AUDIO_RENDER_FULL_VALUE)
1034 return HDF_SUCCESS;
1035 else
1036 return HDF_FAILURE;
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 }