• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 
16 #ifndef LOG_TAG
17 #define LOG_TAG "RemoteAudioCaptureSource"
18 #endif
19 
20 #include "source/remote_audio_capture_source.h"
21 #include <climits>
22 #include "audio_hdi_log.h"
23 #include "audio_errors.h"
24 #include "audio_utils.h"
25 #include "common/hdi_adapter_info.h"
26 #include "manager/hdi_adapter_manager.h"
27 
28 using namespace OHOS::HDI::DistributedAudio::Audio::V1_0;
29 
30 namespace OHOS {
31 namespace AudioStandard {
RemoteAudioCaptureSource(const std::string & deviceNetworkId)32 RemoteAudioCaptureSource::RemoteAudioCaptureSource(const std::string &deviceNetworkId)
33     : deviceNetworkId_(deviceNetworkId)
34 {
35 }
36 
~RemoteAudioCaptureSource()37 RemoteAudioCaptureSource::~RemoteAudioCaptureSource()
38 {
39     if (sourceInited_.load()) {
40         DeInit();
41     }
42 }
43 
Init(const IAudioSourceAttr & attr)44 int32_t RemoteAudioCaptureSource::Init(const IAudioSourceAttr &attr)
45 {
46     AUDIO_INFO_LOG("in");
47     attr_ = attr;
48     sourceInited_.store(true);
49     SetMute(muteState_);
50     AUDIO_DEBUG_LOG("end");
51     return SUCCESS;
52 }
53 
DeInit(void)54 void RemoteAudioCaptureSource::DeInit(void)
55 {
56     AUDIO_INFO_LOG("in");
57     sourceInited_.store(false);
58     captureInited_.store(false);
59     started_.store(false);
60     paused_.store(false);
61 
62     DestroyCapture();
63     DumpFileUtil::CloseDumpFile(&dumpFile_);
64     AUDIO_INFO_LOG("end");
65 }
66 
IsInited(void)67 bool RemoteAudioCaptureSource::IsInited(void)
68 {
69     return sourceInited_.load();
70 }
71 
Start(void)72 int32_t RemoteAudioCaptureSource::Start(void)
73 {
74     AUDIO_INFO_LOG("in");
75     std::lock_guard<std::mutex> lock(createCaptureMutex_);
76     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, DUMP_REMOTE_CAPTURE_SOURCE_FILENAME, &dumpFile_);
77     if (!captureInited_.load()) {
78         int32_t ret = CreateCapture();
79         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create capture fail");
80         captureInited_.store(true);
81     }
82 
83     if (started_.load()) {
84         AUDIO_INFO_LOG("already started");
85         return SUCCESS;
86     }
87     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
88     int32_t ret = audioCapture_->Start();
89     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "start fail, ret: %{public}d", ret);
90     started_.store(true);
91     return SUCCESS;
92 }
93 
Stop(void)94 int32_t RemoteAudioCaptureSource::Stop(void)
95 {
96     AUDIO_INFO_LOG("in");
97     if (!started_.load()) {
98         AUDIO_INFO_LOG("already stopped");
99         return SUCCESS;
100     }
101 
102     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
103     int32_t ret = audioCapture_->Stop();
104     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "stop fail, ret: %{public}d", ret);
105     started_.store(false);
106     if (captureInited_.load()) {
107         DestroyCapture();
108         captureInited_.store(false);
109     }
110     return SUCCESS;
111 }
112 
Resume(void)113 int32_t RemoteAudioCaptureSource::Resume(void)
114 {
115     AUDIO_INFO_LOG("in");
116     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
117 
118     if (!paused_.load()) {
119         AUDIO_INFO_LOG("already resumed");
120         return SUCCESS;
121     }
122 
123     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
124     int32_t ret = audioCapture_->Resume();
125     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "resume fail, ret: %{public}d", ret);
126     paused_.store(false);
127     return SUCCESS;
128 }
129 
Pause(void)130 int32_t RemoteAudioCaptureSource::Pause(void)
131 {
132     AUDIO_INFO_LOG("in");
133     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
134 
135     if (paused_.load()) {
136         AUDIO_INFO_LOG("already paused");
137         return SUCCESS;
138     }
139 
140     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
141     int32_t ret = audioCapture_->Pause();
142     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "pause fail, ret: %{public}d", ret);
143     paused_.store(true);
144     return SUCCESS;
145 }
146 
Flush(void)147 int32_t RemoteAudioCaptureSource::Flush(void)
148 {
149     AUDIO_INFO_LOG("in");
150     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
151 
152     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
153     int32_t ret = audioCapture_->Flush();
154     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "flush fail, ret: %{public}d", ret);
155     return SUCCESS;
156 }
157 
Reset(void)158 int32_t RemoteAudioCaptureSource::Reset(void)
159 {
160     AUDIO_INFO_LOG("in");
161     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
162 
163     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
164     int32_t ret = audioCapture_->Flush();
165     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "reset fail, ret: %{public}d", ret);
166     return SUCCESS;
167 }
168 
CaptureFrame(char * frame,uint64_t requestBytes,uint64_t & replyBytes)169 int32_t RemoteAudioCaptureSource::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes)
170 {
171     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
172     if (!started_.load()) {
173         AUDIO_WARNING_LOG("not start, invalid state");
174         return ERR_ILLEGAL_STATE;
175     }
176 
177     std::vector<int8_t> bufferVec(requestBytes);
178     int32_t ret = audioCapture_->CaptureFrame(bufferVec, replyBytes);
179     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_READ_FAILED, "fail, ret: %{public}x", ret);
180     ret = memcpy_s(frame, requestBytes, bufferVec.data(), requestBytes);
181     CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_OPERATION_FAILED, "copy fail, error code: %{public}d", ret);
182     replyBytes = requestBytes;
183 
184     DumpFileUtil::WriteDumpFile(dumpFile_, frame, requestBytes);
185     CheckUpdateState(frame, requestBytes);
186     return SUCCESS;
187 }
188 
CaptureFrameWithEc(FrameDesc * fdesc,uint64_t & replyBytes,FrameDesc * fdescEc,uint64_t & replyBytesEc)189 int32_t RemoteAudioCaptureSource::CaptureFrameWithEc(FrameDesc *fdesc, uint64_t &replyBytes, FrameDesc *fdescEc,
190     uint64_t &replyBytesEc)
191 {
192     AUDIO_INFO_LOG("not support");
193     return ERR_NOT_SUPPORTED;
194 }
195 
GetAudioParameter(const AudioParamKey key,const std::string & condition)196 std::string RemoteAudioCaptureSource::GetAudioParameter(const AudioParamKey key, const std::string &condition)
197 {
198     return "";
199 }
200 
SetVolume(float left,float right)201 int32_t RemoteAudioCaptureSource::SetVolume(float left, float right)
202 {
203     float leftVolume = left;
204     float rightVolume = right;
205     float volume;
206     if ((leftVolume == 0) && (rightVolume != 0)) {
207         volume = rightVolume;
208     } else if ((leftVolume != 0) && (rightVolume == 0)) {
209         volume = leftVolume;
210     } else {
211         volume = (leftVolume + rightVolume) / HALF_FACTOR;
212     }
213 
214     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
215     int32_t ret = audioCapture_->SetVolume(volume);
216     AUDIO_INFO_LOG("left: %{public}f, right: %{public}f, ret: %{public}d", left, right, ret);
217     return SUCCESS;
218 }
219 
GetVolume(float & left,float & right)220 int32_t RemoteAudioCaptureSource::GetVolume(float &left, float &right)
221 {
222     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
223 
224     float val = 0.0;
225     audioCapture_->GetVolume(val);
226     left = val;
227     right = val;
228     return SUCCESS;
229 }
230 
SetMute(bool isMute)231 int32_t RemoteAudioCaptureSource::SetMute(bool isMute)
232 {
233     muteState_ = isMute;
234     if (!sourceInited_.load()) {
235         AUDIO_INFO_LOG("source not init, just save mute state");
236         return SUCCESS;
237     }
238     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
239     int32_t ret = audioCapture_->SetMute(isMute);
240     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "set mute fail");
241     return SUCCESS;
242 }
GetMute(bool & isMute)243 int32_t RemoteAudioCaptureSource::GetMute(bool &isMute)
244 {
245     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
246     bool hdiMuteState = false;
247     int32_t ret = audioCapture_->GetMute(hdiMuteState);
248     if (ret != SUCCESS) {
249         AUDIO_WARNING_LOG("get mute fail");
250     }
251     AUDIO_DEBUG_LOG("hdiMuteState: %{public}d, muteState: %{public}d", hdiMuteState, muteState_);
252     isMute = muteState_;
253     return SUCCESS;
254 }
255 
GetTransactionId(void)256 uint64_t RemoteAudioCaptureSource::GetTransactionId(void)
257 {
258     AUDIO_INFO_LOG("not support");
259     return ERR_NOT_SUPPORTED;
260 }
261 
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)262 int32_t RemoteAudioCaptureSource::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
263 {
264     AUDIO_INFO_LOG("not support");
265     return ERR_NOT_SUPPORTED;
266 }
267 
GetMaxAmplitude(void)268 float RemoteAudioCaptureSource::GetMaxAmplitude(void)
269 {
270     lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano();
271     startUpdate_ = true;
272     return maxAmplitude_;
273 }
274 
SetAudioScene(AudioScene audioScene,DeviceType activeDevice)275 int32_t RemoteAudioCaptureSource::SetAudioScene(AudioScene audioScene, DeviceType activeDevice)
276 {
277     CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene < AUDIO_SCENE_MAX, ERR_INVALID_PARAM,
278         "invalid scene");
279     AUDIO_INFO_LOG("scene: %{public}d, device: %{public}d", audioScene, activeDevice);
280 
281     struct AudioSceneDescriptor sceneDesc = {
282         .scene.id = GetAudioCategory(audioScene),
283         .desc.pins = AudioPortPin::PIN_IN_MIC,
284     };
285     AUDIO_INFO_LOG("start");
286     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
287     int32_t ret = audioCapture_->SelectScene(sceneDesc);
288     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "select scene fail, ret: %{public}d", ret);
289     AUDIO_INFO_LOG("end");
290     return SUCCESS;
291 }
292 
UpdateActiveDevice(DeviceType inputDevice)293 int32_t RemoteAudioCaptureSource::UpdateActiveDevice(DeviceType inputDevice)
294 {
295     AUDIO_INFO_LOG("not support");
296     return ERR_NOT_SUPPORTED;
297 }
298 
RegistCallback(uint32_t type,IAudioSourceCallback * callback)299 void RemoteAudioCaptureSource::RegistCallback(uint32_t type, IAudioSourceCallback *callback)
300 {
301     AUDIO_INFO_LOG("in");
302     callback_.RegistCallback(type, callback);
303 }
304 
UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE],const size_t size)305 int32_t RemoteAudioCaptureSource::UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE], const size_t size)
306 {
307     return ERR_NOT_SUPPORTED;
308 }
309 
UpdateAppsUid(const std::vector<int32_t> & appsUid)310 int32_t RemoteAudioCaptureSource::UpdateAppsUid(const std::vector<int32_t> &appsUid)
311 {
312     return ERR_NOT_SUPPORTED;
313 }
314 
DumpInfo(std::string & dumpString)315 void RemoteAudioCaptureSource::DumpInfo(std::string &dumpString)
316 {
317     dumpString += "type: RemoteSource\tstarted: " + std::string(started_.load() ? "true" : "false") +
318         "\tdeviceNetworkId: " + deviceNetworkId_ + "\n";
319 }
320 
OnAudioParamChange(const std::string & adapterName,const AudioParamKey key,const std::string & condition,const std::string & value)321 void RemoteAudioCaptureSource::OnAudioParamChange(const std::string &adapterName, const AudioParamKey key,
322     const std::string &condition, const std::string &value)
323 {
324     AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, value: %{public}s", key, condition.c_str(), value.c_str());
325     if (key == AudioParamKey::PARAM_KEY_STATE) {
326         DeInit();
327     }
328 
329     callback_.OnCaptureSourceParamChange(adapterName, key, condition, value);
330 }
331 
ConvertToHdiFormat(AudioSampleFormat format)332 AudioFormat RemoteAudioCaptureSource::ConvertToHdiFormat(AudioSampleFormat format)
333 {
334     AudioFormat hdiFormat;
335     switch (format) {
336         case SAMPLE_U8:
337             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
338             break;
339         case SAMPLE_S16LE:
340             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
341             break;
342         case SAMPLE_S24LE:
343             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
344             break;
345         case SAMPLE_S32LE:
346             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
347             break;
348         default:
349             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
350             break;
351     }
352 
353     return hdiFormat;
354 }
355 
GetAudioCategory(AudioScene audioScene)356 AudioCategory RemoteAudioCaptureSource::GetAudioCategory(AudioScene audioScene)
357 {
358     AudioCategory audioCategory;
359     switch (audioScene) {
360         case AUDIO_SCENE_DEFAULT:
361             audioCategory = AUDIO_IN_MEDIA;
362             break;
363         case AUDIO_SCENE_RINGING:
364         case AUDIO_SCENE_VOICE_RINGING:
365             audioCategory = AUDIO_IN_RINGTONE;
366             break;
367         case AUDIO_SCENE_PHONE_CALL:
368             audioCategory = AUDIO_IN_CALL;
369             break;
370         case AUDIO_SCENE_PHONE_CHAT:
371             audioCategory = AUDIO_IN_COMMUNICATION;
372             break;
373         default:
374             audioCategory = AUDIO_IN_MEDIA;
375             break;
376     }
377     AUDIO_DEBUG_LOG("audioCategory: %{public}d", audioCategory);
378 
379     return audioCategory;
380 }
381 
InitAudioSampleAttr(struct AudioSampleAttributes & param)382 void RemoteAudioCaptureSource::InitAudioSampleAttr(struct AudioSampleAttributes &param)
383 {
384     param.type = AUDIO_IN_MEDIA;
385     param.period = DEEP_BUFFER_CAPTURE_PERIOD_SIZE;
386     param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_CAPTURE_ID_BASE, HDI_CAPTURE_OFFSET_REMOTE));
387     param.isSignedData = true;
388     param.stopThreshold = INT_MAX;
389     param.silenceThreshold = AUDIO_BUFFER_SIZE;
390     // user need to set
391     param.sampleRate = attr_.sampleRate;
392     param.format = ConvertToHdiFormat(attr_.format);
393     param.isBigEndian = attr_.isBigEndian;
394     param.channelCount = attr_.channel;
395     param.silenceThreshold = attr_.bufferSize;
396     param.frameSize = param.format * param.channelCount;
397     param.startThreshold = DEEP_BUFFER_CAPTURE_PERIOD_SIZE / (param.frameSize);
398     param.sourceType = attr_.sourceType;
399 }
400 
InitDeviceDesc(struct AudioDeviceDescriptor & deviceDesc)401 void RemoteAudioCaptureSource::InitDeviceDesc(struct AudioDeviceDescriptor &deviceDesc)
402 {
403     deviceDesc.pins = AudioPortPin::PIN_IN_MIC;
404     deviceDesc.desc = "";
405 }
406 
CreateCapture(void)407 int32_t RemoteAudioCaptureSource::CreateCapture(void)
408 {
409     struct AudioSampleAttributes param;
410     struct AudioDeviceDescriptor deviceDesc;
411     InitAudioSampleAttr(param);
412     InitDeviceDesc(deviceDesc);
413 
414     AUDIO_INFO_LOG("create capture, format: %{public}u", param.format);
415     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
416     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
417     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
418     void *capture = deviceManager->CreateCapture(deviceNetworkId_, &param, &deviceDesc, hdiCaptureId_);
419     audioCapture_.ForceSetRefPtr(static_cast<IAudioCapture *>(capture));
420     CHECK_AND_RETURN_RET(audioCapture_ != nullptr, ERR_NOT_STARTED, "create capture fail");
421     deviceManager->RegistCaptureSourceCallback(deviceNetworkId_, hdiCaptureId_, this);
422     return SUCCESS;
423 }
424 
DestroyCapture(void)425 void RemoteAudioCaptureSource::DestroyCapture(void)
426 {
427     AUDIO_INFO_LOG("destroy capture");
428     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
429     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
430     CHECK_AND_RETURN(deviceManager != nullptr);
431     deviceManager->DestroyCapture(deviceNetworkId_, hdiCaptureId_);
432     deviceManager->UnRegistCaptureSourceCallback(deviceNetworkId_, hdiCaptureId_);
433     audioCapture_.ForceSetRefPtr(nullptr);
434     hdiCaptureId_ = 0;
435 }
436 
CheckUpdateState(char * frame,size_t replyBytes)437 void RemoteAudioCaptureSource::CheckUpdateState(char *frame, size_t replyBytes)
438 {
439     if (startUpdate_) {
440         if (captureFrameNum_ == 0) {
441             last10FrameStartTime_ = ClockTime::GetCurNano();
442         }
443         captureFrameNum_++;
444         maxAmplitude_ = UpdateMaxAmplitude(static_cast<ConvertHdiFormat>(attr_.format), frame, replyBytes);
445         if (captureFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) {
446             captureFrameNum_ = 0;
447             if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) {
448                 startUpdate_ = false;
449                 maxAmplitude_ = 0;
450             }
451         }
452     }
453 }
454 
455 } // namespace AudioStandard
456 } // namespace OHOS
457