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 ~AudioEndpoint() = default; 96 private: 97 virtual bool Config(const DeviceInfo &deviceInfo) = 0; 98 }; 99 100 class AudioEndpointSeparate : public AudioEndpoint { 101 public: 102 explicit AudioEndpointSeparate(EndpointType type, uint64_t id, AudioStreamType streamType); 103 ~AudioEndpointSeparate(); 104 105 bool Config(const DeviceInfo &deviceInfo) override; 106 bool StartDevice(); 107 bool StopDevice(); 108 109 // when audio process start. 110 int32_t OnStart(IAudioProcessStream *processStream) override; 111 // when audio process pause. 112 int32_t OnPause(IAudioProcessStream *processStream) override; 113 // when audio process request update handle info. 114 int32_t OnUpdateHandleInfo(IAudioProcessStream *processStream) override; 115 int32_t LinkProcessStream(IAudioProcessStream *processStream) override; 116 int32_t UnlinkProcessStream(IAudioProcessStream *processStream) override; 117 int32_t GetPreferBufferInfo(uint32_t &totalSizeInframe, uint32_t &spanSizeInframe) override; 118 119 void Dump(std::string &dumpString) override; 120 121 std::string GetEndpointName() override; 122 GetEndpointType()123 inline EndpointType GetEndpointType() override 124 { 125 return endpointType_; 126 } 127 128 // for inner-cap 129 bool ShouldInnerCap() override; 130 int32_t EnableFastInnerCap() override; 131 int32_t DisableFastInnerCap() override; 132 133 int32_t SetVolume(AudioStreamType streamType, float volume) override; 134 135 int32_t ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer) override; 136 137 std::shared_ptr<OHAudioBuffer> GetBuffer() override; 138 139 EndpointStatus GetStatus() override; 140 141 void Release() override; 142 GetDeviceInfo()143 DeviceInfo &GetDeviceInfo() override 144 { 145 return deviceInfo_; 146 } 147 GetDeviceRole()148 DeviceRole GetDeviceRole() override 149 { 150 return deviceInfo_.deviceRole; 151 } 152 153 float GetMaxAmplitude() override; 154 uint32_t GetLinkedProcessCount() override; 155 private: 156 int32_t PrepareDeviceBuffer(const DeviceInfo &deviceInfo); 157 int32_t GetAdapterBufferInfo(const DeviceInfo &deviceInfo); 158 void ResyncPosition(); 159 void InitAudiobuffer(bool resetReadWritePos); 160 void ProcessData(const std::vector<AudioStreamData> &srcDataList, const AudioStreamData &dstData); 161 162 bool GetDeviceHandleInfo(uint64_t &frames, int64_t &nanoTime); 163 int32_t GetProcLastWriteDoneInfo(const std::shared_ptr<OHAudioBuffer> processBuffer, uint64_t curWriteFrame, 164 uint64_t &proHandleFrame, int64_t &proHandleTime); 165 166 bool IsAnyProcessRunning(); 167 168 std::string GetStatusStr(EndpointStatus status); 169 170 int32_t WriteToSpecialProcBuf(const std::shared_ptr<OHAudioBuffer> &procBuf, const BufferDesc &readBuf); 171 void WriteToProcessBuffers(const BufferDesc &readBuf); 172 173 private: 174 static constexpr int64_t ONE_MILLISECOND_DURATION = 1000000; // 1ms 175 // SamplingRate EncodingType SampleFormat Channel 176 DeviceInfo deviceInfo_; 177 AudioStreamInfo dstStreamInfo_; 178 EndpointType endpointType_; 179 uint64_t id_ = 0; 180 AudioStreamType streamType_ = STREAM_DEFAULT; 181 std::mutex listLock_; 182 std::vector<IAudioProcessStream *> processList_; 183 std::vector<std::shared_ptr<OHAudioBuffer>> processBufferList_; 184 185 std::atomic<bool> isInited_ = false; 186 std::shared_ptr<IMmapAudioRendererSink> fastSink_ = nullptr; 187 int64_t spanDuration_ = 0; // nano second 188 int64_t serverAheadReadTime_ = 0; 189 int dstBufferFd_ = -1; // -1: invalid fd. 190 uint32_t dstTotalSizeInframe_ = 0; 191 uint32_t dstSpanSizeInframe_ = 0; 192 uint32_t dstByteSizePerFrame_ = 0; 193 std::shared_ptr<OHAudioBuffer> dstAudioBuffer_ = nullptr; 194 std::atomic<EndpointStatus> endpointStatus_ = INVALID; 195 196 std::mutex loopThreadLock_; 197 std::condition_variable workThreadCV_; 198 199 bool isDeviceRunningInIdel_ = true; // will call start sink when linked. 200 bool needResyncPosition_ = true; 201 }; 202 203 } // namespace AudioStandard 204 } // namespace OHOS 205 #endif // AUDIO_ENDPOINT_H 206