1 /*
2  * Copyright (c) 2020-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 #include "audio_source.h"
17 #include "media_log.h"
18 #include "securec.h"
19 
20 namespace OHOS {
21 namespace Audio {
22 #define AUDIO_RETURN_VAL_IF_NULL(condition)                                            \
23     do {                                                                               \
24         if ((condition) == nullptr) {                                                  \
25             MEDIA_ERR_LOG("" #condition " is NULL");    \
26             return ERR_ILLEGAL_STATE;                                                  \
27         }                                                                              \
28     } while (0)
29 
30 using namespace OHOS::Media;
31 static AudioManager *g_audioManager = nullptr;
32 
AudioSource()33 AudioSource::AudioSource()
34     : initialized_(false),
35       started_(false),
36       audioAdapter_(nullptr),
37       audioCapture_(nullptr)
38 {
39     if (g_audioManager == nullptr) {
40         g_audioManager = GetAudioManagerFuncs();
41         MEDIA_DEBUG_LOG("g_audioManager");
42     }
43     int size = 0;
44     struct AudioAdapterDescriptor *descs = nullptr;
45     g_audioManager->GetAllAdapters(g_audioManager, &descs, &size);
46     MEDIA_DEBUG_LOG("GetAllAdapters size:%d", size);
47 
48     for (int index = 0; index < size; index++) {
49         struct AudioAdapterDescriptor *desc = &descs[index];
50         for (int port = 0; (desc != nullptr && port < static_cast<int>(desc->portNum)); port++) {
51             if ((desc->ports[port].dir != PORT_IN) ||
52                 (g_audioManager->LoadAdapter(g_audioManager, desc, &audioAdapter_))) {
53                 continue;
54             }
55             (void)audioAdapter_->InitAllPorts(audioAdapter_);
56             if (memcpy_s(&capturePort_, sizeof(struct AudioPort),
57                 &desc->ports[port], sizeof(struct AudioPort))) {
58                 MEDIA_WARNING_LOG("memcpy_s capturePort_ failed");
59             }
60             break;
61         }
62     }
63     MEDIA_DEBUG_LOG("LoadAdapter audioAdapter_");
64 }
65 
~AudioSource()66 AudioSource::~AudioSource()
67 {
68     MEDIA_DEBUG_LOG("in");
69     if (initialized_) {
70         Release();
71     }
72 
73     if (audioAdapter_ != nullptr) {
74         MEDIA_INFO_LOG("UnloadModule audioAdapter_");
75         if (g_audioManager == nullptr) {
76             MEDIA_ERR_LOG("~AudioSource g_audioManager is nullptr");
77             audioAdapter_ = nullptr;
78             return;
79         }
80         g_audioManager->UnloadAdapter(g_audioManager, audioAdapter_);
81         audioAdapter_ = nullptr;
82     }
83 }
84 
InitCheck()85 int32_t AudioSource::InitCheck()
86 {
87     if (!initialized_) {
88         MEDIA_ERR_LOG("not initialized");
89         return ERR_ILLEGAL_STATE;
90     }
91     return SUCCESS;
92 }
93 
GetMinFrameCount(int32_t sampleRate,int32_t channelCount,AudioCodecFormat audioFormat,size_t & frameCount)94 bool AudioSource::GetMinFrameCount(int32_t sampleRate, int32_t channelCount,
95                                    AudioCodecFormat audioFormat, size_t &frameCount)
96 {
97     if (sampleRate <= 0 || channelCount <= 0 || audioFormat < AUDIO_DEFAULT ||
98         audioFormat >= FORMAT_BUTT) {
99         MEDIA_ERR_LOG("invalid params sampleRate:%d channelCount:%d audioFormat:%d", sampleRate,
100                       channelCount, audioFormat);
101         return false;
102     }
103     frameCount = 0;
104     return true;
105 }
106 
GetFrameCount()107 uint64_t AudioSource::GetFrameCount()
108 {
109     int32_t ret;
110     if ((ret = InitCheck()) != SUCCESS) {
111         return ret;
112     }
113     AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
114     uint64_t frameCount = 0;
115     ret = audioCapture_->attr.GetFrameCount(reinterpret_cast<AudioHandle>(audioCapture_), &frameCount);
116     if (ret != SUCCESS) {
117         MEDIA_ERR_LOG("attr GetFrameCount failed:0x%x ", ret);
118         return ret;
119     }
120     return frameCount;
121 }
122 
EnumDeviceBySourceType(AudioSourceType inputSource,std::vector<AudioDeviceDesc> & devices)123 int32_t AudioSource::EnumDeviceBySourceType(AudioSourceType inputSource, std::vector<AudioDeviceDesc> &devices)
124 {
125     if (inputSource != AUDIO_MIC && inputSource != AUDIO_SOURCE_DEFAULT) {
126         MEDIA_ERR_LOG("AudioSource only support AUDIO_MIC");
127         return ERR_INVALID_PARAM;
128     }
129     AUDIO_RETURN_VAL_IF_NULL(audioAdapter_);
130 
131     struct AudioPortCapability capability;
132     audioAdapter_->GetPortCapability(audioAdapter_, &capturePort_, &capability);
133     AudioDeviceDesc deviceDesc;
134     deviceDesc.deviceId = capability.deviceId;
135     deviceDesc.inputSourceType = AUDIO_MIC;
136     devices.push_back(deviceDesc);
137     return SUCCESS;
138 }
139 
ConvertCodecFormatToAudioFormat(AudioCodecFormat codecFormat,AudioFormat * audioFormat)140 static bool ConvertCodecFormatToAudioFormat(AudioCodecFormat codecFormat, AudioFormat *audioFormat)
141 {
142     if (audioFormat == nullptr) {
143         MEDIA_ERR_LOG("audioFormat is NULL");
144         return false;
145     }
146 
147     switch (codecFormat) {
148         case AUDIO_DEFAULT:
149         case PCM:
150             *audioFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
151             break;
152         case AAC_LC:
153             *audioFormat = AUDIO_FORMAT_TYPE_AAC_LC;
154             break;
155         case AAC_LD:
156             *audioFormat = AUDIO_FORMAT_TYPE_AAC_LD;
157             break;
158         case AAC_ELD:
159             *audioFormat = AUDIO_FORMAT_TYPE_AAC_ELD;
160             break;
161         case AAC_HE_V1:
162             *audioFormat = AUDIO_FORMAT_TYPE_AAC_HE_V1;
163             break;
164         case AAC_HE_V2:
165             *audioFormat = AUDIO_FORMAT_TYPE_AAC_HE_V2;
166             break;
167         case G711A:
168             *audioFormat = AUDIO_FORMAT_TYPE_G711A;
169             break;
170         case G711U:
171             *audioFormat = AUDIO_FORMAT_TYPE_G711U;
172             break;
173         case G726:
174             *audioFormat = AUDIO_FORMAT_TYPE_G726;
175             break;
176         default: {
177             MEDIA_ERR_LOG("not support this codecFormat:%d", codecFormat);
178             return false;
179         }
180     }
181     return true;
182 }
183 
Initialize(const AudioSourceConfig & config)184 int32_t AudioSource::Initialize(const AudioSourceConfig &config)
185 {
186     AUDIO_RETURN_VAL_IF_NULL(audioAdapter_);
187     MEDIA_INFO_LOG("deviceId:0x%x config.sampleRate:%d", config.deviceId, config.sampleRate);
188     struct AudioDeviceDescriptor desc;
189     desc.pins = PIN_IN_MIC;
190     desc.desc = NULL;
191     struct AudioSampleAttributes attrs;
192     if (config.streamUsage == TYPE_MEDIA || config.streamUsage == TYPE_DEFAULT) {
193         attrs.type = AUDIO_IN_MEDIA;
194     } else if (config.streamUsage == TYPE_VOICE_COMMUNICATION) {
195         attrs.type = AUDIO_IN_COMMUNICATION;
196     }
197     if (config.bitWidth != BIT_WIDTH_16) {
198         MEDIA_ERR_LOG("not support bitWidth:%d, only support 16 bit width", config.bitWidth);
199         return ERR_INVALID_PARAM;
200     }
201     if (!ConvertCodecFormatToAudioFormat(config.audioFormat, &(attrs.format))) {
202         MEDIA_ERR_LOG("not support audioFormat:%d", config.audioFormat);
203         return ERR_INVALID_PARAM;
204     }
205     attrs.sampleRate = config.sampleRate;
206     attrs.channelCount = config.channelCount;
207     attrs.interleaved = config.interleaved;
208     int32_t ret = audioAdapter_->CreateCapture(audioAdapter_, &desc, &attrs, &audioCapture_);
209     if (ret != SUCCESS || audioCapture_ == nullptr) {
210         MEDIA_ERR_LOG("CreateCapture failed:0x%x", ret);
211         return ret;
212     }
213     initialized_ = true;
214     return SUCCESS;
215 }
216 
SetInputDevice(uint32_t deviceId)217 int32_t AudioSource::SetInputDevice(uint32_t deviceId)
218 {
219     (void)deviceId;
220     return SUCCESS;
221 }
222 
GetCurrentDeviceId(uint32_t & deviceId)223 int32_t AudioSource::GetCurrentDeviceId(uint32_t &deviceId)
224 {
225     AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
226     int32_t ret = audioCapture_->attr.GetCurrentChannelId(reinterpret_cast<AudioHandle>(audioCapture_), &deviceId);
227     if (ret != SUCCESS) {
228         MEDIA_ERR_LOG("GetCurrentChannelId failed:0x%x", ret);
229         return ret;
230     }
231     MEDIA_INFO_LOG("deviceId:0x%x", deviceId);
232     return SUCCESS;
233 }
234 
Start()235 int32_t AudioSource::Start()
236 {
237     int32_t ret;
238     if ((ret = InitCheck()) != SUCCESS) {
239         return ret;
240     }
241 
242     AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
243     ret = audioCapture_->control.Start(reinterpret_cast<AudioHandle>(audioCapture_));
244     if (ret != SUCCESS) {
245         MEDIA_ERR_LOG("audioCapture_ Start failed:0x%x", ret);
246         return ret;
247     }
248     started_ = true;
249     return SUCCESS;
250 }
251 
ReadFrame(AudioFrame & frame,bool isBlockingRead)252 int32_t AudioSource::ReadFrame(AudioFrame &frame, bool isBlockingRead)
253 {
254     if (!started_) {
255         MEDIA_ERR_LOG("AudioSource not Start");
256         return ERR_ILLEGAL_STATE;
257     }
258     AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
259     uint64_t readlen = ERR_INVALID_READ;
260     int32_t ret = audioCapture_->CaptureFrame(audioCapture_, frame.buffer, frame.bufferLen, &readlen);
261     if (ret != SUCCESS) {
262         MEDIA_ERR_LOG("audioCapture_::CaptureFrame failed:0x%x", ret);
263         return ERR_INVALID_READ;
264     }
265     ret = audioCapture_->GetCapturePosition(audioCapture_, &frame.frames, &frame.time);
266     if (ret != SUCCESS) {
267         MEDIA_ERR_LOG("audioCapture_::GetCapturePosition failed:0x%x", ret);
268         return ERR_INVALID_READ;
269     }
270     return readlen;
271 }
272 
Stop()273 int32_t AudioSource::Stop()
274 {
275     MEDIA_INFO_LOG("AudioSource::Stop");
276     if (!started_) {
277         MEDIA_ERR_LOG("AudioSource not Start");
278         return ERR_ILLEGAL_STATE;
279     }
280 
281     AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
282     int32_t ret = audioCapture_->control.Stop(reinterpret_cast<AudioHandle>(audioCapture_));
283     if (ret != SUCCESS) {
284         MEDIA_ERR_LOG("Stop failed:0x%x", ret);
285         return ret;
286     }
287     started_ = false;
288     return SUCCESS;
289 }
290 
Release()291 int32_t AudioSource::Release()
292 {
293     int32_t ret;
294     if ((ret = InitCheck()) != SUCCESS) {
295         return ret;
296     }
297     if (audioCapture_) {
298         audioAdapter_->DestroyCapture(audioAdapter_, audioCapture_);
299         audioCapture_ = nullptr;
300     }
301     initialized_ = false;
302     MEDIA_INFO_LOG("AudioSource Released");
303     return SUCCESS;
304 }
305 }  // namespace Audio
306 }  // namespace OHOS
307