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 AUDIO_ENDPOINT_H 17 #define AUDIO_ENDPOINT_H 18 19 #include <sstream> 20 #include <memory> 21 #include <thread> 22 23 #include "i_audio_renderer_sink.h" 24 #include "i_process_status_listener.h" 25 #include "linear_pos_time_model.h" 26 27 namespace OHOS { 28 namespace AudioStandard { 29 // When AudioEndpoint is offline, notify the owner. 30 class IAudioEndpointStatusListener { 31 public: 32 enum HdiDeviceStatus : uint32_t { 33 STATUS_ONLINE = 0, 34 STATUS_OFFLINE, 35 STATUS_INVALID, 36 }; 37 38 /** 39 * When AudioEndpoint changed status, we need to notify AudioProcessStream. 40 */ 41 virtual int32_t OnEndpointStatusChange(HdiDeviceStatus status) = 0; 42 }; 43 44 class AudioEndpoint : public IProcessStatusListener { 45 public: 46 static constexpr int32_t MAX_LINKED_PROCESS = 6; // 6 47 enum EndpointType : uint32_t { 48 TYPE_MMAP = 0, 49 TYPE_INVALID, 50 TYPE_INDEPENDENT, 51 TYPE_VOIP_MMAP 52 }; 53 54 enum EndpointStatus : uint32_t { 55 INVALID = 0, 56 UNLINKED, // no process linked 57 IDEL, // no running process 58 STARTING, // calling start sink 59 RUNNING, // at least one process is running 60 STOPPING, // calling stop sink 61 STOPPED // sink stoped 62 }; 63 64 static std::shared_ptr<AudioEndpoint> CreateEndpoint(EndpointType type, uint64_t id, 65 const AudioProcessConfig &clientConfig, const DeviceInfo &deviceInfo); 66 static std::string GenerateEndpointKey(DeviceInfo &deviceInfo, int32_t endpointFlag); 67 68 virtual std::string GetEndpointName() = 0; 69 70 virtual EndpointType GetEndpointType() = 0; 71 virtual int32_t SetVolume(AudioStreamType streamType, float volume) = 0; 72 virtual int32_t ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer) = 0; 73 virtual std::shared_ptr<OHAudioBuffer> GetBuffer() = 0; 74 75 virtual EndpointStatus GetStatus() = 0; 76 77 virtual void Release() = 0; 78 79 virtual bool ShouldInnerCap() = 0; 80 virtual int32_t EnableFastInnerCap() = 0; 81 virtual int32_t DisableFastInnerCap() = 0; 82 83 virtual int32_t LinkProcessStream(IAudioProcessStream *processStream) = 0; 84 virtual int32_t UnlinkProcessStream(IAudioProcessStream *processStream) = 0; 85 86 virtual int32_t GetPreferBufferInfo(uint32_t &totalSizeInframe, uint32_t &spanSizeInframe) = 0; 87 88 virtual void Dump(std::string &dumpString) = 0; 89 90 virtual DeviceRole GetDeviceRole() = 0; 91 virtual DeviceInfo &GetDeviceInfo() = 0; 92 virtual float GetMaxAmplitude() = 0; 93 virtual uint32_t GetLinkedProcessCount() = 0; 94 95 virtual AudioMode GetAudioMode() const = 0; 96 97 virtual void SetHibernateEndpointRelease(const bool &isHibernate) = 0; 98 99 virtual ~AudioEndpoint() = default; 100 private: 101 virtual bool Config(const DeviceInfo &deviceInfo) = 0; 102 }; 103 104 class AudioEndpointSeparate : public AudioEndpoint { 105 public: 106 explicit AudioEndpointSeparate(EndpointType type, uint64_t id, AudioStreamType streamType); 107 ~AudioEndpointSeparate(); 108 109 bool Config(const DeviceInfo &deviceInfo) override; 110 bool StartDevice(); 111 bool StopDevice(); 112 113 // when audio process start. 114 int32_t OnStart(IAudioProcessStream *processStream) override; 115 // when audio process pause. 116 int32_t OnPause(IAudioProcessStream *processStream) override; 117 // when audio process request update handle info. 118 int32_t OnUpdateHandleInfo(IAudioProcessStream *processStream) override; 119 int32_t LinkProcessStream(IAudioProcessStream *processStream) override; 120 int32_t UnlinkProcessStream(IAudioProcessStream *processStream) override; 121 int32_t GetPreferBufferInfo(uint32_t &totalSizeInframe, uint32_t &spanSizeInframe) override; 122 123 void Dump(std::string &dumpString) override; 124 125 std::string GetEndpointName() override; 126 127 inline EndpointType GetEndpointType() override 128 { 129 return endpointType_; 130 } 131 132 // for inner-cap 133 bool ShouldInnerCap() override; 134 int32_t EnableFastInnerCap() override; 135 int32_t DisableFastInnerCap() override; 136 137 int32_t SetVolume(AudioStreamType streamType, float volume) override; 138 139 int32_t ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer) override; 140 141 std::shared_ptr<OHAudioBuffer> GetBuffer() override; 142 143 EndpointStatus GetStatus() override; 144 145 void Release() override; 146 147 DeviceInfo &GetDeviceInfo() override 148 { 149 return deviceInfo_; 150 } 151 152 DeviceRole GetDeviceRole() override 153 { 154 return deviceInfo_.deviceRole; 155 } 156 157 float GetMaxAmplitude() override; 158 159 uint32_t GetLinkedProcessCount() override; 160 161 AudioMode GetAudioMode() const final; 162 163 void SetHibernateEndpointRelease(const bool &isHibernate) override; 164 private: 165 int32_t PrepareDeviceBuffer(const DeviceInfo &deviceInfo); 166 int32_t GetAdapterBufferInfo(const DeviceInfo &deviceInfo); 167 void ResyncPosition(); 168 void InitAudiobuffer(bool resetReadWritePos); 169 void ProcessData(const std::vector<AudioStreamData> &srcDataList, const AudioStreamData &dstData); 170 171 bool GetDeviceHandleInfo(uint64_t &frames, int64_t &nanoTime); 172 int32_t GetProcLastWriteDoneInfo(const std::shared_ptr<OHAudioBuffer> processBuffer, uint64_t curWriteFrame, 173 uint64_t &proHandleFrame, int64_t &proHandleTime); 174 175 bool IsAnyProcessRunning(); 176 177 std::string GetStatusStr(EndpointStatus status); 178 179 int32_t WriteToSpecialProcBuf(const std::shared_ptr<OHAudioBuffer> &procBuf, const BufferDesc &readBuf); 180 void WriteToProcessBuffers(const BufferDesc &readBuf); 181 182 private: 183 static constexpr int64_t ONE_MILLISECOND_DURATION = 1000000; // 1ms 184 // SamplingRate EncodingType SampleFormat Channel 185 DeviceInfo deviceInfo_; 186 AudioStreamInfo dstStreamInfo_; 187 EndpointType endpointType_; 188 uint64_t id_ = 0; 189 AudioStreamType streamType_ = STREAM_DEFAULT; 190 std::mutex listLock_; 191 std::vector<IAudioProcessStream *> processList_; 192 std::vector<std::shared_ptr<OHAudioBuffer>> processBufferList_; 193 194 std::atomic<bool> isInited_ = false; 195 std::shared_ptr<IMmapAudioRendererSink> fastSink_ = nullptr; 196 int64_t spanDuration_ = 0; // nano second 197 int64_t serverAheadReadTime_ = 0; 198 int dstBufferFd_ = -1; // -1: invalid fd. 199 uint32_t dstTotalSizeInframe_ = 0; 200 uint32_t dstSpanSizeInframe_ = 0; 201 uint32_t dstByteSizePerFrame_ = 0; 202 std::shared_ptr<OHAudioBuffer> dstAudioBuffer_ = nullptr; 203 std::atomic<EndpointStatus> endpointStatus_ = INVALID; 204 205 std::mutex loopThreadLock_; 206 std::condition_variable workThreadCV_; 207 208 bool isDeviceRunningInIdel_ = true; // will call start sink when linked. 209 bool needResyncPosition_ = true; 210 }; 211 212 } // namespace AudioStandard 213 } // namespace OHOS 214 #endif // AUDIO_ENDPOINT_H 215