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