1 /*
2  * Copyright (c) 2023 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 OH_AUDIO_BUFFER_H
17 #define OH_AUDIO_BUFFER_H
18 
19 #include <atomic>
20 #include <string>
21 
22 #include "message_parcel.h"
23 
24 #include "audio_info.h"
25 #include "audio_shared_memory.h"
26 
27 namespace OHOS {
28 namespace AudioStandard {
29 
30 // client or server.
31 enum AudioBufferHolder : uint32_t {
32     // normal stream, Client buffer created when readFromParcel
33     AUDIO_CLIENT = 0,
34     // normal stream, Server buffer shared with Client
35     AUDIO_SERVER_SHARED,
36     // normal stream, Server buffer shared with hdi
37     AUDIO_SERVER_ONLY,
38     // Independent stream
39     AUDIO_SERVER_INDEPENDENT
40 };
41 
42 enum StreamStatus : uint32_t {
43     STREAM_IDEL = 0,
44     STREAM_STARTING,
45     STREAM_RUNNING,
46     STREAM_PAUSING,
47     STREAM_PAUSED,
48     STREAM_STOPPING,
49     STREAM_STOPPED,
50     STREAM_RELEASED,
51     STREAM_STAND_BY,
52     STREAM_INVALID
53 };
54 
55 /**
56  * totalSizeInFrame = spanCount * spanSizeInFrame
57  *
58  * 0 <= write - base < 2 * totalSize
59  * 0 <= read - base < 1 * totalSize
60  * 0 <= write - read < 1 * totalSize
61  */
62 struct BasicBufferInfo {
63     uint32_t totalSizeInFrame;
64     uint32_t spanSizeInFrame;
65     uint32_t byteSizePerFrame;
66 
67     std::atomic<uint32_t> futexObj;
68 
69     std::atomic<StreamStatus> streamStatus;
70 
71     // basic read/write postion
72     std::atomic<uint64_t> basePosInFrame;
73     std::atomic<uint64_t> curWriteFrame;
74     std::atomic<uint64_t> curReadFrame;
75 
76     std::atomic<uint32_t> underrunCount;
77 
78     std::atomic<uint64_t> handlePos;
79     std::atomic<int64_t> handleTime;
80 
81     std::atomic<float> streamVolume;
82     std::atomic<float> duckFactor;
83 };
84 
85 enum SpanStatus : uint32_t {
86     SPAN_IDEL = 0,
87     SPAN_WRITTING,
88     SPAN_WRITE_DONE,
89     SPAN_READING,
90     SPAN_READ_DONE,
91     SPAN_INVALID
92 };
93 
94 // one span represents a collection of audio sampling data for a short period of time
95 struct SpanInfo {
96     std::atomic<SpanStatus> spanStatus;
97     uint64_t offsetInFrame = 0;
98 
99     int64_t writeStartTime;
100     int64_t writeDoneTime;
101 
102     int64_t readStartTime;
103     int64_t readDoneTime;
104 
105     // volume info for each span
106     bool isMute;
107     int32_t volumeStart;
108     int32_t volumeEnd;
109 };
110 
111 class OHAudioBuffer {
112 public:
113     static const int INVALID_BUFFER_FD = -1;
114     OHAudioBuffer(AudioBufferHolder bufferHolder, uint32_t totalSizeInFrame, uint32_t spanSizeInFrame,
115         uint32_t byteSizePerFrame);
116     ~OHAudioBuffer();
117 
118     // create OHAudioBuffer locally or remotely
119     static std::shared_ptr<OHAudioBuffer> CreateFromLocal(uint32_t totalSizeInFrame, uint32_t spanSizeInFrame,
120         uint32_t byteSizePerFrame);
121     static std::shared_ptr<OHAudioBuffer> CreateFromRemote(uint32_t totalSizeInFrame, uint32_t spanSizeInFrame,
122         uint32_t byteSizePerFrame, AudioBufferHolder holder, int dataFd, int infoFd = INVALID_BUFFER_FD);
123 
124     // for ipc.
125     static int32_t WriteToParcel(const std::shared_ptr<OHAudioBuffer> &buffer, MessageParcel &parcel);
126     static std::shared_ptr<OHAudioBuffer> ReadFromParcel(MessageParcel &parcel);
127 
128     AudioBufferHolder GetBufferHolder();
129 
130     int32_t GetSizeParameter(uint32_t &totalSizeInFrame, uint32_t &spanSizeInFrame, uint32_t &byteSizePerFrame);
131 
132     std::atomic<StreamStatus> *GetStreamStatus();
133 
134     uint32_t GetUnderrunCount();
135 
136     bool SetUnderrunCount(uint32_t count);
137 
138     bool GetHandleInfo(uint64_t &frames, int64_t &nanoTime);
139 
140     void SetHandleInfo(uint64_t frames, int64_t nanoTime);
141 
142     float GetStreamVolume();
143     bool SetStreamVolume(float streamVolume);
144 
145     float GetDuckFactor();
146     bool SetDuckFactor(float duckFactor);
147 
148     int32_t GetAvailableDataFrames();
149 
150     int32_t ResetCurReadWritePos(uint64_t readFrame, uint64_t writeFrame);
151 
152     uint64_t GetCurWriteFrame();
153     uint64_t GetCurReadFrame();
154 
155     int32_t SetCurWriteFrame(uint64_t writeFrame);
156     int32_t SetCurReadFrame(uint64_t readFrame);
157 
158     uint32_t GetSessionId();
159     int32_t SetSessionId(uint32_t sessionId);
160 
161     int32_t GetWriteBuffer(uint64_t writePosInFrame, BufferDesc &bufferDesc);
162 
163     int32_t GetReadbuffer(uint64_t readPosInFrame, BufferDesc &bufferDesc);
164 
165     int32_t GetBufferByFrame(uint64_t posInFrame, BufferDesc &bufferDesc);
166 
167     SpanInfo *GetSpanInfo(uint64_t posInFrame);
168     SpanInfo *GetSpanInfoByIndex(uint32_t spanIndex);
169 
170     uint32_t GetSpanCount();
171 
172     int64_t GetLastWrittenTime();
173     void SetLastWrittenTime(int64_t time);
174 
175     std::atomic<uint32_t> *GetFutex();
176     uint8_t *GetDataBase();
177     size_t GetDataSize();
178 private:
179     int32_t Init(int dataFd, int infoFd);
180     int32_t SizeCheck();
181 
182     uint32_t sessionId_ = 0;
183     AudioBufferHolder bufferHolder_;
184     uint32_t totalSizeInFrame_;
185     uint32_t spanSizeInFrame_;
186     uint32_t byteSizePerFrame_;
187 
188     // available only in single process
189     int64_t lastWrittenTime_ = 0;
190 
191     // calculated in advance
192     size_t totalSizeInByte_ = 0;
193     size_t spanSizeInByte_ = 0;
194     uint32_t spanConut_ = 0;
195 
196     // for render or capturer
197     AudioMode audioMode_;
198 
199     // for StatusInfo buffer
200     std::shared_ptr<AudioSharedMemory> statusInfoMem_ = nullptr;
201     BasicBufferInfo *basicBufferInfo_ = nullptr;
202     SpanInfo *spanInfoList_ = nullptr;
203 
204     // for audio data buffer
205     std::shared_ptr<AudioSharedMemory> dataMem_ = nullptr;
206     uint8_t *dataBase_ = nullptr;
207 };
208 } // namespace AudioStandard
209 } // namespace OHOS
210 #endif // OH_AUDIO_BUFFER_H
211