1 /*
2 * Copyright (c) 2023-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_ext_impl.h"
17
18 #include <hdf_base.h>
19 #include <securec.h>
20 #include <unistd.h>
21 #include <sys/time.h>
22
23 #include "cJSON.h"
24
25 #include "daudio_constants.h"
26 #include "daudio_events.h"
27 #include "daudio_log.h"
28
29 #undef DH_LOG_TAG
30 #define DH_LOG_TAG "AudioCaptureExtImpl"
31
32 using namespace OHOS::DistributedHardware;
33 namespace OHOS {
34 namespace HDI {
35 namespace DistributedAudio {
36 namespace Audio {
37 namespace V1_0 {
38
AudioCaptureExtImpl()39 AudioCaptureExtImpl::AudioCaptureExtImpl()
40 {
41 DHLOGI("Distributed lowlatency capture constructed.");
42 }
43
~AudioCaptureExtImpl()44 AudioCaptureExtImpl::~AudioCaptureExtImpl()
45 {
46 UnInitAshmem();
47 DHLOGD("Distributed lowlatency capture destructed, id(%{public}d).", devDesc_.pins);
48 }
49
InitAshmem(int32_t ashmemLength)50 int32_t AudioCaptureExtImpl::InitAshmem(int32_t ashmemLength)
51 {
52 std::string memory_name = "Capture ShareMemory";
53 if (ashmemLength < DAUDIO_MIN_ASHMEM_LEN || ashmemLength > DAUDIO_MAX_ASHMEM_LEN) {
54 DHLOGE("Init ashmem failed. length is illegal.");
55 return HDF_FAILURE;
56 }
57 ashmem_ = OHOS::Ashmem::CreateAshmem(memory_name.c_str(), ashmemLength);
58 if (ashmem_ == nullptr) {
59 DHLOGE("Create ashmem failed.");
60 return HDF_FAILURE;
61 }
62 if (!ashmem_->MapReadAndWriteAshmem()) {
63 DHLOGE("Mmap ashmem failed.");
64 return HDF_FAILURE;
65 }
66 fd_ = ashmem_->GetAshmemFd();
67 DHLOGI("Init Ashmem success, fd: %{public}d, length: %{public}d", fd_, ashmemLength);
68 return HDF_SUCCESS;
69 }
70
UnInitAshmem()71 void AudioCaptureExtImpl::UnInitAshmem()
72 {
73 if (ashmem_ != nullptr) {
74 ashmem_->UnmapAshmem();
75 ashmem_->CloseAshmem();
76 ashmem_ = nullptr;
77 DHLOGI("UnInitAshmem success.");
78 }
79 }
80
GetCapturePosition(uint64_t & frames,AudioTimeStamp & time)81 int32_t AudioCaptureExtImpl::GetCapturePosition(uint64_t &frames, AudioTimeStamp &time)
82 {
83 DHLOGI("Get capture position, not support yet.");
84 (void)frames;
85 (void)time;
86 return HDF_SUCCESS;
87 }
88
CaptureFrame(std::vector<int8_t> & frame,uint64_t & replyBytes)89 int32_t AudioCaptureExtImpl::CaptureFrame(std::vector<int8_t> &frame, uint64_t &replyBytes)
90 {
91 DHLOGI("Render frame. not support in low-latency capture");
92 (void)devAttrs_.sampleRate;
93 (void)devAttrs_.channelCount;
94 (void)devAttrs_.format;
95 return HDF_SUCCESS;
96 }
97
Start()98 int32_t AudioCaptureExtImpl::Start()
99 {
100 DHLOGI("Start capture mmap.");
101 std::string content;
102 std::initializer_list<std::pair<std::string, std::string>> items = { {KEY_DH_ID, std::to_string(dhId_)} };
103 if (WrapCJsonItem(items, content) != HDF_SUCCESS) {
104 DHLOGE("Wrap the event failed.");
105 return HDF_FAILURE;
106 }
107 DAudioEvent event = { HDF_AUDIO_EVENT_MMAP_START_MIC, content };
108 if (audioExtCallback_ == nullptr) {
109 DHLOGE("Callback is nullptr.");
110 return HDF_FAILURE;
111 }
112 int32_t ret = audioExtCallback_->NotifyEvent(captureId_, event);
113 if (ret != HDF_SUCCESS) {
114 DHLOGE("Start capture mmap failed.");
115 return HDF_FAILURE;
116 }
117 return HDF_SUCCESS;
118 }
119
Stop()120 int32_t AudioCaptureExtImpl::Stop()
121 {
122 DHLOGI("Stop capture mmap.");
123 std::string content;
124 std::initializer_list<std::pair<std::string, std::string>> items = { {KEY_DH_ID, std::to_string(dhId_)} };
125 if (WrapCJsonItem(items, content) != HDF_SUCCESS) {
126 DHLOGE("Wrap the event failed.");
127 return HDF_FAILURE;
128 }
129 DAudioEvent event = { HDF_AUDIO_EVENT_MMAP_STOP_MIC, content };
130 if (audioExtCallback_ == nullptr) {
131 DHLOGE("Callback is nullptr.");
132 return HDF_FAILURE;
133 }
134 int32_t ret = audioExtCallback_->NotifyEvent(captureId_, event);
135 if (ret != HDF_SUCCESS) {
136 DHLOGE("Stop capture mmap failed.");
137 return HDF_FAILURE;
138 }
139 return HDF_SUCCESS;
140 }
141
Pause()142 int32_t AudioCaptureExtImpl::Pause()
143 {
144 DHLOGI("Pause capture.");
145 std::lock_guard<std::mutex> captureLck(captureMtx_);
146 captureStatus_ = CAPTURE_STATUS_PAUSE;
147 return HDF_SUCCESS;
148 }
149
Resume()150 int32_t AudioCaptureExtImpl::Resume()
151 {
152 return HDF_SUCCESS;
153 }
154
Flush()155 int32_t AudioCaptureExtImpl::Flush()
156 {
157 return HDF_SUCCESS;
158 }
159
TurnStandbyMode()160 int32_t AudioCaptureExtImpl::TurnStandbyMode()
161 {
162 DHLOGI("Turn stand by mode, not support yet.");
163 return HDF_SUCCESS;
164 }
165
AudioDevDump(int32_t range,int32_t fd)166 int32_t AudioCaptureExtImpl::AudioDevDump(int32_t range, int32_t fd)
167 {
168 DHLOGI("Dump audio info, not support yet.");
169 (void)range;
170 (void)fd;
171 return HDF_SUCCESS;
172 }
173
IsSupportsPauseAndResume(bool & supportPause,bool & supportResume)174 int32_t AudioCaptureExtImpl::IsSupportsPauseAndResume(bool &supportPause, bool &supportResume)
175 {
176 DHLOGI("Check whether pause and resume is supported, not support yet.");
177 (void)supportPause;
178 (void)supportResume;
179 return HDF_SUCCESS;
180 }
181
CheckSceneCapability(const AudioSceneDescriptor & scene,bool & supported)182 int32_t AudioCaptureExtImpl::CheckSceneCapability(const AudioSceneDescriptor &scene, bool &supported)
183 {
184 DHLOGI("Check scene capability.");
185 (void)scene;
186 supported = false;
187 return HDF_SUCCESS;
188 }
189
SelectScene(const AudioSceneDescriptor & scene)190 int32_t AudioCaptureExtImpl::SelectScene(const AudioSceneDescriptor &scene)
191 {
192 DHLOGI("Select audio scene, not support yet.");
193 (void)scene;
194 return HDF_SUCCESS;
195 }
196
SetMute(bool mute)197 int32_t AudioCaptureExtImpl::SetMute(bool mute)
198 {
199 DHLOGI("Set mute, not support yet.");
200 (void)mute;
201 return HDF_SUCCESS;
202 }
203
GetMute(bool & mute)204 int32_t AudioCaptureExtImpl::GetMute(bool &mute)
205 {
206 DHLOGI("Get mute, not support yet.");
207 (void)mute;
208 return HDF_SUCCESS;
209 }
210
SetVolume(float volume)211 int32_t AudioCaptureExtImpl::SetVolume(float volume)
212 {
213 DHLOGI("Can not set vol not by this interface.");
214 (void)volume;
215 return HDF_SUCCESS;
216 }
217
GetVolume(float & volume)218 int32_t AudioCaptureExtImpl::GetVolume(float &volume)
219 {
220 DHLOGI("Can not get vol not by this interface.");
221 (void)volume;
222 return HDF_SUCCESS;
223 }
224
GetGainThreshold(float & min,float & max)225 int32_t AudioCaptureExtImpl::GetGainThreshold(float &min, float &max)
226 {
227 DHLOGI("Get gain threshold, not support yet.");
228 min = 0;
229 max = 0;
230 return HDF_SUCCESS;
231 }
232
SetGain(float gain)233 int32_t AudioCaptureExtImpl::SetGain(float gain)
234 {
235 DHLOGI("Set gain, not support yet.");
236 (void) gain;
237 return HDF_SUCCESS;
238 }
239
GetGain(float & gain)240 int32_t AudioCaptureExtImpl::GetGain(float &gain)
241 {
242 DHLOGI("Get gain, not support yet.");
243 gain = 1.0;
244 return HDF_SUCCESS;
245 }
246
GetFrameSize(uint64_t & size)247 int32_t AudioCaptureExtImpl::GetFrameSize(uint64_t &size)
248 {
249 (void)size;
250 return HDF_SUCCESS;
251 }
252
GetFrameCount(uint64_t & count)253 int32_t AudioCaptureExtImpl::GetFrameCount(uint64_t &count)
254 {
255 (void)count;
256 return HDF_SUCCESS;
257 }
258
SetSampleAttributes(const AudioSampleAttributes & attrs)259 int32_t AudioCaptureExtImpl::SetSampleAttributes(const AudioSampleAttributes &attrs)
260 {
261 DHLOGI("Set sample attributes.");
262 devAttrs_ = attrs;
263 return HDF_SUCCESS;
264 }
265
GetSampleAttributes(AudioSampleAttributes & attrs)266 int32_t AudioCaptureExtImpl::GetSampleAttributes(AudioSampleAttributes &attrs)
267 {
268 DHLOGI("Get sample attributes.");
269 attrs = devAttrs_;
270 return HDF_SUCCESS;
271 }
272
GetCurrentChannelId(uint32_t & channelId)273 int32_t AudioCaptureExtImpl::GetCurrentChannelId(uint32_t &channelId)
274 {
275 DHLOGI("Get current channel id, not support yet.");
276 (void)channelId;
277 return HDF_SUCCESS;
278 }
279
SetExtraParams(const std::string & keyValueList)280 int32_t AudioCaptureExtImpl::SetExtraParams(const std::string &keyValueList)
281 {
282 DHLOGI("Set extra parameters, not support yet.");
283 (void)keyValueList;
284 return HDF_SUCCESS;
285 }
286
GetExtraParams(std::string & keyValueList)287 int32_t AudioCaptureExtImpl::GetExtraParams(std::string &keyValueList)
288 {
289 DHLOGI("Get extra parameters, not support yet.");
290 (void)keyValueList;
291 return HDF_SUCCESS;
292 }
293
ReqMmapBuffer(int32_t reqSize,AudioMmapBufferDescriptor & desc)294 int32_t AudioCaptureExtImpl::ReqMmapBuffer(int32_t reqSize, AudioMmapBufferDescriptor &desc)
295 {
296 DHLOGI("Request mmap buffer.");
297 int32_t minSize = CalculateSampleNum(devAttrs_.sampleRate, minTimeInterval_);
298 int32_t maxSize = CalculateSampleNum(devAttrs_.sampleRate, maxTimeInterval_);
299 int32_t realSize = reqSize;
300 if (reqSize < minSize) {
301 realSize = minSize;
302 } else if (reqSize > maxSize) {
303 realSize = maxSize;
304 }
305 DHLOGI("ReqMmap buffer realsize : %{public}d, minsize: %{public}d, maxsize:%{public}d.",
306 realSize, minSize, maxSize);
307 desc.totalBufferFrames = realSize;
308 ashmemLength_ = realSize * static_cast<int32_t>(devAttrs_.channelCount) * devAttrs_.format;
309 DHLOGI("Init ashmem real sample size : %{public}d, length: %{public}d.", realSize, ashmemLength_);
310 int32_t ret = InitAshmem(ashmemLength_);
311 if (ret != HDF_SUCCESS) {
312 DHLOGE("Init ashmem error..");
313 return HDF_FAILURE;
314 }
315 desc.memoryFd = fd_;
316 desc.transferFrameSize = static_cast<int32_t>(CalculateSampleNum(devAttrs_.sampleRate, timeInterval_));
317 lengthPerTrans_ = desc.transferFrameSize * static_cast<int32_t>(devAttrs_.channelCount) * devAttrs_.format;
318 desc.isShareable = false;
319 if (audioExtCallback_ == nullptr) {
320 DHLOGE("Callback is nullptr.");
321 return HDF_FAILURE;
322 }
323 ret = audioExtCallback_->RefreshAshmemInfo(captureId_, fd_, ashmemLength_, lengthPerTrans_);
324 if (ret != HDF_SUCCESS) {
325 DHLOGE("Refresh ashmem info failed.");
326 return HDF_FAILURE;
327 }
328 return HDF_SUCCESS;
329 }
330
GetMmapPosition(uint64_t & frames,AudioTimeStamp & time)331 int32_t AudioCaptureExtImpl::GetMmapPosition(uint64_t &frames, AudioTimeStamp &time)
332 {
333 DHLOGI("Get capture mmap position.");
334 if (audioExtCallback_ == nullptr) {
335 DHLOGE("Callback is nullptr.");
336 return HDF_FAILURE;
337 }
338 CurrentTime cTime;
339 int32_t ret = audioExtCallback_->ReadMmapPosition(captureId_, frames, cTime);
340 if (ret != HDF_SUCCESS) {
341 DHLOGE("Read mmap position failed.");
342 return HDF_FAILURE;
343 }
344 time.tvSec = cTime.tvSec;
345 time.tvNSec = cTime.tvNSec;
346 DHLOGI("Read mmap position. frames: %{public}" PRIu64", tvSec: %{public}" PRId64", tvNSec: %{public}" PRId64,
347 frames, cTime.tvSec, cTime.tvNSec);
348 return HDF_SUCCESS;
349 }
350
AddAudioEffect(uint64_t effectid)351 int32_t AudioCaptureExtImpl::AddAudioEffect(uint64_t effectid)
352 {
353 DHLOGI("Add audio effect, not support yet.");
354 (void)effectid;
355 return HDF_SUCCESS;
356 }
357
RemoveAudioEffect(uint64_t effectid)358 int32_t AudioCaptureExtImpl::RemoveAudioEffect(uint64_t effectid)
359 {
360 DHLOGI("Remove audio effect, not support yet.");
361 (void)effectid;
362 return HDF_SUCCESS;
363 }
364
GetFrameBufferSize(uint64_t & bufferSize)365 int32_t AudioCaptureExtImpl::GetFrameBufferSize(uint64_t &bufferSize)
366 {
367 DHLOGI("Get frame buffer size, not support yet.");
368 (void)bufferSize;
369 return HDF_SUCCESS;
370 }
371
GetCaptureDesc()372 const AudioDeviceDescriptor &AudioCaptureExtImpl::GetCaptureDesc()
373 {
374 return devDesc_;
375 }
376
SetAttrs(const std::string & adpName,const AudioDeviceDescriptor & desc,const AudioSampleAttributes & attrs,const sptr<IDAudioCallback> & callback,const int32_t dhId)377 void AudioCaptureExtImpl::SetAttrs(const std::string &adpName, const AudioDeviceDescriptor &desc,
378 const AudioSampleAttributes &attrs, const sptr<IDAudioCallback> &callback, const int32_t dhId)
379 {
380 adapterName_ = adpName;
381 devDesc_ = desc;
382 devAttrs_ = attrs;
383 audioExtCallback_ = callback;
384 dhId_ = dhId;
385 if (attrs.type == AUDIO_MMAP_NOIRQ) {
386 timeInterval_ = AUDIO_MMAP_NOIRQ_INTERVAL;
387 } else if (attrs.type == AUDIO_MMAP_VOIP) {
388 timeInterval_ = AUDIO_MMAP_VOIP_INTERVAL;
389 }
390 devAttrs_.frameSize = CalculateFrameSize(attrs.sampleRate, attrs.channelCount, attrs.format, timeInterval_, true);
391 DHLOGI("Distributed lowlatency capture set attrs, id(%{public}d). framesize(%{public}d)",
392 dhId_, devAttrs_.frameSize);
393 }
394
SetDumpFlagInner()395 void AudioCaptureExtImpl::SetDumpFlagInner()
396 {
397 DHLOGI("Set dump flag, not support yet.");
398 }
399
GetCaptureImplExt()400 AudioCaptureInterfaceImplBase *GetCaptureImplExt()
401 {
402 DHLOGI("Get low latency capture impl.");
403 static AudioCaptureExtImpl *implBase = new AudioCaptureExtImpl();
404 return implBase;
405 }
406 } // namespace V1_0
407 } // namespace Audio
408 } // namespace Distributedaudio
409 } // namespace HDI
410 } // namespace OHOS
411