1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <algorithm>
20 #include <functional>
21 #include <iterator>
22 #include <map>
23 #include <set>
24 #include <vector>
25
26 #include <media/TypeConverter.h>
27 #include <system/audio.h>
28
29 namespace android {
30
31 using ChannelMaskSet = std::set<audio_channel_mask_t>;
32 using DeviceTypeSet = std::set<audio_devices_t>;
33 using FormatSet = std::set<audio_format_t>;
34 using SampleRateSet = std::set<uint32_t>;
35 using MixerBehaviorSet = std::set<audio_mixer_behavior_t>;
36
37 using DeviceIdVector = std::vector<audio_port_handle_t>;
38 using FormatVector = std::vector<audio_format_t>;
39 using AudioProfileAttributesMultimap =
40 std::multimap<audio_format_t, std::pair<SampleRateSet, ChannelMaskSet>>;
41
42 const DeviceTypeSet& getAudioDeviceOutAllSet();
43 const DeviceTypeSet& getAudioDeviceOutAllA2dpSet();
44 const DeviceTypeSet& getAudioDeviceOutAllScoSet();
45 const DeviceTypeSet& getAudioDeviceOutAllUsbSet();
46 const DeviceTypeSet& getAudioDeviceInAllSet();
47 const DeviceTypeSet& getAudioDeviceInAllUsbSet();
48 const DeviceTypeSet& getAudioDeviceOutAllBleSet();
49 const DeviceTypeSet& getAudioDeviceOutLeAudioUnicastSet();
50 const DeviceTypeSet& getAudioDeviceOutLeAudioBroadcastSet();
51 const DeviceTypeSet& getAudioDeviceOutPickForVolumeSet();
52
53 template<typename T>
Intersection(const std::set<T> & a,const std::set<T> & b)54 static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) {
55 std::vector<T> intersection;
56 std::set_intersection(a.begin(), a.end(),
57 b.begin(), b.end(),
58 std::back_inserter(intersection));
59 return intersection;
60 }
61
62 template<typename T>
SetIntersection(const std::set<T> & a,const std::set<T> b)63 static std::set<T> SetIntersection(const std::set<T>& a, const std::set<T> b) {
64 std::set<T> intersection;
65 std::set_intersection(a.begin(), a.end(),
66 b.begin(), b.end(),
67 std::inserter(intersection, intersection.begin()));
68 return intersection;
69 }
70
asInMask(const ChannelMaskSet & channelMasks)71 static inline ChannelMaskSet asInMask(const ChannelMaskSet& channelMasks) {
72 ChannelMaskSet inMaskSet;
73 for (const auto &channel : channelMasks) {
74 if (audio_channel_mask_out_to_in(channel) != AUDIO_CHANNEL_INVALID) {
75 inMaskSet.insert(audio_channel_mask_out_to_in(channel));
76 } else if (audio_channel_mask_get_representation(channel)
77 == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
78 inMaskSet.insert(channel);
79 }
80 }
81 return inMaskSet;
82 }
83
asOutMask(const ChannelMaskSet & channelMasks)84 static inline ChannelMaskSet asOutMask(const ChannelMaskSet& channelMasks) {
85 ChannelMaskSet outMaskSet;
86 for (const auto &channel : channelMasks) {
87 if (audio_channel_mask_in_to_out(channel) != AUDIO_CHANNEL_INVALID) {
88 outMaskSet.insert(audio_channel_mask_in_to_out(channel));
89 } else if (audio_channel_mask_get_representation(channel)
90 == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
91 outMaskSet.insert(channel);
92 }
93 }
94 return outMaskSet;
95 }
96
isSingleDeviceType(const DeviceTypeSet & deviceTypes,audio_devices_t deviceType)97 static inline bool isSingleDeviceType(const DeviceTypeSet& deviceTypes,
98 audio_devices_t deviceType) {
99 return deviceTypes.size() == 1 && *(deviceTypes.begin()) == deviceType;
100 }
101
102 typedef bool (*DeviceTypeUnaryPredicate)(audio_devices_t);
isSingleDeviceType(const DeviceTypeSet & deviceTypes,DeviceTypeUnaryPredicate p)103 static inline bool isSingleDeviceType(const DeviceTypeSet& deviceTypes,
104 DeviceTypeUnaryPredicate p) {
105 return deviceTypes.size() == 1 && p(*(deviceTypes.begin()));
106 }
107
areAllOfSameDeviceType(const DeviceTypeSet & deviceTypes,std::function<bool (audio_devices_t)> p)108 static inline bool areAllOfSameDeviceType(const DeviceTypeSet& deviceTypes,
109 std::function<bool(audio_devices_t)> p) {
110 return std::all_of(deviceTypes.begin(), deviceTypes.end(), p);
111 }
112
resetDeviceTypes(DeviceTypeSet & deviceTypes,audio_devices_t typeToAdd)113 static inline void resetDeviceTypes(DeviceTypeSet& deviceTypes, audio_devices_t typeToAdd) {
114 deviceTypes.clear();
115 deviceTypes.insert(typeToAdd);
116 }
117
118 // FIXME: This is temporary helper function. Remove this when getting rid of all
119 // bit mask usages of audio device types.
deviceTypesToBitMask(const DeviceTypeSet & deviceTypes)120 static inline audio_devices_t deviceTypesToBitMask(const DeviceTypeSet& deviceTypes) {
121 audio_devices_t types = AUDIO_DEVICE_NONE;
122 for (auto deviceType : deviceTypes) {
123 types = static_cast<audio_devices_t>(types | deviceType);
124 }
125 return types;
126 }
127
128 std::string deviceTypesToString(const DeviceTypeSet& deviceTypes);
129
130 bool deviceTypesToString(const DeviceTypeSet& deviceTypes, std::string &str);
131
132 std::string dumpDeviceTypes(const DeviceTypeSet& deviceTypes);
133
134 std::string dumpMixerBehaviors(const MixerBehaviorSet& mixerBehaviors);
135
136 /**
137 * Return human readable string for device types.
138 */
toString(const DeviceTypeSet & deviceTypes)139 inline std::string toString(const DeviceTypeSet& deviceTypes) {
140 return deviceTypesToString(deviceTypes);
141 }
142
143 /**
144 * Returns human readable string for a vector of device ids.
145 */
146 std::string toString(const DeviceIdVector& deviceIds);
147
148 /**
149 * Returns the first device id of a vector of device ids or AUDIO_PORT_HANDLE_NONE when its empty.
150 */
151 audio_port_handle_t getFirstDeviceId(const DeviceIdVector& deviceIds);
152
153 /**
154 * Returns whether two vectors of device ids have the same elements.
155 */
156 bool areDeviceIdsEqual(const DeviceIdVector& first, const DeviceIdVector& second);
157
158 /**
159 * Create audio profile attributes map by given audio profile array from the range of [first, last).
160 *
161 * @param profiles the array of audio profiles.
162 * @param first the first index of the profile.
163 * @param last the last index of the profile.
164 * @return a multipmap of audio format to pair of corresponding sample rates and channel masks set.
165 */
166 AudioProfileAttributesMultimap createAudioProfilesAttrMap(audio_profile profiles[],
167 uint32_t first,
168 uint32_t last);
169
170 /**
171 * Populate audio profiles according to given profile attributes, format, channel masks and
172 * sample rates.
173 *
174 * The function will first go over all pairs of channel masks and sample rates that are present in
175 * the profile attributes of the given map. Note that the channel masks and the sample rates that
176 * are not present in the collections of all valid channel masks and all valid sample rates will be
177 * excluded. After that, if there are channel masks and sample rates that present in the all values
178 * collection but not in profile attributes, they will also be place in a new audio profile in the
179 * profile array.
180 *
181 * Note that if the resulting index of the audio profile exceeds the maximum, no new audio profiles
182 * will be placed in the array.
183 *
184 * @param profileAttrs a multimap that contains format and its corresponding channel masks and
185 * sample rates.
186 * @param format the targeted audio format.
187 * @param allChannelMasks all valid channel masks for the format.
188 * @param allSampleRates all valid sample rates for the format.
189 * @param audioProfiles the audio profile array.
190 * @param numAudioProfiles the start index to put audio profile in the array. The value will be
191 * updated if there is new audio profile placed.
192 * @param maxAudioProfiles the maximum number of audio profile.
193 */
194 void populateAudioProfiles(const AudioProfileAttributesMultimap& profileAttrs,
195 audio_format_t format,
196 ChannelMaskSet allChannelMasks,
197 SampleRateSet allSampleRates,
198 audio_profile audioProfiles[],
199 uint32_t* numAudioProfiles,
200 uint32_t maxAudioProfiles = AUDIO_PORT_MAX_AUDIO_PROFILES);
201
202
203 } // namespace android
204