• 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 
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