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
139 AUDIO_INFO_LOG("in");
140 std::lock_guard<std::mutex> lock(wakeupMutex_);
141 if (!sourceInited_) {
142 return;
143 }
144 sourceInited_ = false;
145 --sourceInitCount_;
146 if (sourceInitCount_ == 0) {
147 wakeupBuffer_.reset();
148 audioCaptureSource_.DeInit();
149 }
150 }
151
IsInited(void)152 bool WakeupAudioCaptureSource::IsInited(void)
153 {
154 return sourceInited_;
155 }
156
Start(void)157 int32_t WakeupAudioCaptureSource::Start(void)
158 {
159 std::lock_guard<std::mutex> lock(wakeupMutex_);
160 if (started_) {
161 return SUCCESS;
162 }
163
164 int32_t ret = SUCCESS;
165 if (startCount_ == 0) {
166 ret = audioCaptureSource_.Start();
167 }
168 if (ret == SUCCESS) {
169 started_ = true;
170 ++startCount_;
171 }
172 return SUCCESS;
173 }
174
Stop(void)175 int32_t WakeupAudioCaptureSource::Stop(void)
176 {
177 std::lock_guard<std::mutex> lock(wakeupMutex_);
178 if (!started_) {
179 return SUCCESS;
180 }
181
182 int32_t ret = SUCCESS;
183 if (startCount_ == 1) {
184 ret = audioCaptureSource_.Stop();
185 }
186 if (ret == SUCCESS) {
187 started_ = false;
188 --startCount_;
189 }
190 return SUCCESS;
191 }
192
Resume(void)193 int32_t WakeupAudioCaptureSource::Resume(void)
194 {
195 return audioCaptureSource_.Resume();
196 }
197
Pause(void)198 int32_t WakeupAudioCaptureSource::Pause(void)
199 {
200 return audioCaptureSource_.Pause();
201 }
202
Flush(void)203 int32_t WakeupAudioCaptureSource::Flush(void)
204 {
205 return audioCaptureSource_.Flush();
206 }
207
Reset(void)208 int32_t WakeupAudioCaptureSource::Reset(void)
209 {
210 return audioCaptureSource_.Reset();
211 }
212
CaptureFrame(char * frame,uint64_t requestBytes,uint64_t & replyBytes)213 int32_t WakeupAudioCaptureSource::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes)
214 {
215 int32_t res = wakeupBuffer_->Poll(frame, requestBytes, replyBytes, curWritePos_);
216 curWritePos_ += replyBytes;
217 return res;
218 }
219
CaptureFrameWithEc(FrameDesc * fdesc,uint64_t & replyBytes,FrameDesc * fdescEc,uint64_t & replyBytesEc)220 int32_t WakeupAudioCaptureSource::CaptureFrameWithEc(FrameDesc *fdesc, uint64_t &replyBytes, FrameDesc *fdescEc,
221 uint64_t &replyBytesEc)
222 {
223 AUDIO_INFO_LOG("not support");
224 return ERR_NOT_SUPPORTED;
225 }
226
GetAudioParameter(const AudioParamKey key,const std::string & condition)227 std::string WakeupAudioCaptureSource::GetAudioParameter(const AudioParamKey key, const std::string &condition)
228 {
229 return "";
230 }
231
SetVolume(float left,float right)232 int32_t WakeupAudioCaptureSource::SetVolume(float left, float right)
233 {
234 return audioCaptureSource_.SetVolume(left, right);
235 }
236
GetVolume(float & left,float & right)237 int32_t WakeupAudioCaptureSource::GetVolume(float &left, float &right)
238 {
239 return audioCaptureSource_.GetVolume(left, right);
240 }
241
SetMute(bool isMute)242 int32_t WakeupAudioCaptureSource::SetMute(bool isMute)
243 {
244 return audioCaptureSource_.SetMute(isMute);
245 }
246
GetMute(bool & isMute)247 int32_t WakeupAudioCaptureSource::GetMute(bool &isMute)
248 {
249 return audioCaptureSource_.GetMute(isMute);
250 }
251
GetTransactionId(void)252 uint64_t WakeupAudioCaptureSource::GetTransactionId(void)
253 {
254 return audioCaptureSource_.GetTransactionId();
255 }
256
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)257 int32_t WakeupAudioCaptureSource::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
258 {
259 return audioCaptureSource_.GetPresentationPosition(frames, timeSec, timeNanoSec);
260 }
261
GetMaxAmplitude(void)262 float WakeupAudioCaptureSource::GetMaxAmplitude(void)
263 {
264 return audioCaptureSource_.GetMaxAmplitude();
265 }
266
SetAudioScene(AudioScene audioScene,DeviceType activeDevice)267 int32_t WakeupAudioCaptureSource::SetAudioScene(AudioScene audioScene, DeviceType activeDevice)
268 {
269 return audioCaptureSource_.SetAudioScene(audioScene, activeDevice);
270 }
271
UpdateActiveDevice(DeviceType inputDevice)272 int32_t WakeupAudioCaptureSource::UpdateActiveDevice(DeviceType inputDevice)
273 {
274 return audioCaptureSource_.UpdateActiveDevice(inputDevice);
275 }
276
RegistCallback(uint32_t type,IAudioSourceCallback * callback)277 void WakeupAudioCaptureSource::RegistCallback(uint32_t type, IAudioSourceCallback *callback)
278 {
279 return audioCaptureSource_.RegistCallback(type, callback);
280 }
281
RegistCallback(uint32_t type,std::shared_ptr<IAudioSourceCallback> callback)282 void WakeupAudioCaptureSource::RegistCallback(uint32_t type, std::shared_ptr<IAudioSourceCallback> callback)
283 {
284 return audioCaptureSource_.RegistCallback(type, callback);
285 }
286
UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE],const size_t size)287 int32_t WakeupAudioCaptureSource::UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE], const size_t size)
288 {
289 return audioCaptureSource_.UpdateAppsUid(appsUid, size);
290 }
291
UpdateAppsUid(const std::vector<int32_t> & appsUid)292 int32_t WakeupAudioCaptureSource::UpdateAppsUid(const std::vector<int32_t> &appsUid)
293 {
294 return audioCaptureSource_.UpdateAppsUid(appsUid);
295 }
296
DumpInfo(std::string & dumpString)297 void WakeupAudioCaptureSource::DumpInfo(std::string &dumpString)
298 {
299 dumpString += "type: WakeupSource\tstarted: " + std::string(started_ ? "true" : "false") + "\n";
300 }
301
302 } // namespace AudioStandard
303 } // namespace OHOS
304