• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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