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