• 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 "HpaePcmBuffer"
18 #endif
19 
20 #include "securec.h"
21 #include "simd_utils.h"
22 #include "hpae_pcm_buffer.h"
23 #include "audio_engine_log.h"
24 
25 namespace OHOS {
26 namespace AudioStandard {
27 namespace HPAE {
HpaePcmBuffer(PcmBufferInfo & pcmBufferInfo)28 HpaePcmBuffer::HpaePcmBuffer(PcmBufferInfo &pcmBufferInfo) : pcmBufferInfo_(pcmBufferInfo)
29 {
30     InitPcmProcess();
31 }
32 
operator =(HpaePcmBuffer & other)33 HpaePcmBuffer &HpaePcmBuffer::operator=(HpaePcmBuffer &other)
34 {
35     if (this != &other) {
36         pcmBufferInfo_ = other.pcmBufferInfo_;
37         InitPcmProcess();
38         int32_t ret = memcpy_s(GetPcmDataBuffer(), bufferByteSize_, other.GetPcmDataBuffer(), bufferByteSize_);
39         if (ret != 0) {
40             AUDIO_ERR_LOG("memcpy failed when copy PcmBuffer");
41         }
42     }
43     return *this;
44 }
45 
HpaePcmBuffer(HpaePcmBuffer && other)46 HpaePcmBuffer::HpaePcmBuffer(HpaePcmBuffer &&other)
47 {
48     pcmBufferInfo_ = other.pcmBufferInfo_;
49     bufferByteSize_ = other.bufferByteSize_;
50     bufferFloatSize_ = other.bufferFloatSize_;
51     dataByteSize_ = other.dataByteSize_;
52     pcmDataBuffer_ = std::move(other.pcmDataBuffer_);
53     pcmProcessVec_ = std::move(other.pcmProcessVec_);
54     other.pcmBufferInfo_.frames = 0;
55     other.bufferByteSize_ = 0;
56     other.bufferFloatSize_ = 0;
57     other.dataByteSize_ = 0;
58 }
59 
InitPcmProcess()60 void HpaePcmBuffer::InitPcmProcess()
61 {
62     size_t ch = GetChannelCount();
63     size_t frameLen = GetFrameLen();
64     size_t frames = GetFrames();
65     size_t addBytes = MEMORY_ALIGN_BYTE_NUM - (frameLen * sizeof(float) * ch) % MEMORY_ALIGN_BYTE_NUM;
66     size_t dataSize = frameLen * sizeof(float) * ch;
67     frameByteSize_ = frameLen * sizeof(float) * ch + addBytes;
68     frameFloatSize_ = frameByteSize_ / sizeof(float);
69     bufferByteSize_ = frameByteSize_ * frames;
70     bufferFloatSize_ = frameFloatSize_ * frames;
71     dataByteSize_ = dataSize * frames;
72     frameSample_ = frameLen * ch;
73     pcmDataBuffer_.resize(bufferFloatSize_);
74     readPos_.store(0);
75     writePos_.store(0);
76     curFrames_.store(0);
77     pcmProcessVec_.clear();
78     pcmProcessVec_.reserve(frames);
79     float *itr = pcmDataBuffer_.data();
80     for (size_t i = 0; i < frames; ++i) {
81         pcmProcessVec_.push_back(HpaePcmProcess(itr, frameSample_));
82         itr += frameFloatSize_;
83     }
84 }
85 
operator +=(HpaePcmBuffer & other)86 HpaePcmBuffer &HpaePcmBuffer::operator+=(HpaePcmBuffer &other)
87 {
88     for (size_t i = 0; i < pcmProcessVec_.size(); ++i) {
89         pcmProcessVec_[i] += other[i];
90     }
91     return *this;
92 }
93 
operator -=(HpaePcmBuffer & other)94 HpaePcmBuffer &HpaePcmBuffer::operator-=(HpaePcmBuffer &other)
95 {
96     for (size_t i = 0; i < pcmProcessVec_.size(); ++i) {
97         pcmProcessVec_[i] -= other[i];
98     }
99     return *this;
100 }
101 
operator *=(HpaePcmBuffer & other)102 HpaePcmBuffer &HpaePcmBuffer::operator*=(HpaePcmBuffer &other)
103 {
104     for (size_t i = 0; i < pcmProcessVec_.size(); ++i) {
105         pcmProcessVec_[i] *= other[i];
106     }
107     return *this;
108 }
109 
operator =(const std::vector<std::vector<float>> & other)110 HpaePcmBuffer &HpaePcmBuffer::operator=(const std::vector<std::vector<float>> &other)
111 {
112     for (size_t i = 0; i < other.size() && i < pcmProcessVec_.size(); ++i) {
113         if (IsMultiFrames()) {
114             if (curFrames_.load() < GetFrames()) {
115                 pcmProcessVec_[i + writePos_.load()] = other[i];
116                 writePos_.store((writePos_.load() + 1) % GetFrames());
117                 curFrames_.fetch_add(1);
118             } else {
119                 AUDIO_WARNING_LOG("HpaePcmBuffer::operator=, frames is full index = %{public}zu", i);
120             }
121         } else {
122             pcmProcessVec_[i] = other[i];
123         }
124     }
125     return *this;
126 }
127 
operator =(const std::vector<float> & other)128 HpaePcmBuffer &HpaePcmBuffer::operator=(const std::vector<float> &other)
129 {
130     if (IsMultiFrames()) {
131         if (curFrames_.load() < GetFrames()) {
132             pcmProcessVec_[writePos_.load()] = other;
133             writePos_.store((writePos_.load() + 1) % GetFrames());
134             curFrames_.fetch_add(1);
135         } else {
136             AUDIO_WARNING_LOG("HpaePcmBuffer::operator=, frames is full");
137         }
138     } else {
139         pcmProcessVec_[0] = other;
140     }
141     return *this;
142 }
143 
Reset()144 void HpaePcmBuffer::Reset()
145 {
146     for (HpaePcmProcess &pcmProc : pcmProcessVec_) {
147         pcmProc.Reset();
148     }
149     readPos_.store(0);
150     writePos_.store(0);
151     curFrames_.store(0);
152 }
153 
GetFrameData(std::vector<float> & frameData)154 bool HpaePcmBuffer::GetFrameData(std::vector<float> &frameData)
155 {
156     if (!IsMultiFrames()) {
157         return false;
158     }
159 
160     if (curFrames_.load() <= 0) {
161         AUDIO_WARNING_LOG("GetFrameData vector frames is empty");
162         return false;
163     }
164     int32_t ret = memcpy_s(frameData.data(),
165         sizeof(float) * frameData.size(),
166         pcmProcessVec_[readPos_.load()].Begin(),
167         frameSample_ * sizeof(float));
168     if (ret != 0) {
169         return false;
170     }
171     readPos_.store((readPos_.load() + 1) % GetFrames());
172     curFrames_.fetch_sub(1);
173     return true;
174 }
175 // frameData is not MultiFrames
GetFrameData(HpaePcmBuffer & frameData)176 bool HpaePcmBuffer::GetFrameData(HpaePcmBuffer &frameData)
177 {
178     if (!IsMultiFrames() || frameData.IsMultiFrames()) {
179         return false;
180     }
181 
182     if (curFrames_.load() <= 0) {
183         AUDIO_WARNING_LOG("GetFrameData HpaePcmBuffer frames is empty");
184         return false;
185     }
186     int32_t ret = memcpy_s(frameData.GetPcmDataBuffer(),
187         sizeof(float) * frameData.Size(),
188         pcmProcessVec_[readPos_.load()].Begin(),
189         frameSample_ * sizeof(float));
190     if (ret != 0) {
191         return false;
192     }
193     readPos_.store((readPos_.load() + 1) % GetFrames());
194     curFrames_.fetch_sub(1);
195     return true;
196 }
197 
PushFrameData(std::vector<float> & frameData)198 bool HpaePcmBuffer::PushFrameData(std::vector<float> &frameData)
199 {
200     if (!IsMultiFrames()) {
201         return false;
202     }
203 
204     if (curFrames_.load() >= GetFrames()) {
205         AUDIO_WARNING_LOG("PushFrameData vector frames is full");
206         return false;
207     }
208     int32_t ret = memcpy_s(pcmProcessVec_[writePos_.load()].Begin(), frameByteSize_,
209         frameData.data(), sizeof(float) * frameData.size());
210     if (ret != 0) {
211         AUDIO_ERR_LOG("memcpy failed when PushFrameData");
212         return false;
213     }
214     writePos_.store((writePos_.load() + 1) % GetFrames());
215     curFrames_.fetch_add(1);
216     return true;
217 }
218 
PushFrameData(HpaePcmBuffer & frameData)219 bool HpaePcmBuffer::PushFrameData(HpaePcmBuffer &frameData)
220 {
221     if (!IsMultiFrames() || frameData.IsMultiFrames()) {
222         return false;
223     }
224 
225     if (curFrames_.load() >= GetFrames()) {
226         AUDIO_WARNING_LOG("PushFrameData HpaePcmBuffer frames is full");
227         return false;
228     }
229     int32_t ret = memcpy_s(pcmProcessVec_[writePos_.load()].Begin(), frameByteSize_,
230         frameData.GetPcmDataBuffer(), frameData.Size());
231     if (ret != 0) {
232         AUDIO_ERR_LOG("memcpy failed when PushFrameData");
233         return false;
234     }
235     writePos_.store((writePos_.load() + 1) % GetFrames());
236     curFrames_.fetch_add(1);
237     return true;
238 }
239 
StoreFrameData(HpaePcmBuffer & frameData)240 bool HpaePcmBuffer::StoreFrameData(HpaePcmBuffer &frameData)
241 {
242     if (!IsMultiFrames() || frameData.IsMultiFrames()) {
243         return false;
244     }
245 
246     int32_t ret = memcpy_s(pcmProcessVec_[writePos_.load()].Begin(), frameByteSize_,
247         frameData.GetPcmDataBuffer(), frameData.Size());
248     if (ret != 0) {
249         AUDIO_ERR_LOG("memcpy failed when StoreFrameData");
250         return false;
251     }
252     writePos_.store((writePos_.load() + 1) % GetFrames());
253     readPos_.store((readPos_.load() + 1) % GetFrames());
254     return true;
255 }
256 
RewindBuffer(size_t frames)257 size_t HpaePcmBuffer::RewindBuffer(size_t frames)
258 {
259     if (!IsMultiFrames()) {
260         return 0;
261     }
262     frames = curFrames_.load() + frames > GetFrames() ? GetFrames() - curFrames_.load() : frames;
263     readPos_.store((readPos_.load() - frames + GetFrames()) % GetFrames());
264     curFrames_.fetch_add(frames);
265     return frames;
266 }
267 
UpdateReadPos(size_t readPos)268 bool HpaePcmBuffer::UpdateReadPos(size_t readPos)
269 {
270     readPos_.store(readPos);
271     return true;
272 }
273 
UpdateWritePos(size_t writePos)274 bool HpaePcmBuffer::UpdateWritePos(size_t writePos)
275 {
276     writePos_.store(writePos);
277     return true;
278 }
279 
SetBufferValid(bool valid)280 void HpaePcmBuffer::SetBufferValid(bool valid)
281 {
282     if (valid) {
283         pcmBufferInfo_.state &= ~PCM_BUFFER_STATE_INVALID;
284     } else {
285         pcmBufferInfo_.state |= PCM_BUFFER_STATE_INVALID;
286     }
287 }
288 
SetBufferSilence(bool silence)289 void HpaePcmBuffer::SetBufferSilence(bool silence)
290 {
291     if (silence) {
292         pcmBufferInfo_.state |= PCM_BUFFER_STATE_SILENCE;
293     } else {
294         pcmBufferInfo_.state &= ~PCM_BUFFER_STATE_SILENCE;
295     }
296 }
297 
SetBufferState(uint32_t state)298 void HpaePcmBuffer::SetBufferState(uint32_t state)
299 {
300     pcmBufferInfo_.state = state;
301 }
302 
GetCurFrames() const303 size_t HpaePcmBuffer::GetCurFrames() const
304 {
305     return curFrames_.load();
306 }
307 }  // namespace HPAE
308 }  // namespace AudioStandard
309 }  // namespace OHOS