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