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