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