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