1 /*
2 * Copyright (c) 2022-2024 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_capture_interface_impl.h"
17
18 #include <hdf_base.h>
19 #include <unistd.h>
20 #include "sys/time.h"
21 #include <securec.h>
22
23 #include "cJSON.h"
24
25 #include "daudio_constants.h"
26 #include "daudio_events.h"
27 #include "daudio_log.h"
28 #include "daudio_utils.h"
29
30 #undef DH_LOG_TAG
31 #define DH_LOG_TAG "AudioCaptureInterfaceImpl"
32
33 using namespace OHOS::DistributedHardware;
34 namespace OHOS {
35 namespace HDI {
36 namespace DistributedAudio {
37 namespace Audio {
38 namespace V1_0 {
AudioCaptureInterfaceImpl(const std::string & adpName,const AudioDeviceDescriptor & desc,const AudioSampleAttributes & attrs,const sptr<IDAudioCallback> & callback)39 AudioCaptureInterfaceImpl::AudioCaptureInterfaceImpl(const std::string &adpName, const AudioDeviceDescriptor &desc,
40 const AudioSampleAttributes &attrs, const sptr<IDAudioCallback> &callback)
41 : adapterName_(adpName), devDesc_(desc), devAttrs_(attrs), audioExtCallback_(callback)
42 {
43 devAttrs_.frameSize = CalculateFrameSize(attrs.sampleRate, attrs.channelCount, attrs.format,
44 AUDIO_NORMAL_INTERVAL, false);
45 const int32_t sizePerSec = static_cast<int32_t>(attrs.sampleRate * attrs.channelCount) *attrs.format;
46 if (sizePerSec == 0) {
47 DHLOGE("The 'sizePerSec' is zero. In the constructor for x, the denominator of the division is zero.");
48 } else {
49 framePeriodNs_ = (static_cast<int64_t>(devAttrs_.frameSize) * AUDIO_NS_PER_SECOND) / sizePerSec;
50 }
51 DHLOGD("Distributed audio capture constructed, period(%{public}d),frameSize(%{public}d).",
52 attrs.period, devAttrs_.frameSize);
53 DHLOGD("Distributed audio capture constructed, id(%{public}d).", desc.pins);
54 }
55
~AudioCaptureInterfaceImpl()56 AudioCaptureInterfaceImpl::~AudioCaptureInterfaceImpl()
57 {
58 DHLOGD("Distributed audio capture destructed, id(%{public}d).", devDesc_.pins);
59 }
60
GetCapturePosition(uint64_t & frames,AudioTimeStamp & time)61 int32_t AudioCaptureInterfaceImpl::GetCapturePosition(uint64_t &frames, AudioTimeStamp &time)
62 {
63 DHLOGI("Get capture position, not support yet.");
64 (void)frames;
65 (void)time;
66 return HDF_SUCCESS;
67 }
68
CaptureFrame(std::vector<int8_t> & frame,uint64_t & replyBytes)69 int32_t AudioCaptureInterfaceImpl::CaptureFrame(std::vector<int8_t> &frame, uint64_t &replyBytes)
70 {
71 DHLOGD("Capture frame[sampleRate:%{public}d, channelCount: %{public}d, format: %{public}d, frameSize: %{public}d].",
72 devAttrs_.sampleRate, devAttrs_.channelCount, devAttrs_.format, devAttrs_.frameSize);
73 int64_t timeOffset = UpdateTimeOffset(frameIndex_, framePeriodNs_, startTime_);
74
75 int64_t startTime = GetNowTimeUs();
76 std::lock_guard<std::mutex> captureLck(captureMtx_);
77 if (captureStatus_ != CAPTURE_STATUS_START) {
78 DHLOGE("Capture status wrong, return false.");
79 return HDF_FAILURE;
80 }
81 if (audioExtCallback_ == nullptr) {
82 DHLOGE("Callback is nullptr.");
83 return HDF_FAILURE;
84 }
85
86 AudioData audioData;
87 int32_t ret = audioExtCallback_->ReadStreamData(captureId_, audioData);
88 if (ret != HDF_SUCCESS) {
89 DHLOGE("Read stream data failed.");
90 return HDF_FAILURE;
91 }
92 DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(audioData.data.data()), audioData.data.size());
93 frame.clear();
94 frame.resize(devAttrs_.frameSize, 0);
95 if (!muteState_.load() && memcpy_s(frame.data(), frame.size(), audioData.data.data(), audioData.data.size()) !=
96 EOK) {
97 DHLOGE("Copy capture frame failed");
98 return HDF_FAILURE;
99 }
100 ++frameIndex_;
101 AbsoluteSleep(startTime_ + frameIndex_ * framePeriodNs_ - timeOffset);
102 DHLOGD("Capture audio frame success.");
103 int64_t endTime = GetNowTimeUs();
104 if (IsOutDurationRange(startTime, endTime, lastCaptureStartTime_)) {
105 DHLOGD("This frame spend: %{public}" PRId64" us, interval of two frames: %{public}" PRId64" us",
106 endTime - startTime, startTime - lastCaptureStartTime_);
107 }
108 lastCaptureStartTime_ = startTime;
109 return HDF_SUCCESS;
110 }
111
Start()112 int32_t AudioCaptureInterfaceImpl::Start()
113 {
114 DHLOGI("Start capture.");
115 cJSON *jParam = cJSON_CreateObject();
116 if (jParam == nullptr) {
117 DHLOGE("Failed to create cJSON object.");
118 return HDF_FAILURE;
119 }
120 cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(devDesc_.pins).c_str());
121 char *jsonData = cJSON_PrintUnformatted(jParam);
122 if (jsonData == nullptr) {
123 DHLOGE("Failed to create JSON data.");
124 cJSON_Delete(jParam);
125 return HDF_FAILURE;
126 }
127 std::string content(jsonData);
128 cJSON_Delete(jParam);
129 cJSON_free(jsonData);
130 DAudioEvent event = { HDF_AUDIO_EVENT_START, content };
131 if (audioExtCallback_ == nullptr) {
132 DHLOGE("Callback is nullptr.");
133 return HDF_FAILURE;
134 }
135 if (audioExtCallback_->NotifyEvent(captureId_, event) != HDF_SUCCESS) {
136 DHLOGE("Notify start event failed.");
137 return HDF_FAILURE;
138 }
139 std::lock_guard<std::mutex> captureLck(captureMtx_);
140 captureStatus_ = CAPTURE_STATUS_START;
141 frameIndex_ = 0;
142 startTime_ = 0;
143 DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, HDF_CAPTURE_FROM_SA, &dumpFile_);
144 return HDF_SUCCESS;
145 }
146
Stop()147 int32_t AudioCaptureInterfaceImpl::Stop()
148 {
149 DHLOGI("Stop capture.");
150 if (GetCaptureStatus() != CAPTURE_STATUS_START) {
151 DHLOGI("Capture has not been started.");
152 return HDF_SUCCESS;
153 }
154 cJSON *jParam = cJSON_CreateObject();
155 if (jParam == nullptr) {
156 DHLOGE("Failed to create cJSON object.");
157 return HDF_FAILURE;
158 }
159 cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(devDesc_.pins).c_str());
160 char *jsonData = cJSON_PrintUnformatted(jParam);
161 if (jsonData == nullptr) {
162 DHLOGE("Failed to create JSON data.");
163 cJSON_Delete(jParam);
164 return HDF_FAILURE;
165 }
166 cJSON_Delete(jParam);
167 std::string content(jsonData);
168 cJSON_free(jsonData);
169 DAudioEvent event = { HDF_AUDIO_EVENT_STOP, content };
170 if (audioExtCallback_ == nullptr) {
171 DHLOGE("Callback is nullptr.");
172 return HDF_FAILURE;
173 }
174 if (audioExtCallback_->NotifyEvent(captureId_, event) != HDF_SUCCESS) {
175 DHLOGE("Notify stop event failed.");
176 return HDF_FAILURE;
177 }
178 std::lock_guard<std::mutex> captureLck(captureMtx_);
179 captureStatus_ = CAPTURE_STATUS_STOP;
180 DumpFileUtil::CloseDumpFile(&dumpFile_);
181 return HDF_SUCCESS;
182 }
183
Pause()184 int32_t AudioCaptureInterfaceImpl::Pause()
185 {
186 DHLOGI("Pause capture.");
187 std::lock_guard<std::mutex> captureLck(captureMtx_);
188 captureStatus_ = CAPTURE_STATUS_PAUSE;
189 return HDF_SUCCESS;
190 }
191
Resume()192 int32_t AudioCaptureInterfaceImpl::Resume()
193 {
194 return HDF_SUCCESS;
195 }
196
Flush()197 int32_t AudioCaptureInterfaceImpl::Flush()
198 {
199 return HDF_SUCCESS;
200 }
201
TurnStandbyMode()202 int32_t AudioCaptureInterfaceImpl::TurnStandbyMode()
203 {
204 DHLOGI("Turn stand by mode, not support yet.");
205 return HDF_SUCCESS;
206 }
207
AudioDevDump(int32_t range,int32_t fd)208 int32_t AudioCaptureInterfaceImpl::AudioDevDump(int32_t range, int32_t fd)
209 {
210 DHLOGI("Dump audio info, not support yet.");
211 (void)range;
212 (void)fd;
213 return HDF_SUCCESS;
214 }
215
IsSupportsPauseAndResume(bool & supportPause,bool & supportResume)216 int32_t AudioCaptureInterfaceImpl::IsSupportsPauseAndResume(bool &supportPause, bool &supportResume)
217 {
218 DHLOGI("Check whether pause and resume is supported, not support yet.");
219 (void)supportPause;
220 (void)supportResume;
221 return HDF_SUCCESS;
222 }
223
CheckSceneCapability(const AudioSceneDescriptor & scene,bool & supported)224 int32_t AudioCaptureInterfaceImpl::CheckSceneCapability(const AudioSceneDescriptor &scene, bool &supported)
225 {
226 DHLOGI("Check scene capability.");
227 (void)scene;
228 supported = false;
229 return HDF_SUCCESS;
230 }
231
SelectScene(const AudioSceneDescriptor & scene)232 int32_t AudioCaptureInterfaceImpl::SelectScene(const AudioSceneDescriptor &scene)
233 {
234 DHLOGI("Select audio scene, not support yet.");
235 (void)scene;
236 return HDF_SUCCESS;
237 }
238
SetMute(bool mute)239 int32_t AudioCaptureInterfaceImpl::SetMute(bool mute)
240 {
241 DHLOGI("Set audio mute state.");
242 muteState_.store(mute);
243 return HDF_SUCCESS;
244 }
245
GetMute(bool & mute)246 int32_t AudioCaptureInterfaceImpl::GetMute(bool &mute)
247 {
248 DHLOGI("Get audio mute state.");
249 mute = muteState_.load();
250 return HDF_SUCCESS;
251 }
252
SetVolume(float volume)253 int32_t AudioCaptureInterfaceImpl::SetVolume(float volume)
254 {
255 DHLOGI("Can not set vol not by this interface.");
256 (void)volume;
257 return HDF_SUCCESS;
258 }
259
GetVolume(float & volume)260 int32_t AudioCaptureInterfaceImpl::GetVolume(float &volume)
261 {
262 DHLOGI("Can not get vol not by this interface.");
263 (void)volume;
264 return HDF_SUCCESS;
265 }
266
GetGainThreshold(float & min,float & max)267 int32_t AudioCaptureInterfaceImpl::GetGainThreshold(float &min, float &max)
268 {
269 DHLOGI("Get gain threshold, not support yet.");
270 min = 0;
271 max = 0;
272 return HDF_SUCCESS;
273 }
274
SetGain(float gain)275 int32_t AudioCaptureInterfaceImpl::SetGain(float gain)
276 {
277 DHLOGI("Set gain, not support yet.");
278 (void)gain;
279 return HDF_SUCCESS;
280 }
281
GetGain(float & gain)282 int32_t AudioCaptureInterfaceImpl::GetGain(float &gain)
283 {
284 DHLOGI("Get gain, not support yet.");
285 gain = 1.0;
286 return HDF_SUCCESS;
287 }
288
GetFrameSize(uint64_t & size)289 int32_t AudioCaptureInterfaceImpl::GetFrameSize(uint64_t &size)
290 {
291 (void)size;
292 return HDF_SUCCESS;
293 }
294
GetFrameCount(uint64_t & count)295 int32_t AudioCaptureInterfaceImpl::GetFrameCount(uint64_t &count)
296 {
297 (void)count;
298 return HDF_SUCCESS;
299 }
300
SetSampleAttributes(const AudioSampleAttributes & attrs)301 int32_t AudioCaptureInterfaceImpl::SetSampleAttributes(const AudioSampleAttributes &attrs)
302 {
303 DHLOGI("Set sample attributes.");
304 devAttrs_ = attrs;
305 return HDF_SUCCESS;
306 }
307
GetSampleAttributes(AudioSampleAttributes & attrs)308 int32_t AudioCaptureInterfaceImpl::GetSampleAttributes(AudioSampleAttributes &attrs)
309 {
310 DHLOGI("Get sample attributes.");
311 attrs = devAttrs_;
312 return HDF_SUCCESS;
313 }
314
GetCurrentChannelId(uint32_t & channelId)315 int32_t AudioCaptureInterfaceImpl::GetCurrentChannelId(uint32_t &channelId)
316 {
317 DHLOGI("Get current channel id, not support yet.");
318 (void)channelId;
319 return HDF_SUCCESS;
320 }
321
SetExtraParams(const std::string & keyValueList)322 int32_t AudioCaptureInterfaceImpl::SetExtraParams(const std::string &keyValueList)
323 {
324 DHLOGI("Set extra parameters, not support yet.");
325 (void)keyValueList;
326 return HDF_SUCCESS;
327 }
328
GetExtraParams(std::string & keyValueList)329 int32_t AudioCaptureInterfaceImpl::GetExtraParams(std::string &keyValueList)
330 {
331 DHLOGI("Get extra parameters, not support yet.");
332 (void)keyValueList;
333 return HDF_SUCCESS;
334 }
335
ReqMmapBuffer(int32_t reqSize,AudioMmapBufferDescriptor & desc)336 int32_t AudioCaptureInterfaceImpl::ReqMmapBuffer(int32_t reqSize, AudioMmapBufferDescriptor &desc)
337 {
338 DHLOGI("Request mmap buffer, not support yet.");
339 (void)reqSize;
340 (void)desc;
341 return HDF_SUCCESS;
342 }
343
GetMmapPosition(uint64_t & frames,AudioTimeStamp & time)344 int32_t AudioCaptureInterfaceImpl::GetMmapPosition(uint64_t &frames, AudioTimeStamp &time)
345 {
346 DHLOGI("Get mmap position, not support yet.");
347 (void)frames;
348 (void)time;
349 return HDF_SUCCESS;
350 }
351
AddAudioEffect(uint64_t effectid)352 int32_t AudioCaptureInterfaceImpl::AddAudioEffect(uint64_t effectid)
353 {
354 DHLOGI("Add audio effect, not support yet.");
355 (void)effectid;
356 return HDF_SUCCESS;
357 }
358
RemoveAudioEffect(uint64_t effectid)359 int32_t AudioCaptureInterfaceImpl::RemoveAudioEffect(uint64_t effectid)
360 {
361 DHLOGI("Remove audio effect, not support yet.");
362 (void)effectid;
363 return HDF_SUCCESS;
364 }
365
GetFrameBufferSize(uint64_t & bufferSize)366 int32_t AudioCaptureInterfaceImpl::GetFrameBufferSize(uint64_t &bufferSize)
367 {
368 DHLOGI("Get frame buffer size, not support yet.");
369 (void)bufferSize;
370 return HDF_SUCCESS;
371 }
372
SetAttrs(const std::string & adpName,const AudioDeviceDescriptor & desc,const AudioSampleAttributes & attrs,const sptr<IDAudioCallback> & callback,const int32_t dhId)373 void AudioCaptureInterfaceImpl::SetAttrs(const std::string &adpName, const AudioDeviceDescriptor &desc,
374 const AudioSampleAttributes &attrs, const sptr<IDAudioCallback> &callback, const int32_t dhId)
375 {
376 DHLOGI("Set attrs, not support yet.");
377 }
378
SetDumpFlagInner()379 void AudioCaptureInterfaceImpl::SetDumpFlagInner()
380 {
381 dumpFlag_ = true;
382 }
383
GetCaptureStatus()384 AudioCaptureStatus AudioCaptureInterfaceImpl::GetCaptureStatus()
385 {
386 std::lock_guard<std::mutex> captureLck(captureMtx_);
387 DHLOGI("Get capture status = %{public}d", static_cast<int32_t>(captureStatus_));
388 return captureStatus_;
389 }
390
SetCaptureStatus(AudioCaptureStatus status)391 void AudioCaptureInterfaceImpl::SetCaptureStatus(AudioCaptureStatus status)
392 {
393 std::lock_guard<std::mutex> captureLck(captureMtx_);
394 captureStatus_ = status;
395 DHLOGI("Set capture status = %{public}d", static_cast<int32_t>(captureStatus_));
396 }
397
GetCaptureDesc()398 const AudioDeviceDescriptor &AudioCaptureInterfaceImpl::GetCaptureDesc()
399 {
400 return devDesc_;
401 }
402 } // V1_0
403 } // Audio
404 } // Distributedaudio
405 } // HDI
406 } // OHOS
407