• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }