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 "WakeupAudioCaptureSource"
18 #endif
19
20 #include "source/wakeup_audio_capture_source.h"
21 #include "common/hdi_adapter_info.h"
22
23 namespace OHOS {
24 namespace AudioStandard {
WakeupBuffer(IAudioCaptureSource * source)25 WakeupBuffer::WakeupBuffer(IAudioCaptureSource *source)
26 : source_(source)
27 {
28 buffer_ = std::make_unique<char[]>(MAX_BUFFER_SIZE);
29 }
30
Poll(char * frame,uint64_t requestBytes,uint64_t & replyBytes,uint64_t & curWritePos)31 int32_t WakeupBuffer::Poll(char *frame, uint64_t requestBytes, uint64_t &replyBytes, uint64_t &curWritePos)
32 {
33 std::lock_guard<std::mutex> lock(mutex_);
34
35 if (curWritePos < headNum_) {
36 curWritePos = headNum_;
37 }
38
39 if (curWritePos >= (headNum_ + size_)) {
40 if (requestBytes > MAX_BUFFER_SIZE) {
41 requestBytes = MAX_BUFFER_SIZE;
42 }
43 int32_t res = source_->CaptureFrame(frame, requestBytes, replyBytes);
44 Offer(frame, replyBytes);
45 return res;
46 }
47 if (requestBytes > size_) { // size != 0
48 replyBytes = size_;
49 } else {
50 replyBytes = requestBytes;
51 }
52
53 uint64_t tail = (head_ + size_) % MAX_BUFFER_SIZE;
54 if (tail > head_) {
55 MemcpyAndCheck(frame, replyBytes, buffer_.get() + head_, replyBytes);
56 headNum_ += replyBytes;
57 size_ -= replyBytes;
58 head_ = (head_ + replyBytes) % MAX_BUFFER_SIZE;
59 } else {
60 uint64_t copySize = std::min((MAX_BUFFER_SIZE - head_), replyBytes);
61 if (copySize != 0) {
62 MemcpyAndCheck(frame, replyBytes, buffer_.get() + head_, copySize);
63 headNum_ += copySize;
64 size_ -= copySize;
65 head_ = (head_ + copySize) % MAX_BUFFER_SIZE;
66 }
67
68 uint64_t remainCopySize = replyBytes - copySize;
69 if (remainCopySize != 0) {
70 MemcpyAndCheck(frame + copySize, remainCopySize, buffer_.get(), remainCopySize);
71 headNum_ += remainCopySize;
72 size_ -= remainCopySize;
73 head_ = (head_ + remainCopySize) % MAX_BUFFER_SIZE;
74 }
75 }
76
77 return SUCCESS;
78 }
79
Offer(const char * frame,const uint64_t bufferBytes)80 void WakeupBuffer::Offer(const char *frame, const uint64_t bufferBytes)
81 {
82 if ((size_ + bufferBytes) > MAX_BUFFER_SIZE) { // head_ need shift
83 uint64_t shift = (size_ + bufferBytes) - MAX_BUFFER_SIZE; // 1 to MAX_BUFFER_SIZE
84 headNum_ += shift;
85 if (size_ > shift) {
86 size_ -= shift;
87 head_ = ((head_ + shift) % MAX_BUFFER_SIZE);
88 } else {
89 size_ = 0;
90 head_ = 0;
91 }
92 }
93
94 uint64_t tail = (head_ + size_) % MAX_BUFFER_SIZE;
95 if (tail < head_) {
96 MemcpyAndCheck((buffer_.get() + tail), bufferBytes, frame, bufferBytes);
97 } else {
98 uint64_t copySize = std::min(MAX_BUFFER_SIZE - tail, bufferBytes);
99 MemcpyAndCheck((buffer_.get() + tail), MAX_BUFFER_SIZE - tail, frame, copySize);
100
101 if (copySize < bufferBytes) {
102 MemcpyAndCheck((buffer_.get()), bufferBytes - copySize, frame + copySize, bufferBytes - copySize);
103 }
104 }
105 size_ += bufferBytes;
106 }
107
WakeupAudioCaptureSource(const uint32_t captureId)108 WakeupAudioCaptureSource::WakeupAudioCaptureSource(const uint32_t captureId)
109 : audioCaptureSource_(captureId)
110 {
111 }
112
Init(const IAudioSourceAttr & attr)113 int32_t WakeupAudioCaptureSource::Init(const IAudioSourceAttr &attr)
114 {
115 std::lock_guard<std::mutex> lock(wakeupMutex_);
116 if (sourceInited_) {
117 return SUCCESS;
118 }
119 curWritePos_ = 0;
120
121 int32_t ret = SUCCESS;
122 if (sourceInitCount_ == 0) {
123 if (wakeupBuffer_ == nullptr) {
124 wakeupBuffer_ = std::make_unique<WakeupBuffer>(&audioCaptureSource_);
125 }
126 ret = audioCaptureSource_.Init(attr);
127 CHECK_AND_RETURN_RET(ret == SUCCESS, ret);
128 }
129
130 sourceInited_ = true;
131 ++sourceInitCount_;
132 return SUCCESS;
133 }
134
DeInit(void)135 void WakeupAudioCaptureSource::DeInit(void)
136 {
137 AudioXCollie audioXCollie("WakeupAudioCaptureSource::DeInit", TIMEOUT_SECONDS_5,
138 nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG);
139
140 AUDIO_INFO_LOG("in");
141 std::lock_guard<std::mutex> lock(wakeupMutex_);
142 if (!sourceInited_) {
143 return;
144 }
145 sourceInited_ = false;
146 --sourceInitCount_;
147 if (sourceInitCount_ == 0) {
148 wakeupBuffer_.reset();
149 audioCaptureSource_.DeInit();
150 }
151 }
152
IsInited(void)153 bool WakeupAudioCaptureSource::IsInited(void)
154 {
155 return sourceInited_;
156 }
157
Start(void)158 int32_t WakeupAudioCaptureSource::Start(void)
159 {
160 std::lock_guard<std::mutex> lock(wakeupMutex_);
161 if (started_) {
162 return SUCCESS;
163 }
164
165 int32_t ret = SUCCESS;
166 if (startCount_ == 0) {
167 ret = audioCaptureSource_.Start();
168 }
169 if (ret == SUCCESS) {
170 started_ = true;
171 ++startCount_;
172 }
173 return SUCCESS;
174 }
175
Stop(void)176 int32_t WakeupAudioCaptureSource::Stop(void)
177 {
178 std::lock_guard<std::mutex> lock(wakeupMutex_);
179 if (!started_) {
180 return SUCCESS;
181 }
182
183 int32_t ret = SUCCESS;
184 if (startCount_ == 1) {
185 ret = audioCaptureSource_.Stop();
186 }
187 if (ret == SUCCESS) {
188 started_ = false;
189 --startCount_;
190 }
191 return SUCCESS;
192 }
193
Resume(void)194 int32_t WakeupAudioCaptureSource::Resume(void)
195 {
196 return audioCaptureSource_.Resume();
197 }
198
Pause(void)199 int32_t WakeupAudioCaptureSource::Pause(void)
200 {
201 return audioCaptureSource_.Pause();
202 }
203
Flush(void)204 int32_t WakeupAudioCaptureSource::Flush(void)
205 {
206 return audioCaptureSource_.Flush();
207 }
208
Reset(void)209 int32_t WakeupAudioCaptureSource::Reset(void)
210 {
211 return audioCaptureSource_.Reset();
212 }
213
CaptureFrame(char * frame,uint64_t requestBytes,uint64_t & replyBytes)214 int32_t WakeupAudioCaptureSource::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes)
215 {
216 int32_t res = wakeupBuffer_->Poll(frame, requestBytes, replyBytes, curWritePos_);
217 curWritePos_ += replyBytes;
218 return res;
219 }
220
CaptureFrameWithEc(FrameDesc * fdesc,uint64_t & replyBytes,FrameDesc * fdescEc,uint64_t & replyBytesEc)221 int32_t WakeupAudioCaptureSource::CaptureFrameWithEc(FrameDesc *fdesc, uint64_t &replyBytes, FrameDesc *fdescEc,
222 uint64_t &replyBytesEc)
223 {
224 AUDIO_INFO_LOG("not support");
225 return ERR_NOT_SUPPORTED;
226 }
227
GetAudioParameter(const AudioParamKey key,const std::string & condition)228 std::string WakeupAudioCaptureSource::GetAudioParameter(const AudioParamKey key, const std::string &condition)
229 {
230 return "";
231 }
232
SetVolume(float left,float right)233 int32_t WakeupAudioCaptureSource::SetVolume(float left, float right)
234 {
235 return audioCaptureSource_.SetVolume(left, right);
236 }
237
GetVolume(float & left,float & right)238 int32_t WakeupAudioCaptureSource::GetVolume(float &left, float &right)
239 {
240 return audioCaptureSource_.GetVolume(left, right);
241 }
242
SetMute(bool isMute)243 int32_t WakeupAudioCaptureSource::SetMute(bool isMute)
244 {
245 return audioCaptureSource_.SetMute(isMute);
246 }
247
GetMute(bool & isMute)248 int32_t WakeupAudioCaptureSource::GetMute(bool &isMute)
249 {
250 return audioCaptureSource_.GetMute(isMute);
251 }
252
GetTransactionId(void)253 uint64_t WakeupAudioCaptureSource::GetTransactionId(void)
254 {
255 return audioCaptureSource_.GetTransactionId();
256 }
257
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)258 int32_t WakeupAudioCaptureSource::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
259 {
260 return audioCaptureSource_.GetPresentationPosition(frames, timeSec, timeNanoSec);
261 }
262
GetMaxAmplitude(void)263 float WakeupAudioCaptureSource::GetMaxAmplitude(void)
264 {
265 return audioCaptureSource_.GetMaxAmplitude();
266 }
267
SetAudioScene(AudioScene audioScene,bool scoExcludeFlag)268 int32_t WakeupAudioCaptureSource::SetAudioScene(AudioScene audioScene, bool scoExcludeFlag)
269 {
270 return audioCaptureSource_.SetAudioScene(audioScene);
271 }
272
UpdateActiveDevice(DeviceType inputDevice)273 int32_t WakeupAudioCaptureSource::UpdateActiveDevice(DeviceType inputDevice)
274 {
275 return audioCaptureSource_.UpdateActiveDevice(inputDevice);
276 }
277
RegistCallback(uint32_t type,IAudioSourceCallback * callback)278 void WakeupAudioCaptureSource::RegistCallback(uint32_t type, IAudioSourceCallback *callback)
279 {
280 return audioCaptureSource_.RegistCallback(type, callback);
281 }
282
RegistCallback(uint32_t type,std::shared_ptr<IAudioSourceCallback> callback)283 void WakeupAudioCaptureSource::RegistCallback(uint32_t type, std::shared_ptr<IAudioSourceCallback> callback)
284 {
285 return audioCaptureSource_.RegistCallback(type, callback);
286 }
287
UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE],const size_t size)288 int32_t WakeupAudioCaptureSource::UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE], const size_t size)
289 {
290 return audioCaptureSource_.UpdateAppsUid(appsUid, size);
291 }
292
UpdateAppsUid(const std::vector<int32_t> & appsUid)293 int32_t WakeupAudioCaptureSource::UpdateAppsUid(const std::vector<int32_t> &appsUid)
294 {
295 return audioCaptureSource_.UpdateAppsUid(appsUid);
296 }
297
DumpInfo(std::string & dumpString)298 void WakeupAudioCaptureSource::DumpInfo(std::string &dumpString)
299 {
300 dumpString += "type: WakeupSource\tstarted: " + std::string(started_ ? "true" : "false") + "\n";
301 }
302
SetDmDeviceType(uint16_t dmDeviceType,DeviceType deviceType)303 void WakeupAudioCaptureSource::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType)
304 {
305 AUDIO_INFO_LOG("not support");
306 }
307
308 } // namespace AudioStandard
309 } // namespace OHOS
310