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