• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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