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