• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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