Loading media/libaudiofoundation/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ cc_library_shared { vendor_available: true, srcs: [ "AudioContainers.cpp", "AudioGain.cpp", "AudioPort.cpp", "AudioProfile.cpp", Loading media/libaudiofoundation/AudioContainers.cpp 0 → 100644 +86 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <sstream> #include <string> #include <media/AudioContainers.h> namespace android { const DeviceTypeSet& getAudioDeviceOutAllSet() { static const DeviceTypeSet audioDeviceOutAllSet = DeviceTypeSet( std::begin(AUDIO_DEVICE_OUT_ALL_ARRAY), std::end(AUDIO_DEVICE_OUT_ALL_ARRAY)); return audioDeviceOutAllSet; } const DeviceTypeSet& getAudioDeviceOutAllA2dpSet() { static const DeviceTypeSet audioDeviceOutAllA2dpSet = DeviceTypeSet( std::begin(AUDIO_DEVICE_OUT_ALL_A2DP_ARRAY), std::end(AUDIO_DEVICE_OUT_ALL_A2DP_ARRAY)); return audioDeviceOutAllA2dpSet; } const DeviceTypeSet& getAudioDeviceOutAllScoSet() { static const DeviceTypeSet audioDeviceOutAllScoSet = DeviceTypeSet( std::begin(AUDIO_DEVICE_OUT_ALL_SCO_ARRAY), std::end(AUDIO_DEVICE_OUT_ALL_SCO_ARRAY)); return audioDeviceOutAllScoSet; } const DeviceTypeSet& getAudioDeviceInAllSet() { static const DeviceTypeSet audioDeviceInAllSet = DeviceTypeSet( std::begin(AUDIO_DEVICE_IN_ALL_ARRAY), std::end(AUDIO_DEVICE_IN_ALL_ARRAY)); return audioDeviceInAllSet; } bool deviceTypesToString(const DeviceTypeSet &deviceTypes, std::string &str) { bool ret = true; for (auto it = deviceTypes.begin(); it != deviceTypes.end();) { std::string deviceTypeStr; ret = audio_is_output_device(*it) ? OutputDeviceConverter::toString(*it, deviceTypeStr) : InputDeviceConverter::toString(*it, deviceTypeStr); if (!ret) { break; } str.append(deviceTypeStr); if (++it != deviceTypes.end()) { str.append(" , "); } } if (!ret) { str = "Unknown values"; } return ret; } std::string dumpDeviceTypes(const DeviceTypeSet &deviceTypes) { std::string ret; for (auto it = deviceTypes.begin(); it != deviceTypes.end();) { std::stringstream ss; ss << "0x" << std::hex << (*it); ret.append(ss.str()); if (++it != deviceTypes.end()) { ret.append(" , "); } } return ret; } } // namespace android media/libaudiofoundation/include/media/AudioContainers.h +69 −0 Original line number Diff line number Diff line Loading @@ -16,19 +16,37 @@ #pragma once #include <algorithm> #include <iterator> #include <set> #include <vector> #include <media/TypeConverter.h> #include <system/audio.h> namespace android { using ChannelMaskSet = std::set<audio_channel_mask_t>; using DeviceTypeSet = std::set<audio_devices_t>; using FormatSet = std::set<audio_format_t>; using SampleRateSet = std::set<uint32_t>; using FormatVector = std::vector<audio_format_t>; const DeviceTypeSet& getAudioDeviceOutAllSet(); const DeviceTypeSet& getAudioDeviceOutAllA2dpSet(); const DeviceTypeSet& getAudioDeviceOutAllScoSet(); const DeviceTypeSet& getAudioDeviceInAllSet(); template<typename T> static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) { std::vector<T> intersection; std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(intersection)); return intersection; } static inline ChannelMaskSet asInMask(const ChannelMaskSet& channelMasks) { ChannelMaskSet inMaskSet; for (const auto &channel : channelMasks) { Loading @@ -49,4 +67,55 @@ static inline ChannelMaskSet asOutMask(const ChannelMaskSet& channelMasks) { return outMaskSet; } static inline bool isSingleDeviceType(const DeviceTypeSet& deviceTypes, audio_devices_t deviceType) { return deviceTypes.size() == 1 && *(deviceTypes.begin()) == deviceType; } typedef bool (*DeviceTypeUnaryPredicate)(audio_devices_t); static inline bool isSingleDeviceType(const DeviceTypeSet& deviceTypes, DeviceTypeUnaryPredicate p) { return deviceTypes.size() == 1 && p(*(deviceTypes.begin())); } static inline void resetDeviceTypes(DeviceTypeSet& deviceTypes, audio_devices_t typeToAdd) { deviceTypes.clear(); deviceTypes.insert(typeToAdd); } // FIXME: This is temporary helper function. Remove this when getting rid of all // bit mask usages of audio device types. static inline audio_devices_t deviceTypesToBitMask(const DeviceTypeSet& deviceTypes) { audio_devices_t types = AUDIO_DEVICE_NONE; for (auto deviceType : deviceTypes) { types |= deviceType; } return types; } // FIXME: This is temporary helper function. Remove this when getting rid of all // bit mask usages of audio device types. static inline DeviceTypeSet deviceTypesFromBitMask(audio_devices_t types) { DeviceTypeSet deviceTypes; if ((types & AUDIO_DEVICE_BIT_IN) == 0) { for (auto deviceType : AUDIO_DEVICE_OUT_ALL_ARRAY) { if ((types & deviceType) == deviceType) { deviceTypes.insert(deviceType); } } } else { for (auto deviceType : AUDIO_DEVICE_IN_ALL_ARRAY) { if ((types & deviceType) == deviceType) { deviceTypes.insert(deviceType); } } } return deviceTypes; } bool deviceTypesToString(const DeviceTypeSet& deviceTypes, std::string &str); std::string dumpDeviceTypes(const DeviceTypeSet& deviceTypes); } // namespace android No newline at end of file services/audiopolicy/common/Android.bp +3 −0 Original line number Diff line number Diff line cc_library_headers { name: "libaudiopolicycommon", header_libs: [ "libaudiofoundation_headers", ], export_include_dirs: ["include"], } services/audiopolicy/common/include/Volume.h +36 −23 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #pragma once #include <media/AudioCommonTypes.h> #include <media/AudioContainers.h> #include <system/audio.h> #include <utils/Log.h> #include <math.h> Loading Loading @@ -82,43 +83,55 @@ public: * * @return subset of device required to limit the number of volume category per device */ static audio_devices_t getDeviceForVolume(audio_devices_t device) static audio_devices_t getDeviceForVolume(const android::DeviceTypeSet& deviceTypes) { if (device == AUDIO_DEVICE_NONE) { audio_devices_t deviceType = AUDIO_DEVICE_NONE; if (deviceTypes.empty()) { // this happens when forcing a route update and no track is active on an output. // In this case the returned category is not important. device = AUDIO_DEVICE_OUT_SPEAKER; } else if (popcount(device) > 1) { deviceType = AUDIO_DEVICE_OUT_SPEAKER; } else if (deviceTypes.size() > 1) { // Multiple device selection is either: // - speaker + one other device: give priority to speaker in this case. // - one A2DP device + another device: happens with duplicated output. In this case // retain the device on the A2DP output as the other must not correspond to an active // selection if not the speaker. // - HDMI-CEC system audio mode only output: give priority to available item in order. if (device & AUDIO_DEVICE_OUT_SPEAKER) { device = AUDIO_DEVICE_OUT_SPEAKER; } else if (device & AUDIO_DEVICE_OUT_SPEAKER_SAFE) { device = AUDIO_DEVICE_OUT_SPEAKER_SAFE; } else if (device & AUDIO_DEVICE_OUT_HDMI_ARC) { device = AUDIO_DEVICE_OUT_HDMI_ARC; } else if (device & AUDIO_DEVICE_OUT_AUX_LINE) { device = AUDIO_DEVICE_OUT_AUX_LINE; } else if (device & AUDIO_DEVICE_OUT_SPDIF) { device = AUDIO_DEVICE_OUT_SPDIF; if (deviceTypes.count(AUDIO_DEVICE_OUT_SPEAKER) != 0) { deviceType = AUDIO_DEVICE_OUT_SPEAKER; } else if (deviceTypes.count(AUDIO_DEVICE_OUT_SPEAKER_SAFE) != 0) { deviceType = AUDIO_DEVICE_OUT_SPEAKER_SAFE; } else if (deviceTypes.count(AUDIO_DEVICE_OUT_HDMI_ARC) != 0) { deviceType = AUDIO_DEVICE_OUT_HDMI_ARC; } else if (deviceTypes.count(AUDIO_DEVICE_OUT_AUX_LINE) != 0) { deviceType = AUDIO_DEVICE_OUT_AUX_LINE; } else if (deviceTypes.count(AUDIO_DEVICE_OUT_SPDIF) != 0) { deviceType = AUDIO_DEVICE_OUT_SPDIF; } else { device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); std::vector<audio_devices_t> a2dpDevices = android::Intersection( deviceTypes, android::getAudioDeviceOutAllA2dpSet()); if (a2dpDevices.size() > 1) { ALOGW("getDeviceForVolume() invalid device combination: %s", android::dumpDeviceTypes(deviceTypes).c_str()); } if (!a2dpDevices.empty()) { deviceType = a2dpDevices[0]; } } } else { deviceType = *(deviceTypes.begin()); } /*SPEAKER_SAFE is an alias of SPEAKER for purposes of volume control*/ if (device == AUDIO_DEVICE_OUT_SPEAKER_SAFE) device = AUDIO_DEVICE_OUT_SPEAKER; if (deviceType == AUDIO_DEVICE_OUT_SPEAKER_SAFE) { deviceType = AUDIO_DEVICE_OUT_SPEAKER; } ALOGW_IF(popcount(device) != 1, "getDeviceForVolume() invalid device combination: %08x", device); ALOGW_IF(deviceType == AUDIO_DEVICE_NONE, "getDeviceForVolume() invalid device combination: %s, returning AUDIO_DEVICE_NONE", android::dumpDeviceTypes(deviceTypes).c_str()); return device; return deviceType; } /** Loading @@ -128,9 +141,9 @@ public: * * @return device category. */ static device_category getDeviceCategory(audio_devices_t device) static device_category getDeviceCategory(const android::DeviceTypeSet& deviceTypes) { switch(getDeviceForVolume(device)) { switch(getDeviceForVolume(deviceTypes)) { case AUDIO_DEVICE_OUT_EARPIECE: return DEVICE_CATEGORY_EARPIECE; case AUDIO_DEVICE_OUT_WIRED_HEADSET: Loading Loading
media/libaudiofoundation/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ cc_library_shared { vendor_available: true, srcs: [ "AudioContainers.cpp", "AudioGain.cpp", "AudioPort.cpp", "AudioProfile.cpp", Loading
media/libaudiofoundation/AudioContainers.cpp 0 → 100644 +86 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <sstream> #include <string> #include <media/AudioContainers.h> namespace android { const DeviceTypeSet& getAudioDeviceOutAllSet() { static const DeviceTypeSet audioDeviceOutAllSet = DeviceTypeSet( std::begin(AUDIO_DEVICE_OUT_ALL_ARRAY), std::end(AUDIO_DEVICE_OUT_ALL_ARRAY)); return audioDeviceOutAllSet; } const DeviceTypeSet& getAudioDeviceOutAllA2dpSet() { static const DeviceTypeSet audioDeviceOutAllA2dpSet = DeviceTypeSet( std::begin(AUDIO_DEVICE_OUT_ALL_A2DP_ARRAY), std::end(AUDIO_DEVICE_OUT_ALL_A2DP_ARRAY)); return audioDeviceOutAllA2dpSet; } const DeviceTypeSet& getAudioDeviceOutAllScoSet() { static const DeviceTypeSet audioDeviceOutAllScoSet = DeviceTypeSet( std::begin(AUDIO_DEVICE_OUT_ALL_SCO_ARRAY), std::end(AUDIO_DEVICE_OUT_ALL_SCO_ARRAY)); return audioDeviceOutAllScoSet; } const DeviceTypeSet& getAudioDeviceInAllSet() { static const DeviceTypeSet audioDeviceInAllSet = DeviceTypeSet( std::begin(AUDIO_DEVICE_IN_ALL_ARRAY), std::end(AUDIO_DEVICE_IN_ALL_ARRAY)); return audioDeviceInAllSet; } bool deviceTypesToString(const DeviceTypeSet &deviceTypes, std::string &str) { bool ret = true; for (auto it = deviceTypes.begin(); it != deviceTypes.end();) { std::string deviceTypeStr; ret = audio_is_output_device(*it) ? OutputDeviceConverter::toString(*it, deviceTypeStr) : InputDeviceConverter::toString(*it, deviceTypeStr); if (!ret) { break; } str.append(deviceTypeStr); if (++it != deviceTypes.end()) { str.append(" , "); } } if (!ret) { str = "Unknown values"; } return ret; } std::string dumpDeviceTypes(const DeviceTypeSet &deviceTypes) { std::string ret; for (auto it = deviceTypes.begin(); it != deviceTypes.end();) { std::stringstream ss; ss << "0x" << std::hex << (*it); ret.append(ss.str()); if (++it != deviceTypes.end()) { ret.append(" , "); } } return ret; } } // namespace android
media/libaudiofoundation/include/media/AudioContainers.h +69 −0 Original line number Diff line number Diff line Loading @@ -16,19 +16,37 @@ #pragma once #include <algorithm> #include <iterator> #include <set> #include <vector> #include <media/TypeConverter.h> #include <system/audio.h> namespace android { using ChannelMaskSet = std::set<audio_channel_mask_t>; using DeviceTypeSet = std::set<audio_devices_t>; using FormatSet = std::set<audio_format_t>; using SampleRateSet = std::set<uint32_t>; using FormatVector = std::vector<audio_format_t>; const DeviceTypeSet& getAudioDeviceOutAllSet(); const DeviceTypeSet& getAudioDeviceOutAllA2dpSet(); const DeviceTypeSet& getAudioDeviceOutAllScoSet(); const DeviceTypeSet& getAudioDeviceInAllSet(); template<typename T> static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) { std::vector<T> intersection; std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(intersection)); return intersection; } static inline ChannelMaskSet asInMask(const ChannelMaskSet& channelMasks) { ChannelMaskSet inMaskSet; for (const auto &channel : channelMasks) { Loading @@ -49,4 +67,55 @@ static inline ChannelMaskSet asOutMask(const ChannelMaskSet& channelMasks) { return outMaskSet; } static inline bool isSingleDeviceType(const DeviceTypeSet& deviceTypes, audio_devices_t deviceType) { return deviceTypes.size() == 1 && *(deviceTypes.begin()) == deviceType; } typedef bool (*DeviceTypeUnaryPredicate)(audio_devices_t); static inline bool isSingleDeviceType(const DeviceTypeSet& deviceTypes, DeviceTypeUnaryPredicate p) { return deviceTypes.size() == 1 && p(*(deviceTypes.begin())); } static inline void resetDeviceTypes(DeviceTypeSet& deviceTypes, audio_devices_t typeToAdd) { deviceTypes.clear(); deviceTypes.insert(typeToAdd); } // FIXME: This is temporary helper function. Remove this when getting rid of all // bit mask usages of audio device types. static inline audio_devices_t deviceTypesToBitMask(const DeviceTypeSet& deviceTypes) { audio_devices_t types = AUDIO_DEVICE_NONE; for (auto deviceType : deviceTypes) { types |= deviceType; } return types; } // FIXME: This is temporary helper function. Remove this when getting rid of all // bit mask usages of audio device types. static inline DeviceTypeSet deviceTypesFromBitMask(audio_devices_t types) { DeviceTypeSet deviceTypes; if ((types & AUDIO_DEVICE_BIT_IN) == 0) { for (auto deviceType : AUDIO_DEVICE_OUT_ALL_ARRAY) { if ((types & deviceType) == deviceType) { deviceTypes.insert(deviceType); } } } else { for (auto deviceType : AUDIO_DEVICE_IN_ALL_ARRAY) { if ((types & deviceType) == deviceType) { deviceTypes.insert(deviceType); } } } return deviceTypes; } bool deviceTypesToString(const DeviceTypeSet& deviceTypes, std::string &str); std::string dumpDeviceTypes(const DeviceTypeSet& deviceTypes); } // namespace android No newline at end of file
services/audiopolicy/common/Android.bp +3 −0 Original line number Diff line number Diff line cc_library_headers { name: "libaudiopolicycommon", header_libs: [ "libaudiofoundation_headers", ], export_include_dirs: ["include"], }
services/audiopolicy/common/include/Volume.h +36 −23 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #pragma once #include <media/AudioCommonTypes.h> #include <media/AudioContainers.h> #include <system/audio.h> #include <utils/Log.h> #include <math.h> Loading Loading @@ -82,43 +83,55 @@ public: * * @return subset of device required to limit the number of volume category per device */ static audio_devices_t getDeviceForVolume(audio_devices_t device) static audio_devices_t getDeviceForVolume(const android::DeviceTypeSet& deviceTypes) { if (device == AUDIO_DEVICE_NONE) { audio_devices_t deviceType = AUDIO_DEVICE_NONE; if (deviceTypes.empty()) { // this happens when forcing a route update and no track is active on an output. // In this case the returned category is not important. device = AUDIO_DEVICE_OUT_SPEAKER; } else if (popcount(device) > 1) { deviceType = AUDIO_DEVICE_OUT_SPEAKER; } else if (deviceTypes.size() > 1) { // Multiple device selection is either: // - speaker + one other device: give priority to speaker in this case. // - one A2DP device + another device: happens with duplicated output. In this case // retain the device on the A2DP output as the other must not correspond to an active // selection if not the speaker. // - HDMI-CEC system audio mode only output: give priority to available item in order. if (device & AUDIO_DEVICE_OUT_SPEAKER) { device = AUDIO_DEVICE_OUT_SPEAKER; } else if (device & AUDIO_DEVICE_OUT_SPEAKER_SAFE) { device = AUDIO_DEVICE_OUT_SPEAKER_SAFE; } else if (device & AUDIO_DEVICE_OUT_HDMI_ARC) { device = AUDIO_DEVICE_OUT_HDMI_ARC; } else if (device & AUDIO_DEVICE_OUT_AUX_LINE) { device = AUDIO_DEVICE_OUT_AUX_LINE; } else if (device & AUDIO_DEVICE_OUT_SPDIF) { device = AUDIO_DEVICE_OUT_SPDIF; if (deviceTypes.count(AUDIO_DEVICE_OUT_SPEAKER) != 0) { deviceType = AUDIO_DEVICE_OUT_SPEAKER; } else if (deviceTypes.count(AUDIO_DEVICE_OUT_SPEAKER_SAFE) != 0) { deviceType = AUDIO_DEVICE_OUT_SPEAKER_SAFE; } else if (deviceTypes.count(AUDIO_DEVICE_OUT_HDMI_ARC) != 0) { deviceType = AUDIO_DEVICE_OUT_HDMI_ARC; } else if (deviceTypes.count(AUDIO_DEVICE_OUT_AUX_LINE) != 0) { deviceType = AUDIO_DEVICE_OUT_AUX_LINE; } else if (deviceTypes.count(AUDIO_DEVICE_OUT_SPDIF) != 0) { deviceType = AUDIO_DEVICE_OUT_SPDIF; } else { device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); std::vector<audio_devices_t> a2dpDevices = android::Intersection( deviceTypes, android::getAudioDeviceOutAllA2dpSet()); if (a2dpDevices.size() > 1) { ALOGW("getDeviceForVolume() invalid device combination: %s", android::dumpDeviceTypes(deviceTypes).c_str()); } if (!a2dpDevices.empty()) { deviceType = a2dpDevices[0]; } } } else { deviceType = *(deviceTypes.begin()); } /*SPEAKER_SAFE is an alias of SPEAKER for purposes of volume control*/ if (device == AUDIO_DEVICE_OUT_SPEAKER_SAFE) device = AUDIO_DEVICE_OUT_SPEAKER; if (deviceType == AUDIO_DEVICE_OUT_SPEAKER_SAFE) { deviceType = AUDIO_DEVICE_OUT_SPEAKER; } ALOGW_IF(popcount(device) != 1, "getDeviceForVolume() invalid device combination: %08x", device); ALOGW_IF(deviceType == AUDIO_DEVICE_NONE, "getDeviceForVolume() invalid device combination: %s, returning AUDIO_DEVICE_NONE", android::dumpDeviceTypes(deviceTypes).c_str()); return device; return deviceType; } /** Loading @@ -128,9 +141,9 @@ public: * * @return device category. */ static device_category getDeviceCategory(audio_devices_t device) static device_category getDeviceCategory(const android::DeviceTypeSet& deviceTypes) { switch(getDeviceForVolume(device)) { switch(getDeviceForVolume(deviceTypes)) { case AUDIO_DEVICE_OUT_EARPIECE: return DEVICE_CATEGORY_EARPIECE; case AUDIO_DEVICE_OUT_WIRED_HEADSET: Loading