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