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 PA_ADAPTER_MANAGER_H 17 #define PA_ADAPTER_MANAGER_H 18 #ifdef SUPPORT_OLD_ENGINE 19 #include <map> 20 #include <set> 21 #include <mutex> 22 #include <pulse/pulseaudio.h> 23 #include <pulse/thread-mainloop.h> 24 #include "audio_timer.h" 25 #include "i_stream_manager.h" 26 #include "audio_effect.h" 27 28 namespace OHOS { 29 namespace AudioStandard { 30 31 enum class AppendType { 32 APPEND_RENDER, 33 APPEND_CAPTURE 34 }; 35 36 static std::map<uint8_t, AudioChannelLayout> defaultChCountToLayoutMap = { 37 {1, CH_LAYOUT_MONO}, {2, CH_LAYOUT_STEREO}, {3, CH_LAYOUT_SURROUND}, 38 {4, CH_LAYOUT_2POINT0POINT2}, {5, CH_LAYOUT_5POINT0_BACK}, {6, CH_LAYOUT_5POINT1}, 39 {7, CH_LAYOUT_6POINT1_BACK}, {8, CH_LAYOUT_5POINT1POINT2}, {9, CH_LAYOUT_HOA_ORDER2_ACN_N3D}, 40 {10, CH_LAYOUT_7POINT1POINT2}, {12, CH_LAYOUT_7POINT1POINT4}, {14, CH_LAYOUT_9POINT1POINT4}, 41 {16, CH_LAYOUT_9POINT1POINT6} 42 }; 43 44 static std::map<AudioChannelSet, pa_channel_position> chSetToPaPositionMap = { 45 {FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_LEFT}, {FRONT_RIGHT, PA_CHANNEL_POSITION_FRONT_RIGHT}, 46 {FRONT_CENTER, PA_CHANNEL_POSITION_FRONT_CENTER}, {LOW_FREQUENCY, PA_CHANNEL_POSITION_LFE}, 47 {SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_LEFT}, {SIDE_RIGHT, PA_CHANNEL_POSITION_SIDE_RIGHT}, 48 {BACK_LEFT, PA_CHANNEL_POSITION_REAR_LEFT}, {BACK_RIGHT, PA_CHANNEL_POSITION_REAR_RIGHT}, 49 {FRONT_LEFT_OF_CENTER, PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, 50 {FRONT_RIGHT_OF_CENTER, PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, 51 {BACK_CENTER, PA_CHANNEL_POSITION_REAR_CENTER}, {TOP_CENTER, PA_CHANNEL_POSITION_TOP_CENTER}, 52 {TOP_FRONT_LEFT, PA_CHANNEL_POSITION_TOP_FRONT_LEFT}, {TOP_FRONT_CENTER, PA_CHANNEL_POSITION_TOP_FRONT_CENTER}, 53 {TOP_FRONT_RIGHT, PA_CHANNEL_POSITION_TOP_FRONT_RIGHT}, {TOP_BACK_LEFT, PA_CHANNEL_POSITION_TOP_REAR_LEFT}, 54 {TOP_BACK_CENTER, PA_CHANNEL_POSITION_TOP_REAR_CENTER}, {TOP_BACK_RIGHT, PA_CHANNEL_POSITION_TOP_REAR_RIGHT}, 55 /** Channel layout positions below do not have precise mapped pulseaudio positions */ 56 {STEREO_LEFT, PA_CHANNEL_POSITION_FRONT_LEFT}, {STEREO_RIGHT, PA_CHANNEL_POSITION_FRONT_RIGHT}, 57 {WIDE_LEFT, PA_CHANNEL_POSITION_FRONT_LEFT}, {WIDE_RIGHT, PA_CHANNEL_POSITION_FRONT_RIGHT}, 58 {SURROUND_DIRECT_LEFT, PA_CHANNEL_POSITION_SIDE_LEFT}, {SURROUND_DIRECT_RIGHT, PA_CHANNEL_POSITION_SIDE_LEFT}, 59 {BOTTOM_FRONT_CENTER, PA_CHANNEL_POSITION_FRONT_CENTER}, 60 {BOTTOM_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_LEFT}, {BOTTOM_FRONT_RIGHT, PA_CHANNEL_POSITION_FRONT_RIGHT}, 61 {TOP_SIDE_LEFT, PA_CHANNEL_POSITION_TOP_REAR_LEFT}, {TOP_SIDE_RIGHT, PA_CHANNEL_POSITION_TOP_REAR_RIGHT}, 62 {LOW_FREQUENCY_2, PA_CHANNEL_POSITION_LFE}, 63 }; 64 65 class PaAdapterManager : public IStreamManager { 66 public: 67 PaAdapterManager(ManagerType type); 68 69 int32_t CreateRender(AudioProcessConfig processConfig, std::shared_ptr<IRendererStream> &stream) override; 70 int32_t ReleaseRender(uint32_t streamIndex_) override; 71 int32_t StartRender(uint32_t streamIndex) override; 72 int32_t StopRender(uint32_t streamIndex) override; 73 int32_t PauseRender(uint32_t streamIndex) override; 74 int32_t GetStreamCount() const noexcept override; 75 int32_t TriggerStartIfNecessary() override; 76 int32_t CreateCapturer(AudioProcessConfig processConfig, std::shared_ptr<ICapturerStream> &stream) override; 77 int32_t ReleaseCapturer(uint32_t streamIndex_) override; 78 int32_t AddUnprocessStream(int32_t appUid) override; 79 uint32_t ConvertChLayoutToPaChMap(const uint64_t &channelLayout, pa_channel_map &paMap); 80 uint64_t GetLatency() noexcept override; 81 void GetAllSinkInputs(std::vector<SinkInput> &sinkInputs) override; 82 83 private: 84 // audio channel index 85 static const uint8_t CHANNEL1_IDX = 0; 86 static const uint8_t CHANNEL2_IDX = 1; 87 static const uint8_t CHANNEL3_IDX = 2; 88 static const uint8_t CHANNEL4_IDX = 3; 89 static const uint8_t CHANNEL5_IDX = 4; 90 static const uint8_t CHANNEL6_IDX = 5; 91 static const uint8_t CHANNEL7_IDX = 6; 92 static const uint8_t CHANNEL8_IDX = 7; 93 94 int32_t ResetPaContext(); 95 int32_t InitPaContext(); 96 int32_t HandleMainLoopStart(); 97 pa_stream *InitPaStream(AudioProcessConfig processConfig, uint32_t sessionId, bool isRecording); 98 int32_t SetPaProplist(pa_proplist *propList, pa_channel_map &map, AudioProcessConfig &processConfig, 99 const std::string &streamName, uint32_t sessionId); 100 std::shared_ptr<IRendererStream> CreateRendererStream(AudioProcessConfig processConfig, pa_stream *paStream); 101 std::shared_ptr<ICapturerStream> CreateCapturerStream(AudioProcessConfig processConfig, pa_stream *paStream); 102 int32_t ConnectStreamToPA(pa_stream *paStream, pa_sample_spec sampleSpec, 103 SourceType source, int32_t innerCapId, std::string &adapterName, const std::string &deviceName = ""); 104 void ReleasePaStream(pa_stream *paStream); 105 int32_t ConnectRendererStreamToPA( 106 pa_stream *paStream, pa_sample_spec sampleSpec, std::string &adapterName, int32_t innerCapId); 107 int32_t ConnectCapturerStreamToPA(pa_stream *paStream, pa_sample_spec sampleSpec, std::string &adapterName, 108 SourceType source, const std::string &deviceName); 109 110 const std::string GetEnhanceSceneName(SourceType sourceType); 111 112 // Callbacks to be implemented 113 static void PAStreamStateCb(pa_stream *stream, void *userdata); 114 static void PAContextStateCb(pa_context *context, void *userdata); 115 116 static void PAStreamUpdateStreamIndexSuccessCb(pa_stream *stream, int32_t success, void *userdata); 117 118 const std::string GetStreamName(AudioStreamType audioType); 119 pa_sample_spec ConvertToPAAudioParams(AudioProcessConfig processConfig); 120 121 int32_t GetDeviceNameForConnect(AudioProcessConfig processConfig, 122 uint32_t sessionId, std::string &deviceName); 123 124 void SetHighResolution(pa_proplist *propList, AudioProcessConfig &processConfig, uint32_t sessionId); 125 bool CheckHighResolution(const AudioProcessConfig &processConfig); 126 void SetRecordProplist(pa_proplist *propList, AudioProcessConfig &processConfig); 127 void SetPlaybackProplist(pa_proplist *propList, AudioProcessConfig &processConfig); 128 std::string AppendDeviceName(int32_t innerCapId, AppendType type); 129 130 std::mutex paElementsMutex_; 131 pa_threaded_mainloop *mainLoop_; 132 pa_mainloop_api *api_; 133 pa_context *context_; 134 std::mutex streamMapMutex_; 135 std::map<int32_t, std::shared_ptr<IRendererStream>> rendererStreamMap_; 136 std::map<int32_t, std::shared_ptr<ICapturerStream>> capturerStreamMap_; 137 bool isContextConnected_; 138 bool isMainLoopStarted_; 139 ManagerType managerType_ = PLAYBACK; 140 bool waitConnect_ = true; 141 uint32_t highResolutionIndex_ = 0; 142 bool isHighResolutionExist_ = false; 143 std::set<int32_t> unprocessAppUidSet_; 144 std::mutex sinkInputsMutex_; 145 std::vector<SinkInput> sinkInputs_; 146 }; 147 } // namespace AudioStandard 148 } // namespace OHOS 149 #endif // SUPPORT_OLD_ENGINE 150 #endif // PA_ADAPTER_MANAGER_H 151