1 /*
2 * Copyright (c) 2024-2025 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 #include "multimedia_audio_capturer_impl.h"
16 #include "cj_lambda.h"
17 #include "audio_capturer_log.h"
18 #include "multimedia_audio_common.h"
19 #include "multimedia_audio_error.h"
20 #include "timestamp.h"
21
22 namespace OHOS {
23 namespace AudioStandard {
24 extern "C" {
MMAAudioCapturerImpl()25 MMAAudioCapturerImpl::MMAAudioCapturerImpl()
26 {
27 capturerReadDataCb_ = std::make_shared<CjAudioCapturerReadCallback>();
28 }
29
CreateAudioCapturer(CAudioCapturerOptions options)30 int32_t MMAAudioCapturerImpl::CreateAudioCapturer(CAudioCapturerOptions options)
31 {
32 AudioCapturerOptions capturerOptions{};
33 Convert2AudioCapturerOptions(capturerOptions, options);
34 audioCapturer_ = AudioCapturer::CreateCapturer(capturerOptions);
35 if (audioCapturer_ == nullptr) {
36 AUDIO_ERR_LOG("Create AudioCapturer failed.");
37 return ERR_INVALID_INSTANCE_CODE;
38 }
39 if (callback_ == nullptr) {
40 callback_ = std::make_shared<CjAudioCapturerCallback>();
41 int ret = audioCapturer_->SetCapturerCallback(callback_);
42 if (ret != SUCCESS_CODE) {
43 AUDIO_ERR_LOG("SetCapturerCallback failed.");
44 return CJ_ERR_SYSTEM;
45 }
46 }
47 return SUCCESS_CODE;
48 }
49
~MMAAudioCapturerImpl()50 MMAAudioCapturerImpl::~MMAAudioCapturerImpl()
51 {
52 if (audioCapturer_ != nullptr) {
53 audioCapturer_.reset();
54 }
55 }
56
GetState()57 int32_t MMAAudioCapturerImpl::GetState()
58 {
59 if (audioCapturer_ == nullptr) {
60 return CJ_ERR_INVALID_RETURN_VALUE;
61 }
62 return audioCapturer_->GetStatus();
63 }
64
GetStreamId(int32_t * errorCode)65 uint32_t MMAAudioCapturerImpl::GetStreamId(int32_t *errorCode)
66 {
67 uint32_t id = 0;
68 if (audioCapturer_ == nullptr) {
69 *errorCode = CJ_ERR_SYSTEM;
70 return CJ_ERR_INVALID_RETURN_VALUE;
71 }
72 int32_t ret = audioCapturer_->GetAudioStreamId(id);
73 if (ret != SUCCESS_CODE) {
74 AUDIO_ERR_LOG("Get streamId failed.");
75 *errorCode = CJ_ERR_INVALID_VALUE;
76 }
77 return id;
78 }
79
GetAudioTime(int32_t * errorCode)80 int64_t MMAAudioCapturerImpl::GetAudioTime(int32_t *errorCode)
81 {
82 Timestamp timestamp{};
83 if (audioCapturer_ == nullptr) {
84 *errorCode = CJ_ERR_SYSTEM;
85 return CJ_ERR_INVALID_RETURN_VALUE;
86 }
87 bool ret = audioCapturer_->GetAudioTime(timestamp, Timestamp::Timestampbase::MONOTONIC);
88 if (!ret) {
89 AUDIO_ERR_LOG("Get audioTime failed.");
90 *errorCode = CJ_ERR_INVALID_VALUE;
91 return CJ_ERR_INVALID_RETURN_VALUE;
92 }
93 const uint64_t secToNanosecond = 1000000000;
94 uint64_t time =
95 static_cast<uint64_t>(timestamp.time.tv_nsec) + static_cast<uint64_t>(timestamp.time.tv_sec) * secToNanosecond;
96 return static_cast<int64_t>(time);
97 }
98
GetBufferSize(int32_t * errorCode)99 uint32_t MMAAudioCapturerImpl::GetBufferSize(int32_t *errorCode)
100 {
101 size_t bufferSize = 0;
102 if (audioCapturer_ == nullptr) {
103 *errorCode = CJ_ERR_SYSTEM;
104 return CJ_ERR_INVALID_RETURN_VALUE;
105 }
106 int32_t ret = audioCapturer_->GetBufferSize(bufferSize);
107 if (ret != SUCCESS_CODE) {
108 AUDIO_ERR_LOG("Get bufferSize failed.");
109 *errorCode = CJ_ERR_INVALID_VALUE;
110 return CJ_ERR_INVALID_RETURN_VALUE;
111 }
112 return bufferSize;
113 }
114
GetOverflowCount()115 uint32_t MMAAudioCapturerImpl::GetOverflowCount()
116 {
117 if (audioCapturer_ == nullptr) {
118 return CJ_ERR_INVALID_RETURN_VALUE;
119 }
120 return audioCapturer_->GetOverflowCount();
121 }
122
Start()123 int32_t MMAAudioCapturerImpl::Start()
124 {
125 if (audioCapturer_ == nullptr) {
126 return CJ_ERR_SYSTEM;
127 }
128 bool isSuccess = audioCapturer_->Start();
129 if (!isSuccess) {
130 AUDIO_ERR_LOG("AudioCapturer start failed.");
131 return CJ_ERR_SYSTEM;
132 }
133 return SUCCESS_CODE;
134 }
135
Stop()136 int32_t MMAAudioCapturerImpl::Stop()
137 {
138 if (audioCapturer_ == nullptr) {
139 return CJ_ERR_SYSTEM;
140 }
141 bool isSuccess = audioCapturer_->Stop();
142 if (!isSuccess) {
143 AUDIO_ERR_LOG("AudioCapturer stop failed.");
144 return CJ_ERR_SYSTEM;
145 }
146 return SUCCESS_CODE;
147 }
148
Release()149 int32_t MMAAudioCapturerImpl::Release()
150 {
151 if (audioCapturer_ == nullptr) {
152 return CJ_ERR_SYSTEM;
153 }
154 bool isSuccess = audioCapturer_->Release();
155 if (!isSuccess) {
156 AUDIO_ERR_LOG("AudioCapturer Release failed.");
157 return CJ_ERR_SYSTEM;
158 }
159 return SUCCESS_CODE;
160 }
161
GetCurrentCapturerInfo(int32_t * errorCode)162 CAudioCapturerInfo MMAAudioCapturerImpl::GetCurrentCapturerInfo(int32_t *errorCode)
163 {
164 AudioCapturerInfo capturerInfo{};
165 if (audioCapturer_ == nullptr) {
166 *errorCode = CJ_ERR_SYSTEM;
167 return CAudioCapturerInfo();
168 }
169 int32_t ret = audioCapturer_->GetCapturerInfo(capturerInfo);
170 if (ret != SUCCESS_CODE) {
171 AUDIO_ERR_LOG("GetCapturerInfo failure!");
172 *errorCode = CJ_ERR_SYSTEM;
173 return CAudioCapturerInfo();
174 }
175 CAudioCapturerInfo cInfo{};
176 Convert2CAudioCapturerInfo(cInfo, capturerInfo);
177 return cInfo;
178 }
179
GetStreamInfo(int32_t * errorCode)180 CAudioStreamInfo MMAAudioCapturerImpl::GetStreamInfo(int32_t *errorCode)
181 {
182 AudioStreamInfo streamInfo{};
183 if (audioCapturer_ == nullptr) {
184 *errorCode = CJ_ERR_SYSTEM;
185 return CAudioStreamInfo();
186 }
187 int32_t ret = audioCapturer_->GetStreamInfo(streamInfo);
188 if (ret != SUCCESS_CODE) {
189 AUDIO_ERR_LOG("GetStreamInfo failure!");
190 *errorCode = CJ_ERR_SYSTEM;
191 return CAudioStreamInfo();
192 }
193 CAudioStreamInfo cInfo{};
194 Convert2CAudioStreamInfo(cInfo, streamInfo);
195 return cInfo;
196 }
197
GetAudioCapturerChangeInfo(int32_t * errorCode)198 CAudioCapturerChangeInfo MMAAudioCapturerImpl::GetAudioCapturerChangeInfo(int32_t *errorCode)
199 {
200 AudioCapturerChangeInfo changeInfo{};
201 if (audioCapturer_ == nullptr) {
202 *errorCode = CJ_ERR_SYSTEM;
203 return CAudioCapturerChangeInfo();
204 }
205 int32_t ret = audioCapturer_->GetCurrentCapturerChangeInfo(changeInfo);
206 if (ret != SUCCESS_CODE) {
207 AUDIO_ERR_LOG("GetAudioCapturerChangeInfo failure!");
208 *errorCode = CJ_ERR_SYSTEM;
209 return CAudioCapturerChangeInfo();
210 }
211 CAudioCapturerChangeInfo cInfo{};
212 Convert2CAudioCapturerChangeInfo(cInfo, changeInfo, errorCode);
213 if (*errorCode != SUCCESS_CODE) {
214 FreeCArrDeviceDescriptor(cInfo.deviceDescriptors);
215 return CAudioCapturerChangeInfo();
216 }
217 return cInfo;
218 }
219
GetInputDevices(int32_t * errorCode)220 CArrDeviceDescriptor MMAAudioCapturerImpl::GetInputDevices(int32_t *errorCode)
221 {
222 AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO);
223 if (audioCapturer_ == nullptr) {
224 *errorCode = CJ_ERR_SYSTEM;
225 return CArrDeviceDescriptor();
226 }
227 int32_t ret = audioCapturer_->GetCurrentInputDevices(deviceInfo);
228 if (ret != SUCCESS_CODE) {
229 AUDIO_ERR_LOG("GetCurrentInputDevices failure!");
230 *errorCode = CJ_ERR_SYSTEM;
231 return CArrDeviceDescriptor();
232 }
233 CArrDeviceDescriptor devices{};
234 Convert2CArrDeviceDescriptorByDeviceInfo(devices, deviceInfo, errorCode);
235 if (*errorCode != SUCCESS_CODE) {
236 FreeCArrDeviceDescriptor(devices);
237 return CArrDeviceDescriptor();
238 }
239 return devices;
240 }
241
RegisterCArrCallback(int32_t callbackType,void (* callback)(),int32_t * errorCode)242 void MMAAudioCapturerImpl::RegisterCArrCallback(int32_t callbackType, void (*callback)(), int32_t *errorCode)
243 {
244 if (audioCapturer_ == nullptr) {
245 *errorCode = CJ_ERR_SYSTEM;
246 return;
247 }
248 if (callbackType == AudioCapturerCallbackType::INPUT_DEVICE_CHANGE) {
249 auto func = CJLambda::Create(reinterpret_cast<void (*)(CArrDeviceDescriptor)>(callback));
250 if (func == nullptr) {
251 AUDIO_ERR_LOG("Register preferredInputDeviceChangeForCapturerInfo event failure!");
252 *errorCode = CJ_ERR_SYSTEM;
253 return;
254 }
255 auto cb = std::make_shared<CjAudioCapturerDeviceChangeCallback>();
256 cb->RegisterFunc(func);
257 audioCapturer_->SetAudioCapturerDeviceChangeCallback(cb);
258 deviceChangeCallbacks_.push_back(cb);
259 }
260 if (callbackType == AudioCapturerCallbackType::READ_DATA) {
261 auto func = CJLambda::Create(reinterpret_cast<void (*)(CArrUI8)>(callback));
262 if (func == nullptr) {
263 AUDIO_ERR_LOG("Register read_data event failure!");
264 *errorCode = CJ_ERR_SYSTEM;
265 }
266 auto ret = audioCapturer_->SetCaptureMode(CAPTURE_MODE_CALLBACK);
267 if (ret != SUCCESS_CODE) {
268 AUDIO_ERR_LOG("SetCaptureMode failure!");
269 *errorCode = CJ_ERR_SYSTEM;
270 }
271 capturerReadDataCb_->RegisterFunc(func, audioCapturer_);
272 ret = audioCapturer_->SetCapturerReadCallback(capturerReadDataCb_);
273 if (ret != SUCCESS_CODE) {
274 AUDIO_ERR_LOG("SetCapturerReadCallback failure!");
275 *errorCode = CJ_ERR_SYSTEM;
276 }
277 }
278 }
279
RegisterCallback(int32_t callbackType,void (* callback)(),int32_t * errorCode)280 void MMAAudioCapturerImpl::RegisterCallback(int32_t callbackType, void (*callback)(), int32_t *errorCode)
281 {
282 if (audioCapturer_ == nullptr) {
283 *errorCode = CJ_ERR_SYSTEM;
284 return;
285 }
286 if (callbackType == AudioCapturerCallbackType::AUDIO_CAPTURER_CHANGE) {
287 auto func = CJLambda::Create(reinterpret_cast<void (*)(CAudioCapturerChangeInfo)>(callback));
288 if (func == nullptr) {
289 AUDIO_ERR_LOG("Register audiocapturerchange event failure!");
290 *errorCode = CJ_ERR_SYSTEM;
291 return;
292 }
293 auto cb = std::make_shared<CjAudioCapturerInfoChangeCallback>();
294 cb->RegisterFunc(func);
295 audioCapturer_->SetAudioCapturerInfoChangeCallback(cb);
296 capturerInfoChangeCallbacks_.emplace_back(cb);
297 }
298 if (callbackType == AudioCapturerCallbackType::AUDIO_INTERRUPT) {
299 auto func = CJLambda::Create(reinterpret_cast<void (*)(CInterruptEvent)>(callback));
300 if (func == nullptr) {
301 AUDIO_ERR_LOG("Register audio_interrupt event failure!");
302 *errorCode = CJ_ERR_SYSTEM;
303 return;
304 }
305 callback_->RegisterInterruptFunc(func);
306 }
307 if (callbackType == AudioCapturerCallbackType::STATE_CHANGE) {
308 auto func = CJLambda::Create(reinterpret_cast<void (*)(int32_t)>(callback));
309 if (func == nullptr) {
310 AUDIO_ERR_LOG("Register state_change event failure!");
311 *errorCode = CJ_ERR_SYSTEM;
312 return;
313 }
314 callback_->RegisterStateChangeFunc(func);
315 auto state = audioCapturer_->GetStatus();
316 if (state == CAPTURER_PREPARED) {
317 callback_->OnStateChange(state);
318 }
319 }
320 RegisterCArrCallback(callbackType, callback, errorCode);
321 }
322
RegisterCallbackWithFrame(int32_t callbackType,void (* callback)(),int64_t frame,int32_t * errorCode)323 void MMAAudioCapturerImpl::RegisterCallbackWithFrame(int32_t callbackType, void (*callback)(), int64_t frame,
324 int32_t *errorCode)
325 {
326 if (audioCapturer_ == nullptr) {
327 *errorCode = CJ_ERR_SYSTEM;
328 return;
329 }
330 if (callbackType == AudioCapturerCallbackType::MARK_REACH) {
331 auto func = CJLambda::Create(reinterpret_cast<void (*)(int64_t)>(callback));
332 if (func == nullptr) {
333 AUDIO_ERR_LOG("Register mark_reach event failure!");
334 *errorCode = CJ_ERR_SYSTEM;
335 return;
336 }
337 if (frame <= 0) {
338 AUDIO_ERR_LOG("mark position not supported!");
339 *errorCode = CJ_ERR_INVALID_PARAM;
340 return;
341 }
342 positionCb_ = std::make_shared<CjCapturerPositionCallback>();
343 positionCb_->RegisterFunc(func);
344 int32_t ret = audioCapturer_->SetCapturerPositionCallback(frame, positionCb_);
345 if (ret != SUCCESS_CODE) {
346 AUDIO_ERR_LOG("SetCapturerPositionCallback failure!");
347 *errorCode = CJ_ERR_SYSTEM;
348 }
349 }
350 if (callbackType == AudioCapturerCallbackType::PERIOD_REACH) {
351 auto func = CJLambda::Create(reinterpret_cast<void (*)(int64_t)>(callback));
352 if (func == nullptr) {
353 AUDIO_ERR_LOG("Register period_reach event failure!");
354 *errorCode = CJ_ERR_SYSTEM;
355 return;
356 }
357 if (frame <= 0) {
358 AUDIO_ERR_LOG("framecount not supported!");
359 *errorCode = CJ_ERR_INVALID_PARAM;
360 return;
361 }
362 if (periodPositionCb_ != nullptr) {
363 AUDIO_ERR_LOG("period_reach already subscribed!");
364 return;
365 }
366 periodPositionCb_ = std::make_shared<CjCapturerPeriodPositionCallback>();
367 periodPositionCb_->RegisterFunc(func);
368 int32_t ret = audioCapturer_->SetCapturerPeriodPositionCallback(frame, periodPositionCb_);
369 if (ret != SUCCESS_CODE) {
370 AUDIO_ERR_LOG("SetCapturerPeriodPositionCallback failure!");
371 *errorCode = CJ_ERR_SYSTEM;
372 }
373 }
374 }
375 }
376 } // namespace AudioStandard
377 } // namespace OHOS
378