1 /* 2 ** 3 ** Copyright 2019, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #ifndef ANDROID_AUDIO_MIXER_BASE_H 19 #define ANDROID_AUDIO_MIXER_BASE_H 20 21 #include <map> 22 #include <memory> 23 #include <string> 24 #include <unordered_map> 25 #include <vector> 26 27 #include <media/AudioBufferProvider.h> 28 #include <media/AudioResampler.h> 29 #include <media/AudioResamplerPublic.h> 30 #include <system/audio.h> 31 #include <utils/Compat.h> 32 33 // This must match frameworks/av/services/audioflinger/Configuration.h 34 // when used with the Audio Framework. 35 #define FLOAT_AUX 36 37 namespace android { 38 39 // ---------------------------------------------------------------------------- 40 41 // AudioMixerBase is functional on its own if only mixing and resampling 42 // is needed. 43 44 class AudioMixerBase 45 { 46 public: 47 // Do not change these unless underlying code changes. 48 // This mixer has a hard-coded upper limit of 8 channels for output. 49 static constexpr uint32_t MAX_NUM_CHANNELS = FCC_8; 50 static constexpr uint32_t MAX_NUM_VOLUMES = FCC_2; // stereo volume only 51 52 static const uint16_t UNITY_GAIN_INT = 0x1000; 53 static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f; 54 55 enum { // names 56 // setParameter targets 57 TRACK = 0x3000, 58 RESAMPLE = 0x3001, 59 RAMP_VOLUME = 0x3002, // ramp to new volume 60 VOLUME = 0x3003, // don't ramp 61 TIMESTRETCH = 0x3004, 62 63 // set Parameter names 64 // for target TRACK 65 CHANNEL_MASK = 0x4000, 66 FORMAT = 0x4001, 67 MAIN_BUFFER = 0x4002, 68 AUX_BUFFER = 0x4003, 69 // 0x4004 reserved 70 MIXER_FORMAT = 0x4005, // AUDIO_FORMAT_PCM_(FLOAT|16_BIT) 71 MIXER_CHANNEL_MASK = 0x4006, // Channel mask for mixer output 72 // for target RESAMPLE 73 SAMPLE_RATE = 0x4100, // Configure sample rate conversion on this track name; 74 // parameter 'value' is the new sample rate in Hz. 75 // Only creates a sample rate converter the first time that 76 // the track sample rate is different from the mix sample rate. 77 // If the new sample rate is the same as the mix sample rate, 78 // and a sample rate converter already exists, 79 // then the sample rate converter remains present but is a no-op. 80 RESET = 0x4101, // Reset sample rate converter without changing sample rate. 81 // This clears out the resampler's input buffer. 82 REMOVE = 0x4102, // Remove the sample rate converter on this track name; 83 // the track is restored to the mix sample rate. 84 // for target RAMP_VOLUME and VOLUME (8 channels max) 85 // FIXME use float for these 3 to improve the dynamic range 86 VOLUME0 = 0x4200, 87 VOLUME1 = 0x4201, 88 AUXLEVEL = 0x4210, 89 }; 90 AudioMixerBase(size_t frameCount,uint32_t sampleRate)91 AudioMixerBase(size_t frameCount, uint32_t sampleRate) 92 : mSampleRate(sampleRate) 93 , mFrameCount(frameCount) { 94 } 95 ~AudioMixerBase()96 virtual ~AudioMixerBase() {} 97 98 virtual bool isValidFormat(audio_format_t format) const; 99 virtual bool isValidChannelMask(audio_channel_mask_t channelMask) const; 100 101 // Create a new track in the mixer. 102 // 103 // \param name a unique user-provided integer associated with the track. 104 // If name already exists, the function will abort. 105 // \param channelMask output channel mask. 106 // \param format PCM format 107 // \param sessionId Session id for the track. Tracks with the same 108 // session id will be submixed together. 109 // 110 // \return OK on success. 111 // BAD_VALUE if the format does not satisfy isValidFormat() 112 // or the channelMask does not satisfy isValidChannelMask(). 113 status_t create( 114 int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId); 115 exists(int name)116 bool exists(int name) const { 117 return mTracks.count(name) > 0; 118 } 119 120 // Free an allocated track by name. 121 void destroy(int name); 122 123 // Enable or disable an allocated track by name 124 void enable(int name); 125 void disable(int name); 126 127 virtual void setParameter(int name, int target, int param, void *value); 128 process()129 void process() { 130 preProcess(); 131 (this->*mHook)(); 132 postProcess(); 133 } 134 135 size_t getUnreleasedFrames(int name) const; 136 137 std::string trackNames() const; 138 139 protected: 140 // Set kUseNewMixer to true to use the new mixer engine always. Otherwise the 141 // original code will be used for stereo sinks, the new mixer for everything else. 142 static constexpr bool kUseNewMixer = true; 143 144 // Set kUseFloat to true to allow floating input into the mixer engine. 145 // If kUseNewMixer is false, this is ignored or may be overridden internally 146 static constexpr bool kUseFloat = true; 147 148 #ifdef FLOAT_AUX 149 using TYPE_AUX = float; 150 static_assert(kUseNewMixer && kUseFloat, 151 "kUseNewMixer and kUseFloat must be true for FLOAT_AUX option"); 152 #else 153 using TYPE_AUX = int32_t; // q4.27 154 #endif 155 156 /* For multi-format functions (calls template functions 157 * in AudioMixerOps.h). The template parameters are as follows: 158 * 159 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration) 160 * USEFLOATVOL (set to true if float volume is used) 161 * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards) 162 * TO: int32_t (Q4.27) or float 163 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float 164 * TA: int32_t (Q4.27) 165 */ 166 167 enum { 168 // FIXME this representation permits up to 8 channels 169 NEEDS_CHANNEL_COUNT__MASK = 0x00000007, 170 }; 171 172 enum { 173 NEEDS_CHANNEL_1 = 0x00000000, // mono 174 NEEDS_CHANNEL_2 = 0x00000001, // stereo 175 176 // sample format is not explicitly specified, and is assumed to be AUDIO_FORMAT_PCM_16_BIT 177 178 NEEDS_MUTE = 0x00000100, 179 NEEDS_RESAMPLE = 0x00001000, 180 NEEDS_AUX = 0x00010000, 181 }; 182 183 // hook types 184 enum { 185 PROCESSTYPE_NORESAMPLEONETRACK, // others set elsewhere 186 }; 187 188 enum { 189 TRACKTYPE_NOP, 190 TRACKTYPE_RESAMPLE, 191 TRACKTYPE_RESAMPLEMONO, 192 TRACKTYPE_RESAMPLESTEREO, 193 TRACKTYPE_NORESAMPLE, 194 TRACKTYPE_NORESAMPLEMONO, 195 TRACKTYPE_NORESAMPLESTEREO, 196 }; 197 198 // process hook functionality 199 using process_hook_t = void(AudioMixerBase::*)(); 200 isAudioChannelPositionMask(audio_channel_mask_t channelMask)201 static bool isAudioChannelPositionMask(audio_channel_mask_t channelMask) { 202 return audio_channel_mask_get_representation(channelMask) 203 == AUDIO_CHANNEL_REPRESENTATION_POSITION; 204 } 205 206 struct TrackBase; 207 using hook_t = void(TrackBase::*)( 208 int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux); 209 210 struct TrackBase { TrackBaseTrackBase211 TrackBase() 212 : bufferProvider(nullptr) 213 { 214 // TODO: move additional initialization here. 215 } ~TrackBaseTrackBase216 virtual ~TrackBase() {} 217 getOutputChannelCountTrackBase218 virtual uint32_t getOutputChannelCount() { return channelCount; } getMixerChannelCountTrackBase219 virtual uint32_t getMixerChannelCount() { return mMixerChannelCount; } 220 needsRampTrackBase221 bool needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; } 222 bool setResampler(uint32_t trackSampleRate, uint32_t devSampleRate); doesResampleTrackBase223 bool doesResample() const { return mResampler.get() != nullptr; } 224 void recreateResampler(uint32_t devSampleRate); resetResamplerTrackBase225 void resetResampler() { if (mResampler.get() != nullptr) mResampler->reset(); } 226 void adjustVolumeRamp(bool aux, bool useFloat = false); getUnreleasedFramesTrackBase227 size_t getUnreleasedFrames() const { return mResampler.get() != nullptr ? 228 mResampler->getUnreleasedFrames() : 0; }; 229 useStereoVolumeTrackBase230 bool useStereoVolume() const { return channelMask == AUDIO_CHANNEL_OUT_STEREO 231 && isAudioChannelPositionMask(mMixerChannelMask); } 232 233 static hook_t getTrackHook(int trackType, uint32_t channelCount, 234 audio_format_t mixerInFormat, audio_format_t mixerOutFormat); 235 236 void track__nop(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); 237 238 template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL, 239 typename TO, typename TI, typename TA> 240 void volumeMix(TO *out, size_t outFrames, const TI *in, TA *aux, bool ramp); 241 242 uint32_t needs; 243 244 // TODO: Eventually remove legacy integer volume settings 245 union { 246 int16_t volume[MAX_NUM_VOLUMES]; // U4.12 fixed point (top bit should be zero) 247 int32_t volumeRL; 248 }; 249 250 int32_t prevVolume[MAX_NUM_VOLUMES]; 251 int32_t volumeInc[MAX_NUM_VOLUMES]; 252 int32_t auxInc; 253 int32_t prevAuxLevel; 254 int16_t auxLevel; // 0 <= auxLevel <= MAX_GAIN_INT, but signed for mul performance 255 256 uint16_t frameCount; 257 258 uint8_t channelCount; // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK) 259 uint8_t unused_padding; // formerly format, was always 16 260 uint16_t enabled; // actually bool 261 audio_channel_mask_t channelMask; 262 263 // actual buffer provider used by the track hooks 264 AudioBufferProvider* bufferProvider; 265 266 mutable AudioBufferProvider::Buffer buffer; // 8 bytes 267 268 hook_t hook; 269 const void *mIn; // current location in buffer 270 271 std::unique_ptr<AudioResampler> mResampler; 272 uint32_t sampleRate; 273 int32_t* mainBuffer; 274 int32_t* auxBuffer; 275 276 int32_t sessionId; 277 278 audio_format_t mMixerFormat; // output mix format: AUDIO_FORMAT_PCM_(FLOAT|16_BIT) 279 audio_format_t mFormat; // input track format 280 audio_format_t mMixerInFormat; // mix internal format AUDIO_FORMAT_PCM_(FLOAT|16_BIT) 281 // each track must be converted to this format. 282 283 float mVolume[MAX_NUM_VOLUMES]; // floating point set volume 284 float mPrevVolume[MAX_NUM_VOLUMES]; // floating point previous volume 285 float mVolumeInc[MAX_NUM_VOLUMES]; // floating point volume increment 286 287 float mAuxLevel; // floating point set aux level 288 float mPrevAuxLevel; // floating point prev aux level 289 float mAuxInc; // floating point aux increment 290 291 audio_channel_mask_t mMixerChannelMask; 292 uint32_t mMixerChannelCount; 293 294 protected: 295 296 // hooks 297 void track__genericResample(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); 298 void track__16BitsStereo(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); 299 void track__16BitsMono(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux); 300 301 void volumeRampStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux); 302 void volumeStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux); 303 304 // multi-format track hooks 305 template <int MIXTYPE, typename TO, typename TI, typename TA> 306 void track__Resample(TO* out, size_t frameCount, TO* temp __unused, TA* aux); 307 template <int MIXTYPE, typename TO, typename TI, typename TA> 308 void track__NoResample(TO* out, size_t frameCount, TO* temp __unused, TA* aux); 309 }; 310 311 // preCreateTrack must create an instance of a proper TrackBase descendant. 312 // postCreateTrack is called after filling out fields of TrackBase. It can 313 // abort track creation by returning non-OK status. See the implementation 314 // of create() for details. 315 virtual std::shared_ptr<TrackBase> preCreateTrack(); postCreateTrack(TrackBase * track __unused)316 virtual status_t postCreateTrack(TrackBase *track __unused) { return OK; } 317 318 // preProcess is called before the process hook, postProcess after, 319 // see the implementation of process() method. preProcess()320 virtual void preProcess() {} postProcess()321 virtual void postProcess() {} 322 323 virtual bool setChannelMasks(int name, 324 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask); 325 326 // Called when track info changes and a new process hook should be determined. invalidate()327 void invalidate() { 328 mHook = &AudioMixerBase::process__validate; 329 } 330 331 void process__validate(); 332 void process__nop(); 333 void process__genericNoResampling(); 334 void process__genericResampling(); 335 void process__oneTrack16BitsStereoNoResampling(); 336 337 template <int MIXTYPE, typename TO, typename TI, typename TA> 338 void process__noResampleOneTrack(); 339 340 static process_hook_t getProcessHook(int processType, uint32_t channelCount, 341 audio_format_t mixerInFormat, audio_format_t mixerOutFormat, 342 bool useStereoVolume); 343 344 static void convertMixerFormat(void *out, audio_format_t mixerOutFormat, 345 void *in, audio_format_t mixerInFormat, size_t sampleCount); 346 347 // initialization constants 348 const uint32_t mSampleRate; 349 const size_t mFrameCount; 350 351 process_hook_t mHook = &AudioMixerBase::process__nop; // one of process__*, never nullptr 352 353 // the size of the type (int32_t) should be the largest of all types supported 354 // by the mixer. 355 std::unique_ptr<int32_t[]> mOutputTemp; 356 std::unique_ptr<int32_t[]> mResampleTemp; 357 358 // track names grouped by main buffer, in no particular order of main buffer. 359 // however names for a particular main buffer are in order (by construction). 360 std::unordered_map<void * /* mainBuffer */, std::vector<int /* name */>> mGroups; 361 362 // track names that are enabled, in increasing order (by construction). 363 std::vector<int /* name */> mEnabled; 364 365 // track smart pointers, by name, in increasing order of name. 366 std::map<int /* name */, std::shared_ptr<TrackBase>> mTracks; 367 }; 368 369 } // namespace android 370 371 #endif // ANDROID_AUDIO_MIXER_BASE_H 372