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 #ifdef DUMP_CAPTURE_FILE
93     if (dumpFlag_) {
94         SaveFile(HDF_CAPTURE_FILENAME, reinterpret_cast<uint8_t*>(audioData.data.data()), audioData.data.size());
95     }
96 #endif
97     frame.clear();
98     frame.resize(devAttrs_.frameSize, 0);
99     if (!muteState_.load() && memcpy_s(frame.data(), frame.size(), audioData.data.data(), audioData.data.size()) !=
100         EOK) {
101         DHLOGE("Copy capture frame failed");
102         return HDF_FAILURE;
103     }
104     ++frameIndex_;
105     AbsoluteSleep(startTime_ + frameIndex_ * framePeriodNs_ - timeOffset);
106     DHLOGD("Capture audio frame success.");
107     int64_t endTime = GetNowTimeUs();
108     if (IsOutDurationRange(startTime, endTime, lastCaptureStartTime_)) {
109         DHLOGD("This time capture frame spend: %" PRId64" us, The interval of this time and the last time: %" PRId64
110             " us", endTime - startTime, startTime - lastCaptureStartTime_);
111     }
112     lastCaptureStartTime_ = startTime;
113     return HDF_SUCCESS;
114 }
115 
Start()116 int32_t AudioCaptureInterfaceImpl::Start()
117 {
118     DHLOGI("Start capture.");
119     cJSON *jParam = cJSON_CreateObject();
120     if (jParam == nullptr) {
121         DHLOGE("Failed to create cJSON object.");
122         return HDF_FAILURE;
123     }
124     cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(devDesc_.pins).c_str());
125     char *jsonData = cJSON_PrintUnformatted(jParam);
126     if (jsonData == nullptr) {
127         DHLOGE("Failed to create JSON data.");
128         cJSON_Delete(jParam);
129         return HDF_FAILURE;
130     }
131     std::string content(jsonData);
132     cJSON_Delete(jParam);
133     cJSON_free(jsonData);
134     DAudioEvent event = { HDF_AUDIO_EVENT_START, content };
135     if (audioExtCallback_ == nullptr) {
136         DHLOGE("Callback is nullptr.");
137         return HDF_FAILURE;
138     }
139     if (audioExtCallback_->NotifyEvent(captureId_, event) != HDF_SUCCESS) {
140         DHLOGE("Notify start event failed.");
141         return HDF_FAILURE;
142     }
143     std::lock_guard<std::mutex> captureLck(captureMtx_);
144     captureStatus_ = CAPTURE_STATUS_START;
145     frameIndex_ = 0;
146     startTime_ = 0;
147     return HDF_SUCCESS;
148 }
149 
Stop()150 int32_t AudioCaptureInterfaceImpl::Stop()
151 {
152     DHLOGI("Stop capture.");
153     cJSON *jParam = cJSON_CreateObject();
154     if (jParam == nullptr) {
155         DHLOGE("Failed to create cJSON object.");
156         return HDF_FAILURE;
157     }
158     cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(devDesc_.pins).c_str());
159     char *jsonData = cJSON_PrintUnformatted(jParam);
160     if (jsonData == nullptr) {
161         DHLOGE("Failed to create JSON data.");
162         cJSON_Delete(jParam);
163         return HDF_FAILURE;
164     }
165     cJSON_Delete(jParam);
166     cJSON_free(jsonData);
167     std::string content(jsonData);
168     DAudioEvent event = { HDF_AUDIO_EVENT_STOP, content };
169     if (audioExtCallback_ == nullptr) {
170         DHLOGE("Callback is nullptr.");
171         return HDF_FAILURE;
172     }
173     if (audioExtCallback_->NotifyEvent(captureId_, event) != HDF_SUCCESS) {
174         DHLOGE("Notify stop event failed.");
175         return HDF_FAILURE;
176     }
177     std::lock_guard<std::mutex> captureLck(captureMtx_);
178     captureStatus_ = CAPTURE_STATUS_STOP;
179     return HDF_SUCCESS;
180 }
181 
Pause()182 int32_t AudioCaptureInterfaceImpl::Pause()
183 {
184     DHLOGI("Pause capture.");
185     std::lock_guard<std::mutex> captureLck(captureMtx_);
186     captureStatus_ = CAPTURE_STATUS_PAUSE;
187     return HDF_SUCCESS;
188 }
189 
Resume()190 int32_t AudioCaptureInterfaceImpl::Resume()
191 {
192     return HDF_SUCCESS;
193 }
194 
Flush()195 int32_t AudioCaptureInterfaceImpl::Flush()
196 {
197     return HDF_SUCCESS;
198 }
199 
TurnStandbyMode()200 int32_t AudioCaptureInterfaceImpl::TurnStandbyMode()
201 {
202     DHLOGI("Turn stand by mode, not support yet.");
203     return HDF_SUCCESS;
204 }
205 
AudioDevDump(int32_t range,int32_t fd)206 int32_t AudioCaptureInterfaceImpl::AudioDevDump(int32_t range, int32_t fd)
207 {
208     DHLOGI("Dump audio info, not support yet.");
209     (void)range;
210     (void)fd;
211     return HDF_SUCCESS;
212 }
213 
IsSupportsPauseAndResume(bool & supportPause,bool & supportResume)214 int32_t AudioCaptureInterfaceImpl::IsSupportsPauseAndResume(bool &supportPause, bool &supportResume)
215 {
216     DHLOGI("Check whether pause and resume is supported, not support yet.");
217     (void)supportPause;
218     (void)supportResume;
219     return HDF_SUCCESS;
220 }
221 
CheckSceneCapability(const AudioSceneDescriptor & scene,bool & supported)222 int32_t AudioCaptureInterfaceImpl::CheckSceneCapability(const AudioSceneDescriptor &scene, bool &supported)
223 {
224     DHLOGI("Check scene capability.");
225     (void)scene;
226     supported = false;
227     return HDF_SUCCESS;
228 }
229 
SelectScene(const AudioSceneDescriptor & scene)230 int32_t AudioCaptureInterfaceImpl::SelectScene(const AudioSceneDescriptor &scene)
231 {
232     DHLOGI("Select audio scene, not support yet.");
233     (void)scene;
234     return HDF_SUCCESS;
235 }
236 
SetMute(bool mute)237 int32_t AudioCaptureInterfaceImpl::SetMute(bool mute)
238 {
239     DHLOGI("Set audio mute state.");
240     muteState_.store(mute);
241     return HDF_SUCCESS;
242 }
243 
GetMute(bool & mute)244 int32_t AudioCaptureInterfaceImpl::GetMute(bool &mute)
245 {
246     DHLOGI("Get audio mute state.");
247     mute = muteState_.load();
248     return HDF_SUCCESS;
249 }
250 
SetVolume(float volume)251 int32_t AudioCaptureInterfaceImpl::SetVolume(float volume)
252 {
253     DHLOGI("Can not set vol not by this interface.");
254     (void)volume;
255     return HDF_SUCCESS;
256 }
257 
GetVolume(float & volume)258 int32_t AudioCaptureInterfaceImpl::GetVolume(float &volume)
259 {
260     DHLOGI("Can not get vol not by this interface.");
261     (void)volume;
262     return HDF_SUCCESS;
263 }
264 
GetGainThreshold(float & min,float & max)265 int32_t AudioCaptureInterfaceImpl::GetGainThreshold(float &min, float &max)
266 {
267     DHLOGI("Get gain threshold, not support yet.");
268     min = 0;
269     max = 0;
270     return HDF_SUCCESS;
271 }
272 
SetGain(float gain)273 int32_t AudioCaptureInterfaceImpl::SetGain(float gain)
274 {
275     DHLOGI("Set gain, not support yet.");
276     (void)gain;
277     return HDF_SUCCESS;
278 }
279 
GetGain(float & gain)280 int32_t AudioCaptureInterfaceImpl::GetGain(float &gain)
281 {
282     DHLOGI("Get gain, not support yet.");
283     gain = 1.0;
284     return HDF_SUCCESS;
285 }
286 
GetFrameSize(uint64_t & size)287 int32_t AudioCaptureInterfaceImpl::GetFrameSize(uint64_t &size)
288 {
289     (void)size;
290     return HDF_SUCCESS;
291 }
292 
GetFrameCount(uint64_t & count)293 int32_t AudioCaptureInterfaceImpl::GetFrameCount(uint64_t &count)
294 {
295     (void)count;
296     return HDF_SUCCESS;
297 }
298 
SetSampleAttributes(const AudioSampleAttributes & attrs)299 int32_t AudioCaptureInterfaceImpl::SetSampleAttributes(const AudioSampleAttributes &attrs)
300 {
301     DHLOGI("Set sample attributes.");
302     devAttrs_ = attrs;
303     return HDF_SUCCESS;
304 }
305 
GetSampleAttributes(AudioSampleAttributes & attrs)306 int32_t AudioCaptureInterfaceImpl::GetSampleAttributes(AudioSampleAttributes &attrs)
307 {
308     DHLOGI("Get sample attributes.");
309     attrs = devAttrs_;
310     return HDF_SUCCESS;
311 }
312 
GetCurrentChannelId(uint32_t & channelId)313 int32_t AudioCaptureInterfaceImpl::GetCurrentChannelId(uint32_t &channelId)
314 {
315     DHLOGI("Get current channel id, not support yet.");
316     (void)channelId;
317     return HDF_SUCCESS;
318 }
319 
SetExtraParams(const std::string & keyValueList)320 int32_t AudioCaptureInterfaceImpl::SetExtraParams(const std::string &keyValueList)
321 {
322     DHLOGI("Set extra parameters, not support yet.");
323     (void)keyValueList;
324     return HDF_SUCCESS;
325 }
326 
GetExtraParams(std::string & keyValueList)327 int32_t AudioCaptureInterfaceImpl::GetExtraParams(std::string &keyValueList)
328 {
329     DHLOGI("Get extra parameters, not support yet.");
330     (void)keyValueList;
331     return HDF_SUCCESS;
332 }
333 
ReqMmapBuffer(int32_t reqSize,AudioMmapBufferDescriptor & desc)334 int32_t AudioCaptureInterfaceImpl::ReqMmapBuffer(int32_t reqSize, AudioMmapBufferDescriptor &desc)
335 {
336     DHLOGI("Request mmap buffer, not support yet.");
337     (void)reqSize;
338     (void)desc;
339     return HDF_SUCCESS;
340 }
341 
GetMmapPosition(uint64_t & frames,AudioTimeStamp & time)342 int32_t AudioCaptureInterfaceImpl::GetMmapPosition(uint64_t &frames, AudioTimeStamp &time)
343 {
344     DHLOGI("Get mmap position, not support yet.");
345     (void)frames;
346     (void)time;
347     return HDF_SUCCESS;
348 }
349 
AddAudioEffect(uint64_t effectid)350 int32_t AudioCaptureInterfaceImpl::AddAudioEffect(uint64_t effectid)
351 {
352     DHLOGI("Add audio effect, not support yet.");
353     (void)effectid;
354     return HDF_SUCCESS;
355 }
356 
RemoveAudioEffect(uint64_t effectid)357 int32_t AudioCaptureInterfaceImpl::RemoveAudioEffect(uint64_t effectid)
358 {
359     DHLOGI("Remove audio effect, not support yet.");
360     (void)effectid;
361     return HDF_SUCCESS;
362 }
363 
GetFrameBufferSize(uint64_t & bufferSize)364 int32_t AudioCaptureInterfaceImpl::GetFrameBufferSize(uint64_t &bufferSize)
365 {
366     DHLOGI("Get frame buffer size, not support yet.");
367     (void)bufferSize;
368     return HDF_SUCCESS;
369 }
370 
SetAttrs(const std::string & adpName,const AudioDeviceDescriptor & desc,const AudioSampleAttributes & attrs,const sptr<IDAudioCallback> & callback,const int32_t dhId)371 void AudioCaptureInterfaceImpl::SetAttrs(const std::string &adpName, const AudioDeviceDescriptor &desc,
372     const AudioSampleAttributes &attrs, const sptr<IDAudioCallback> &callback, const int32_t dhId)
373 {
374     DHLOGI("Set attrs, not support yet.");
375 }
376 
SetDumpFlagInner()377 void AudioCaptureInterfaceImpl::SetDumpFlagInner()
378 {
379     dumpFlag_ = true;
380 }
381 
GetCaptureDesc()382 const AudioDeviceDescriptor &AudioCaptureInterfaceImpl::GetCaptureDesc()
383 {
384     return devDesc_;
385 }
386 } // V1_0
387 } // Audio
388 } // Distributedaudio
389 } // HDI
390 } // OHOS
391