• 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 HPAE_PCM_BUFFER_H
17 #define HPAE_PCM_BUFFER_H
18 #include <vector>
19 #include <type_traits>
20 #include <memory>
21 #include <algorithm>
22 #include "hpae_pcm_process.h"
23 namespace OHOS {
24 namespace AudioStandard {
25 namespace HPAE {
26 constexpr size_t MEMORY_ALIGN_BYTE_NUM = 64;
27 
28 enum HpaeSourceBufferType {
29     HPAE_SOURCE_BUFFER_TYPE_DEFAULT,
30     HPAE_SOURCE_BUFFER_TYPE_MIC,
31     HPAE_SOURCE_BUFFER_TYPE_EC,
32     HPAE_SOURCE_BUFFER_TYPE_MICREF,
33 };
34 
35 enum HpaeSplitStreamType {
36     STREAM_TYPE_DEFAULT = 0,
37     STREAM_TYPE_MEDIA = 1,
38     STREAM_TYPE_COMMUNICATION = 2,
39     STREAM_TYPE_NAVIGATION = 13
40 };
41 
42 enum PcmBufferState : uint32_t {
43     PCM_BUFFER_STATE_INVALID = 1, // bit 0
44     PCM_BUFFER_STATE_SILENCE = 2, // bit 1
45 };
46 
47 // redefine allocator to ensure memory alignment
48 template <typename T, size_t Alignment>
49 class AlignedAllocator : public std::allocator<T> {
50 public:
51     using pointer = T *;
52     using size_type = size_t;
53 
Allocate(size_type n)54     pointer Allocate(size_type n)
55     {
56         void *ptr = std::aligned_alloc(Alignment, n * sizeof(T));
57         return static_cast<pointer>(ptr);
58     }
59 
DeAllocate(pointer p,size_type n)60     void DeAllocate(pointer p, size_type n)
61     {
62         std::free(p);
63     }
64 };
65 
66 struct PcmBufferInfo {
PcmBufferInfoPcmBufferInfo67     PcmBufferInfo(uint32_t ch1, uint32_t frameLen1, uint32_t rate1)
68         : ch(ch1), frameLen(frameLen1), rate(rate1)
69     {}
PcmBufferInfoPcmBufferInfo70     PcmBufferInfo(uint32_t ch1, uint32_t frameLen1, uint32_t rate1, uint64_t channelLayout1)
71         : ch(ch1), frameLen(frameLen1), rate(rate1), channelLayout(channelLayout1)
72     {}
PcmBufferInfoPcmBufferInfo73     PcmBufferInfo(uint32_t ch1, uint32_t frameLen1, uint32_t rate1, uint64_t channelLayout1,
74         uint32_t frames1)
75         : ch(ch1), frameLen(frameLen1), rate(rate1), channelLayout(channelLayout1), frames(frames1)
76     {}
77     PcmBufferInfo() = default;
78     uint32_t ch;
79     uint32_t frameLen;
80     uint32_t rate;
81     uint64_t channelLayout = 0;
82     uint32_t frames = 1;
83     bool isMultiFrames = false;
84     uint32_t state = 0;
85 };
86 
87 // todo: multithread access?
88 class HpaePcmBuffer {
89 public:
90     HpaePcmBuffer() = delete;
91     explicit HpaePcmBuffer(PcmBufferInfo &pcmBufferInfo);
92     HpaePcmBuffer(HpaePcmBuffer &&other);
93     HpaePcmBuffer(const HpaePcmBuffer &other) = delete;
~HpaePcmBuffer()94     ~HpaePcmBuffer()
95     {
96     }
97     HpaePcmBuffer &operator=(HpaePcmBuffer &other);
98     HpaePcmBuffer &operator=(HpaePcmBuffer &&other) = delete;
99 
GetPcmBufferInfo()100     PcmBufferInfo GetPcmBufferInfo() const
101     {
102         return pcmBufferInfo_;
103     }
104 
GetChannelCount()105     uint32_t GetChannelCount() const
106     {
107         return pcmBufferInfo_.ch;
108     }
109 
GetFrameLen()110     uint32_t GetFrameLen() const
111     {
112         return pcmBufferInfo_.frameLen;
113     }
114 
GetSampleRate()115     uint32_t GetSampleRate() const
116     {
117         return pcmBufferInfo_.rate;
118     }
119 
IsMultiFrames()120     bool IsMultiFrames() const
121     {
122         return pcmBufferInfo_.isMultiFrames;
123     }
124 
IsValid()125     bool IsValid() const
126     {
127         return (pcmBufferInfo_.state & PCM_BUFFER_STATE_INVALID) != PCM_BUFFER_STATE_INVALID;
128     }
129 
IsSilence()130     bool IsSilence() const
131     {
132         return (pcmBufferInfo_.state & PCM_BUFFER_STATE_SILENCE) == PCM_BUFFER_STATE_SILENCE;
133     }
134 
GetBufferState()135     uint32_t GetBufferState() const
136     {
137         return pcmBufferInfo_.state;
138     }
139 
GetChannelLayout()140     uint64_t GetChannelLayout() const
141     {
142         return pcmBufferInfo_.channelLayout;
143     }
144 
ReConfig(const PcmBufferInfo & pcmBufferInfo)145     void ReConfig(const PcmBufferInfo &pcmBufferInfo)
146     {
147         pcmBufferInfo_ = pcmBufferInfo;
148         InitPcmProcess();
149     }
150 
151     bool GetFrameData(std::vector<float> &frameData);
152     bool GetFrameData(HpaePcmBuffer &frameData);
153     bool PushFrameData(std::vector<float> &frameData);
154     bool PushFrameData(HpaePcmBuffer &frameData);
155     // store history frame for offload
156     bool StoreFrameData(HpaePcmBuffer &frameData);
157     // rewind history frame for offload, return frames that rewinded
158     size_t RewindBuffer(size_t frames);
159 
160     HpaePcmProcess &operator[](size_t index)
161     {
162         return pcmProcessVec_[index];
163     }
164 
165     const HpaePcmProcess &operator[](size_t index) const
166     {
167         return pcmProcessVec_[index];
168     }
169 
Size()170     size_t Size() const
171     {
172         return bufferByteSize_;
173     }
174 
DataSize()175     size_t DataSize() const
176     {
177         return dataByteSize_;
178     }
179 
GetFrames()180     size_t GetFrames() const
181     {
182         return pcmBufferInfo_.frames;
183     }
184 
GetReadPos()185     size_t GetReadPos() const
186     {
187         return readPos_.load();
188     }
189 
GetWritePos()190     size_t GetWritePos() const
191     {
192         return writePos_.load();
193     }
194 
195     bool UpdateReadPos(size_t readPos);
196     bool UpdateWritePos(size_t writePos);
197     void SetBufferValid(bool valid);
198     void SetBufferSilence(bool silence);
199     void SetBufferState(uint32_t state);
200     size_t GetCurFrames() const;
201 
202     HpaePcmBuffer &operator=(const std::vector<std::vector<float>> &other);
203     HpaePcmBuffer &operator=(const std::vector<float> &other);
204 
205     HpaePcmBuffer &operator+=(HpaePcmBuffer &other);
206     HpaePcmBuffer &operator-=(HpaePcmBuffer &other);
207     HpaePcmBuffer &operator*=(HpaePcmBuffer &other);
208     void Reset();
209 
begin()210     std::vector<HpaePcmProcess>::iterator begin()
211     {
212         return pcmProcessVec_.begin();
213     }
214 
end()215     std::vector<HpaePcmProcess>::iterator end()
216     {
217         return pcmProcessVec_.end();
218     }
219 
begin()220     std::vector<HpaePcmProcess>::const_iterator begin() const
221     {
222         return pcmProcessVec_.begin();
223     }
224 
end()225     std::vector<HpaePcmProcess>::const_iterator end() const
226     {
227         return pcmProcessVec_.end();
228     }
229 
GetPcmDataBuffer()230     float *GetPcmDataBuffer()
231     {
232         return pcmDataBuffer_.data();
233     }
234 
GetFrameSample()235     size_t GetFrameSample()
236     {
237         return frameSample_;
238     }
239 
GetSourceBufferType()240     HpaeSourceBufferType GetSourceBufferType()
241     {
242         return sourceBufferType_;
243     }
244 
SetSourceBufferType(HpaeSourceBufferType type)245     void SetSourceBufferType(HpaeSourceBufferType type)
246     {
247         sourceBufferType_ = type;
248     }
249 
GetSplitStreamType()250     HpaeSplitStreamType GetSplitStreamType()
251     {
252         return splitStreamType_;
253     }
254 
SetSplitStreamType(HpaeSplitStreamType type)255     void SetSplitStreamType(HpaeSplitStreamType type)
256     {
257         splitStreamType_ = type;
258     }
259 
260 private:
261     void InitPcmProcess();
262 
263     // todo: add err to deal with operator override
264     std::vector<float, AlignedAllocator<float, MEMORY_ALIGN_BYTE_NUM>> pcmDataBuffer_;
265     size_t bufferFloatSize_;
266     size_t bufferByteSize_;
267     size_t frameFloatSize_;
268     size_t frameByteSize_;
269     size_t frameSample_;
270     size_t dataByteSize_;
271     std::atomic<size_t> readPos_;
272     std::atomic<size_t> writePos_;
273     std::atomic<size_t> curFrames_;
274     std::vector<HpaePcmProcess> pcmProcessVec_;
275     PcmBufferInfo pcmBufferInfo_;
276     HpaeSourceBufferType sourceBufferType_ = HPAE_SOURCE_BUFFER_TYPE_DEFAULT;
277     HpaeSplitStreamType splitStreamType_ = STREAM_TYPE_DEFAULT;
278 };
279 }  // namespace HPAE
280 }  // namespace AudioStandard
281 }  // namespace OHOS
282 #endif