1 /*
2 **
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 #define LOG_TAG "AudioMixer"
19 //#define LOG_NDEBUG 0
20
21 #include <sstream>
22 #include <stdint.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <math.h>
26 #include <sys/types.h>
27
28 #include <utils/Errors.h>
29 #include <utils/Log.h>
30
31 #include <system/audio.h>
32
33 #include <audio_utils/primitives.h>
34 #include <audio_utils/format.h>
35 #include <media/AudioMixer.h>
36
37 #include "AudioMixerOps.h"
38
39 // The FCC_2 macro refers to the Fixed Channel Count of 2 for the legacy integer mixer.
40 #ifndef FCC_2
41 #define FCC_2 2
42 #endif
43
44 // Look for MONO_HACK for any Mono hack involving legacy mono channel to
45 // stereo channel conversion.
46
47 /* VERY_VERY_VERBOSE_LOGGING will show exactly which process hook and track hook is
48 * being used. This is a considerable amount of log spam, so don't enable unless you
49 * are verifying the hook based code.
50 */
51 //#define VERY_VERY_VERBOSE_LOGGING
52 #ifdef VERY_VERY_VERBOSE_LOGGING
53 #define ALOGVV ALOGV
54 //define ALOGVV printf // for test-mixer.cpp
55 #else
56 #define ALOGVV(a...) do { } while (0)
57 #endif
58
59 // Set to default copy buffer size in frames for input processing.
60 static constexpr size_t kCopyBufferFrameCount = 256;
61
62 namespace android {
63
64 // ----------------------------------------------------------------------------
65
isValidChannelMask(audio_channel_mask_t channelMask) const66 bool AudioMixer::isValidChannelMask(audio_channel_mask_t channelMask) const {
67 return audio_channel_mask_is_valid(channelMask); // the RemixBufferProvider is flexible.
68 }
69
70 // Called when channel masks have changed for a track name
71 // TODO: Fix DownmixerBufferProvider not to (possibly) change mixer input format,
72 // which will simplify this logic.
setChannelMasks(int name,audio_channel_mask_t trackChannelMask,audio_channel_mask_t mixerChannelMask)73 bool AudioMixer::setChannelMasks(int name,
74 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) {
75 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
76 const std::shared_ptr<Track> &track = getTrack(name);
77
78 if (trackChannelMask == (track->channelMask | track->mHapticChannelMask)
79 && mixerChannelMask == (track->mMixerChannelMask | track->mMixerHapticChannelMask)) {
80 return false; // no need to change
81 }
82 const audio_channel_mask_t hapticChannelMask =
83 static_cast<audio_channel_mask_t>(trackChannelMask & AUDIO_CHANNEL_HAPTIC_ALL);
84 trackChannelMask = static_cast<audio_channel_mask_t>(
85 trackChannelMask & ~AUDIO_CHANNEL_HAPTIC_ALL);
86 const audio_channel_mask_t mixerHapticChannelMask = static_cast<audio_channel_mask_t>(
87 mixerChannelMask & AUDIO_CHANNEL_HAPTIC_ALL);
88 mixerChannelMask = static_cast<audio_channel_mask_t>(
89 mixerChannelMask & ~AUDIO_CHANNEL_HAPTIC_ALL);
90 // always recompute for both channel masks even if only one has changed.
91 const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
92 const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
93 const uint32_t hapticChannelCount = audio_channel_count_from_out_mask(hapticChannelMask);
94 const uint32_t mixerHapticChannelCount =
95 audio_channel_count_from_out_mask(mixerHapticChannelMask);
96
97 ALOG_ASSERT((trackChannelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX)
98 && trackChannelCount
99 && mixerChannelCount);
100 track->channelMask = trackChannelMask;
101 track->channelCount = trackChannelCount;
102 track->mMixerChannelMask = mixerChannelMask;
103 track->mMixerChannelCount = mixerChannelCount;
104 track->mHapticChannelMask = hapticChannelMask;
105 track->mHapticChannelCount = hapticChannelCount;
106 track->mMixerHapticChannelMask = mixerHapticChannelMask;
107 track->mMixerHapticChannelCount = mixerHapticChannelCount;
108
109 if (track->mHapticChannelCount > 0) {
110 track->mAdjustInChannelCount = track->channelCount + track->mHapticChannelCount;
111 track->mAdjustOutChannelCount = track->channelCount;
112 track->mKeepContractedChannels = track->mHapticPlaybackEnabled;
113 } else {
114 track->mAdjustInChannelCount = 0;
115 track->mAdjustOutChannelCount = 0;
116 track->mKeepContractedChannels = false;
117 }
118
119 // channel masks have changed, does this track need a downmixer?
120 // update to try using our desired format (if we aren't already using it)
121 const status_t status = track->prepareForDownmix();
122 ALOGE_IF(status != OK,
123 "prepareForDownmix error %d, track channel mask %#x, mixer channel mask %#x",
124 status, track->channelMask, track->mMixerChannelMask);
125
126 // always do reformat since channel mask changed,
127 // do it after downmix since track format may change!
128 track->prepareForReformat();
129
130 track->prepareForAdjustChannels(mFrameCount);
131
132 // Resampler channels may have changed.
133 track->recreateResampler(mSampleRate);
134 return true;
135 }
136
unprepareForDownmix()137 void AudioMixer::Track::unprepareForDownmix() {
138 ALOGV("AudioMixer::unprepareForDownmix(%p)", this);
139
140 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
141 // release any buffers held by the mPostDownmixReformatBufferProvider
142 // before deallocating the mDownmixerBufferProvider.
143 mPostDownmixReformatBufferProvider->reset();
144 }
145
146 mDownmixRequiresFormat = AUDIO_FORMAT_INVALID;
147 if (mDownmixerBufferProvider.get() != nullptr) {
148 // this track had previously been configured with a downmixer, delete it
149 mDownmixerBufferProvider.reset(nullptr);
150 reconfigureBufferProviders();
151 } else {
152 ALOGV(" nothing to do, no downmixer to delete");
153 }
154 }
155
prepareForDownmix()156 status_t AudioMixer::Track::prepareForDownmix()
157 {
158 ALOGV("AudioMixer::prepareForDownmix(%p) with mask 0x%x",
159 this, channelMask);
160
161 // discard the previous downmixer if there was one
162 unprepareForDownmix();
163 // MONO_HACK Only remix (upmix or downmix) if the track and mixer/device channel masks
164 // are not the same and not handled internally, as mono for channel position masks is.
165 if (channelMask == mMixerChannelMask
166 || (channelMask == AUDIO_CHANNEL_OUT_MONO
167 && isAudioChannelPositionMask(mMixerChannelMask))) {
168 return NO_ERROR;
169 }
170 // DownmixerBufferProvider is only used for position masks.
171 if (audio_channel_mask_get_representation(channelMask)
172 == AUDIO_CHANNEL_REPRESENTATION_POSITION
173 && DownmixerBufferProvider::isMultichannelCapable()) {
174
175 // Check if we have a float or int16 downmixer, in that order.
176 for (const audio_format_t format : { AUDIO_FORMAT_PCM_FLOAT, AUDIO_FORMAT_PCM_16_BIT }) {
177 mDownmixerBufferProvider.reset(new DownmixerBufferProvider(
178 channelMask, mMixerChannelMask,
179 format,
180 sampleRate, sessionId, kCopyBufferFrameCount));
181 if (static_cast<DownmixerBufferProvider *>(mDownmixerBufferProvider.get())
182 ->isValid()) {
183 mDownmixRequiresFormat = format;
184 reconfigureBufferProviders();
185 return NO_ERROR;
186 }
187 }
188 // mDownmixerBufferProvider reset below.
189 }
190
191 // See if we should use our built-in non-effect downmixer.
192 if (mMixerInFormat == AUDIO_FORMAT_PCM_FLOAT
193 && mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO
194 && audio_channel_mask_get_representation(channelMask)
195 == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
196 mDownmixerBufferProvider.reset(new ChannelMixBufferProvider(channelMask,
197 mMixerChannelMask, mMixerInFormat, kCopyBufferFrameCount));
198 if (static_cast<ChannelMixBufferProvider *>(mDownmixerBufferProvider.get())
199 ->isValid()) {
200 mDownmixRequiresFormat = mMixerInFormat;
201 reconfigureBufferProviders();
202 ALOGD("%s: Fallback using ChannelMix", __func__);
203 return NO_ERROR;
204 } else {
205 ALOGD("%s: ChannelMix not supported for channel mask %#x", __func__, channelMask);
206 }
207 }
208
209 // Effect downmixer does not accept the channel conversion. Let's use our remixer.
210 mDownmixerBufferProvider.reset(new RemixBufferProvider(channelMask,
211 mMixerChannelMask, mMixerInFormat, kCopyBufferFrameCount));
212 // Remix always finds a conversion whereas Downmixer effect above may fail.
213 reconfigureBufferProviders();
214 return NO_ERROR;
215 }
216
unprepareForReformat()217 void AudioMixer::Track::unprepareForReformat() {
218 ALOGV("AudioMixer::unprepareForReformat(%p)", this);
219 bool requiresReconfigure = false;
220 if (mReformatBufferProvider.get() != nullptr) {
221 mReformatBufferProvider.reset(nullptr);
222 requiresReconfigure = true;
223 }
224 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
225 mPostDownmixReformatBufferProvider.reset(nullptr);
226 requiresReconfigure = true;
227 }
228 if (requiresReconfigure) {
229 reconfigureBufferProviders();
230 }
231 }
232
prepareForReformat()233 status_t AudioMixer::Track::prepareForReformat()
234 {
235 ALOGV("AudioMixer::prepareForReformat(%p) with format %#x", this, mFormat);
236 // discard previous reformatters
237 unprepareForReformat();
238 // only configure reformatters as needed
239 const audio_format_t targetFormat = mDownmixRequiresFormat != AUDIO_FORMAT_INVALID
240 ? mDownmixRequiresFormat : mMixerInFormat;
241 bool requiresReconfigure = false;
242 if (mFormat != targetFormat) {
243 mReformatBufferProvider.reset(new ReformatBufferProvider(
244 audio_channel_count_from_out_mask(channelMask),
245 mFormat,
246 targetFormat,
247 kCopyBufferFrameCount));
248 requiresReconfigure = true;
249 } else if (mFormat == AUDIO_FORMAT_PCM_FLOAT) {
250 // Input and output are floats, make sure application did not provide > 3db samples
251 // that would break volume application (b/68099072)
252 // TODO: add a trusted source flag to avoid the overhead
253 mReformatBufferProvider.reset(new ClampFloatBufferProvider(
254 audio_channel_count_from_out_mask(channelMask),
255 kCopyBufferFrameCount));
256 requiresReconfigure = true;
257 }
258 if (targetFormat != mMixerInFormat) {
259 mPostDownmixReformatBufferProvider.reset(new ReformatBufferProvider(
260 audio_channel_count_from_out_mask(mMixerChannelMask),
261 targetFormat,
262 mMixerInFormat,
263 kCopyBufferFrameCount));
264 requiresReconfigure = true;
265 }
266 if (requiresReconfigure) {
267 reconfigureBufferProviders();
268 }
269 return NO_ERROR;
270 }
271
unprepareForAdjustChannels()272 void AudioMixer::Track::unprepareForAdjustChannels()
273 {
274 ALOGV("AUDIOMIXER::unprepareForAdjustChannels");
275 if (mAdjustChannelsBufferProvider.get() != nullptr) {
276 mAdjustChannelsBufferProvider.reset(nullptr);
277 reconfigureBufferProviders();
278 }
279 }
280
prepareForAdjustChannels(size_t frames)281 status_t AudioMixer::Track::prepareForAdjustChannels(size_t frames)
282 {
283 ALOGV("AudioMixer::prepareForAdjustChannels(%p) with inChannelCount: %u, outChannelCount: %u",
284 this, mAdjustInChannelCount, mAdjustOutChannelCount);
285 unprepareForAdjustChannels();
286 if (mAdjustInChannelCount != mAdjustOutChannelCount) {
287 uint8_t* buffer = mKeepContractedChannels
288 ? (uint8_t*)mainBuffer + frames * audio_bytes_per_frame(
289 mMixerChannelCount, mMixerFormat)
290 : nullptr;
291 mAdjustChannelsBufferProvider.reset(new AdjustChannelsBufferProvider(
292 mFormat, mAdjustInChannelCount, mAdjustOutChannelCount, frames,
293 mKeepContractedChannels ? mMixerFormat : AUDIO_FORMAT_INVALID,
294 buffer, mMixerHapticChannelCount));
295 reconfigureBufferProviders();
296 }
297 return NO_ERROR;
298 }
299
clearContractedBuffer()300 void AudioMixer::Track::clearContractedBuffer()
301 {
302 if (mAdjustChannelsBufferProvider.get() != nullptr) {
303 static_cast<AdjustChannelsBufferProvider*>(
304 mAdjustChannelsBufferProvider.get())->clearContractedFrames();
305 }
306 }
307
reconfigureBufferProviders()308 void AudioMixer::Track::reconfigureBufferProviders()
309 {
310 // configure from upstream to downstream buffer providers.
311 bufferProvider = mInputBufferProvider;
312 if (mAdjustChannelsBufferProvider.get() != nullptr) {
313 mAdjustChannelsBufferProvider->setBufferProvider(bufferProvider);
314 bufferProvider = mAdjustChannelsBufferProvider.get();
315 }
316 if (mReformatBufferProvider.get() != nullptr) {
317 mReformatBufferProvider->setBufferProvider(bufferProvider);
318 bufferProvider = mReformatBufferProvider.get();
319 }
320 if (mDownmixerBufferProvider.get() != nullptr) {
321 mDownmixerBufferProvider->setBufferProvider(bufferProvider);
322 bufferProvider = mDownmixerBufferProvider.get();
323 }
324 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
325 mPostDownmixReformatBufferProvider->setBufferProvider(bufferProvider);
326 bufferProvider = mPostDownmixReformatBufferProvider.get();
327 }
328 if (mTimestretchBufferProvider.get() != nullptr) {
329 mTimestretchBufferProvider->setBufferProvider(bufferProvider);
330 bufferProvider = mTimestretchBufferProvider.get();
331 }
332 }
333
setParameter(int name,int target,int param,void * value)334 void AudioMixer::setParameter(int name, int target, int param, void *value)
335 {
336 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
337 const std::shared_ptr<Track> &track = getTrack(name);
338
339 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
340 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
341
342 switch (target) {
343
344 case TRACK:
345 switch (param) {
346 case CHANNEL_MASK: {
347 const audio_channel_mask_t trackChannelMask =
348 static_cast<audio_channel_mask_t>(valueInt);
349 if (setChannelMasks(name, trackChannelMask,
350 static_cast<audio_channel_mask_t>(
351 track->mMixerChannelMask | track->mMixerHapticChannelMask))) {
352 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
353 invalidate();
354 }
355 } break;
356 case MAIN_BUFFER:
357 if (track->mainBuffer != valueBuf) {
358 track->mainBuffer = valueBuf;
359 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
360 if (track->mKeepContractedChannels) {
361 track->prepareForAdjustChannels(mFrameCount);
362 }
363 invalidate();
364 }
365 break;
366 case AUX_BUFFER:
367 AudioMixerBase::setParameter(name, target, param, value);
368 break;
369 case FORMAT: {
370 audio_format_t format = static_cast<audio_format_t>(valueInt);
371 if (track->mFormat != format) {
372 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
373 track->mFormat = format;
374 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
375 track->prepareForReformat();
376 invalidate();
377 }
378 } break;
379 // FIXME do we want to support setting the downmix type from AudioFlinger?
380 // for a specific track? or per mixer?
381 /* case DOWNMIX_TYPE:
382 break */
383 case MIXER_FORMAT: {
384 audio_format_t format = static_cast<audio_format_t>(valueInt);
385 if (track->mMixerFormat != format) {
386 track->mMixerFormat = format;
387 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
388 if (track->mKeepContractedChannels) {
389 track->prepareForAdjustChannels(mFrameCount);
390 }
391 }
392 } break;
393 case MIXER_CHANNEL_MASK: {
394 const audio_channel_mask_t mixerChannelMask =
395 static_cast<audio_channel_mask_t>(valueInt);
396 if (setChannelMasks(name, static_cast<audio_channel_mask_t>(
397 track->channelMask | track->mHapticChannelMask),
398 mixerChannelMask)) {
399 ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
400 invalidate();
401 }
402 } break;
403 case HAPTIC_ENABLED: {
404 const bool hapticPlaybackEnabled = static_cast<bool>(valueInt);
405 if (track->mHapticPlaybackEnabled != hapticPlaybackEnabled) {
406 track->mHapticPlaybackEnabled = hapticPlaybackEnabled;
407 track->mKeepContractedChannels = hapticPlaybackEnabled;
408 track->prepareForAdjustChannels(mFrameCount);
409 }
410 } break;
411 case HAPTIC_INTENSITY: {
412 const os::HapticScale hapticIntensity = static_cast<os::HapticScale>(valueInt);
413 if (track->mHapticIntensity != hapticIntensity) {
414 track->mHapticIntensity = hapticIntensity;
415 }
416 } break;
417 case HAPTIC_MAX_AMPLITUDE: {
418 const float hapticMaxAmplitude = *reinterpret_cast<float*>(value);
419 if (track->mHapticMaxAmplitude != hapticMaxAmplitude) {
420 track->mHapticMaxAmplitude = hapticMaxAmplitude;
421 }
422 } break;
423 default:
424 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
425 }
426 break;
427
428 case RESAMPLE:
429 case RAMP_VOLUME:
430 case VOLUME:
431 AudioMixerBase::setParameter(name, target, param, value);
432 break;
433 case TIMESTRETCH:
434 switch (param) {
435 case PLAYBACK_RATE: {
436 const AudioPlaybackRate *playbackRate =
437 reinterpret_cast<AudioPlaybackRate*>(value);
438 ALOGW_IF(!isAudioPlaybackRateValid(*playbackRate),
439 "bad parameters speed %f, pitch %f",
440 playbackRate->mSpeed, playbackRate->mPitch);
441 if (track->setPlaybackRate(*playbackRate)) {
442 ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE "
443 "%f %f %d %d",
444 playbackRate->mSpeed,
445 playbackRate->mPitch,
446 playbackRate->mStretchMode,
447 playbackRate->mFallbackMode);
448 // invalidate(); (should not require reconfigure)
449 }
450 } break;
451 default:
452 LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);
453 }
454 break;
455
456 default:
457 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
458 }
459 }
460
setPlaybackRate(const AudioPlaybackRate & playbackRate)461 bool AudioMixer::Track::setPlaybackRate(const AudioPlaybackRate &playbackRate)
462 {
463 if ((mTimestretchBufferProvider.get() == nullptr &&
464 fabs(playbackRate.mSpeed - mPlaybackRate.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
465 fabs(playbackRate.mPitch - mPlaybackRate.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA) ||
466 isAudioPlaybackRateEqual(playbackRate, mPlaybackRate)) {
467 return false;
468 }
469 mPlaybackRate = playbackRate;
470 if (mTimestretchBufferProvider.get() == nullptr) {
471 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
472 // but if none exists, it is the channel count (1 for mono).
473 const int timestretchChannelCount = getOutputChannelCount();
474 mTimestretchBufferProvider.reset(new TimestretchBufferProvider(timestretchChannelCount,
475 mMixerInFormat, sampleRate, playbackRate));
476 reconfigureBufferProviders();
477 } else {
478 static_cast<TimestretchBufferProvider*>(mTimestretchBufferProvider.get())
479 ->setPlaybackRate(playbackRate);
480 }
481 return true;
482 }
483
setBufferProvider(int name,AudioBufferProvider * bufferProvider)484 void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
485 {
486 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
487 const std::shared_ptr<Track> &track = getTrack(name);
488
489 if (track->mInputBufferProvider == bufferProvider) {
490 return; // don't reset any buffer providers if identical.
491 }
492 // reset order from downstream to upstream buffer providers.
493 if (track->mTimestretchBufferProvider.get() != nullptr) {
494 track->mTimestretchBufferProvider->reset();
495 } else if (track->mPostDownmixReformatBufferProvider.get() != nullptr) {
496 track->mPostDownmixReformatBufferProvider->reset();
497 } else if (track->mDownmixerBufferProvider != nullptr) {
498 track->mDownmixerBufferProvider->reset();
499 } else if (track->mReformatBufferProvider.get() != nullptr) {
500 track->mReformatBufferProvider->reset();
501 } else if (track->mAdjustChannelsBufferProvider.get() != nullptr) {
502 track->mAdjustChannelsBufferProvider->reset();
503 }
504
505 track->mInputBufferProvider = bufferProvider;
506 track->reconfigureBufferProviders();
507 }
508
509 /*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
510
sInitRoutine()511 /*static*/ void AudioMixer::sInitRoutine()
512 {
513 DownmixerBufferProvider::init(); // for the downmixer
514 }
515
preCreateTrack()516 std::shared_ptr<AudioMixerBase::TrackBase> AudioMixer::preCreateTrack()
517 {
518 return std::make_shared<Track>();
519 }
520
postCreateTrack(TrackBase * track)521 status_t AudioMixer::postCreateTrack(TrackBase *track)
522 {
523 Track* t = static_cast<Track*>(track);
524
525 audio_channel_mask_t channelMask = t->channelMask;
526 t->mHapticChannelMask = static_cast<audio_channel_mask_t>(
527 channelMask & AUDIO_CHANNEL_HAPTIC_ALL);
528 t->mHapticChannelCount = audio_channel_count_from_out_mask(t->mHapticChannelMask);
529 channelMask = static_cast<audio_channel_mask_t>(channelMask & ~AUDIO_CHANNEL_HAPTIC_ALL);
530 t->channelCount = audio_channel_count_from_out_mask(channelMask);
531 ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
532 "Non-stereo channel mask: %d\n", channelMask);
533 t->channelMask = channelMask;
534 t->mInputBufferProvider = NULL;
535 t->mDownmixRequiresFormat = AUDIO_FORMAT_INVALID; // no format required
536 t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
537 // haptic
538 t->mHapticPlaybackEnabled = false;
539 t->mHapticIntensity = os::HapticScale::NONE;
540 t->mHapticMaxAmplitude = NAN;
541 t->mMixerHapticChannelMask = AUDIO_CHANNEL_NONE;
542 t->mMixerHapticChannelCount = 0;
543 t->mAdjustInChannelCount = t->channelCount + t->mHapticChannelCount;
544 t->mAdjustOutChannelCount = t->channelCount;
545 t->mKeepContractedChannels = false;
546 // Check the downmixing (or upmixing) requirements.
547 status_t status = t->prepareForDownmix();
548 if (status != OK) {
549 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
550 return BAD_VALUE;
551 }
552 // prepareForDownmix() may change mDownmixRequiresFormat
553 ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
554 t->prepareForReformat();
555 t->prepareForAdjustChannels(mFrameCount);
556 return OK;
557 }
558
preProcess()559 void AudioMixer::preProcess()
560 {
561 for (const auto &pair : mTracks) {
562 // Clear contracted buffer before processing if contracted channels are saved
563 const std::shared_ptr<TrackBase> &tb = pair.second;
564 Track *t = static_cast<Track*>(tb.get());
565 if (t->mKeepContractedChannels) {
566 t->clearContractedBuffer();
567 }
568 }
569 }
570
postProcess()571 void AudioMixer::postProcess()
572 {
573 // Process haptic data.
574 // Need to keep consistent with VibrationEffect.scale(int, float, int)
575 for (const auto &pair : mGroups) {
576 // process by group of tracks with same output main buffer.
577 const auto &group = pair.second;
578 for (const int name : group) {
579 const std::shared_ptr<Track> &t = getTrack(name);
580 if (t->mHapticPlaybackEnabled) {
581 size_t sampleCount = mFrameCount * t->mMixerHapticChannelCount;
582 uint8_t* buffer = (uint8_t*)pair.first + mFrameCount * audio_bytes_per_frame(
583 t->mMixerChannelCount, t->mMixerFormat);
584 switch (t->mMixerFormat) {
585 // Mixer format should be AUDIO_FORMAT_PCM_FLOAT.
586 case AUDIO_FORMAT_PCM_FLOAT: {
587 os::scaleHapticData((float*) buffer, sampleCount, t->mHapticIntensity,
588 t->mHapticMaxAmplitude);
589 } break;
590 default:
591 LOG_ALWAYS_FATAL("bad mMixerFormat: %#x", t->mMixerFormat);
592 break;
593 }
594 break;
595 }
596 }
597 }
598 }
599
600 // ----------------------------------------------------------------------------
601 } // namespace android
602