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