1 /* 2 * Copyright (C) 2015 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 "AudioCollections.h" 20 #include "AudioProfile.h" 21 #include "AudioGain.h" 22 #include "HandleGenerator.h" 23 #include <utils/String8.h> 24 #include <utils/Vector.h> 25 #include <utils/RefBase.h> 26 #include <utils/Errors.h> 27 #include <system/audio.h> 28 #include <cutils/config_utils.h> 29 30 namespace android { 31 32 class HwModule; 33 class AudioRoute; 34 35 class AudioPort : public virtual RefBase, private HandleGenerator<audio_port_handle_t> 36 { 37 public: AudioPort(const String8 & name,audio_port_type_t type,audio_port_role_t role)38 AudioPort(const String8& name, audio_port_type_t type, audio_port_role_t role) : 39 mName(name), mType(type), mRole(role), mFlags(AUDIO_OUTPUT_FLAG_NONE) {} 40 ~AudioPort()41 virtual ~AudioPort() {} 42 setName(const String8 & name)43 void setName(const String8 &name) { mName = name; } getName()44 const String8 &getName() const { return mName; } 45 getType()46 audio_port_type_t getType() const { return mType; } getRole()47 audio_port_role_t getRole() const { return mRole; } 48 49 virtual const String8 getTagName() const = 0; 50 setGains(const AudioGains & gains)51 void setGains(const AudioGains &gains) { mGains = gains; } getGains()52 const AudioGains &getGains() const { return mGains; } 53 setFlags(uint32_t flags)54 virtual void setFlags(uint32_t flags) 55 { 56 //force direct flag if offload flag is set: offloading implies a direct output stream 57 // and all common behaviors are driven by checking only the direct flag 58 // this should normally be set appropriately in the policy configuration file 59 if (mRole == AUDIO_PORT_ROLE_SOURCE && (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 60 flags |= AUDIO_OUTPUT_FLAG_DIRECT; 61 } 62 mFlags = flags; 63 } getFlags()64 uint32_t getFlags() const { return mFlags; } 65 66 virtual void attach(const sp<HwModule>& module); 67 virtual void detach(); isAttached()68 bool isAttached() { return mModule != 0; } 69 70 // Audio port IDs are in a different namespace than AudioFlinger unique IDs 71 static audio_port_handle_t getNextUniqueId(); 72 73 virtual void toAudioPort(struct audio_port *port) const; 74 75 virtual void importAudioPort(const sp<AudioPort>& port, bool force = false); 76 addAudioProfile(const sp<AudioProfile> & profile)77 void addAudioProfile(const sp<AudioProfile> &profile) { mProfiles.add(profile); } 78 setAudioProfiles(const AudioProfileVector & profiles)79 void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; } getAudioProfiles()80 AudioProfileVector &getAudioProfiles() { return mProfiles; } 81 hasValidAudioProfile()82 bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); } 83 hasDynamicAudioProfile()84 bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); } 85 86 // searches for an exact match 87 virtual status_t checkExactAudioProfile(const struct audio_port_config *config) const; 88 89 // searches for a compatible match, currently implemented for input 90 // parameters are input|output, returned value is the best match. checkCompatibleAudioProfile(uint32_t & samplingRate,audio_channel_mask_t & channelMask,audio_format_t & format)91 status_t checkCompatibleAudioProfile(uint32_t &samplingRate, 92 audio_channel_mask_t &channelMask, 93 audio_format_t &format) const 94 { 95 return mProfiles.checkCompatibleProfile(samplingRate, channelMask, format, mType, mRole); 96 } 97 clearAudioProfiles()98 void clearAudioProfiles() { return mProfiles.clearProfiles(); } 99 100 status_t checkGain(const struct audio_gain_config *gainConfig, int index) const; 101 102 void pickAudioProfile(uint32_t &samplingRate, 103 audio_channel_mask_t &channelMask, 104 audio_format_t &format) const; 105 106 static const audio_format_t sPcmFormatCompareTable[]; 107 108 static int compareFormats(audio_format_t format1, audio_format_t format2); 109 110 // Used to select an audio HAL output stream with a sample format providing the 111 // less degradation for a given AudioTrack sample format. 112 static bool isBetterFormatMatch(audio_format_t newFormat, 113 audio_format_t currentFormat, 114 audio_format_t targetFormat); 115 static uint32_t formatDistance(audio_format_t format1, 116 audio_format_t format2); 117 static const uint32_t kFormatDistanceMax = 4; 118 119 audio_module_handle_t getModuleHandle() const; 120 uint32_t getModuleVersionMajor() const; 121 const char *getModuleName() const; getModule()122 sp<HwModule> getModule() const { return mModule; } 123 useInputChannelMask()124 bool useInputChannelMask() const 125 { 126 return ((mType == AUDIO_PORT_TYPE_DEVICE) && (mRole == AUDIO_PORT_ROLE_SOURCE)) || 127 ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SINK)); 128 } 129 isDirectOutput()130 inline bool isDirectOutput() const 131 { 132 return (mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && 133 (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)); 134 } 135 addRoute(const sp<AudioRoute> & route)136 void addRoute(const sp<AudioRoute> &route) { mRoutes.add(route); } getRoutes()137 const AudioRouteVector &getRoutes() const { return mRoutes; } 138 139 void dump(String8 *dst, int spaces, bool verbose = true) const; 140 141 void log(const char* indent) const; 142 143 AudioGains mGains; // gain controllers 144 145 private: 146 void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelsVector &channelMasks) const; 147 void pickSamplingRate(uint32_t &rate,const SampleRateVector &samplingRates) const; 148 149 sp<HwModule> mModule; // audio HW module exposing this I/O stream 150 String8 mName; 151 audio_port_type_t mType; 152 audio_port_role_t mRole; 153 uint32_t mFlags; // attribute flags mask (e.g primary output, direct output...). 154 AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels) 155 AudioRouteVector mRoutes; // Routes involving this port 156 }; 157 158 class AudioPortConfig : public virtual RefBase 159 { 160 public: 161 status_t applyAudioPortConfig(const struct audio_port_config *config, 162 struct audio_port_config *backupConfig = NULL); 163 virtual void toAudioPortConfig(struct audio_port_config *dstConfig, 164 const struct audio_port_config *srcConfig = NULL) const = 0; 165 virtual sp<AudioPort> getAudioPort() const = 0; hasSameHwModuleAs(const sp<AudioPortConfig> & other)166 virtual bool hasSameHwModuleAs(const sp<AudioPortConfig>& other) const { 167 return (other != 0) && (other->getAudioPort() != 0) && (getAudioPort() != 0) && 168 (other->getAudioPort()->getModuleHandle() == getAudioPort()->getModuleHandle()); 169 } 170 bool hasGainController(bool canUseForVolume = false) const; 171 172 unsigned int mSamplingRate = 0u; 173 audio_format_t mFormat = AUDIO_FORMAT_INVALID; 174 audio_channel_mask_t mChannelMask = AUDIO_CHANNEL_NONE; 175 struct audio_gain_config mGain = { .index = -1 }; 176 union audio_io_flags mFlags = { AUDIO_INPUT_FLAG_NONE }; 177 }; 178 179 } // namespace android 180