blob: 783eef38ec901954942f51debb2ed992d61f50d1 [file] [log] [blame]
Glenn Kasten99e53b82012-01-19 08:59:58 -08001/*
Mathias Agopian65ab4712010-07-14 17:59:35 -07002**
3** Copyright 2007, 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_H
19#define ANDROID_AUDIO_MIXER_H
20
Eric Tanace588c2018-09-12 11:44:43 -070021#include <map>
Andy Hung8ed196a2018-01-05 13:21:11 -080022#include <pthread.h>
23#include <sstream>
Mathias Agopian65ab4712010-07-14 17:59:35 -070024#include <stdint.h>
25#include <sys/types.h>
Andy Hung8ed196a2018-01-05 13:21:11 -080026#include <unordered_map>
Eric Tanace588c2018-09-12 11:44:43 -070027#include <vector>
Mathias Agopian65ab4712010-07-14 17:59:35 -070028
jiabinbf6b0ec2019-02-12 12:30:12 -080029#include <android/os/IExternalVibratorService.h>
Dan Albert36802bd2014-11-20 11:31:17 -080030#include <media/AudioBufferProvider.h>
Andy Hung068561c2017-01-03 17:09:32 -080031#include <media/AudioResampler.h>
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -070032#include <media/AudioResamplerPublic.h>
Andy Hung068561c2017-01-03 17:09:32 -080033#include <media/BufferProviders.h>
Dan Albert36802bd2014-11-20 11:31:17 -080034#include <system/audio.h>
35#include <utils/Compat.h>
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070036#include <utils/threads.h>
37
Glenn Kastenc56f3422014-03-21 17:53:17 -070038// FIXME This is actually unity gain, which might not be max in future, expressed in U.12
Andy Hung97ae8242014-05-30 10:35:47 -070039#define MAX_GAIN_INT AudioMixer::UNITY_GAIN_INT
Glenn Kastenc56f3422014-03-21 17:53:17 -070040
Andy Hung116a4982017-11-30 10:15:08 -080041// This must match frameworks/av/services/audioflinger/Configuration.h
42#define FLOAT_AUX
43
Mathias Agopian65ab4712010-07-14 17:59:35 -070044namespace android {
45
Eric Tanace588c2018-09-12 11:44:43 -070046namespace NBLog {
47class Writer;
48} // namespace NBLog
49
Mathias Agopian65ab4712010-07-14 17:59:35 -070050// ----------------------------------------------------------------------------
51
Mathias Agopian65ab4712010-07-14 17:59:35 -070052class AudioMixer
53{
54public:
Andy Hung8ed196a2018-01-05 13:21:11 -080055 // Do not change these unless underlying code changes.
Andy Hunge93b6b72014-07-17 21:30:53 -070056 // This mixer has a hard-coded upper limit of 8 channels for output.
Andy Hung8ed196a2018-01-05 13:21:11 -080057 static constexpr uint32_t MAX_NUM_CHANNELS = FCC_8;
58 static constexpr uint32_t MAX_NUM_VOLUMES = FCC_2; // stereo volume only
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070059 // maximum number of channels supported for the content
Andy Hunge93b6b72014-07-17 21:30:53 -070060 static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = AUDIO_CHANNEL_COUNT_MAX;
Mathias Agopian65ab4712010-07-14 17:59:35 -070061
Andy Hung97ae8242014-05-30 10:35:47 -070062 static const uint16_t UNITY_GAIN_INT = 0x1000;
Dan Albert36802bd2014-11-20 11:31:17 -080063 static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f;
Mathias Agopian65ab4712010-07-14 17:59:35 -070064
65 enum { // names
Mathias Agopian65ab4712010-07-14 17:59:35 -070066 // setParameter targets
67 TRACK = 0x3000,
68 RESAMPLE = 0x3001,
69 RAMP_VOLUME = 0x3002, // ramp to new volume
70 VOLUME = 0x3003, // don't ramp
Andy Hungc5656cc2015-03-26 19:04:33 -070071 TIMESTRETCH = 0x3004,
Mathias Agopian65ab4712010-07-14 17:59:35 -070072
73 // set Parameter names
74 // for target TRACK
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070075 CHANNEL_MASK = 0x4000,
Mathias Agopian65ab4712010-07-14 17:59:35 -070076 FORMAT = 0x4001,
77 MAIN_BUFFER = 0x4002,
78 AUX_BUFFER = 0x4003,
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070079 DOWNMIX_TYPE = 0X4004,
Andy Hung78820702014-02-28 16:23:02 -080080 MIXER_FORMAT = 0x4005, // AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
Andy Hunge93b6b72014-07-17 21:30:53 -070081 MIXER_CHANNEL_MASK = 0x4006, // Channel mask for mixer output
jiabin245cdd92018-12-07 17:55:15 -080082 // for haptic
83 HAPTIC_ENABLED = 0x4007, // Set haptic data from this track should be played or not.
jiabin77270b82018-12-18 15:41:29 -080084 HAPTIC_INTENSITY = 0x4008, // Set the intensity to play haptic data.
Glenn Kasten362c4e62011-12-14 10:28:06 -080085 // for target RESAMPLE
Glenn Kasten4e2293f2012-04-12 09:39:07 -070086 SAMPLE_RATE = 0x4100, // Configure sample rate conversion on this track name;
87 // parameter 'value' is the new sample rate in Hz.
88 // Only creates a sample rate converter the first time that
89 // the track sample rate is different from the mix sample rate.
90 // If the new sample rate is the same as the mix sample rate,
91 // and a sample rate converter already exists,
92 // then the sample rate converter remains present but is a no-op.
93 RESET = 0x4101, // Reset sample rate converter without changing sample rate.
94 // This clears out the resampler's input buffer.
95 REMOVE = 0x4102, // Remove the sample rate converter on this track name;
96 // the track is restored to the mix sample rate.
Glenn Kasten362c4e62011-12-14 10:28:06 -080097 // for target RAMP_VOLUME and VOLUME (8 channels max)
Glenn Kastenc56f3422014-03-21 17:53:17 -070098 // FIXME use float for these 3 to improve the dynamic range
Mathias Agopian65ab4712010-07-14 17:59:35 -070099 VOLUME0 = 0x4200,
100 VOLUME1 = 0x4201,
101 AUXLEVEL = 0x4210,
Andy Hungc5656cc2015-03-26 19:04:33 -0700102 // for target TIMESTRETCH
103 PLAYBACK_RATE = 0x4300, // Configure timestretch on this track name;
104 // parameter 'value' is a pointer to the new playback rate.
Mathias Agopian65ab4712010-07-14 17:59:35 -0700105 };
106
jiabinbf6b0ec2019-02-12 12:30:12 -0800107 typedef enum { // Haptic intensity, should keep consistent with VibratorService
108 HAPTIC_SCALE_MUTE = os::IExternalVibratorService::SCALE_MUTE,
109 HAPTIC_SCALE_VERY_LOW = os::IExternalVibratorService::SCALE_VERY_LOW,
110 HAPTIC_SCALE_LOW = os::IExternalVibratorService::SCALE_LOW,
111 HAPTIC_SCALE_NONE = os::IExternalVibratorService::SCALE_NONE,
112 HAPTIC_SCALE_HIGH = os::IExternalVibratorService::SCALE_HIGH,
113 HAPTIC_SCALE_VERY_HIGH = os::IExternalVibratorService::SCALE_VERY_HIGH,
114 } haptic_intensity_t;
115 static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2.0f / 3.0f;
116 static constexpr float HAPTIC_SCALE_LOW_RATIO = 3.0f / 4.0f;
117 static const constexpr float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f;
jiabin77270b82018-12-18 15:41:29 -0800118
119 static inline bool isValidHapticIntensity(haptic_intensity_t hapticIntensity) {
120 switch (hapticIntensity) {
jiabinbf6b0ec2019-02-12 12:30:12 -0800121 case HAPTIC_SCALE_MUTE:
jiabin77270b82018-12-18 15:41:29 -0800122 case HAPTIC_SCALE_VERY_LOW:
123 case HAPTIC_SCALE_LOW:
124 case HAPTIC_SCALE_NONE:
125 case HAPTIC_SCALE_HIGH:
126 case HAPTIC_SCALE_VERY_HIGH:
127 return true;
128 default:
129 return false;
130 }
131 }
132
Andy Hung1bc088a2018-02-09 15:57:31 -0800133 AudioMixer(size_t frameCount, uint32_t sampleRate)
134 : mSampleRate(sampleRate)
Andy Hung8ed196a2018-01-05 13:21:11 -0800135 , mFrameCount(frameCount) {
136 pthread_once(&sOnceControl, &sInitRoutine);
137 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700138
Andy Hung1bc088a2018-02-09 15:57:31 -0800139 // Create a new track in the mixer.
140 //
141 // \param name a unique user-provided integer associated with the track.
142 // If name already exists, the function will abort.
143 // \param channelMask output channel mask.
144 // \param format PCM format
145 // \param sessionId Session id for the track. Tracks with the same
146 // session id will be submixed together.
147 //
148 // \return OK on success.
149 // BAD_VALUE if the format does not satisfy isValidFormat()
150 // or the channelMask does not satisfy isValidChannelMask().
151 status_t create(
152 int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId);
Glenn Kasten17a736c2012-02-14 08:52:15 -0800153
Andy Hung1bc088a2018-02-09 15:57:31 -0800154 bool exists(int name) const {
155 return mTracks.count(name) > 0;
156 }
Glenn Kasten17a736c2012-02-14 08:52:15 -0800157
Andy Hung1bc088a2018-02-09 15:57:31 -0800158 // Free an allocated track by name.
159 void destroy(int name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700160
Glenn Kasten17a736c2012-02-14 08:52:15 -0800161 // Enable or disable an allocated track by name
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800162 void enable(int name);
163 void disable(int name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700164
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800165 void setParameter(int name, int target, int param, void *value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700166
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800167 void setBufferProvider(int name, AudioBufferProvider* bufferProvider);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700168
Andy Hung8ed196a2018-01-05 13:21:11 -0800169 void process() {
jiabindce8f8c2018-12-10 17:49:31 -0800170 for (const auto &pair : mTracks) {
171 // Clear contracted buffer before processing if contracted channels are saved
172 const std::shared_ptr<Track> &t = pair.second;
173 if (t->mKeepContractedChannels) {
174 t->clearContractedBuffer();
175 }
176 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800177 (this->*mHook)();
jiabin77270b82018-12-18 15:41:29 -0800178 processHapticData();
Andy Hung8ed196a2018-01-05 13:21:11 -0800179 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700180
Glenn Kastenc59c0042012-02-02 14:06:11 -0800181 size_t getUnreleasedFrames(int name) const;
Eric Laurent071ccd52011-12-22 16:08:41 -0800182
Andy Hung8ed196a2018-01-05 13:21:11 -0800183 std::string trackNames() const {
184 std::stringstream ss;
185 for (const auto &pair : mTracks) {
186 ss << pair.first << " ";
Andy Hungabdb9902015-01-12 15:08:22 -0800187 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800188 return ss.str();
189 }
190
191 void setNBLogWriter(NBLog::Writer *logWriter) {
192 mNBLogWriter = logWriter;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700193 }
194
Andy Hung1bc088a2018-02-09 15:57:31 -0800195 static inline bool isValidFormat(audio_format_t format) {
196 switch (format) {
197 case AUDIO_FORMAT_PCM_8_BIT:
198 case AUDIO_FORMAT_PCM_16_BIT:
199 case AUDIO_FORMAT_PCM_24_BIT_PACKED:
200 case AUDIO_FORMAT_PCM_32_BIT:
201 case AUDIO_FORMAT_PCM_FLOAT:
202 return true;
203 default:
204 return false;
205 }
206 }
207
208 static inline bool isValidChannelMask(audio_channel_mask_t channelMask) {
209 return audio_channel_mask_is_valid(channelMask); // the RemixBufferProvider is flexible.
210 }
211
Mathias Agopian65ab4712010-07-14 17:59:35 -0700212private:
213
Andy Hung8ed196a2018-01-05 13:21:11 -0800214 /* For multi-format functions (calls template functions
215 * in AudioMixerOps.h). The template parameters are as follows:
216 *
217 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
218 * USEFLOATVOL (set to true if float volume is used)
219 * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards)
220 * TO: int32_t (Q4.27) or float
221 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
222 * TA: int32_t (Q4.27)
223 */
224
Mathias Agopian65ab4712010-07-14 17:59:35 -0700225 enum {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700226 // FIXME this representation permits up to 8 channels
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700227 NEEDS_CHANNEL_COUNT__MASK = 0x00000007,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700228 };
229
230 enum {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700231 NEEDS_CHANNEL_1 = 0x00000000, // mono
232 NEEDS_CHANNEL_2 = 0x00000001, // stereo
Mathias Agopian65ab4712010-07-14 17:59:35 -0700233
Glenn Kastend6fadf02013-10-30 14:37:29 -0700234 // sample format is not explicitly specified, and is assumed to be AUDIO_FORMAT_PCM_16_BIT
Mathias Agopian65ab4712010-07-14 17:59:35 -0700235
Glenn Kastend6fadf02013-10-30 14:37:29 -0700236 NEEDS_MUTE = 0x00000100,
237 NEEDS_RESAMPLE = 0x00001000,
238 NEEDS_AUX = 0x00010000,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700239 };
240
Andy Hung8ed196a2018-01-05 13:21:11 -0800241 // hook types
242 enum {
243 PROCESSTYPE_NORESAMPLEONETRACK, // others set elsewhere
244 };
Mathias Agopian65ab4712010-07-14 17:59:35 -0700245
Andy Hung8ed196a2018-01-05 13:21:11 -0800246 enum {
247 TRACKTYPE_NOP,
248 TRACKTYPE_RESAMPLE,
249 TRACKTYPE_NORESAMPLE,
250 TRACKTYPE_NORESAMPLEMONO,
251 };
Mathias Agopian65ab4712010-07-14 17:59:35 -0700252
Andy Hung8ed196a2018-01-05 13:21:11 -0800253 // process hook functionality
254 using process_hook_t = void(AudioMixer::*)();
255
256 struct Track;
257 using hook_t = void(Track::*)(int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux);
258
259 struct Track {
260 Track()
261 : bufferProvider(nullptr)
262 {
263 // TODO: move additional initialization here.
264 }
265
266 ~Track()
267 {
268 // bufferProvider, mInputBufferProvider need not be deleted.
269 mResampler.reset(nullptr);
270 // Ensure the order of destruction of buffer providers as they
271 // release the upstream provider in the destructor.
272 mTimestretchBufferProvider.reset(nullptr);
273 mPostDownmixReformatBufferProvider.reset(nullptr);
274 mDownmixerBufferProvider.reset(nullptr);
275 mReformatBufferProvider.reset(nullptr);
jiabinea8fa7a2019-02-22 14:41:50 -0800276 mContractChannelsNonDestructiveBufferProvider.reset(nullptr);
jiabindce8f8c2018-12-10 17:49:31 -0800277 mAdjustChannelsBufferProvider.reset(nullptr);
Andy Hung8ed196a2018-01-05 13:21:11 -0800278 }
279
280 bool needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; }
281 bool setResampler(uint32_t trackSampleRate, uint32_t devSampleRate);
282 bool doesResample() const { return mResampler.get() != nullptr; }
283 void resetResampler() { if (mResampler.get() != nullptr) mResampler->reset(); }
284 void adjustVolumeRamp(bool aux, bool useFloat = false);
285 size_t getUnreleasedFrames() const { return mResampler.get() != nullptr ?
286 mResampler->getUnreleasedFrames() : 0; };
287
288 status_t prepareForDownmix();
289 void unprepareForDownmix();
290 status_t prepareForReformat();
291 void unprepareForReformat();
jiabindce8f8c2018-12-10 17:49:31 -0800292 status_t prepareForAdjustChannels();
293 void unprepareForAdjustChannels();
294 status_t prepareForAdjustChannelsNonDestructive(size_t frames);
295 void unprepareForAdjustChannelsNonDestructive();
296 void clearContractedBuffer();
Andy Hung8ed196a2018-01-05 13:21:11 -0800297 bool setPlaybackRate(const AudioPlaybackRate &playbackRate);
298 void reconfigureBufferProviders();
299
300 static hook_t getTrackHook(int trackType, uint32_t channelCount,
301 audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
302
303 void track__nop(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
304
305 template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
306 typename TO, typename TI, typename TA>
307 void volumeMix(TO *out, size_t outFrames, const TI *in, TA *aux, bool ramp);
308
Mathias Agopian65ab4712010-07-14 17:59:35 -0700309 uint32_t needs;
310
Andy Hung5e58b0a2014-06-23 19:07:29 -0700311 // TODO: Eventually remove legacy integer volume settings
Mathias Agopian65ab4712010-07-14 17:59:35 -0700312 union {
Andy Hunge93b6b72014-07-17 21:30:53 -0700313 int16_t volume[MAX_NUM_VOLUMES]; // U4.12 fixed point (top bit should be zero)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700314 int32_t volumeRL;
315 };
316
Andy Hunge93b6b72014-07-17 21:30:53 -0700317 int32_t prevVolume[MAX_NUM_VOLUMES];
Andy Hunge93b6b72014-07-17 21:30:53 -0700318 int32_t volumeInc[MAX_NUM_VOLUMES];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700319 int32_t auxInc;
320 int32_t prevAuxLevel;
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800321 int16_t auxLevel; // 0 <= auxLevel <= MAX_GAIN_INT, but signed for mul performance
Andy Hung8ed196a2018-01-05 13:21:11 -0800322
Mathias Agopian65ab4712010-07-14 17:59:35 -0700323 uint16_t frameCount;
324
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800325 uint8_t channelCount; // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK)
Andy Hungef7c7fb2014-05-12 16:51:41 -0700326 uint8_t unused_padding; // formerly format, was always 16
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800327 uint16_t enabled; // actually bool
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700328 audio_channel_mask_t channelMask;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700329
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700330 // actual buffer provider used by the track hooks, see DownmixerBufferProvider below
331 // for how the Track buffer provider is wrapped by another one when dowmixing is required
Mathias Agopian65ab4712010-07-14 17:59:35 -0700332 AudioBufferProvider* bufferProvider;
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800333
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800334 mutable AudioBufferProvider::Buffer buffer; // 8 bytes
Mathias Agopian65ab4712010-07-14 17:59:35 -0700335
336 hook_t hook;
Andy Hung8ed196a2018-01-05 13:21:11 -0800337 const void *mIn; // current location in buffer
Mathias Agopian65ab4712010-07-14 17:59:35 -0700338
Andy Hung8ed196a2018-01-05 13:21:11 -0800339 std::unique_ptr<AudioResampler> mResampler;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700340 uint32_t sampleRate;
341 int32_t* mainBuffer;
342 int32_t* auxBuffer;
343
Andy Hung7f475492014-08-25 16:36:37 -0700344 /* Buffer providers are constructed to translate the track input data as needed.
345 *
Andy Hungc5656cc2015-03-26 19:04:33 -0700346 * TODO: perhaps make a single PlaybackConverterProvider class to move
347 * all pre-mixer track buffer conversions outside the AudioMixer class.
348 *
Andy Hung7f475492014-08-25 16:36:37 -0700349 * 1) mInputBufferProvider: The AudioTrack buffer provider.
jiabinea8fa7a2019-02-22 14:41:50 -0800350 * 2) mAdjustChannelsBufferProvider: Expands or contracts sample data from one interleaved
351 * channel format to another. Expanded channels are filled with zeros and put at the end
352 * of each audio frame. Contracted channels are copied to the end of the buffer.
353 * 3) mContractChannelsNonDestructiveBufferProvider: Non-destructively contract sample data.
354 * This is currently using at audio-haptic coupled playback to separate audio and haptic
355 * data. Contracted channels could be written to given buffer.
jiabindce8f8c2018-12-10 17:49:31 -0800356 * 4) mReformatBufferProvider: If not NULL, performs the audio reformat to
Andy Hung7f475492014-08-25 16:36:37 -0700357 * match either mMixerInFormat or mDownmixRequiresFormat, if the downmixer
358 * requires reformat. For example, it may convert floating point input to
359 * PCM_16_bit if that's required by the downmixer.
jiabindce8f8c2018-12-10 17:49:31 -0800360 * 5) mDownmixerBufferProvider: If not NULL, performs the channel remixing to match
Andy Hung7f475492014-08-25 16:36:37 -0700361 * the number of channels required by the mixer sink.
jiabindce8f8c2018-12-10 17:49:31 -0800362 * 6) mPostDownmixReformatBufferProvider: If not NULL, performs reformatting from
Andy Hung7f475492014-08-25 16:36:37 -0700363 * the downmixer requirements to the mixer engine input requirements.
jiabindce8f8c2018-12-10 17:49:31 -0800364 * 7) mTimestretchBufferProvider: Adds timestretching for playback rate
Andy Hung7f475492014-08-25 16:36:37 -0700365 */
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700366 AudioBufferProvider* mInputBufferProvider; // externally provided buffer provider.
jiabinea8fa7a2019-02-22 14:41:50 -0800367 // TODO: combine mAdjustChannelsBufferProvider and
368 // mContractChannelsNonDestructiveBufferProvider
jiabindce8f8c2018-12-10 17:49:31 -0800369 std::unique_ptr<PassthruBufferProvider> mAdjustChannelsBufferProvider;
jiabinea8fa7a2019-02-22 14:41:50 -0800370 std::unique_ptr<PassthruBufferProvider> mContractChannelsNonDestructiveBufferProvider;
Andy Hung8ed196a2018-01-05 13:21:11 -0800371 std::unique_ptr<PassthruBufferProvider> mReformatBufferProvider;
372 std::unique_ptr<PassthruBufferProvider> mDownmixerBufferProvider;
373 std::unique_ptr<PassthruBufferProvider> mPostDownmixReformatBufferProvider;
374 std::unique_ptr<PassthruBufferProvider> mTimestretchBufferProvider;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700375
Andy Hung7f475492014-08-25 16:36:37 -0700376 int32_t sessionId;
377
Andy Hunge8a1ced2014-05-09 15:02:21 -0700378 audio_format_t mMixerFormat; // output mix format: AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
379 audio_format_t mFormat; // input track format
Andy Hungef7c7fb2014-05-12 16:51:41 -0700380 audio_format_t mMixerInFormat; // mix internal format AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
381 // each track must be converted to this format.
Andy Hung7f475492014-08-25 16:36:37 -0700382 audio_format_t mDownmixRequiresFormat; // required downmixer format
383 // AUDIO_FORMAT_PCM_16_BIT if 16 bit necessary
384 // AUDIO_FORMAT_INVALID if no required format
Andy Hungef7c7fb2014-05-12 16:51:41 -0700385
Andy Hunge93b6b72014-07-17 21:30:53 -0700386 float mVolume[MAX_NUM_VOLUMES]; // floating point set volume
387 float mPrevVolume[MAX_NUM_VOLUMES]; // floating point previous volume
388 float mVolumeInc[MAX_NUM_VOLUMES]; // floating point volume increment
Andy Hung5e58b0a2014-06-23 19:07:29 -0700389
390 float mAuxLevel; // floating point set aux level
391 float mPrevAuxLevel; // floating point prev aux level
392 float mAuxInc; // floating point aux increment
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800393
Andy Hunge93b6b72014-07-17 21:30:53 -0700394 audio_channel_mask_t mMixerChannelMask;
395 uint32_t mMixerChannelCount;
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800396
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700397 AudioPlaybackRate mPlaybackRate;
Andy Hungc5656cc2015-03-26 19:04:33 -0700398
jiabindce8f8c2018-12-10 17:49:31 -0800399 // Haptic
jiabin245cdd92018-12-07 17:55:15 -0800400 bool mHapticPlaybackEnabled;
jiabin77270b82018-12-18 15:41:29 -0800401 haptic_intensity_t mHapticIntensity;
jiabin245cdd92018-12-07 17:55:15 -0800402 audio_channel_mask_t mHapticChannelMask;
403 uint32_t mHapticChannelCount;
404 audio_channel_mask_t mMixerHapticChannelMask;
405 uint32_t mMixerHapticChannelCount;
jiabindce8f8c2018-12-10 17:49:31 -0800406 uint32_t mAdjustInChannelCount;
407 uint32_t mAdjustOutChannelCount;
408 uint32_t mAdjustNonDestructiveInChannelCount;
409 uint32_t mAdjustNonDestructiveOutChannelCount;
410 bool mKeepContractedChannels;
411
jiabin77270b82018-12-18 15:41:29 -0800412 float getHapticScaleGamma() const {
413 // Need to keep consistent with the value in VibratorService.
414 switch (mHapticIntensity) {
415 case HAPTIC_SCALE_VERY_LOW:
416 return 2.0f;
417 case HAPTIC_SCALE_LOW:
418 return 1.5f;
419 case HAPTIC_SCALE_HIGH:
420 return 0.5f;
421 case HAPTIC_SCALE_VERY_HIGH:
422 return 0.25f;
423 default:
424 return 1.0f;
425 }
426 }
427
428 float getHapticMaxAmplitudeRatio() const {
429 // Need to keep consistent with the value in VibratorService.
430 switch (mHapticIntensity) {
431 case HAPTIC_SCALE_VERY_LOW:
432 return HAPTIC_SCALE_VERY_LOW_RATIO;
433 case HAPTIC_SCALE_LOW:
434 return HAPTIC_SCALE_LOW_RATIO;
435 case HAPTIC_SCALE_NONE:
436 case HAPTIC_SCALE_HIGH:
437 case HAPTIC_SCALE_VERY_HIGH:
jiabin77270b82018-12-18 15:41:29 -0800438 return 1.0f;
jiabinbf6b0ec2019-02-12 12:30:12 -0800439 default:
440 return 0.0f;
jiabin77270b82018-12-18 15:41:29 -0800441 }
442 }
443
Andy Hung8ed196a2018-01-05 13:21:11 -0800444 private:
445 // hooks
446 void track__genericResample(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
447 void track__16BitsStereo(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
448 void track__16BitsMono(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
Andy Hung0f451e92014-08-04 21:28:47 -0700449
Andy Hung8ed196a2018-01-05 13:21:11 -0800450 void volumeRampStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
451 void volumeStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
452
453 // multi-format track hooks
454 template <int MIXTYPE, typename TO, typename TI, typename TA>
455 void track__Resample(TO* out, size_t frameCount, TO* temp __unused, TA* aux);
456 template <int MIXTYPE, typename TO, typename TI, typename TA>
457 void track__NoResample(TO* out, size_t frameCount, TO* temp __unused, TA* aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700458 };
459
Andy Hung8ed196a2018-01-05 13:21:11 -0800460 // TODO: remove BLOCKSIZE unit of processing - it isn't needed anymore.
461 static constexpr int BLOCKSIZE = 16;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700462
Andy Hunge93b6b72014-07-17 21:30:53 -0700463 bool setChannelMasks(int name,
464 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask);
465
Andy Hung8ed196a2018-01-05 13:21:11 -0800466 // Called when track info changes and a new process hook should be determined.
467 void invalidate() {
468 mHook = &AudioMixer::process__validate;
469 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700470
Andy Hung8ed196a2018-01-05 13:21:11 -0800471 void process__validate();
472 void process__nop();
473 void process__genericNoResampling();
474 void process__genericResampling();
475 void process__oneTrack16BitsStereoNoResampling();
John Grossman4ff14ba2012-02-08 16:37:41 -0800476
Andy Hunge93b6b72014-07-17 21:30:53 -0700477 template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -0800478 void process__noResampleOneTrack();
Andy Hung296b7412014-06-17 15:25:47 -0700479
jiabin77270b82018-12-18 15:41:29 -0800480 void processHapticData();
481
Andy Hung8ed196a2018-01-05 13:21:11 -0800482 static process_hook_t getProcessHook(int processType, uint32_t channelCount,
483 audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
Andy Hung296b7412014-06-17 15:25:47 -0700484
485 static void convertMixerFormat(void *out, audio_format_t mixerOutFormat,
486 void *in, audio_format_t mixerInFormat, size_t sampleCount);
487
Andy Hung8ed196a2018-01-05 13:21:11 -0800488 static void sInitRoutine();
489
490 // initialization constants
Andy Hung8ed196a2018-01-05 13:21:11 -0800491 const uint32_t mSampleRate;
492 const size_t mFrameCount;
493
494 NBLog::Writer *mNBLogWriter = nullptr; // associated NBLog::Writer
495
496 process_hook_t mHook = &AudioMixer::process__nop; // one of process__*, never nullptr
497
498 // the size of the type (int32_t) should be the largest of all types supported
499 // by the mixer.
500 std::unique_ptr<int32_t[]> mOutputTemp;
501 std::unique_ptr<int32_t[]> mResampleTemp;
502
Andy Hung8ed196a2018-01-05 13:21:11 -0800503 // track names grouped by main buffer, in no particular order of main buffer.
504 // however names for a particular main buffer are in order (by construction).
505 std::unordered_map<void * /* mainBuffer */, std::vector<int /* name */>> mGroups;
506
507 // track names that are enabled, in increasing order (by construction).
508 std::vector<int /* name */> mEnabled;
509
510 // track smart pointers, by name, in increasing order of name.
511 std::map<int /* name */, std::shared_ptr<Track>> mTracks;
512
513 static pthread_once_t sOnceControl; // initialized in constructor by first new
Mathias Agopian65ab4712010-07-14 17:59:35 -0700514};
515
516// ----------------------------------------------------------------------------
Glenn Kasten63238ef2015-03-02 15:50:29 -0800517} // namespace android
Mathias Agopian65ab4712010-07-14 17:59:35 -0700518
519#endif // ANDROID_AUDIO_MIXER_H