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