1 /*
2 **
3 ** Copyright 2019, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #define LOG_TAG "AudioMixer"
19 //#define LOG_NDEBUG 0
20
21 #include <array>
22 #include <sstream>
23 #include <string.h>
24
25 #include <audio_utils/primitives.h>
26 #include <cutils/compiler.h>
27 #include <media/AudioMixerBase.h>
28 #include <utils/Log.h>
29
30 #include "AudioMixerOps.h"
31
32 // The FCC_2 macro refers to the Fixed Channel Count of 2 for the legacy integer mixer.
33 #ifndef FCC_2
34 #define FCC_2 2
35 #endif
36
37 // Look for MONO_HACK for any Mono hack involving legacy mono channel to
38 // stereo channel conversion.
39
40 /* VERY_VERY_VERBOSE_LOGGING will show exactly which process hook and track hook is
41 * being used. This is a considerable amount of log spam, so don't enable unless you
42 * are verifying the hook based code.
43 */
44 //#define VERY_VERY_VERBOSE_LOGGING
45 #ifdef VERY_VERY_VERBOSE_LOGGING
46 #define ALOGVV ALOGV
47 //define ALOGVV printf // for test-mixer.cpp
48 #else
49 #define ALOGVV(a...) do { } while (0)
50 #endif
51
52 // TODO: remove BLOCKSIZE unit of processing - it isn't needed anymore.
53 static constexpr int BLOCKSIZE = 16;
54
55 namespace android {
56
57 // ----------------------------------------------------------------------------
58
isValidFormat(audio_format_t format) const59 bool AudioMixerBase::isValidFormat(audio_format_t format) const
60 {
61 switch (format) {
62 case AUDIO_FORMAT_PCM_8_BIT:
63 case AUDIO_FORMAT_PCM_16_BIT:
64 case AUDIO_FORMAT_PCM_24_BIT_PACKED:
65 case AUDIO_FORMAT_PCM_32_BIT:
66 case AUDIO_FORMAT_PCM_FLOAT:
67 return true;
68 default:
69 return false;
70 }
71 }
72
isValidChannelMask(audio_channel_mask_t channelMask) const73 bool AudioMixerBase::isValidChannelMask(audio_channel_mask_t channelMask) const
74 {
75 return audio_channel_count_from_out_mask(channelMask) <= MAX_NUM_CHANNELS;
76 }
77
preCreateTrack()78 std::shared_ptr<AudioMixerBase::TrackBase> AudioMixerBase::preCreateTrack()
79 {
80 return std::make_shared<TrackBase>();
81 }
82
create(int name,audio_channel_mask_t channelMask,audio_format_t format,int sessionId)83 status_t AudioMixerBase::create(
84 int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId)
85 {
86 LOG_ALWAYS_FATAL_IF(exists(name), "name %d already exists", name);
87
88 if (!isValidChannelMask(channelMask)) {
89 ALOGE("%s invalid channelMask: %#x", __func__, channelMask);
90 return BAD_VALUE;
91 }
92 if (!isValidFormat(format)) {
93 ALOGE("%s invalid format: %#x", __func__, format);
94 return BAD_VALUE;
95 }
96
97 auto t = preCreateTrack();
98 {
99 // TODO: move initialization to the Track constructor.
100 // assume default parameters for the track, except where noted below
101 t->needs = 0;
102
103 // Integer volume.
104 // Currently integer volume is kept for the legacy integer mixer.
105 // Will be removed when the legacy mixer path is removed.
106 t->volume[0] = 0;
107 t->volume[1] = 0;
108 t->prevVolume[0] = 0 << 16;
109 t->prevVolume[1] = 0 << 16;
110 t->volumeInc[0] = 0;
111 t->volumeInc[1] = 0;
112 t->auxLevel = 0;
113 t->auxInc = 0;
114 t->prevAuxLevel = 0;
115
116 // Floating point volume.
117 t->mVolume[0] = 0.f;
118 t->mVolume[1] = 0.f;
119 t->mPrevVolume[0] = 0.f;
120 t->mPrevVolume[1] = 0.f;
121 t->mVolumeInc[0] = 0.;
122 t->mVolumeInc[1] = 0.;
123 t->mAuxLevel = 0.;
124 t->mAuxInc = 0.;
125 t->mPrevAuxLevel = 0.;
126
127 // no initialization needed
128 // t->frameCount
129 t->channelCount = audio_channel_count_from_out_mask(channelMask);
130 t->enabled = false;
131 ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
132 "Non-stereo channel mask: %d\n", channelMask);
133 t->channelMask = channelMask;
134 t->sessionId = sessionId;
135 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
136 t->bufferProvider = NULL;
137 t->buffer.raw = NULL;
138 // no initialization needed
139 // t->buffer.frameCount
140 t->hook = NULL;
141 t->mIn = NULL;
142 t->sampleRate = mSampleRate;
143 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
144 t->mainBuffer = NULL;
145 t->auxBuffer = NULL;
146 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
147 t->mFormat = format;
148 t->mMixerInFormat = kUseFloat && kUseNewMixer ?
149 AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
150 t->mMixerChannelMask = audio_channel_mask_from_representation_and_bits(
151 AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
152 t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
153 status_t status = postCreateTrack(t.get());
154 if (status != OK) return status;
155 mTracks[name] = t;
156 return OK;
157 }
158 }
159
160 // Called when channel masks have changed for a track name
setChannelMasks(int name,audio_channel_mask_t trackChannelMask,audio_channel_mask_t mixerChannelMask)161 bool AudioMixerBase::setChannelMasks(int name,
162 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask)
163 {
164 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
165 const std::shared_ptr<TrackBase> &track = mTracks[name];
166
167 if (trackChannelMask == track->channelMask && mixerChannelMask == track->mMixerChannelMask) {
168 return false; // no need to change
169 }
170 // always recompute for both channel masks even if only one has changed.
171 const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
172 const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
173
174 ALOG_ASSERT(trackChannelCount && mixerChannelCount);
175 track->channelMask = trackChannelMask;
176 track->channelCount = trackChannelCount;
177 track->mMixerChannelMask = mixerChannelMask;
178 track->mMixerChannelCount = mixerChannelCount;
179
180 // Resampler channels may have changed.
181 track->recreateResampler(mSampleRate);
182 return true;
183 }
184
destroy(int name)185 void AudioMixerBase::destroy(int name)
186 {
187 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
188 ALOGV("deleteTrackName(%d)", name);
189
190 if (mTracks[name]->enabled) {
191 invalidate();
192 }
193 mTracks.erase(name); // deallocate track
194 }
195
enable(int name)196 void AudioMixerBase::enable(int name)
197 {
198 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
199 const std::shared_ptr<TrackBase> &track = mTracks[name];
200
201 if (!track->enabled) {
202 track->enabled = true;
203 ALOGV("enable(%d)", name);
204 invalidate();
205 }
206 }
207
disable(int name)208 void AudioMixerBase::disable(int name)
209 {
210 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
211 const std::shared_ptr<TrackBase> &track = mTracks[name];
212
213 if (track->enabled) {
214 track->enabled = false;
215 ALOGV("disable(%d)", name);
216 invalidate();
217 }
218 }
219
220 /* Sets the volume ramp variables for the AudioMixer.
221 *
222 * The volume ramp variables are used to transition from the previous
223 * volume to the set volume. ramp controls the duration of the transition.
224 * Its value is typically one state framecount period, but may also be 0,
225 * meaning "immediate."
226 *
227 * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
228 * even if there is a nonzero floating point increment (in that case, the volume
229 * change is immediate). This restriction should be changed when the legacy mixer
230 * is removed (see #2).
231 * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
232 * when no longer needed.
233 *
234 * @param newVolume set volume target in floating point [0.0, 1.0].
235 * @param ramp number of frames to increment over. if ramp is 0, the volume
236 * should be set immediately. Currently ramp should not exceed 65535 (frames).
237 * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
238 * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
239 * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
240 * @param pSetVolume pointer to the float target volume, set on return.
241 * @param pPrevVolume pointer to the float previous volume, set on return.
242 * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
243 * @return true if the volume has changed, false if volume is same.
244 */
setVolumeRampVariables(float newVolume,int32_t ramp,int16_t * pIntSetVolume,int32_t * pIntPrevVolume,int32_t * pIntVolumeInc,float * pSetVolume,float * pPrevVolume,float * pVolumeInc)245 static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
246 int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
247 float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
248 // check floating point volume to see if it is identical to the previously
249 // set volume.
250 // We do not use a tolerance here (and reject changes too small)
251 // as it may be confusing to use a different value than the one set.
252 // If the resulting volume is too small to ramp, it is a direct set of the volume.
253 if (newVolume == *pSetVolume) {
254 return false;
255 }
256 if (newVolume < 0) {
257 newVolume = 0; // should not have negative volumes
258 } else {
259 switch (fpclassify(newVolume)) {
260 case FP_SUBNORMAL:
261 case FP_NAN:
262 newVolume = 0;
263 break;
264 case FP_ZERO:
265 break; // zero volume is fine
266 case FP_INFINITE:
267 // Infinite volume could be handled consistently since
268 // floating point math saturates at infinities,
269 // but we limit volume to unity gain float.
270 // ramp = 0; break;
271 //
272 newVolume = AudioMixerBase::UNITY_GAIN_FLOAT;
273 break;
274 case FP_NORMAL:
275 default:
276 // Floating point does not have problems with overflow wrap
277 // that integer has. However, we limit the volume to
278 // unity gain here.
279 // TODO: Revisit the volume limitation and perhaps parameterize.
280 if (newVolume > AudioMixerBase::UNITY_GAIN_FLOAT) {
281 newVolume = AudioMixerBase::UNITY_GAIN_FLOAT;
282 }
283 break;
284 }
285 }
286
287 // set floating point volume ramp
288 if (ramp != 0) {
289 // when the ramp completes, *pPrevVolume is set to *pSetVolume, so there
290 // is no computational mismatch; hence equality is checked here.
291 ALOGD_IF(*pPrevVolume != *pSetVolume, "previous float ramp hasn't finished,"
292 " prev:%f set_to:%f", *pPrevVolume, *pSetVolume);
293 const float inc = (newVolume - *pPrevVolume) / ramp; // could be inf, nan, subnormal
294 // could be inf, cannot be nan, subnormal
295 const float maxv = std::max(newVolume, *pPrevVolume);
296
297 if (isnormal(inc) // inc must be a normal number (no subnormals, infinite, nan)
298 && maxv + inc != maxv) { // inc must make forward progress
299 *pVolumeInc = inc;
300 // ramp is set now.
301 // Note: if newVolume is 0, then near the end of the ramp,
302 // it may be possible that the ramped volume may be subnormal or
303 // temporarily negative by a small amount or subnormal due to floating
304 // point inaccuracies.
305 } else {
306 ramp = 0; // ramp not allowed
307 }
308 }
309
310 // compute and check integer volume, no need to check negative values
311 // The integer volume is limited to "unity_gain" to avoid wrapping and other
312 // audio artifacts, so it never reaches the range limit of U4.28.
313 // We safely use signed 16 and 32 bit integers here.
314 const float scaledVolume = newVolume * AudioMixerBase::UNITY_GAIN_INT; // not neg, subnormal, nan
315 const int32_t intVolume = (scaledVolume >= (float)AudioMixerBase::UNITY_GAIN_INT) ?
316 AudioMixerBase::UNITY_GAIN_INT : (int32_t)scaledVolume;
317
318 // set integer volume ramp
319 if (ramp != 0) {
320 // integer volume is U4.12 (to use 16 bit multiplies), but ramping uses U4.28.
321 // when the ramp completes, *pIntPrevVolume is set to *pIntSetVolume << 16, so there
322 // is no computational mismatch; hence equality is checked here.
323 ALOGD_IF(*pIntPrevVolume != *pIntSetVolume << 16, "previous int ramp hasn't finished,"
324 " prev:%d set_to:%d", *pIntPrevVolume, *pIntSetVolume << 16);
325 const int32_t inc = ((intVolume << 16) - *pIntPrevVolume) / ramp;
326
327 if (inc != 0) { // inc must make forward progress
328 *pIntVolumeInc = inc;
329 } else {
330 ramp = 0; // ramp not allowed
331 }
332 }
333
334 // if no ramp, or ramp not allowed, then clear float and integer increments
335 if (ramp == 0) {
336 *pVolumeInc = 0;
337 *pPrevVolume = newVolume;
338 *pIntVolumeInc = 0;
339 *pIntPrevVolume = intVolume << 16;
340 }
341 *pSetVolume = newVolume;
342 *pIntSetVolume = intVolume;
343 return true;
344 }
345
setParameter(int name,int target,int param,void * value)346 void AudioMixerBase::setParameter(int name, int target, int param, void *value)
347 {
348 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
349 const std::shared_ptr<TrackBase> &track = mTracks[name];
350
351 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
352 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
353
354 switch (target) {
355
356 case TRACK:
357 switch (param) {
358 case CHANNEL_MASK: {
359 const audio_channel_mask_t trackChannelMask =
360 static_cast<audio_channel_mask_t>(valueInt);
361 if (setChannelMasks(name, trackChannelMask, track->mMixerChannelMask)) {
362 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
363 invalidate();
364 }
365 } break;
366 case MAIN_BUFFER:
367 if (track->mainBuffer != valueBuf) {
368 track->mainBuffer = valueBuf;
369 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
370 invalidate();
371 }
372 break;
373 case AUX_BUFFER:
374 if (track->auxBuffer != valueBuf) {
375 track->auxBuffer = valueBuf;
376 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
377 invalidate();
378 }
379 break;
380 case FORMAT: {
381 audio_format_t format = static_cast<audio_format_t>(valueInt);
382 if (track->mFormat != format) {
383 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
384 track->mFormat = format;
385 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
386 invalidate();
387 }
388 } break;
389 case MIXER_FORMAT: {
390 audio_format_t format = static_cast<audio_format_t>(valueInt);
391 if (track->mMixerFormat != format) {
392 track->mMixerFormat = format;
393 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
394 }
395 } break;
396 case MIXER_CHANNEL_MASK: {
397 const audio_channel_mask_t mixerChannelMask =
398 static_cast<audio_channel_mask_t>(valueInt);
399 if (setChannelMasks(name, track->channelMask, mixerChannelMask)) {
400 ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
401 invalidate();
402 }
403 } break;
404 default:
405 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
406 }
407 break;
408
409 case RESAMPLE:
410 switch (param) {
411 case SAMPLE_RATE:
412 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
413 if (track->setResampler(uint32_t(valueInt), mSampleRate)) {
414 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
415 uint32_t(valueInt));
416 invalidate();
417 }
418 break;
419 case RESET:
420 track->resetResampler();
421 invalidate();
422 break;
423 case REMOVE:
424 track->mResampler.reset(nullptr);
425 track->sampleRate = mSampleRate;
426 invalidate();
427 break;
428 default:
429 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
430 }
431 break;
432
433 case RAMP_VOLUME:
434 case VOLUME:
435 switch (param) {
436 case AUXLEVEL:
437 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
438 target == RAMP_VOLUME ? mFrameCount : 0,
439 &track->auxLevel, &track->prevAuxLevel, &track->auxInc,
440 &track->mAuxLevel, &track->mPrevAuxLevel, &track->mAuxInc)) {
441 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
442 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track->auxLevel);
443 invalidate();
444 }
445 break;
446 default:
447 if ((unsigned)param >= VOLUME0 && (unsigned)param < VOLUME0 + MAX_NUM_VOLUMES) {
448 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
449 target == RAMP_VOLUME ? mFrameCount : 0,
450 &track->volume[param - VOLUME0],
451 &track->prevVolume[param - VOLUME0],
452 &track->volumeInc[param - VOLUME0],
453 &track->mVolume[param - VOLUME0],
454 &track->mPrevVolume[param - VOLUME0],
455 &track->mVolumeInc[param - VOLUME0])) {
456 ALOGV("setParameter(%s, VOLUME%d: %04x)",
457 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
458 track->volume[param - VOLUME0]);
459 invalidate();
460 }
461 } else {
462 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
463 }
464 }
465 break;
466
467 default:
468 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
469 }
470 }
471
setResampler(uint32_t trackSampleRate,uint32_t devSampleRate)472 bool AudioMixerBase::TrackBase::setResampler(uint32_t trackSampleRate, uint32_t devSampleRate)
473 {
474 if (trackSampleRate != devSampleRate || mResampler.get() != nullptr) {
475 if (sampleRate != trackSampleRate) {
476 sampleRate = trackSampleRate;
477 if (mResampler.get() == nullptr) {
478 ALOGV("Creating resampler from track %d Hz to device %d Hz",
479 trackSampleRate, devSampleRate);
480 AudioResampler::src_quality quality;
481 // force lowest quality level resampler if use case isn't music or video
482 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
483 // quality level based on the initial ratio, but that could change later.
484 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
485 if (isMusicRate(trackSampleRate)) {
486 quality = AudioResampler::DEFAULT_QUALITY;
487 } else {
488 quality = AudioResampler::DYN_LOW_QUALITY;
489 }
490
491 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
492 // but if none exists, it is the channel count (1 for mono).
493 const int resamplerChannelCount = getOutputChannelCount();
494 ALOGVV("Creating resampler:"
495 " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
496 mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
497 mResampler.reset(AudioResampler::create(
498 mMixerInFormat,
499 resamplerChannelCount,
500 devSampleRate, quality));
501 }
502 return true;
503 }
504 }
505 return false;
506 }
507
508 /* Checks to see if the volume ramp has completed and clears the increment
509 * variables appropriately.
510 *
511 * FIXME: There is code to handle int/float ramp variable switchover should it not
512 * complete within a mixer buffer processing call, but it is preferred to avoid switchover
513 * due to precision issues. The switchover code is included for legacy code purposes
514 * and can be removed once the integer volume is removed.
515 *
516 * It is not sufficient to clear only the volumeInc integer variable because
517 * if one channel requires ramping, all channels are ramped.
518 *
519 * There is a bit of duplicated code here, but it keeps backward compatibility.
520 */
adjustVolumeRamp(bool aux,bool useFloat)521 void AudioMixerBase::TrackBase::adjustVolumeRamp(bool aux, bool useFloat)
522 {
523 if (useFloat) {
524 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
525 if ((mVolumeInc[i] > 0 && mPrevVolume[i] + mVolumeInc[i] >= mVolume[i]) ||
526 (mVolumeInc[i] < 0 && mPrevVolume[i] + mVolumeInc[i] <= mVolume[i])) {
527 volumeInc[i] = 0;
528 prevVolume[i] = volume[i] << 16;
529 mVolumeInc[i] = 0.;
530 mPrevVolume[i] = mVolume[i];
531 } else {
532 //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
533 prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
534 }
535 }
536 } else {
537 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
538 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
539 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
540 volumeInc[i] = 0;
541 prevVolume[i] = volume[i] << 16;
542 mVolumeInc[i] = 0.;
543 mPrevVolume[i] = mVolume[i];
544 } else {
545 //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
546 mPrevVolume[i] = float_from_u4_28(prevVolume[i]);
547 }
548 }
549 }
550
551 if (aux) {
552 #ifdef FLOAT_AUX
553 if (useFloat) {
554 if ((mAuxInc > 0.f && mPrevAuxLevel + mAuxInc >= mAuxLevel) ||
555 (mAuxInc < 0.f && mPrevAuxLevel + mAuxInc <= mAuxLevel)) {
556 auxInc = 0;
557 prevAuxLevel = auxLevel << 16;
558 mAuxInc = 0.f;
559 mPrevAuxLevel = mAuxLevel;
560 }
561 } else
562 #endif
563 if ((auxInc > 0 && ((prevAuxLevel + auxInc) >> 16) >= auxLevel) ||
564 (auxInc < 0 && ((prevAuxLevel + auxInc) >> 16) <= auxLevel)) {
565 auxInc = 0;
566 prevAuxLevel = auxLevel << 16;
567 mAuxInc = 0.f;
568 mPrevAuxLevel = mAuxLevel;
569 }
570 }
571 }
572
recreateResampler(uint32_t devSampleRate)573 void AudioMixerBase::TrackBase::recreateResampler(uint32_t devSampleRate)
574 {
575 if (mResampler.get() != nullptr) {
576 const uint32_t resetToSampleRate = sampleRate;
577 mResampler.reset(nullptr);
578 sampleRate = devSampleRate; // without resampler, track rate is device sample rate.
579 // recreate the resampler with updated format, channels, saved sampleRate.
580 setResampler(resetToSampleRate /*trackSampleRate*/, devSampleRate);
581 }
582 }
583
getUnreleasedFrames(int name) const584 size_t AudioMixerBase::getUnreleasedFrames(int name) const
585 {
586 const auto it = mTracks.find(name);
587 if (it != mTracks.end()) {
588 return it->second->getUnreleasedFrames();
589 }
590 return 0;
591 }
592
trackNames() const593 std::string AudioMixerBase::trackNames() const
594 {
595 std::stringstream ss;
596 for (const auto &pair : mTracks) {
597 ss << pair.first << " ";
598 }
599 return ss.str();
600 }
601
process__validate()602 void AudioMixerBase::process__validate()
603 {
604 // TODO: fix all16BitsStereNoResample logic to
605 // either properly handle muted tracks (it should ignore them)
606 // or remove altogether as an obsolete optimization.
607 bool all16BitsStereoNoResample = true;
608 bool resampling = false;
609 bool volumeRamp = false;
610
611 mEnabled.clear();
612 mGroups.clear();
613 for (const auto &pair : mTracks) {
614 const int name = pair.first;
615 const std::shared_ptr<TrackBase> &t = pair.second;
616 if (!t->enabled) continue;
617
618 mEnabled.emplace_back(name); // we add to mEnabled in order of name.
619 mGroups[t->mainBuffer].emplace_back(name); // mGroups also in order of name.
620
621 uint32_t n = 0;
622 // FIXME can overflow (mask is only 3 bits)
623 n |= NEEDS_CHANNEL_1 + t->channelCount - 1;
624 if (t->doesResample()) {
625 n |= NEEDS_RESAMPLE;
626 }
627 if (t->auxLevel != 0 && t->auxBuffer != NULL) {
628 n |= NEEDS_AUX;
629 }
630
631 if (t->volumeInc[0]|t->volumeInc[1]) {
632 volumeRamp = true;
633 } else if (!t->doesResample() && t->volumeRL == 0) {
634 n |= NEEDS_MUTE;
635 }
636 t->needs = n;
637
638 if (n & NEEDS_MUTE) {
639 t->hook = &TrackBase::track__nop;
640 } else {
641 if (n & NEEDS_AUX) {
642 all16BitsStereoNoResample = false;
643 }
644 if (n & NEEDS_RESAMPLE) {
645 all16BitsStereoNoResample = false;
646 resampling = true;
647 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1
648 && t->channelMask == AUDIO_CHANNEL_OUT_MONO // MONO_HACK
649 && isAudioChannelPositionMask(t->mMixerChannelMask)) {
650 t->hook = TrackBase::getTrackHook(
651 TRACKTYPE_RESAMPLEMONO, t->mMixerChannelCount,
652 t->mMixerInFormat, t->mMixerFormat);
653 } else if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2
654 && t->useStereoVolume()) {
655 t->hook = TrackBase::getTrackHook(
656 TRACKTYPE_RESAMPLESTEREO, t->mMixerChannelCount,
657 t->mMixerInFormat, t->mMixerFormat);
658 } else {
659 t->hook = TrackBase::getTrackHook(
660 TRACKTYPE_RESAMPLE, t->mMixerChannelCount,
661 t->mMixerInFormat, t->mMixerFormat);
662 }
663 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
664 "Track %d needs downmix + resample", name);
665 } else {
666 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
667 t->hook = TrackBase::getTrackHook(
668 (isAudioChannelPositionMask(t->mMixerChannelMask) // TODO: MONO_HACK
669 && t->channelMask == AUDIO_CHANNEL_OUT_MONO)
670 ? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,
671 t->mMixerChannelCount,
672 t->mMixerInFormat, t->mMixerFormat);
673 all16BitsStereoNoResample = false;
674 }
675 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
676 t->hook = TrackBase::getTrackHook(
677 t->useStereoVolume() ? TRACKTYPE_NORESAMPLESTEREO
678 : TRACKTYPE_NORESAMPLE,
679 t->mMixerChannelCount, t->mMixerInFormat,
680 t->mMixerFormat);
681 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
682 "Track %d needs downmix", name);
683 }
684 }
685 }
686 }
687
688 // select the processing hooks
689 mHook = &AudioMixerBase::process__nop;
690 if (mEnabled.size() > 0) {
691 if (resampling) {
692 if (mOutputTemp.get() == nullptr) {
693 mOutputTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
694 }
695 if (mResampleTemp.get() == nullptr) {
696 mResampleTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
697 }
698 mHook = &AudioMixerBase::process__genericResampling;
699 } else {
700 // we keep temp arrays around.
701 mHook = &AudioMixerBase::process__genericNoResampling;
702 if (all16BitsStereoNoResample && !volumeRamp) {
703 if (mEnabled.size() == 1) {
704 const std::shared_ptr<TrackBase> &t = mTracks[mEnabled[0]];
705 if ((t->needs & NEEDS_MUTE) == 0) {
706 // The check prevents a muted track from acquiring a process hook.
707 //
708 // This is dangerous if the track is MONO as that requires
709 // special case handling due to implicit channel duplication.
710 // Stereo or Multichannel should actually be fine here.
711 mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
712 t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat,
713 t->useStereoVolume());
714 }
715 }
716 }
717 }
718 }
719
720 ALOGV("mixer configuration change: %zu "
721 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
722 mEnabled.size(), all16BitsStereoNoResample, resampling, volumeRamp);
723
724 process();
725
726 // Now that the volume ramp has been done, set optimal state and
727 // track hooks for subsequent mixer process
728 if (mEnabled.size() > 0) {
729 bool allMuted = true;
730
731 for (const int name : mEnabled) {
732 const std::shared_ptr<TrackBase> &t = mTracks[name];
733 if (!t->doesResample() && t->volumeRL == 0) {
734 t->needs |= NEEDS_MUTE;
735 t->hook = &TrackBase::track__nop;
736 } else {
737 allMuted = false;
738 }
739 }
740 if (allMuted) {
741 mHook = &AudioMixerBase::process__nop;
742 } else if (all16BitsStereoNoResample) {
743 if (mEnabled.size() == 1) {
744 //const int i = 31 - __builtin_clz(enabledTracks);
745 const std::shared_ptr<TrackBase> &t = mTracks[mEnabled[0]];
746 // Muted single tracks handled by allMuted above.
747 mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
748 t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat,
749 t->useStereoVolume());
750 }
751 }
752 }
753 }
754
track__genericResample(int32_t * out,size_t outFrameCount,int32_t * temp,int32_t * aux)755 void AudioMixerBase::TrackBase::track__genericResample(
756 int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
757 {
758 ALOGVV("track__genericResample\n");
759 mResampler->setSampleRate(sampleRate);
760
761 // ramp gain - resample to temp buffer and scale/mix in 2nd step
762 if (aux != NULL) {
763 // always resample with unity gain when sending to auxiliary buffer to be able
764 // to apply send level after resampling
765 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
766 memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(int32_t));
767 mResampler->resample(temp, outFrameCount, bufferProvider);
768 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
769 volumeRampStereo(out, outFrameCount, temp, aux);
770 } else {
771 volumeStereo(out, outFrameCount, temp, aux);
772 }
773 } else {
774 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
775 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
776 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
777 mResampler->resample(temp, outFrameCount, bufferProvider);
778 volumeRampStereo(out, outFrameCount, temp, aux);
779 }
780
781 // constant gain
782 else {
783 mResampler->setVolume(mVolume[0], mVolume[1]);
784 mResampler->resample(out, outFrameCount, bufferProvider);
785 }
786 }
787 }
788
track__nop(int32_t * out __unused,size_t outFrameCount __unused,int32_t * temp __unused,int32_t * aux __unused)789 void AudioMixerBase::TrackBase::track__nop(int32_t* out __unused,
790 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
791 {
792 }
793
volumeRampStereo(int32_t * out,size_t frameCount,int32_t * temp,int32_t * aux)794 void AudioMixerBase::TrackBase::volumeRampStereo(
795 int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
796 {
797 int32_t vl = prevVolume[0];
798 int32_t vr = prevVolume[1];
799 const int32_t vlInc = volumeInc[0];
800 const int32_t vrInc = volumeInc[1];
801
802 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
803 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
804 // (vl + vlInc*frameCount)/65536.0f, frameCount);
805
806 // ramp volume
807 if (CC_UNLIKELY(aux != NULL)) {
808 int32_t va = prevAuxLevel;
809 const int32_t vaInc = auxInc;
810 int32_t l;
811 int32_t r;
812
813 do {
814 l = (*temp++ >> 12);
815 r = (*temp++ >> 12);
816 *out++ += (vl >> 16) * l;
817 *out++ += (vr >> 16) * r;
818 *aux++ += (va >> 17) * (l + r);
819 vl += vlInc;
820 vr += vrInc;
821 va += vaInc;
822 } while (--frameCount);
823 prevAuxLevel = va;
824 } else {
825 do {
826 *out++ += (vl >> 16) * (*temp++ >> 12);
827 *out++ += (vr >> 16) * (*temp++ >> 12);
828 vl += vlInc;
829 vr += vrInc;
830 } while (--frameCount);
831 }
832 prevVolume[0] = vl;
833 prevVolume[1] = vr;
834 adjustVolumeRamp(aux != NULL);
835 }
836
volumeStereo(int32_t * out,size_t frameCount,int32_t * temp,int32_t * aux)837 void AudioMixerBase::TrackBase::volumeStereo(
838 int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
839 {
840 const int16_t vl = volume[0];
841 const int16_t vr = volume[1];
842
843 if (CC_UNLIKELY(aux != NULL)) {
844 const int16_t va = auxLevel;
845 do {
846 int16_t l = (int16_t)(*temp++ >> 12);
847 int16_t r = (int16_t)(*temp++ >> 12);
848 out[0] = mulAdd(l, vl, out[0]);
849 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
850 out[1] = mulAdd(r, vr, out[1]);
851 out += 2;
852 aux[0] = mulAdd(a, va, aux[0]);
853 aux++;
854 } while (--frameCount);
855 } else {
856 do {
857 int16_t l = (int16_t)(*temp++ >> 12);
858 int16_t r = (int16_t)(*temp++ >> 12);
859 out[0] = mulAdd(l, vl, out[0]);
860 out[1] = mulAdd(r, vr, out[1]);
861 out += 2;
862 } while (--frameCount);
863 }
864 }
865
track__16BitsStereo(int32_t * out,size_t frameCount,int32_t * temp __unused,int32_t * aux)866 void AudioMixerBase::TrackBase::track__16BitsStereo(
867 int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
868 {
869 ALOGVV("track__16BitsStereo\n");
870 const int16_t *in = static_cast<const int16_t *>(mIn);
871
872 if (CC_UNLIKELY(aux != NULL)) {
873 int32_t l;
874 int32_t r;
875 // ramp gain
876 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
877 int32_t vl = prevVolume[0];
878 int32_t vr = prevVolume[1];
879 int32_t va = prevAuxLevel;
880 const int32_t vlInc = volumeInc[0];
881 const int32_t vrInc = volumeInc[1];
882 const int32_t vaInc = auxInc;
883 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
884 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
885 // (vl + vlInc*frameCount)/65536.0f, frameCount);
886
887 do {
888 l = (int32_t)*in++;
889 r = (int32_t)*in++;
890 *out++ += (vl >> 16) * l;
891 *out++ += (vr >> 16) * r;
892 *aux++ += (va >> 17) * (l + r);
893 vl += vlInc;
894 vr += vrInc;
895 va += vaInc;
896 } while (--frameCount);
897
898 prevVolume[0] = vl;
899 prevVolume[1] = vr;
900 prevAuxLevel = va;
901 adjustVolumeRamp(true);
902 }
903
904 // constant gain
905 else {
906 const uint32_t vrl = volumeRL;
907 const int16_t va = (int16_t)auxLevel;
908 do {
909 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
910 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
911 in += 2;
912 out[0] = mulAddRL(1, rl, vrl, out[0]);
913 out[1] = mulAddRL(0, rl, vrl, out[1]);
914 out += 2;
915 aux[0] = mulAdd(a, va, aux[0]);
916 aux++;
917 } while (--frameCount);
918 }
919 } else {
920 // ramp gain
921 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
922 int32_t vl = prevVolume[0];
923 int32_t vr = prevVolume[1];
924 const int32_t vlInc = volumeInc[0];
925 const int32_t vrInc = volumeInc[1];
926
927 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
928 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
929 // (vl + vlInc*frameCount)/65536.0f, frameCount);
930
931 do {
932 *out++ += (vl >> 16) * (int32_t) *in++;
933 *out++ += (vr >> 16) * (int32_t) *in++;
934 vl += vlInc;
935 vr += vrInc;
936 } while (--frameCount);
937
938 prevVolume[0] = vl;
939 prevVolume[1] = vr;
940 adjustVolumeRamp(false);
941 }
942
943 // constant gain
944 else {
945 const uint32_t vrl = volumeRL;
946 do {
947 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
948 in += 2;
949 out[0] = mulAddRL(1, rl, vrl, out[0]);
950 out[1] = mulAddRL(0, rl, vrl, out[1]);
951 out += 2;
952 } while (--frameCount);
953 }
954 }
955 mIn = in;
956 }
957
track__16BitsMono(int32_t * out,size_t frameCount,int32_t * temp __unused,int32_t * aux)958 void AudioMixerBase::TrackBase::track__16BitsMono(
959 int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
960 {
961 ALOGVV("track__16BitsMono\n");
962 const int16_t *in = static_cast<int16_t const *>(mIn);
963
964 if (CC_UNLIKELY(aux != NULL)) {
965 // ramp gain
966 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
967 int32_t vl = prevVolume[0];
968 int32_t vr = prevVolume[1];
969 int32_t va = prevAuxLevel;
970 const int32_t vlInc = volumeInc[0];
971 const int32_t vrInc = volumeInc[1];
972 const int32_t vaInc = auxInc;
973
974 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
975 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
976 // (vl + vlInc*frameCount)/65536.0f, frameCount);
977
978 do {
979 int32_t l = *in++;
980 *out++ += (vl >> 16) * l;
981 *out++ += (vr >> 16) * l;
982 *aux++ += (va >> 16) * l;
983 vl += vlInc;
984 vr += vrInc;
985 va += vaInc;
986 } while (--frameCount);
987
988 prevVolume[0] = vl;
989 prevVolume[1] = vr;
990 prevAuxLevel = va;
991 adjustVolumeRamp(true);
992 }
993 // constant gain
994 else {
995 const int16_t vl = volume[0];
996 const int16_t vr = volume[1];
997 const int16_t va = (int16_t)auxLevel;
998 do {
999 int16_t l = *in++;
1000 out[0] = mulAdd(l, vl, out[0]);
1001 out[1] = mulAdd(l, vr, out[1]);
1002 out += 2;
1003 aux[0] = mulAdd(l, va, aux[0]);
1004 aux++;
1005 } while (--frameCount);
1006 }
1007 } else {
1008 // ramp gain
1009 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
1010 int32_t vl = prevVolume[0];
1011 int32_t vr = prevVolume[1];
1012 const int32_t vlInc = volumeInc[0];
1013 const int32_t vrInc = volumeInc[1];
1014
1015 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
1016 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
1017 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1018
1019 do {
1020 int32_t l = *in++;
1021 *out++ += (vl >> 16) * l;
1022 *out++ += (vr >> 16) * l;
1023 vl += vlInc;
1024 vr += vrInc;
1025 } while (--frameCount);
1026
1027 prevVolume[0] = vl;
1028 prevVolume[1] = vr;
1029 adjustVolumeRamp(false);
1030 }
1031 // constant gain
1032 else {
1033 const int16_t vl = volume[0];
1034 const int16_t vr = volume[1];
1035 do {
1036 int16_t l = *in++;
1037 out[0] = mulAdd(l, vl, out[0]);
1038 out[1] = mulAdd(l, vr, out[1]);
1039 out += 2;
1040 } while (--frameCount);
1041 }
1042 }
1043 mIn = in;
1044 }
1045
1046 // no-op case
process__nop()1047 void AudioMixerBase::process__nop()
1048 {
1049 ALOGVV("process__nop\n");
1050
1051 for (const auto &pair : mGroups) {
1052 // process by group of tracks with same output buffer to
1053 // avoid multiple memset() on same buffer
1054 const auto &group = pair.second;
1055
1056 const std::shared_ptr<TrackBase> &t = mTracks[group[0]];
1057 memset(t->mainBuffer, 0,
1058 mFrameCount * audio_bytes_per_frame(t->getMixerChannelCount(), t->mMixerFormat));
1059
1060 // now consume data
1061 for (const int name : group) {
1062 const std::shared_ptr<TrackBase> &t = mTracks[name];
1063 size_t outFrames = mFrameCount;
1064 while (outFrames) {
1065 t->buffer.frameCount = outFrames;
1066 t->bufferProvider->getNextBuffer(&t->buffer);
1067 if (t->buffer.raw == NULL) break;
1068 outFrames -= t->buffer.frameCount;
1069 t->bufferProvider->releaseBuffer(&t->buffer);
1070 }
1071 }
1072 }
1073 }
1074
1075 // generic code without resampling
process__genericNoResampling()1076 void AudioMixerBase::process__genericNoResampling()
1077 {
1078 ALOGVV("process__genericNoResampling\n");
1079 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1080
1081 for (const auto &pair : mGroups) {
1082 // process by group of tracks with same output main buffer to
1083 // avoid multiple memset() on same buffer
1084 const auto &group = pair.second;
1085
1086 // acquire buffer
1087 for (const int name : group) {
1088 const std::shared_ptr<TrackBase> &t = mTracks[name];
1089 t->buffer.frameCount = mFrameCount;
1090 t->bufferProvider->getNextBuffer(&t->buffer);
1091 t->frameCount = t->buffer.frameCount;
1092 t->mIn = t->buffer.raw;
1093 }
1094
1095 int32_t *out = (int *)pair.first;
1096 size_t numFrames = 0;
1097 do {
1098 const size_t frameCount = std::min((size_t)BLOCKSIZE, mFrameCount - numFrames);
1099 memset(outTemp, 0, sizeof(outTemp));
1100 for (const int name : group) {
1101 const std::shared_ptr<TrackBase> &t = mTracks[name];
1102 int32_t *aux = NULL;
1103 if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
1104 aux = t->auxBuffer + numFrames;
1105 }
1106 for (int outFrames = frameCount; outFrames > 0; ) {
1107 // t->in == nullptr can happen if the track was flushed just after having
1108 // been enabled for mixing.
1109 if (t->mIn == nullptr) {
1110 break;
1111 }
1112 size_t inFrames = (t->frameCount > outFrames)?outFrames:t->frameCount;
1113 if (inFrames > 0) {
1114 (t.get()->*t->hook)(
1115 outTemp + (frameCount - outFrames) * t->mMixerChannelCount,
1116 inFrames, mResampleTemp.get() /* naked ptr */, aux);
1117 t->frameCount -= inFrames;
1118 outFrames -= inFrames;
1119 if (CC_UNLIKELY(aux != NULL)) {
1120 aux += inFrames;
1121 }
1122 }
1123 if (t->frameCount == 0 && outFrames) {
1124 t->bufferProvider->releaseBuffer(&t->buffer);
1125 t->buffer.frameCount = (mFrameCount - numFrames) -
1126 (frameCount - outFrames);
1127 t->bufferProvider->getNextBuffer(&t->buffer);
1128 t->mIn = t->buffer.raw;
1129 if (t->mIn == nullptr) {
1130 break;
1131 }
1132 t->frameCount = t->buffer.frameCount;
1133 }
1134 }
1135 }
1136
1137 const std::shared_ptr<TrackBase> &t1 = mTracks[group[0]];
1138 convertMixerFormat(out, t1->mMixerFormat, outTemp, t1->mMixerInFormat,
1139 frameCount * t1->mMixerChannelCount);
1140 // TODO: fix ugly casting due to choice of out pointer type
1141 out = reinterpret_cast<int32_t*>((uint8_t*)out
1142 + frameCount * t1->mMixerChannelCount
1143 * audio_bytes_per_sample(t1->mMixerFormat));
1144 numFrames += frameCount;
1145 } while (numFrames < mFrameCount);
1146
1147 // release each track's buffer
1148 for (const int name : group) {
1149 const std::shared_ptr<TrackBase> &t = mTracks[name];
1150 t->bufferProvider->releaseBuffer(&t->buffer);
1151 }
1152 }
1153 }
1154
1155 // generic code with resampling
process__genericResampling()1156 void AudioMixerBase::process__genericResampling()
1157 {
1158 ALOGVV("process__genericResampling\n");
1159 int32_t * const outTemp = mOutputTemp.get(); // naked ptr
1160 size_t numFrames = mFrameCount;
1161
1162 for (const auto &pair : mGroups) {
1163 const auto &group = pair.second;
1164 const std::shared_ptr<TrackBase> &t1 = mTracks[group[0]];
1165
1166 // clear temp buffer
1167 memset(outTemp, 0, sizeof(*outTemp) * t1->mMixerChannelCount * mFrameCount);
1168 for (const int name : group) {
1169 const std::shared_ptr<TrackBase> &t = mTracks[name];
1170 int32_t *aux = NULL;
1171 if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
1172 aux = t->auxBuffer;
1173 }
1174
1175 // this is a little goofy, on the resampling case we don't
1176 // acquire/release the buffers because it's done by
1177 // the resampler.
1178 if (t->needs & NEEDS_RESAMPLE) {
1179 (t.get()->*t->hook)(outTemp, numFrames, mResampleTemp.get() /* naked ptr */, aux);
1180 } else {
1181
1182 size_t outFrames = 0;
1183
1184 while (outFrames < numFrames) {
1185 t->buffer.frameCount = numFrames - outFrames;
1186 t->bufferProvider->getNextBuffer(&t->buffer);
1187 t->mIn = t->buffer.raw;
1188 // t->mIn == nullptr can happen if the track was flushed just after having
1189 // been enabled for mixing.
1190 if (t->mIn == nullptr) break;
1191
1192 (t.get()->*t->hook)(
1193 outTemp + outFrames * t->mMixerChannelCount, t->buffer.frameCount,
1194 mResampleTemp.get() /* naked ptr */,
1195 aux != nullptr ? aux + outFrames : nullptr);
1196 outFrames += t->buffer.frameCount;
1197
1198 t->bufferProvider->releaseBuffer(&t->buffer);
1199 }
1200 }
1201 }
1202 convertMixerFormat(t1->mainBuffer, t1->mMixerFormat,
1203 outTemp, t1->mMixerInFormat, numFrames * t1->mMixerChannelCount);
1204 }
1205 }
1206
1207 // one track, 16 bits stereo without resampling is the most common case
process__oneTrack16BitsStereoNoResampling()1208 void AudioMixerBase::process__oneTrack16BitsStereoNoResampling()
1209 {
1210 ALOGVV("process__oneTrack16BitsStereoNoResampling\n");
1211 LOG_ALWAYS_FATAL_IF(mEnabled.size() != 0,
1212 "%zu != 1 tracks enabled", mEnabled.size());
1213 const int name = mEnabled[0];
1214 const std::shared_ptr<TrackBase> &t = mTracks[name];
1215
1216 AudioBufferProvider::Buffer& b(t->buffer);
1217
1218 int32_t* out = t->mainBuffer;
1219 float *fout = reinterpret_cast<float*>(out);
1220 size_t numFrames = mFrameCount;
1221
1222 const int16_t vl = t->volume[0];
1223 const int16_t vr = t->volume[1];
1224 const uint32_t vrl = t->volumeRL;
1225 while (numFrames) {
1226 b.frameCount = numFrames;
1227 t->bufferProvider->getNextBuffer(&b);
1228 const int16_t *in = b.i16;
1229
1230 // in == NULL can happen if the track was flushed just after having
1231 // been enabled for mixing.
1232 if (in == NULL || (((uintptr_t)in) & 3)) {
1233 if ( AUDIO_FORMAT_PCM_FLOAT == t->mMixerFormat ) {
1234 memset((char*)fout, 0, numFrames
1235 * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
1236 } else {
1237 memset((char*)out, 0, numFrames
1238 * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
1239 }
1240 ALOGE_IF((((uintptr_t)in) & 3),
1241 "process__oneTrack16BitsStereoNoResampling: misaligned buffer"
1242 " %p track %d, channels %d, needs %08x, volume %08x vfl %f vfr %f",
1243 in, name, t->channelCount, t->needs, vrl, t->mVolume[0], t->mVolume[1]);
1244 return;
1245 }
1246 size_t outFrames = b.frameCount;
1247
1248 switch (t->mMixerFormat) {
1249 case AUDIO_FORMAT_PCM_FLOAT:
1250 do {
1251 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1252 in += 2;
1253 int32_t l = mulRL(1, rl, vrl);
1254 int32_t r = mulRL(0, rl, vrl);
1255 *fout++ = float_from_q4_27(l);
1256 *fout++ = float_from_q4_27(r);
1257 // Note: In case of later int16_t sink output,
1258 // conversion and clamping is done by memcpy_to_i16_from_float().
1259 } while (--outFrames);
1260 break;
1261 case AUDIO_FORMAT_PCM_16_BIT:
1262 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
1263 // volume is boosted, so we might need to clamp even though
1264 // we process only one track.
1265 do {
1266 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1267 in += 2;
1268 int32_t l = mulRL(1, rl, vrl) >> 12;
1269 int32_t r = mulRL(0, rl, vrl) >> 12;
1270 // clamping...
1271 l = clamp16(l);
1272 r = clamp16(r);
1273 *out++ = (r<<16) | (l & 0xFFFF);
1274 } while (--outFrames);
1275 } else {
1276 do {
1277 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1278 in += 2;
1279 int32_t l = mulRL(1, rl, vrl) >> 12;
1280 int32_t r = mulRL(0, rl, vrl) >> 12;
1281 *out++ = (r<<16) | (l & 0xFFFF);
1282 } while (--outFrames);
1283 }
1284 break;
1285 default:
1286 LOG_ALWAYS_FATAL("bad mixer format: %d", t->mMixerFormat);
1287 }
1288 numFrames -= b.frameCount;
1289 t->bufferProvider->releaseBuffer(&b);
1290 }
1291 }
1292
1293 /* TODO: consider whether this level of optimization is necessary.
1294 * Perhaps just stick with a single for loop.
1295 */
1296
1297 // Needs to derive a compile time constant (constexpr). Could be targeted to go
1298 // to a MONOVOL mixtype based on MAX_NUM_VOLUMES, but that's an unnecessary complication.
1299
MIXTYPE_MONOVOL(int mixtype,int channels)1300 constexpr int MIXTYPE_MONOVOL(int mixtype, int channels) {
1301 if (channels <= FCC_2) {
1302 return mixtype;
1303 } else if (mixtype == MIXTYPE_MULTI) {
1304 return MIXTYPE_MULTI_MONOVOL;
1305 } else if (mixtype == MIXTYPE_MULTI_SAVEONLY) {
1306 return MIXTYPE_MULTI_SAVEONLY_MONOVOL;
1307 } else {
1308 return mixtype;
1309 }
1310 }
1311
1312 // Helper to make a functional array from volumeRampMulti.
1313 template <int MIXTYPE, typename TO, typename TI, typename TV, typename TA, typename TAV,
1314 std::size_t ... Is>
makeVRMArray(std::index_sequence<Is...>)1315 static constexpr auto makeVRMArray(std::index_sequence<Is...>)
1316 {
1317 using F = void(*)(TO*, size_t, const TI*, TA*, TV*, const TV*, TAV*, TAV);
1318 return std::array<F, sizeof...(Is)>{
1319 { &volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE, Is + 1), Is + 1, TO, TI, TV, TA, TAV> ...}
1320 };
1321 }
1322
1323 /* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1324 * TO: int32_t (Q4.27) or float
1325 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1326 * TA: int32_t (Q4.27) or float
1327 */
1328 template <int MIXTYPE,
1329 typename TO, typename TI, typename TV, typename TA, typename TAV>
volumeRampMulti(uint32_t channels,TO * out,size_t frameCount,const TI * in,TA * aux,TV * vol,const TV * volinc,TAV * vola,TAV volainc)1330 static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
1331 const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc)
1332 {
1333 static constexpr auto volumeRampMultiArray =
1334 makeVRMArray<MIXTYPE, TO, TI, TV, TA, TAV>(std::make_index_sequence<FCC_LIMIT>());
1335 if (channels > 0 && channels <= volumeRampMultiArray.size()) {
1336 volumeRampMultiArray[channels - 1](out, frameCount, in, aux, vol, volinc, vola, volainc);
1337 } else {
1338 ALOGE("%s: invalid channel count:%d", __func__, channels);
1339 }
1340 }
1341
1342 // Helper to make a functional array from volumeMulti.
1343 template <int MIXTYPE, typename TO, typename TI, typename TV, typename TA, typename TAV,
1344 std::size_t ... Is>
makeVMArray(std::index_sequence<Is...>)1345 static constexpr auto makeVMArray(std::index_sequence<Is...>)
1346 {
1347 using F = void(*)(TO*, size_t, const TI*, TA*, const TV*, TAV);
1348 return std::array<F, sizeof...(Is)>{
1349 { &volumeMulti<MIXTYPE_MONOVOL(MIXTYPE, Is + 1), Is + 1, TO, TI, TV, TA, TAV> ... }
1350 };
1351 }
1352
1353 /* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1354 * TO: int32_t (Q4.27) or float
1355 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1356 * TA: int32_t (Q4.27) or float
1357 */
1358 template <int MIXTYPE,
1359 typename TO, typename TI, typename TV, typename TA, typename TAV>
volumeMulti(uint32_t channels,TO * out,size_t frameCount,const TI * in,TA * aux,const TV * vol,TAV vola)1360 static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
1361 const TI* in, TA* aux, const TV *vol, TAV vola)
1362 {
1363 static constexpr auto volumeMultiArray =
1364 makeVMArray<MIXTYPE, TO, TI, TV, TA, TAV>(std::make_index_sequence<FCC_LIMIT>());
1365 if (channels > 0 && channels <= volumeMultiArray.size()) {
1366 volumeMultiArray[channels - 1](out, frameCount, in, aux, vol, vola);
1367 } else {
1368 ALOGE("%s: invalid channel count:%d", __func__, channels);
1369 }
1370 }
1371
1372 /* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1373 * USEFLOATVOL (set to true if float volume is used)
1374 * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards)
1375 * TO: int32_t (Q4.27) or float
1376 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1377 * TA: int32_t (Q4.27) or float
1378 */
1379 template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
1380 typename TO, typename TI, typename TA>
volumeMix(TO * out,size_t outFrames,const TI * in,TA * aux,bool ramp)1381 void AudioMixerBase::TrackBase::volumeMix(TO *out, size_t outFrames,
1382 const TI *in, TA *aux, bool ramp)
1383 {
1384 if (USEFLOATVOL) {
1385 if (ramp) {
1386 volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1387 mPrevVolume, mVolumeInc,
1388 #ifdef FLOAT_AUX
1389 &mPrevAuxLevel, mAuxInc
1390 #else
1391 &prevAuxLevel, auxInc
1392 #endif
1393 );
1394 if (ADJUSTVOL) {
1395 adjustVolumeRamp(aux != NULL, true);
1396 }
1397 } else {
1398 volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1399 mVolume,
1400 #ifdef FLOAT_AUX
1401 mAuxLevel
1402 #else
1403 auxLevel
1404 #endif
1405 );
1406 }
1407 } else {
1408 if (ramp) {
1409 volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1410 prevVolume, volumeInc, &prevAuxLevel, auxInc);
1411 if (ADJUSTVOL) {
1412 adjustVolumeRamp(aux != NULL);
1413 }
1414 } else {
1415 volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1416 volume, auxLevel);
1417 }
1418 }
1419 }
1420
1421 /* This process hook is called when there is a single track without
1422 * aux buffer, volume ramp, or resampling.
1423 * TODO: Update the hook selection: this can properly handle aux and ramp.
1424 *
1425 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1426 * TO: int32_t (Q4.27) or float
1427 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1428 * TA: int32_t (Q4.27)
1429 */
1430 template <int MIXTYPE, typename TO, typename TI, typename TA>
process__noResampleOneTrack()1431 void AudioMixerBase::process__noResampleOneTrack()
1432 {
1433 ALOGVV("process__noResampleOneTrack\n");
1434 LOG_ALWAYS_FATAL_IF(mEnabled.size() != 1,
1435 "%zu != 1 tracks enabled", mEnabled.size());
1436 const std::shared_ptr<TrackBase> &t = mTracks[mEnabled[0]];
1437 const uint32_t channels = t->mMixerChannelCount;
1438 TO* out = reinterpret_cast<TO*>(t->mainBuffer);
1439 TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
1440 const bool ramp = t->needsRamp();
1441
1442 for (size_t numFrames = mFrameCount; numFrames > 0; ) {
1443 AudioBufferProvider::Buffer& b(t->buffer);
1444 // get input buffer
1445 b.frameCount = numFrames;
1446 t->bufferProvider->getNextBuffer(&b);
1447 const TI *in = reinterpret_cast<TI*>(b.raw);
1448
1449 // in == NULL can happen if the track was flushed just after having
1450 // been enabled for mixing.
1451 if (in == NULL || (((uintptr_t)in) & 3)) {
1452 memset(out, 0, numFrames
1453 * channels * audio_bytes_per_sample(t->mMixerFormat));
1454 ALOGE_IF((((uintptr_t)in) & 3), "process__noResampleOneTrack: bus error: "
1455 "buffer %p track %p, channels %d, needs %#x",
1456 in, &t, t->channelCount, t->needs);
1457 return;
1458 }
1459
1460 const size_t outFrames = b.frameCount;
1461 t->volumeMix<MIXTYPE, std::is_same_v<TI, float> /* USEFLOATVOL */, false /* ADJUSTVOL */> (
1462 out, outFrames, in, aux, ramp);
1463
1464 out += outFrames * channels;
1465 if (aux != NULL) {
1466 aux += outFrames;
1467 }
1468 numFrames -= b.frameCount;
1469
1470 // release buffer
1471 t->bufferProvider->releaseBuffer(&b);
1472 }
1473 if (ramp) {
1474 t->adjustVolumeRamp(aux != NULL, std::is_same_v<TI, float>);
1475 }
1476 }
1477
1478 /* This track hook is called to do resampling then mixing,
1479 * pulling from the track's upstream AudioBufferProvider.
1480 *
1481 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1482 * TO: int32_t (Q4.27) or float
1483 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1484 * TA: int32_t (Q4.27) or float
1485 */
1486 template <int MIXTYPE, typename TO, typename TI, typename TA>
track__Resample(TO * out,size_t outFrameCount,TO * temp,TA * aux)1487 void AudioMixerBase::TrackBase::track__Resample(TO* out, size_t outFrameCount, TO* temp, TA* aux)
1488 {
1489 ALOGVV("track__Resample\n");
1490 mResampler->setSampleRate(sampleRate);
1491 const bool ramp = needsRamp();
1492 if (MIXTYPE == MIXTYPE_MONOEXPAND || MIXTYPE == MIXTYPE_STEREOEXPAND // custom volume handling
1493 || ramp || aux != NULL) {
1494 // if ramp: resample with unity gain to temp buffer and scale/mix in 2nd step.
1495 // if aux != NULL: resample with unity gain to temp buffer then apply send level.
1496
1497 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
1498 memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(TO));
1499 mResampler->resample((int32_t*)temp, outFrameCount, bufferProvider);
1500
1501 volumeMix<MIXTYPE, std::is_same_v<TI, float> /* USEFLOATVOL */, true /* ADJUSTVOL */>(
1502 out, outFrameCount, temp, aux, ramp);
1503
1504 } else { // constant volume gain
1505 mResampler->setVolume(mVolume[0], mVolume[1]);
1506 mResampler->resample((int32_t*)out, outFrameCount, bufferProvider);
1507 }
1508 }
1509
1510 /* This track hook is called to mix a track, when no resampling is required.
1511 * The input buffer should be present in in.
1512 *
1513 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1514 * TO: int32_t (Q4.27) or float
1515 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1516 * TA: int32_t (Q4.27) or float
1517 */
1518 template <int MIXTYPE, typename TO, typename TI, typename TA>
track__NoResample(TO * out,size_t frameCount,TO * temp __unused,TA * aux)1519 void AudioMixerBase::TrackBase::track__NoResample(
1520 TO* out, size_t frameCount, TO* temp __unused, TA* aux)
1521 {
1522 ALOGVV("track__NoResample\n");
1523 const TI *in = static_cast<const TI *>(mIn);
1524
1525 volumeMix<MIXTYPE, std::is_same_v<TI, float> /* USEFLOATVOL */, true /* ADJUSTVOL */>(
1526 out, frameCount, in, aux, needsRamp());
1527
1528 // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
1529 // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
1530 in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * mMixerChannelCount;
1531 mIn = in;
1532 }
1533
1534 /* The Mixer engine generates either int32_t (Q4_27) or float data.
1535 * We use this function to convert the engine buffers
1536 * to the desired mixer output format, either int16_t (Q.15) or float.
1537 */
1538 /* static */
convertMixerFormat(void * out,audio_format_t mixerOutFormat,void * in,audio_format_t mixerInFormat,size_t sampleCount)1539 void AudioMixerBase::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
1540 void *in, audio_format_t mixerInFormat, size_t sampleCount)
1541 {
1542 switch (mixerInFormat) {
1543 case AUDIO_FORMAT_PCM_FLOAT:
1544 switch (mixerOutFormat) {
1545 case AUDIO_FORMAT_PCM_FLOAT:
1546 memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
1547 break;
1548 case AUDIO_FORMAT_PCM_16_BIT:
1549 memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
1550 break;
1551 default:
1552 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1553 break;
1554 }
1555 break;
1556 case AUDIO_FORMAT_PCM_16_BIT:
1557 switch (mixerOutFormat) {
1558 case AUDIO_FORMAT_PCM_FLOAT:
1559 memcpy_to_float_from_q4_27((float*)out, (const int32_t*)in, sampleCount);
1560 break;
1561 case AUDIO_FORMAT_PCM_16_BIT:
1562 memcpy_to_i16_from_q4_27((int16_t*)out, (const int32_t*)in, sampleCount);
1563 break;
1564 default:
1565 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1566 break;
1567 }
1568 break;
1569 default:
1570 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1571 break;
1572 }
1573 }
1574
1575 /* Returns the proper track hook to use for mixing the track into the output buffer.
1576 */
1577 /* static */
getTrackHook(int trackType,uint32_t channelCount,audio_format_t mixerInFormat,audio_format_t mixerOutFormat __unused)1578 AudioMixerBase::hook_t AudioMixerBase::TrackBase::getTrackHook(int trackType, uint32_t channelCount,
1579 audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
1580 {
1581 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
1582 switch (trackType) {
1583 case TRACKTYPE_NOP:
1584 return &TrackBase::track__nop;
1585 case TRACKTYPE_RESAMPLE:
1586 return &TrackBase::track__genericResample;
1587 case TRACKTYPE_NORESAMPLEMONO:
1588 return &TrackBase::track__16BitsMono;
1589 case TRACKTYPE_NORESAMPLE:
1590 return &TrackBase::track__16BitsStereo;
1591 default:
1592 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1593 break;
1594 }
1595 }
1596 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
1597 switch (trackType) {
1598 case TRACKTYPE_NOP:
1599 return &TrackBase::track__nop;
1600 case TRACKTYPE_RESAMPLE:
1601 switch (mixerInFormat) {
1602 case AUDIO_FORMAT_PCM_FLOAT:
1603 return (AudioMixerBase::hook_t) &TrackBase::track__Resample<
1604 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
1605 case AUDIO_FORMAT_PCM_16_BIT:
1606 return (AudioMixerBase::hook_t) &TrackBase::track__Resample<
1607 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
1608 default:
1609 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1610 break;
1611 }
1612 break;
1613 case TRACKTYPE_RESAMPLESTEREO:
1614 switch (mixerInFormat) {
1615 case AUDIO_FORMAT_PCM_FLOAT:
1616 return (AudioMixerBase::hook_t) &TrackBase::track__Resample<
1617 MIXTYPE_MULTI_STEREOVOL, float /*TO*/, float /*TI*/,
1618 TYPE_AUX>;
1619 case AUDIO_FORMAT_PCM_16_BIT:
1620 return (AudioMixerBase::hook_t) &TrackBase::track__Resample<
1621 MIXTYPE_MULTI_STEREOVOL, int32_t /*TO*/, int16_t /*TI*/,
1622 TYPE_AUX>;
1623 default:
1624 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1625 break;
1626 }
1627 break;
1628 // RESAMPLEMONO needs MIXTYPE_STEREOEXPAND since resampler will upmix mono
1629 // track to stereo track
1630 case TRACKTYPE_RESAMPLEMONO:
1631 switch (mixerInFormat) {
1632 case AUDIO_FORMAT_PCM_FLOAT:
1633 return (AudioMixerBase::hook_t) &TrackBase::track__Resample<
1634 MIXTYPE_STEREOEXPAND, float /*TO*/, float /*TI*/,
1635 TYPE_AUX>;
1636 case AUDIO_FORMAT_PCM_16_BIT:
1637 return (AudioMixerBase::hook_t) &TrackBase::track__Resample<
1638 MIXTYPE_STEREOEXPAND, int32_t /*TO*/, int16_t /*TI*/,
1639 TYPE_AUX>;
1640 default:
1641 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1642 break;
1643 }
1644 break;
1645 case TRACKTYPE_NORESAMPLEMONO:
1646 switch (mixerInFormat) {
1647 case AUDIO_FORMAT_PCM_FLOAT:
1648 return (AudioMixerBase::hook_t) &TrackBase::track__NoResample<
1649 MIXTYPE_MONOEXPAND, float /*TO*/, float /*TI*/, TYPE_AUX>;
1650 case AUDIO_FORMAT_PCM_16_BIT:
1651 return (AudioMixerBase::hook_t) &TrackBase::track__NoResample<
1652 MIXTYPE_MONOEXPAND, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
1653 default:
1654 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1655 break;
1656 }
1657 break;
1658 case TRACKTYPE_NORESAMPLE:
1659 switch (mixerInFormat) {
1660 case AUDIO_FORMAT_PCM_FLOAT:
1661 return (AudioMixerBase::hook_t) &TrackBase::track__NoResample<
1662 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
1663 case AUDIO_FORMAT_PCM_16_BIT:
1664 return (AudioMixerBase::hook_t) &TrackBase::track__NoResample<
1665 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
1666 default:
1667 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1668 break;
1669 }
1670 break;
1671 case TRACKTYPE_NORESAMPLESTEREO:
1672 switch (mixerInFormat) {
1673 case AUDIO_FORMAT_PCM_FLOAT:
1674 return (AudioMixerBase::hook_t) &TrackBase::track__NoResample<
1675 MIXTYPE_MULTI_STEREOVOL, float /*TO*/, float /*TI*/,
1676 TYPE_AUX>;
1677 case AUDIO_FORMAT_PCM_16_BIT:
1678 return (AudioMixerBase::hook_t) &TrackBase::track__NoResample<
1679 MIXTYPE_MULTI_STEREOVOL, int32_t /*TO*/, int16_t /*TI*/,
1680 TYPE_AUX>;
1681 default:
1682 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1683 break;
1684 }
1685 break;
1686 default:
1687 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1688 break;
1689 }
1690 return NULL;
1691 }
1692
1693 /* Returns the proper process hook for mixing tracks. Currently works only for
1694 * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
1695 *
1696 * TODO: Due to the special mixing considerations of duplicating to
1697 * a stereo output track, the input track cannot be MONO. This should be
1698 * prevented by the caller.
1699 */
1700 /* static */
getProcessHook(int processType,uint32_t channelCount,audio_format_t mixerInFormat,audio_format_t mixerOutFormat,bool stereoVolume)1701 AudioMixerBase::process_hook_t AudioMixerBase::getProcessHook(
1702 int processType, uint32_t channelCount,
1703 audio_format_t mixerInFormat, audio_format_t mixerOutFormat,
1704 bool stereoVolume)
1705 {
1706 if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
1707 LOG_ALWAYS_FATAL("bad processType: %d", processType);
1708 return NULL;
1709 }
1710 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
1711 return &AudioMixerBase::process__oneTrack16BitsStereoNoResampling;
1712 }
1713 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
1714
1715 if (stereoVolume) { // templated arguments require explicit values.
1716 switch (mixerInFormat) {
1717 case AUDIO_FORMAT_PCM_FLOAT:
1718 switch (mixerOutFormat) {
1719 case AUDIO_FORMAT_PCM_FLOAT:
1720 return &AudioMixerBase::process__noResampleOneTrack<
1721 MIXTYPE_MULTI_SAVEONLY_STEREOVOL, float /*TO*/,
1722 float /*TI*/, TYPE_AUX>;
1723 case AUDIO_FORMAT_PCM_16_BIT:
1724 return &AudioMixerBase::process__noResampleOneTrack<
1725 MIXTYPE_MULTI_SAVEONLY_STEREOVOL, int16_t /*TO*/,
1726 float /*TI*/, TYPE_AUX>;
1727 default:
1728 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1729 break;
1730 }
1731 break;
1732 case AUDIO_FORMAT_PCM_16_BIT:
1733 switch (mixerOutFormat) {
1734 case AUDIO_FORMAT_PCM_FLOAT:
1735 return &AudioMixerBase::process__noResampleOneTrack<
1736 MIXTYPE_MULTI_SAVEONLY_STEREOVOL, float /*TO*/,
1737 int16_t /*TI*/, TYPE_AUX>;
1738 case AUDIO_FORMAT_PCM_16_BIT:
1739 return &AudioMixerBase::process__noResampleOneTrack<
1740 MIXTYPE_MULTI_SAVEONLY_STEREOVOL, int16_t /*TO*/,
1741 int16_t /*TI*/, TYPE_AUX>;
1742 default:
1743 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1744 break;
1745 }
1746 break;
1747 default:
1748 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1749 break;
1750 }
1751 } else {
1752 switch (mixerInFormat) {
1753 case AUDIO_FORMAT_PCM_FLOAT:
1754 switch (mixerOutFormat) {
1755 case AUDIO_FORMAT_PCM_FLOAT:
1756 return &AudioMixerBase::process__noResampleOneTrack<
1757 MIXTYPE_MULTI_SAVEONLY, float /*TO*/,
1758 float /*TI*/, TYPE_AUX>;
1759 case AUDIO_FORMAT_PCM_16_BIT:
1760 return &AudioMixerBase::process__noResampleOneTrack<
1761 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/,
1762 float /*TI*/, TYPE_AUX>;
1763 default:
1764 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1765 break;
1766 }
1767 break;
1768 case AUDIO_FORMAT_PCM_16_BIT:
1769 switch (mixerOutFormat) {
1770 case AUDIO_FORMAT_PCM_FLOAT:
1771 return &AudioMixerBase::process__noResampleOneTrack<
1772 MIXTYPE_MULTI_SAVEONLY, float /*TO*/,
1773 int16_t /*TI*/, TYPE_AUX>;
1774 case AUDIO_FORMAT_PCM_16_BIT:
1775 return &AudioMixerBase::process__noResampleOneTrack<
1776 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/,
1777 int16_t /*TI*/, TYPE_AUX>;
1778 default:
1779 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1780 break;
1781 }
1782 break;
1783 default:
1784 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1785 break;
1786 }
1787 }
1788 return NULL;
1789 }
1790
1791 // ----------------------------------------------------------------------------
1792 } // namespace android
1793