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