blob: 2d740ab68f7a3f5f2cc8901ca14008bce8ff14ba [file] [log] [blame]
Glenn Kasten99e53b82012-01-19 08:59:58 -08001/*
Mathias Agopian65ab4712010-07-14 17:59:35 -07002**
3** Copyright 2007, 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"
Glenn Kasten7f5d3352013-02-15 23:55:04 +000019//#define LOG_NDEBUG 0
Mathias Agopian65ab4712010-07-14 17:59:35 -070020
Mikhail Naganova4f00e22019-07-31 14:53:29 -070021#include <sstream>
Mathias Agopian65ab4712010-07-14 17:59:35 -070022#include <stdint.h>
23#include <string.h>
24#include <stdlib.h>
Andy Hung5e58b0a2014-06-23 19:07:29 -070025#include <math.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070026#include <sys/types.h>
27
28#include <utils/Errors.h>
29#include <utils/Log.h>
30
Glenn Kastenf6b16782011-12-15 09:51:17 -080031#include <cutils/compiler.h>
Glenn Kasten5798d4e2012-03-08 12:18:35 -080032#include <utils/Debug.h>
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070033
34#include <system/audio.h>
35
Glenn Kasten3b21c502011-12-15 09:52:39 -080036#include <audio_utils/primitives.h>
Andy Hungef7c7fb2014-05-12 16:51:41 -070037#include <audio_utils/format.h>
Andy Hung068561c2017-01-03 17:09:32 -080038#include <media/AudioMixer.h>
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070039
Andy Hung296b7412014-06-17 15:25:47 -070040#include "AudioMixerOps.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070041
Andy Hunge93b6b72014-07-17 21:30:53 -070042// The FCC_2 macro refers to the Fixed Channel Count of 2 for the legacy integer mixer.
Andy Hung296b7412014-06-17 15:25:47 -070043#ifndef FCC_2
44#define FCC_2 2
45#endif
46
Andy Hunge93b6b72014-07-17 21:30:53 -070047// Look for MONO_HACK for any Mono hack involving legacy mono channel to
48// stereo channel conversion.
49
Andy Hung296b7412014-06-17 15:25:47 -070050/* VERY_VERY_VERBOSE_LOGGING will show exactly which process hook and track hook is
51 * being used. This is a considerable amount of log spam, so don't enable unless you
52 * are verifying the hook based code.
53 */
54//#define VERY_VERY_VERBOSE_LOGGING
55#ifdef VERY_VERY_VERBOSE_LOGGING
56#define ALOGVV ALOGV
57//define ALOGVV printf // for test-mixer.cpp
58#else
59#define ALOGVV(a...) do { } while (0)
60#endif
61
Andy Hung5b8fde72014-09-02 21:14:34 -070062// Set kUseNewMixer to true to use the new mixer engine always. Otherwise the
63// original code will be used for stereo sinks, the new mixer for multichannel.
Andy Hung116a4982017-11-30 10:15:08 -080064static constexpr bool kUseNewMixer = true;
Andy Hung296b7412014-06-17 15:25:47 -070065
66// Set kUseFloat to true to allow floating input into the mixer engine.
67// If kUseNewMixer is false, this is ignored or may be overridden internally
68// because of downmix/upmix support.
Andy Hung116a4982017-11-30 10:15:08 -080069static constexpr bool kUseFloat = true;
70
71#ifdef FLOAT_AUX
72using TYPE_AUX = float;
73static_assert(kUseNewMixer && kUseFloat,
74 "kUseNewMixer and kUseFloat must be true for FLOAT_AUX option");
75#else
76using TYPE_AUX = int32_t; // q4.27
77#endif
Andy Hung296b7412014-06-17 15:25:47 -070078
Mikhail Naganova4f00e22019-07-31 14:53:29 -070079// TODO: remove BLOCKSIZE unit of processing - it isn't needed anymore.
80static constexpr int BLOCKSIZE = 16;
81
Andy Hung1b2fdcb2014-07-16 17:44:34 -070082// Set to default copy buffer size in frames for input processing.
Mikhail Naganova4f00e22019-07-31 14:53:29 -070083static constexpr size_t kCopyBufferFrameCount = 256;
Andy Hung1b2fdcb2014-07-16 17:44:34 -070084
Mathias Agopian65ab4712010-07-14 17:59:35 -070085namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070086
87// ----------------------------------------------------------------------------
Andy Hung1b2fdcb2014-07-16 17:44:34 -070088
Andy Hung7f475492014-08-25 16:36:37 -070089static inline audio_format_t selectMixerInFormat(audio_format_t inputFormat __unused) {
90 return kUseFloat && kUseNewMixer ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
91}
92
Andy Hung1bc088a2018-02-09 15:57:31 -080093status_t AudioMixer::create(
94 int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080095{
Andy Hung1bc088a2018-02-09 15:57:31 -080096 LOG_ALWAYS_FATAL_IF(exists(name), "name %d already exists", name);
Andy Hung8ed196a2018-01-05 13:21:11 -080097
Andy Hung1bc088a2018-02-09 15:57:31 -080098 if (!isValidChannelMask(channelMask)) {
99 ALOGE("%s invalid channelMask: %#x", __func__, channelMask);
100 return BAD_VALUE;
Andy Hung8ed196a2018-01-05 13:21:11 -0800101 }
Andy Hung1bc088a2018-02-09 15:57:31 -0800102 if (!isValidFormat(format)) {
103 ALOGE("%s invalid format: %#x", __func__, format);
104 return BAD_VALUE;
105 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800106
107 auto t = std::make_shared<Track>();
Andy Hung8ed196a2018-01-05 13:21:11 -0800108 {
109 // TODO: move initialization to the Track constructor.
Glenn Kastendeeb1282012-03-25 11:59:31 -0700110 // assume default parameters for the track, except where noted below
Glenn Kastendeeb1282012-03-25 11:59:31 -0700111 t->needs = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700112
113 // Integer volume.
114 // Currently integer volume is kept for the legacy integer mixer.
115 // Will be removed when the legacy mixer path is removed.
Andy Hungc7c48f12018-11-16 16:42:32 -0800116 t->volume[0] = 0;
117 t->volume[1] = 0;
118 t->prevVolume[0] = 0 << 16;
119 t->prevVolume[1] = 0 << 16;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700120 t->volumeInc[0] = 0;
121 t->volumeInc[1] = 0;
122 t->auxLevel = 0;
123 t->auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700124 t->prevAuxLevel = 0;
125
126 // Floating point volume.
Andy Hungc7c48f12018-11-16 16:42:32 -0800127 t->mVolume[0] = 0.f;
128 t->mVolume[1] = 0.f;
129 t->mPrevVolume[0] = 0.f;
130 t->mPrevVolume[1] = 0.f;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700131 t->mVolumeInc[0] = 0.;
132 t->mVolumeInc[1] = 0.;
133 t->mAuxLevel = 0.;
134 t->mAuxInc = 0.;
135 t->mPrevAuxLevel = 0.;
136
Glenn Kastendeeb1282012-03-25 11:59:31 -0700137 // no initialization needed
Glenn Kastendeeb1282012-03-25 11:59:31 -0700138 // t->frameCount
jiabin245cdd92018-12-07 17:55:15 -0800139 t->mHapticChannelMask = channelMask & AUDIO_CHANNEL_HAPTIC_ALL;
140 t->mHapticChannelCount = audio_channel_count_from_out_mask(t->mHapticChannelMask);
141 channelMask &= ~AUDIO_CHANNEL_HAPTIC_ALL;
Andy Hung68112fc2014-05-14 14:13:23 -0700142 t->channelCount = audio_channel_count_from_out_mask(channelMask);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700143 t->enabled = false;
Andy Hunge93b6b72014-07-17 21:30:53 -0700144 ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
Andy Hungef7c7fb2014-05-12 16:51:41 -0700145 "Non-stereo channel mask: %d\n", channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700146 t->channelMask = channelMask;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700147 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700148 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
149 t->bufferProvider = NULL;
150 t->buffer.raw = NULL;
151 // no initialization needed
152 // t->buffer.frameCount
153 t->hook = NULL;
Andy Hung8ed196a2018-01-05 13:21:11 -0800154 t->mIn = NULL;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700155 t->sampleRate = mSampleRate;
156 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
157 t->mainBuffer = NULL;
158 t->auxBuffer = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700159 t->mInputBufferProvider = NULL;
Andy Hung78820702014-02-28 16:23:02 -0800160 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700161 t->mFormat = format;
Andy Hung7f475492014-08-25 16:36:37 -0700162 t->mMixerInFormat = selectMixerInFormat(format);
163 t->mDownmixRequiresFormat = AUDIO_FORMAT_INVALID; // no format required
Andy Hunge93b6b72014-07-17 21:30:53 -0700164 t->mMixerChannelMask = audio_channel_mask_from_representation_and_bits(
165 AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
166 t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700167 t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
jiabindce8f8c2018-12-10 17:49:31 -0800168 // haptic
jiabin245cdd92018-12-07 17:55:15 -0800169 t->mHapticPlaybackEnabled = false;
jiabin77270b82018-12-18 15:41:29 -0800170 t->mHapticIntensity = HAPTIC_SCALE_NONE;
jiabin245cdd92018-12-07 17:55:15 -0800171 t->mMixerHapticChannelMask = AUDIO_CHANNEL_NONE;
172 t->mMixerHapticChannelCount = 0;
173 t->mAdjustInChannelCount = t->channelCount + t->mHapticChannelCount;
174 t->mAdjustOutChannelCount = t->channelCount + t->mMixerHapticChannelCount;
175 t->mAdjustNonDestructiveInChannelCount = t->mAdjustOutChannelCount;
176 t->mAdjustNonDestructiveOutChannelCount = t->channelCount;
jiabindce8f8c2018-12-10 17:49:31 -0800177 t->mKeepContractedChannels = false;
Andy Hung296b7412014-06-17 15:25:47 -0700178 // Check the downmixing (or upmixing) requirements.
Andy Hung0f451e92014-08-04 21:28:47 -0700179 status_t status = t->prepareForDownmix();
Andy Hung68112fc2014-05-14 14:13:23 -0700180 if (status != OK) {
181 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
Andy Hung1bc088a2018-02-09 15:57:31 -0800182 return BAD_VALUE;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700183 }
Andy Hung7f475492014-08-25 16:36:37 -0700184 // prepareForDownmix() may change mDownmixRequiresFormat
Andy Hung296b7412014-06-17 15:25:47 -0700185 ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
Andy Hung0f451e92014-08-04 21:28:47 -0700186 t->prepareForReformat();
jiabindce8f8c2018-12-10 17:49:31 -0800187 t->prepareForAdjustChannelsNonDestructive(mFrameCount);
188 t->prepareForAdjustChannels();
Andy Hung1bc088a2018-02-09 15:57:31 -0800189
190 mTracks[name] = t;
191 return OK;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700192 }
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800193}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700194
Andy Hunge93b6b72014-07-17 21:30:53 -0700195// Called when channel masks have changed for a track name
Andy Hung7f475492014-08-25 16:36:37 -0700196// TODO: Fix DownmixerBufferProvider not to (possibly) change mixer input format,
Andy Hunge93b6b72014-07-17 21:30:53 -0700197// which will simplify this logic.
198bool AudioMixer::setChannelMasks(int name,
199 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) {
Andy Hung1bc088a2018-02-09 15:57:31 -0800200 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800201 const std::shared_ptr<Track> &track = mTracks[name];
Andy Hunge93b6b72014-07-17 21:30:53 -0700202
jiabin245cdd92018-12-07 17:55:15 -0800203 if (trackChannelMask == (track->channelMask | track->mHapticChannelMask)
204 && mixerChannelMask == (track->mMixerChannelMask | track->mMixerHapticChannelMask)) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700205 return false; // no need to change
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700206 }
jiabin245cdd92018-12-07 17:55:15 -0800207 const audio_channel_mask_t hapticChannelMask = trackChannelMask & AUDIO_CHANNEL_HAPTIC_ALL;
208 trackChannelMask &= ~AUDIO_CHANNEL_HAPTIC_ALL;
209 const audio_channel_mask_t mixerHapticChannelMask = mixerChannelMask & AUDIO_CHANNEL_HAPTIC_ALL;
210 mixerChannelMask &= ~AUDIO_CHANNEL_HAPTIC_ALL;
Andy Hunge93b6b72014-07-17 21:30:53 -0700211 // always recompute for both channel masks even if only one has changed.
212 const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
213 const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
jiabin245cdd92018-12-07 17:55:15 -0800214 const uint32_t hapticChannelCount = audio_channel_count_from_out_mask(hapticChannelMask);
215 const uint32_t mixerHapticChannelCount =
216 audio_channel_count_from_out_mask(mixerHapticChannelMask);
Andy Hunge93b6b72014-07-17 21:30:53 -0700217
218 ALOG_ASSERT((trackChannelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX)
219 && trackChannelCount
220 && mixerChannelCount);
Andy Hung8ed196a2018-01-05 13:21:11 -0800221 track->channelMask = trackChannelMask;
222 track->channelCount = trackChannelCount;
223 track->mMixerChannelMask = mixerChannelMask;
224 track->mMixerChannelCount = mixerChannelCount;
jiabin245cdd92018-12-07 17:55:15 -0800225 track->mHapticChannelMask = hapticChannelMask;
226 track->mHapticChannelCount = hapticChannelCount;
227 track->mMixerHapticChannelMask = mixerHapticChannelMask;
228 track->mMixerHapticChannelCount = mixerHapticChannelCount;
229
230 if (track->mHapticChannelCount > 0) {
231 track->mAdjustInChannelCount = track->channelCount + track->mHapticChannelCount;
232 track->mAdjustOutChannelCount = track->channelCount + track->mMixerHapticChannelCount;
233 track->mAdjustNonDestructiveInChannelCount = track->mAdjustOutChannelCount;
234 track->mAdjustNonDestructiveOutChannelCount = track->channelCount;
235 track->mKeepContractedChannels = track->mHapticPlaybackEnabled;
236 } else {
237 track->mAdjustInChannelCount = 0;
238 track->mAdjustOutChannelCount = 0;
239 track->mAdjustNonDestructiveInChannelCount = 0;
240 track->mAdjustNonDestructiveOutChannelCount = 0;
241 track->mKeepContractedChannels = false;
242 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700243
244 // channel masks have changed, does this track need a downmixer?
245 // update to try using our desired format (if we aren't already using it)
Andy Hung8ed196a2018-01-05 13:21:11 -0800246 const status_t status = track->prepareForDownmix();
Andy Hunge93b6b72014-07-17 21:30:53 -0700247 ALOGE_IF(status != OK,
Andy Hung0f451e92014-08-04 21:28:47 -0700248 "prepareForDownmix error %d, track channel mask %#x, mixer channel mask %#x",
Andy Hung8ed196a2018-01-05 13:21:11 -0800249 status, track->channelMask, track->mMixerChannelMask);
Andy Hunge93b6b72014-07-17 21:30:53 -0700250
Yung Ti Su1a0ecc32018-05-07 11:09:15 +0800251 // always do reformat since channel mask changed,
252 // do it after downmix since track format may change!
253 track->prepareForReformat();
Andy Hunge93b6b72014-07-17 21:30:53 -0700254
jiabindce8f8c2018-12-10 17:49:31 -0800255 track->prepareForAdjustChannelsNonDestructive(mFrameCount);
256 track->prepareForAdjustChannels();
257
Yung Ti Sub5d11952018-05-22 22:31:14 +0800258 if (track->mResampler.get() != nullptr) {
Andy Hung7f475492014-08-25 16:36:37 -0700259 // resampler channels may have changed.
Andy Hung8ed196a2018-01-05 13:21:11 -0800260 const uint32_t resetToSampleRate = track->sampleRate;
261 track->mResampler.reset(nullptr);
262 track->sampleRate = mSampleRate; // without resampler, track rate is device sample rate.
Andy Hunge93b6b72014-07-17 21:30:53 -0700263 // recreate the resampler with updated format, channels, saved sampleRate.
Andy Hung8ed196a2018-01-05 13:21:11 -0800264 track->setResampler(resetToSampleRate /*trackSampleRate*/, mSampleRate /*devSampleRate*/);
Andy Hunge93b6b72014-07-17 21:30:53 -0700265 }
266 return true;
267}
268
Andy Hung8ed196a2018-01-05 13:21:11 -0800269void AudioMixer::Track::unprepareForDownmix() {
Andy Hung0f451e92014-08-04 21:28:47 -0700270 ALOGV("AudioMixer::unprepareForDownmix(%p)", this);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700271
Andy Hung8ed196a2018-01-05 13:21:11 -0800272 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
Andy Hung85395892017-04-25 16:47:52 -0700273 // release any buffers held by the mPostDownmixReformatBufferProvider
Andy Hung8ed196a2018-01-05 13:21:11 -0800274 // before deallocating the mDownmixerBufferProvider.
Andy Hung85395892017-04-25 16:47:52 -0700275 mPostDownmixReformatBufferProvider->reset();
276 }
277
Andy Hung7f475492014-08-25 16:36:37 -0700278 mDownmixRequiresFormat = AUDIO_FORMAT_INVALID;
Andy Hung8ed196a2018-01-05 13:21:11 -0800279 if (mDownmixerBufferProvider.get() != nullptr) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700280 // this track had previously been configured with a downmixer, delete it
Andy Hung8ed196a2018-01-05 13:21:11 -0800281 mDownmixerBufferProvider.reset(nullptr);
Andy Hung0f451e92014-08-04 21:28:47 -0700282 reconfigureBufferProviders();
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700283 } else {
284 ALOGV(" nothing to do, no downmixer to delete");
285 }
286}
287
Andy Hung8ed196a2018-01-05 13:21:11 -0800288status_t AudioMixer::Track::prepareForDownmix()
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700289{
Andy Hung0f451e92014-08-04 21:28:47 -0700290 ALOGV("AudioMixer::prepareForDownmix(%p) with mask 0x%x",
291 this, channelMask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700292
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700293 // discard the previous downmixer if there was one
Andy Hung0f451e92014-08-04 21:28:47 -0700294 unprepareForDownmix();
Andy Hung73e62e22015-04-20 12:06:38 -0700295 // MONO_HACK Only remix (upmix or downmix) if the track and mixer/device channel masks
Andy Hung0f451e92014-08-04 21:28:47 -0700296 // are not the same and not handled internally, as mono -> stereo currently is.
297 if (channelMask == mMixerChannelMask
298 || (channelMask == AUDIO_CHANNEL_OUT_MONO
299 && mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO)) {
300 return NO_ERROR;
301 }
Andy Hung650ceb92015-01-29 13:31:12 -0800302 // DownmixerBufferProvider is only used for position masks.
303 if (audio_channel_mask_get_representation(channelMask)
304 == AUDIO_CHANNEL_REPRESENTATION_POSITION
305 && DownmixerBufferProvider::isMultichannelCapable()) {
Andy Hung66942552018-12-21 16:07:12 -0800306
307 // Check if we have a float or int16 downmixer, in that order.
308 for (const audio_format_t format : { AUDIO_FORMAT_PCM_FLOAT, AUDIO_FORMAT_PCM_16_BIT }) {
309 mDownmixerBufferProvider.reset(new DownmixerBufferProvider(
310 channelMask, mMixerChannelMask,
311 format,
312 sampleRate, sessionId, kCopyBufferFrameCount));
313 if (static_cast<DownmixerBufferProvider *>(mDownmixerBufferProvider.get())
314 ->isValid()) {
315 mDownmixRequiresFormat = format;
316 reconfigureBufferProviders();
317 return NO_ERROR;
318 }
Andy Hung34803d52014-07-16 21:41:35 -0700319 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800320 // mDownmixerBufferProvider reset below.
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700321 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700322
323 // Effect downmixer does not accept the channel conversion. Let's use our remixer.
Andy Hung8ed196a2018-01-05 13:21:11 -0800324 mDownmixerBufferProvider.reset(new RemixBufferProvider(channelMask,
325 mMixerChannelMask, mMixerInFormat, kCopyBufferFrameCount));
Andy Hunge93b6b72014-07-17 21:30:53 -0700326 // Remix always finds a conversion whereas Downmixer effect above may fail.
Andy Hung0f451e92014-08-04 21:28:47 -0700327 reconfigureBufferProviders();
Andy Hunge93b6b72014-07-17 21:30:53 -0700328 return NO_ERROR;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700329}
330
Andy Hung8ed196a2018-01-05 13:21:11 -0800331void AudioMixer::Track::unprepareForReformat() {
Andy Hung0f451e92014-08-04 21:28:47 -0700332 ALOGV("AudioMixer::unprepareForReformat(%p)", this);
Andy Hung7f475492014-08-25 16:36:37 -0700333 bool requiresReconfigure = false;
Andy Hung8ed196a2018-01-05 13:21:11 -0800334 if (mReformatBufferProvider.get() != nullptr) {
335 mReformatBufferProvider.reset(nullptr);
Andy Hung7f475492014-08-25 16:36:37 -0700336 requiresReconfigure = true;
337 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800338 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
339 mPostDownmixReformatBufferProvider.reset(nullptr);
Andy Hung7f475492014-08-25 16:36:37 -0700340 requiresReconfigure = true;
341 }
342 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700343 reconfigureBufferProviders();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700344 }
345}
346
Andy Hung8ed196a2018-01-05 13:21:11 -0800347status_t AudioMixer::Track::prepareForReformat()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700348{
Andy Hung0f451e92014-08-04 21:28:47 -0700349 ALOGV("AudioMixer::prepareForReformat(%p) with format %#x", this, mFormat);
Andy Hung7f475492014-08-25 16:36:37 -0700350 // discard previous reformatters
Andy Hung0f451e92014-08-04 21:28:47 -0700351 unprepareForReformat();
Andy Hung7f475492014-08-25 16:36:37 -0700352 // only configure reformatters as needed
353 const audio_format_t targetFormat = mDownmixRequiresFormat != AUDIO_FORMAT_INVALID
354 ? mDownmixRequiresFormat : mMixerInFormat;
355 bool requiresReconfigure = false;
356 if (mFormat != targetFormat) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800357 mReformatBufferProvider.reset(new ReformatBufferProvider(
Andy Hung0f451e92014-08-04 21:28:47 -0700358 audio_channel_count_from_out_mask(channelMask),
Andy Hung7f475492014-08-25 16:36:37 -0700359 mFormat,
360 targetFormat,
Andy Hung8ed196a2018-01-05 13:21:11 -0800361 kCopyBufferFrameCount));
Andy Hung7f475492014-08-25 16:36:37 -0700362 requiresReconfigure = true;
Kevin Rocarde053bfa2017-11-09 22:07:34 -0800363 } else if (mFormat == AUDIO_FORMAT_PCM_FLOAT) {
364 // Input and output are floats, make sure application did not provide > 3db samples
365 // that would break volume application (b/68099072)
366 // TODO: add a trusted source flag to avoid the overhead
367 mReformatBufferProvider.reset(new ClampFloatBufferProvider(
368 audio_channel_count_from_out_mask(channelMask),
369 kCopyBufferFrameCount));
370 requiresReconfigure = true;
Andy Hung7f475492014-08-25 16:36:37 -0700371 }
372 if (targetFormat != mMixerInFormat) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800373 mPostDownmixReformatBufferProvider.reset(new ReformatBufferProvider(
Andy Hung7f475492014-08-25 16:36:37 -0700374 audio_channel_count_from_out_mask(mMixerChannelMask),
375 targetFormat,
376 mMixerInFormat,
Andy Hung8ed196a2018-01-05 13:21:11 -0800377 kCopyBufferFrameCount));
Andy Hung7f475492014-08-25 16:36:37 -0700378 requiresReconfigure = true;
379 }
380 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700381 reconfigureBufferProviders();
Andy Hung296b7412014-06-17 15:25:47 -0700382 }
383 return NO_ERROR;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700384}
385
jiabindce8f8c2018-12-10 17:49:31 -0800386void AudioMixer::Track::unprepareForAdjustChannels()
387{
388 ALOGV("AUDIOMIXER::unprepareForAdjustChannels");
389 if (mAdjustChannelsBufferProvider.get() != nullptr) {
390 mAdjustChannelsBufferProvider.reset(nullptr);
391 reconfigureBufferProviders();
392 }
393}
394
395status_t AudioMixer::Track::prepareForAdjustChannels()
396{
397 ALOGV("AudioMixer::prepareForAdjustChannels(%p) with inChannelCount: %u, outChannelCount: %u",
398 this, mAdjustInChannelCount, mAdjustOutChannelCount);
399 unprepareForAdjustChannels();
400 if (mAdjustInChannelCount != mAdjustOutChannelCount) {
401 mAdjustChannelsBufferProvider.reset(new AdjustChannelsBufferProvider(
402 mFormat, mAdjustInChannelCount, mAdjustOutChannelCount, kCopyBufferFrameCount));
403 reconfigureBufferProviders();
404 }
405 return NO_ERROR;
406}
407
408void AudioMixer::Track::unprepareForAdjustChannelsNonDestructive()
409{
410 ALOGV("AUDIOMIXER::unprepareForAdjustChannelsNonDestructive");
jiabinea8fa7a2019-02-22 14:41:50 -0800411 if (mContractChannelsNonDestructiveBufferProvider.get() != nullptr) {
412 mContractChannelsNonDestructiveBufferProvider.reset(nullptr);
jiabindce8f8c2018-12-10 17:49:31 -0800413 reconfigureBufferProviders();
414 }
415}
416
417status_t AudioMixer::Track::prepareForAdjustChannelsNonDestructive(size_t frames)
418{
419 ALOGV("AudioMixer::prepareForAdjustChannelsNonDestructive(%p) with inChannelCount: %u, "
420 "outChannelCount: %u, keepContractedChannels: %d",
421 this, mAdjustNonDestructiveInChannelCount, mAdjustNonDestructiveOutChannelCount,
422 mKeepContractedChannels);
423 unprepareForAdjustChannelsNonDestructive();
424 if (mAdjustNonDestructiveInChannelCount != mAdjustNonDestructiveOutChannelCount) {
425 uint8_t* buffer = mKeepContractedChannels
426 ? (uint8_t*)mainBuffer + frames * audio_bytes_per_frame(
427 mMixerChannelCount, mMixerFormat)
428 : NULL;
jiabinea8fa7a2019-02-22 14:41:50 -0800429 mContractChannelsNonDestructiveBufferProvider.reset(
430 new AdjustChannelsBufferProvider(
jiabindce8f8c2018-12-10 17:49:31 -0800431 mFormat,
432 mAdjustNonDestructiveInChannelCount,
433 mAdjustNonDestructiveOutChannelCount,
jiabindce8f8c2018-12-10 17:49:31 -0800434 frames,
jiabinea8fa7a2019-02-22 14:41:50 -0800435 mKeepContractedChannels ? mMixerFormat : AUDIO_FORMAT_INVALID,
jiabindce8f8c2018-12-10 17:49:31 -0800436 buffer));
437 reconfigureBufferProviders();
438 }
439 return NO_ERROR;
440}
441
442void AudioMixer::Track::clearContractedBuffer()
443{
jiabinea8fa7a2019-02-22 14:41:50 -0800444 if (mContractChannelsNonDestructiveBufferProvider.get() != nullptr) {
445 static_cast<AdjustChannelsBufferProvider*>(
446 mContractChannelsNonDestructiveBufferProvider.get())->clearContractedFrames();
jiabindce8f8c2018-12-10 17:49:31 -0800447 }
448}
449
Andy Hung8ed196a2018-01-05 13:21:11 -0800450void AudioMixer::Track::reconfigureBufferProviders()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700451{
Andy Hung3a34df92018-08-21 12:32:30 -0700452 // configure from upstream to downstream buffer providers.
Andy Hung0f451e92014-08-04 21:28:47 -0700453 bufferProvider = mInputBufferProvider;
jiabindce8f8c2018-12-10 17:49:31 -0800454 if (mAdjustChannelsBufferProvider.get() != nullptr) {
455 mAdjustChannelsBufferProvider->setBufferProvider(bufferProvider);
456 bufferProvider = mAdjustChannelsBufferProvider.get();
457 }
jiabinea8fa7a2019-02-22 14:41:50 -0800458 if (mContractChannelsNonDestructiveBufferProvider.get() != nullptr) {
459 mContractChannelsNonDestructiveBufferProvider->setBufferProvider(bufferProvider);
460 bufferProvider = mContractChannelsNonDestructiveBufferProvider.get();
jiabindce8f8c2018-12-10 17:49:31 -0800461 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800462 if (mReformatBufferProvider.get() != nullptr) {
Andy Hung0f451e92014-08-04 21:28:47 -0700463 mReformatBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800464 bufferProvider = mReformatBufferProvider.get();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700465 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800466 if (mDownmixerBufferProvider.get() != nullptr) {
467 mDownmixerBufferProvider->setBufferProvider(bufferProvider);
468 bufferProvider = mDownmixerBufferProvider.get();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700469 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800470 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
Andy Hung7f475492014-08-25 16:36:37 -0700471 mPostDownmixReformatBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800472 bufferProvider = mPostDownmixReformatBufferProvider.get();
Andy Hung7f475492014-08-25 16:36:37 -0700473 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800474 if (mTimestretchBufferProvider.get() != nullptr) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700475 mTimestretchBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800476 bufferProvider = mTimestretchBufferProvider.get();
Andy Hungc5656cc2015-03-26 19:04:33 -0700477 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700478}
479
Andy Hung1bc088a2018-02-09 15:57:31 -0800480void AudioMixer::destroy(int name)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800481{
Andy Hung1bc088a2018-02-09 15:57:31 -0800482 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800483 ALOGV("deleteTrackName(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800484
485 if (mTracks[name]->enabled) {
486 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700487 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800488 mTracks.erase(name); // deallocate track
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800489}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700490
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800491void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700492{
Andy Hung1bc088a2018-02-09 15:57:31 -0800493 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800494 const std::shared_ptr<Track> &track = mTracks[name];
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800495
Andy Hung8ed196a2018-01-05 13:21:11 -0800496 if (!track->enabled) {
497 track->enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800498 ALOGV("enable(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800499 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700500 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700501}
502
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800503void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700504{
Andy Hung1bc088a2018-02-09 15:57:31 -0800505 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800506 const std::shared_ptr<Track> &track = mTracks[name];
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800507
Andy Hung8ed196a2018-01-05 13:21:11 -0800508 if (track->enabled) {
509 track->enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800510 ALOGV("disable(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800511 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700512 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700513}
514
Andy Hung5866a3b2014-05-29 21:33:13 -0700515/* Sets the volume ramp variables for the AudioMixer.
516 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700517 * The volume ramp variables are used to transition from the previous
518 * volume to the set volume. ramp controls the duration of the transition.
519 * Its value is typically one state framecount period, but may also be 0,
520 * meaning "immediate."
Andy Hung5866a3b2014-05-29 21:33:13 -0700521 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700522 * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
523 * even if there is a nonzero floating point increment (in that case, the volume
524 * change is immediate). This restriction should be changed when the legacy mixer
525 * is removed (see #2).
526 * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
527 * when no longer needed.
528 *
529 * @param newVolume set volume target in floating point [0.0, 1.0].
530 * @param ramp number of frames to increment over. if ramp is 0, the volume
531 * should be set immediately. Currently ramp should not exceed 65535 (frames).
532 * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
533 * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
534 * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
535 * @param pSetVolume pointer to the float target volume, set on return.
536 * @param pPrevVolume pointer to the float previous volume, set on return.
537 * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
Andy Hung5866a3b2014-05-29 21:33:13 -0700538 * @return true if the volume has changed, false if volume is same.
539 */
Andy Hung5e58b0a2014-06-23 19:07:29 -0700540static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
541 int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
542 float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
Andy Hunge09c9942015-05-08 16:58:13 -0700543 // check floating point volume to see if it is identical to the previously
544 // set volume.
545 // We do not use a tolerance here (and reject changes too small)
546 // as it may be confusing to use a different value than the one set.
547 // If the resulting volume is too small to ramp, it is a direct set of the volume.
Andy Hung5e58b0a2014-06-23 19:07:29 -0700548 if (newVolume == *pSetVolume) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700549 return false;
550 }
Andy Hunge09c9942015-05-08 16:58:13 -0700551 if (newVolume < 0) {
552 newVolume = 0; // should not have negative volumes
Andy Hung5866a3b2014-05-29 21:33:13 -0700553 } else {
Andy Hunge09c9942015-05-08 16:58:13 -0700554 switch (fpclassify(newVolume)) {
555 case FP_SUBNORMAL:
556 case FP_NAN:
557 newVolume = 0;
558 break;
559 case FP_ZERO:
560 break; // zero volume is fine
561 case FP_INFINITE:
562 // Infinite volume could be handled consistently since
563 // floating point math saturates at infinities,
564 // but we limit volume to unity gain float.
565 // ramp = 0; break;
566 //
567 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
568 break;
569 case FP_NORMAL:
570 default:
571 // Floating point does not have problems with overflow wrap
572 // that integer has. However, we limit the volume to
573 // unity gain here.
574 // TODO: Revisit the volume limitation and perhaps parameterize.
575 if (newVolume > AudioMixer::UNITY_GAIN_FLOAT) {
576 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
577 }
578 break;
579 }
Andy Hung5866a3b2014-05-29 21:33:13 -0700580 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700581
Andy Hunge09c9942015-05-08 16:58:13 -0700582 // set floating point volume ramp
583 if (ramp != 0) {
584 // when the ramp completes, *pPrevVolume is set to *pSetVolume, so there
585 // is no computational mismatch; hence equality is checked here.
586 ALOGD_IF(*pPrevVolume != *pSetVolume, "previous float ramp hasn't finished,"
587 " prev:%f set_to:%f", *pPrevVolume, *pSetVolume);
588 const float inc = (newVolume - *pPrevVolume) / ramp; // could be inf, nan, subnormal
Andy Hung8ed196a2018-01-05 13:21:11 -0800589 // could be inf, cannot be nan, subnormal
590 const float maxv = std::max(newVolume, *pPrevVolume);
Andy Hunge09c9942015-05-08 16:58:13 -0700591
592 if (isnormal(inc) // inc must be a normal number (no subnormals, infinite, nan)
593 && maxv + inc != maxv) { // inc must make forward progress
594 *pVolumeInc = inc;
595 // ramp is set now.
596 // Note: if newVolume is 0, then near the end of the ramp,
597 // it may be possible that the ramped volume may be subnormal or
598 // temporarily negative by a small amount or subnormal due to floating
599 // point inaccuracies.
600 } else {
601 ramp = 0; // ramp not allowed
602 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700603 }
Andy Hunge09c9942015-05-08 16:58:13 -0700604
605 // compute and check integer volume, no need to check negative values
606 // The integer volume is limited to "unity_gain" to avoid wrapping and other
607 // audio artifacts, so it never reaches the range limit of U4.28.
608 // We safely use signed 16 and 32 bit integers here.
609 const float scaledVolume = newVolume * AudioMixer::UNITY_GAIN_INT; // not neg, subnormal, nan
610 const int32_t intVolume = (scaledVolume >= (float)AudioMixer::UNITY_GAIN_INT) ?
611 AudioMixer::UNITY_GAIN_INT : (int32_t)scaledVolume;
612
613 // set integer volume ramp
614 if (ramp != 0) {
615 // integer volume is U4.12 (to use 16 bit multiplies), but ramping uses U4.28.
616 // when the ramp completes, *pIntPrevVolume is set to *pIntSetVolume << 16, so there
617 // is no computational mismatch; hence equality is checked here.
618 ALOGD_IF(*pIntPrevVolume != *pIntSetVolume << 16, "previous int ramp hasn't finished,"
619 " prev:%d set_to:%d", *pIntPrevVolume, *pIntSetVolume << 16);
620 const int32_t inc = ((intVolume << 16) - *pIntPrevVolume) / ramp;
621
622 if (inc != 0) { // inc must make forward progress
623 *pIntVolumeInc = inc;
624 } else {
625 ramp = 0; // ramp not allowed
626 }
627 }
628
629 // if no ramp, or ramp not allowed, then clear float and integer increments
630 if (ramp == 0) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700631 *pVolumeInc = 0;
632 *pPrevVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700633 *pIntVolumeInc = 0;
634 *pIntPrevVolume = intVolume << 16;
635 }
Andy Hunge09c9942015-05-08 16:58:13 -0700636 *pSetVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700637 *pIntSetVolume = intVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700638 return true;
639}
640
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800641void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700642{
Andy Hung1bc088a2018-02-09 15:57:31 -0800643 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800644 const std::shared_ptr<Track> &track = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700645
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000646 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
647 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700648
649 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700650
Mathias Agopian65ab4712010-07-14 17:59:35 -0700651 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800652 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700653 case CHANNEL_MASK: {
Andy Hunge93b6b72014-07-17 21:30:53 -0700654 const audio_channel_mask_t trackChannelMask =
655 static_cast<audio_channel_mask_t>(valueInt);
jiabin245cdd92018-12-07 17:55:15 -0800656 if (setChannelMasks(name, trackChannelMask,
657 (track->mMixerChannelMask | track->mMixerHapticChannelMask))) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700658 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
Andy Hung8ed196a2018-01-05 13:21:11 -0800659 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700660 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700661 } break;
662 case MAIN_BUFFER:
Andy Hung8ed196a2018-01-05 13:21:11 -0800663 if (track->mainBuffer != valueBuf) {
664 track->mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100665 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
jiabindce8f8c2018-12-10 17:49:31 -0800666 if (track->mKeepContractedChannels) {
667 track->prepareForAdjustChannelsNonDestructive(mFrameCount);
668 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800669 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700670 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700671 break;
672 case AUX_BUFFER:
Andy Hung8ed196a2018-01-05 13:21:11 -0800673 if (track->auxBuffer != valueBuf) {
674 track->auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100675 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Andy Hung8ed196a2018-01-05 13:21:11 -0800676 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700677 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700678 break;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700679 case FORMAT: {
680 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800681 if (track->mFormat != format) {
Andy Hungef7c7fb2014-05-12 16:51:41 -0700682 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
Andy Hung8ed196a2018-01-05 13:21:11 -0800683 track->mFormat = format;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700684 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
Andy Hung8ed196a2018-01-05 13:21:11 -0800685 track->prepareForReformat();
686 invalidate();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700687 }
688 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700689 // FIXME do we want to support setting the downmix type from AudioFlinger?
690 // for a specific track? or per mixer?
691 /* case DOWNMIX_TYPE:
692 break */
Andy Hung78820702014-02-28 16:23:02 -0800693 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800694 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800695 if (track->mMixerFormat != format) {
696 track->mMixerFormat = format;
Andy Hung78820702014-02-28 16:23:02 -0800697 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
jiabindce8f8c2018-12-10 17:49:31 -0800698 if (track->mKeepContractedChannels) {
699 track->prepareForAdjustChannelsNonDestructive(mFrameCount);
700 }
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800701 }
702 } break;
Andy Hunge93b6b72014-07-17 21:30:53 -0700703 case MIXER_CHANNEL_MASK: {
704 const audio_channel_mask_t mixerChannelMask =
705 static_cast<audio_channel_mask_t>(valueInt);
jiabin245cdd92018-12-07 17:55:15 -0800706 if (setChannelMasks(name, track->channelMask | track->mHapticChannelMask,
707 mixerChannelMask)) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700708 ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
Andy Hung8ed196a2018-01-05 13:21:11 -0800709 invalidate();
Andy Hunge93b6b72014-07-17 21:30:53 -0700710 }
711 } break;
jiabin245cdd92018-12-07 17:55:15 -0800712 case HAPTIC_ENABLED: {
713 const bool hapticPlaybackEnabled = static_cast<bool>(valueInt);
714 if (track->mHapticPlaybackEnabled != hapticPlaybackEnabled) {
715 track->mHapticPlaybackEnabled = hapticPlaybackEnabled;
716 track->mKeepContractedChannels = hapticPlaybackEnabled;
717 track->prepareForAdjustChannelsNonDestructive(mFrameCount);
718 track->prepareForAdjustChannels();
719 }
720 } break;
jiabin77270b82018-12-18 15:41:29 -0800721 case HAPTIC_INTENSITY: {
722 const haptic_intensity_t hapticIntensity = static_cast<haptic_intensity_t>(valueInt);
723 if (track->mHapticIntensity != hapticIntensity) {
724 track->mHapticIntensity = hapticIntensity;
725 }
726 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700727 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800728 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700729 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700730 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700731
Mathias Agopian65ab4712010-07-14 17:59:35 -0700732 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800733 switch (param) {
734 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800735 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800736 if (track->setResampler(uint32_t(valueInt), mSampleRate)) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700737 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
738 uint32_t(valueInt));
Andy Hung8ed196a2018-01-05 13:21:11 -0800739 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700740 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800741 break;
742 case RESET:
Andy Hung8ed196a2018-01-05 13:21:11 -0800743 track->resetResampler();
744 invalidate();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800745 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700746 case REMOVE:
Andy Hung8ed196a2018-01-05 13:21:11 -0800747 track->mResampler.reset(nullptr);
748 track->sampleRate = mSampleRate;
749 invalidate();
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700750 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700751 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800752 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800753 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700754 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700755
Mathias Agopian65ab4712010-07-14 17:59:35 -0700756 case RAMP_VOLUME:
757 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800758 switch (param) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800759 case AUXLEVEL:
Andy Hung6be49402014-05-30 10:42:03 -0700760 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung8ed196a2018-01-05 13:21:11 -0800761 target == RAMP_VOLUME ? mFrameCount : 0,
762 &track->auxLevel, &track->prevAuxLevel, &track->auxInc,
763 &track->mAuxLevel, &track->mPrevAuxLevel, &track->mAuxInc)) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700764 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
Andy Hung8ed196a2018-01-05 13:21:11 -0800765 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track->auxLevel);
766 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700767 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800768 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700769 default:
Andy Hunge93b6b72014-07-17 21:30:53 -0700770 if ((unsigned)param >= VOLUME0 && (unsigned)param < VOLUME0 + MAX_NUM_VOLUMES) {
771 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung8ed196a2018-01-05 13:21:11 -0800772 target == RAMP_VOLUME ? mFrameCount : 0,
773 &track->volume[param - VOLUME0],
774 &track->prevVolume[param - VOLUME0],
775 &track->volumeInc[param - VOLUME0],
776 &track->mVolume[param - VOLUME0],
777 &track->mPrevVolume[param - VOLUME0],
778 &track->mVolumeInc[param - VOLUME0])) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700779 ALOGV("setParameter(%s, VOLUME%d: %04x)",
780 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
Andy Hung8ed196a2018-01-05 13:21:11 -0800781 track->volume[param - VOLUME0]);
782 invalidate();
Andy Hunge93b6b72014-07-17 21:30:53 -0700783 }
784 } else {
785 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
786 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700787 }
788 break;
Mikhail Naganova4f00e22019-07-31 14:53:29 -0700789 case TIMESTRETCH:
790 switch (param) {
791 case PLAYBACK_RATE: {
792 const AudioPlaybackRate *playbackRate =
793 reinterpret_cast<AudioPlaybackRate*>(value);
794 ALOGW_IF(!isAudioPlaybackRateValid(*playbackRate),
795 "bad parameters speed %f, pitch %f",
796 playbackRate->mSpeed, playbackRate->mPitch);
797 if (track->setPlaybackRate(*playbackRate)) {
798 ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE "
799 "%f %f %d %d",
800 playbackRate->mSpeed,
801 playbackRate->mPitch,
802 playbackRate->mStretchMode,
803 playbackRate->mFallbackMode);
804 // invalidate(); (should not require reconfigure)
Andy Hungc5656cc2015-03-26 19:04:33 -0700805 }
Mikhail Naganova4f00e22019-07-31 14:53:29 -0700806 } break;
807 default:
808 LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);
809 }
810 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700811
812 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800813 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700814 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700815}
816
Andy Hung8ed196a2018-01-05 13:21:11 -0800817bool AudioMixer::Track::setResampler(uint32_t trackSampleRate, uint32_t devSampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700818{
Andy Hung8ed196a2018-01-05 13:21:11 -0800819 if (trackSampleRate != devSampleRate || mResampler.get() != nullptr) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700820 if (sampleRate != trackSampleRate) {
821 sampleRate = trackSampleRate;
Andy Hung8ed196a2018-01-05 13:21:11 -0800822 if (mResampler.get() == nullptr) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700823 ALOGV("Creating resampler from track %d Hz to device %d Hz",
824 trackSampleRate, devSampleRate);
Glenn Kastenac602052012-10-01 14:04:31 -0700825 AudioResampler::src_quality quality;
826 // force lowest quality level resampler if use case isn't music or video
827 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
828 // quality level based on the initial ratio, but that could change later.
829 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
Andy Hungdb4c0312015-05-06 08:46:52 -0700830 if (isMusicRate(trackSampleRate)) {
Glenn Kastenac602052012-10-01 14:04:31 -0700831 quality = AudioResampler::DEFAULT_QUALITY;
Andy Hungdb4c0312015-05-06 08:46:52 -0700832 } else {
833 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700834 }
Andy Hung296b7412014-06-17 15:25:47 -0700835
Andy Hunge93b6b72014-07-17 21:30:53 -0700836 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
837 // but if none exists, it is the channel count (1 for mono).
Andy Hung8ed196a2018-01-05 13:21:11 -0800838 const int resamplerChannelCount = mDownmixerBufferProvider.get() != nullptr
Andy Hunge93b6b72014-07-17 21:30:53 -0700839 ? mMixerChannelCount : channelCount;
Andy Hung9a592762014-07-21 21:56:01 -0700840 ALOGVV("Creating resampler:"
841 " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
842 mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
Andy Hung8ed196a2018-01-05 13:21:11 -0800843 mResampler.reset(AudioResampler::create(
Andy Hung3348e362014-07-07 10:21:44 -0700844 mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -0700845 resamplerChannelCount,
Andy Hung8ed196a2018-01-05 13:21:11 -0800846 devSampleRate, quality));
Mathias Agopian65ab4712010-07-14 17:59:35 -0700847 }
848 return true;
849 }
850 }
851 return false;
852}
853
Andy Hung8ed196a2018-01-05 13:21:11 -0800854bool AudioMixer::Track::setPlaybackRate(const AudioPlaybackRate &playbackRate)
Andy Hungc5656cc2015-03-26 19:04:33 -0700855{
Andy Hung8ed196a2018-01-05 13:21:11 -0800856 if ((mTimestretchBufferProvider.get() == nullptr &&
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700857 fabs(playbackRate.mSpeed - mPlaybackRate.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
858 fabs(playbackRate.mPitch - mPlaybackRate.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA) ||
859 isAudioPlaybackRateEqual(playbackRate, mPlaybackRate)) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700860 return false;
861 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700862 mPlaybackRate = playbackRate;
Andy Hung8ed196a2018-01-05 13:21:11 -0800863 if (mTimestretchBufferProvider.get() == nullptr) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700864 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
865 // but if none exists, it is the channel count (1 for mono).
Andy Hung8ed196a2018-01-05 13:21:11 -0800866 const int timestretchChannelCount = mDownmixerBufferProvider.get() != nullptr
Andy Hungc5656cc2015-03-26 19:04:33 -0700867 ? mMixerChannelCount : channelCount;
Andy Hung8ed196a2018-01-05 13:21:11 -0800868 mTimestretchBufferProvider.reset(new TimestretchBufferProvider(timestretchChannelCount,
869 mMixerInFormat, sampleRate, playbackRate));
Andy Hungc5656cc2015-03-26 19:04:33 -0700870 reconfigureBufferProviders();
871 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -0800872 static_cast<TimestretchBufferProvider*>(mTimestretchBufferProvider.get())
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700873 ->setPlaybackRate(playbackRate);
Andy Hungc5656cc2015-03-26 19:04:33 -0700874 }
875 return true;
876}
877
Andy Hung5e58b0a2014-06-23 19:07:29 -0700878/* Checks to see if the volume ramp has completed and clears the increment
879 * variables appropriately.
880 *
881 * FIXME: There is code to handle int/float ramp variable switchover should it not
882 * complete within a mixer buffer processing call, but it is preferred to avoid switchover
883 * due to precision issues. The switchover code is included for legacy code purposes
884 * and can be removed once the integer volume is removed.
885 *
886 * It is not sufficient to clear only the volumeInc integer variable because
887 * if one channel requires ramping, all channels are ramped.
888 *
889 * There is a bit of duplicated code here, but it keeps backward compatibility.
890 */
Andy Hung8ed196a2018-01-05 13:21:11 -0800891inline void AudioMixer::Track::adjustVolumeRamp(bool aux, bool useFloat)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700892{
Andy Hung5e58b0a2014-06-23 19:07:29 -0700893 if (useFloat) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700894 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Eric Laurent43412fc2015-05-08 16:14:36 -0700895 if ((mVolumeInc[i] > 0 && mPrevVolume[i] + mVolumeInc[i] >= mVolume[i]) ||
896 (mVolumeInc[i] < 0 && mPrevVolume[i] + mVolumeInc[i] <= mVolume[i])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700897 volumeInc[i] = 0;
898 prevVolume[i] = volume[i] << 16;
899 mVolumeInc[i] = 0.;
900 mPrevVolume[i] = mVolume[i];
Andy Hung5e58b0a2014-06-23 19:07:29 -0700901 } else {
902 //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
903 prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
904 }
905 }
906 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -0700907 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700908 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
909 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
910 volumeInc[i] = 0;
911 prevVolume[i] = volume[i] << 16;
912 mVolumeInc[i] = 0.;
913 mPrevVolume[i] = mVolume[i];
914 } else {
915 //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
916 mPrevVolume[i] = float_from_u4_28(prevVolume[i]);
917 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700918 }
919 }
Andy Hung116a4982017-11-30 10:15:08 -0800920
Mathias Agopian65ab4712010-07-14 17:59:35 -0700921 if (aux) {
Andy Hung116a4982017-11-30 10:15:08 -0800922#ifdef FLOAT_AUX
923 if (useFloat) {
924 if ((mAuxInc > 0.f && mPrevAuxLevel + mAuxInc >= mAuxLevel) ||
925 (mAuxInc < 0.f && mPrevAuxLevel + mAuxInc <= mAuxLevel)) {
926 auxInc = 0;
927 prevAuxLevel = auxLevel << 16;
928 mAuxInc = 0.f;
929 mPrevAuxLevel = mAuxLevel;
930 }
931 } else
932#endif
933 if ((auxInc > 0 && ((prevAuxLevel + auxInc) >> 16) >= auxLevel) ||
934 (auxInc < 0 && ((prevAuxLevel + auxInc) >> 16) <= auxLevel)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700935 auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700936 prevAuxLevel = auxLevel << 16;
Andy Hung116a4982017-11-30 10:15:08 -0800937 mAuxInc = 0.f;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700938 mPrevAuxLevel = mAuxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700939 }
940 }
941}
942
Glenn Kastenc59c0042012-02-02 14:06:11 -0800943size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800944{
Andy Hung8ed196a2018-01-05 13:21:11 -0800945 const auto it = mTracks.find(name);
946 if (it != mTracks.end()) {
947 return it->second->getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800948 }
949 return 0;
950}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700951
Mikhail Naganova4f00e22019-07-31 14:53:29 -0700952std::string AudioMixer::trackNames() const {
953 std::stringstream ss;
954 for (const auto &pair : mTracks) {
955 ss << pair.first << " ";
956 }
957 return ss.str();
958}
959
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800960void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700961{
Andy Hung1bc088a2018-02-09 15:57:31 -0800962 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800963 const std::shared_ptr<Track> &track = mTracks[name];
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700964
Andy Hung8ed196a2018-01-05 13:21:11 -0800965 if (track->mInputBufferProvider == bufferProvider) {
Andy Hung1d26ddf2014-05-29 15:53:09 -0700966 return; // don't reset any buffer providers if identical.
967 }
Andy Hung3a34df92018-08-21 12:32:30 -0700968 // reset order from downstream to upstream buffer providers.
969 if (track->mTimestretchBufferProvider.get() != nullptr) {
970 track->mTimestretchBufferProvider->reset();
Andy Hung8ed196a2018-01-05 13:21:11 -0800971 } else if (track->mPostDownmixReformatBufferProvider.get() != nullptr) {
972 track->mPostDownmixReformatBufferProvider->reset();
Andy Hung3a34df92018-08-21 12:32:30 -0700973 } else if (track->mDownmixerBufferProvider != nullptr) {
974 track->mDownmixerBufferProvider->reset();
975 } else if (track->mReformatBufferProvider.get() != nullptr) {
976 track->mReformatBufferProvider->reset();
jiabinea8fa7a2019-02-22 14:41:50 -0800977 } else if (track->mContractChannelsNonDestructiveBufferProvider.get() != nullptr) {
978 track->mContractChannelsNonDestructiveBufferProvider->reset();
jiabindce8f8c2018-12-10 17:49:31 -0800979 } else if (track->mAdjustChannelsBufferProvider.get() != nullptr) {
980 track->mAdjustChannelsBufferProvider->reset();
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700981 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700982
Andy Hung8ed196a2018-01-05 13:21:11 -0800983 track->mInputBufferProvider = bufferProvider;
984 track->reconfigureBufferProviders();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700985}
986
Andy Hung8ed196a2018-01-05 13:21:11 -0800987void AudioMixer::process__validate()
Mathias Agopian65ab4712010-07-14 17:59:35 -0700988{
Andy Hung395db4b2014-08-25 17:15:29 -0700989 // TODO: fix all16BitsStereNoResample logic to
990 // either properly handle muted tracks (it should ignore them)
991 // or remove altogether as an obsolete optimization.
Glenn Kasten4c340c62012-01-27 12:33:54 -0800992 bool all16BitsStereoNoResample = true;
993 bool resampling = false;
994 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700995
Andy Hung8ed196a2018-01-05 13:21:11 -0800996 mEnabled.clear();
997 mGroups.clear();
998 for (const auto &pair : mTracks) {
999 const int name = pair.first;
1000 const std::shared_ptr<Track> &t = pair.second;
1001 if (!t->enabled) continue;
1002
1003 mEnabled.emplace_back(name); // we add to mEnabled in order of name.
1004 mGroups[t->mainBuffer].emplace_back(name); // mGroups also in order of name.
1005
Mathias Agopian65ab4712010-07-14 17:59:35 -07001006 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001007 // FIXME can overflow (mask is only 3 bits)
Andy Hung8ed196a2018-01-05 13:21:11 -08001008 n |= NEEDS_CHANNEL_1 + t->channelCount - 1;
1009 if (t->doesResample()) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001010 n |= NEEDS_RESAMPLE;
1011 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001012 if (t->auxLevel != 0 && t->auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001013 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001014 }
1015
Andy Hung8ed196a2018-01-05 13:21:11 -08001016 if (t->volumeInc[0]|t->volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001017 volumeRamp = true;
Andy Hung8ed196a2018-01-05 13:21:11 -08001018 } else if (!t->doesResample() && t->volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001019 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001020 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001021 t->needs = n;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001022
Glenn Kastend6fadf02013-10-30 14:37:29 -07001023 if (n & NEEDS_MUTE) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001024 t->hook = &Track::track__nop;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001025 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001026 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001027 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001028 }
Glenn Kastend6fadf02013-10-30 14:37:29 -07001029 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001030 all16BitsStereoNoResample = false;
1031 resampling = true;
Andy Hung8ed196a2018-01-05 13:21:11 -08001032 t->hook = Track::getTrackHook(TRACKTYPE_RESAMPLE, t->mMixerChannelCount,
1033 t->mMixerInFormat, t->mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001034 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Chih-Hung Hsieh09f9c022018-07-27 10:22:35 -07001035 "Track %d needs downmix + resample", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001036 } else {
1037 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
Andy Hung8ed196a2018-01-05 13:21:11 -08001038 t->hook = Track::getTrackHook(
1039 (t->mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO // TODO: MONO_HACK
1040 && t->channelMask == AUDIO_CHANNEL_OUT_MONO)
Andy Hunge93b6b72014-07-17 21:30:53 -07001041 ? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,
Andy Hung8ed196a2018-01-05 13:21:11 -08001042 t->mMixerChannelCount,
1043 t->mMixerInFormat, t->mMixerFormat);
Glenn Kasten4c340c62012-01-27 12:33:54 -08001044 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001045 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001046 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Andy Hung8ed196a2018-01-05 13:21:11 -08001047 t->hook = Track::getTrackHook(TRACKTYPE_NORESAMPLE, t->mMixerChannelCount,
1048 t->mMixerInFormat, t->mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001049 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Chih-Hung Hsieh09f9c022018-07-27 10:22:35 -07001050 "Track %d needs downmix", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001051 }
1052 }
1053 }
1054 }
1055
1056 // select the processing hooks
Andy Hung8ed196a2018-01-05 13:21:11 -08001057 mHook = &AudioMixer::process__nop;
1058 if (mEnabled.size() > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001059 if (resampling) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001060 if (mOutputTemp.get() == nullptr) {
1061 mOutputTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001062 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001063 if (mResampleTemp.get() == nullptr) {
1064 mResampleTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001065 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001066 mHook = &AudioMixer::process__genericResampling;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001067 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001068 // we keep temp arrays around.
1069 mHook = &AudioMixer::process__genericNoResampling;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001070 if (all16BitsStereoNoResample && !volumeRamp) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001071 if (mEnabled.size() == 1) {
1072 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
1073 if ((t->needs & NEEDS_MUTE) == 0) {
Andy Hung395db4b2014-08-25 17:15:29 -07001074 // The check prevents a muted track from acquiring a process hook.
1075 //
1076 // This is dangerous if the track is MONO as that requires
1077 // special case handling due to implicit channel duplication.
1078 // Stereo or Multichannel should actually be fine here.
Andy Hung8ed196a2018-01-05 13:21:11 -08001079 mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
1080 t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
Andy Hung395db4b2014-08-25 17:15:29 -07001081 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001082 }
1083 }
1084 }
1085 }
1086
Andy Hung8ed196a2018-01-05 13:21:11 -08001087 ALOGV("mixer configuration change: %zu "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001088 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001089 mEnabled.size(), all16BitsStereoNoResample, resampling, volumeRamp);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001090
Mikhail Naganova4f00e22019-07-31 14:53:29 -07001091 process();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001092
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001093 // Now that the volume ramp has been done, set optimal state and
1094 // track hooks for subsequent mixer process
Andy Hung8ed196a2018-01-05 13:21:11 -08001095 if (mEnabled.size() > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001096 bool allMuted = true;
Andy Hung8ed196a2018-01-05 13:21:11 -08001097
1098 for (const int name : mEnabled) {
1099 const std::shared_ptr<Track> &t = mTracks[name];
1100 if (!t->doesResample() && t->volumeRL == 0) {
1101 t->needs |= NEEDS_MUTE;
1102 t->hook = &Track::track__nop;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001103 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001104 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001105 }
1106 }
1107 if (allMuted) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001108 mHook = &AudioMixer::process__nop;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001109 } else if (all16BitsStereoNoResample) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001110 if (mEnabled.size() == 1) {
1111 //const int i = 31 - __builtin_clz(enabledTracks);
1112 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
Andy Hung395db4b2014-08-25 17:15:29 -07001113 // Muted single tracks handled by allMuted above.
Andy Hung8ed196a2018-01-05 13:21:11 -08001114 mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
1115 t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001116 }
1117 }
1118 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001119}
1120
Andy Hung8ed196a2018-01-05 13:21:11 -08001121void AudioMixer::Track::track__genericResample(
1122 int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001123{
Andy Hung296b7412014-06-17 15:25:47 -07001124 ALOGVV("track__genericResample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001125 mResampler->setSampleRate(sampleRate);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001126
1127 // ramp gain - resample to temp buffer and scale/mix in 2nd step
1128 if (aux != NULL) {
1129 // always resample with unity gain when sending to auxiliary buffer to be able
1130 // to apply send level after resampling
Andy Hung8ed196a2018-01-05 13:21:11 -08001131 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
1132 memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(int32_t));
1133 mResampler->resample(temp, outFrameCount, bufferProvider);
1134 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
1135 volumeRampStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001136 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001137 volumeStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001138 }
1139 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001140 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
1141 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001142 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
Andy Hung8ed196a2018-01-05 13:21:11 -08001143 mResampler->resample(temp, outFrameCount, bufferProvider);
1144 volumeRampStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001145 }
1146
1147 // constant gain
1148 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001149 mResampler->setVolume(mVolume[0], mVolume[1]);
1150 mResampler->resample(out, outFrameCount, bufferProvider);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001151 }
1152 }
1153}
1154
Andy Hung8ed196a2018-01-05 13:21:11 -08001155void AudioMixer::Track::track__nop(int32_t* out __unused,
Andy Hungee931ff2014-01-28 13:44:14 -08001156 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001157{
1158}
1159
Andy Hung8ed196a2018-01-05 13:21:11 -08001160void AudioMixer::Track::volumeRampStereo(
1161 int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001162{
Andy Hung8ed196a2018-01-05 13:21:11 -08001163 int32_t vl = prevVolume[0];
1164 int32_t vr = prevVolume[1];
1165 const int32_t vlInc = volumeInc[0];
1166 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001167
Steve Blockb8a80522011-12-20 16:23:08 +00001168 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001169 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001170 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1171
1172 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -08001173 if (CC_UNLIKELY(aux != NULL)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001174 int32_t va = prevAuxLevel;
1175 const int32_t vaInc = auxInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001176 int32_t l;
1177 int32_t r;
1178
1179 do {
1180 l = (*temp++ >> 12);
1181 r = (*temp++ >> 12);
1182 *out++ += (vl >> 16) * l;
1183 *out++ += (vr >> 16) * r;
1184 *aux++ += (va >> 17) * (l + r);
1185 vl += vlInc;
1186 vr += vrInc;
1187 va += vaInc;
1188 } while (--frameCount);
Andy Hung8ed196a2018-01-05 13:21:11 -08001189 prevAuxLevel = va;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001190 } else {
1191 do {
1192 *out++ += (vl >> 16) * (*temp++ >> 12);
1193 *out++ += (vr >> 16) * (*temp++ >> 12);
1194 vl += vlInc;
1195 vr += vrInc;
1196 } while (--frameCount);
1197 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001198 prevVolume[0] = vl;
1199 prevVolume[1] = vr;
1200 adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001201}
1202
Andy Hung8ed196a2018-01-05 13:21:11 -08001203void AudioMixer::Track::volumeStereo(
1204 int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001205{
Andy Hung8ed196a2018-01-05 13:21:11 -08001206 const int16_t vl = volume[0];
1207 const int16_t vr = volume[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001208
Glenn Kastenf6b16782011-12-15 09:51:17 -08001209 if (CC_UNLIKELY(aux != NULL)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001210 const int16_t va = auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001211 do {
1212 int16_t l = (int16_t)(*temp++ >> 12);
1213 int16_t r = (int16_t)(*temp++ >> 12);
1214 out[0] = mulAdd(l, vl, out[0]);
1215 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1216 out[1] = mulAdd(r, vr, out[1]);
1217 out += 2;
1218 aux[0] = mulAdd(a, va, aux[0]);
1219 aux++;
1220 } while (--frameCount);
1221 } else {
1222 do {
1223 int16_t l = (int16_t)(*temp++ >> 12);
1224 int16_t r = (int16_t)(*temp++ >> 12);
1225 out[0] = mulAdd(l, vl, out[0]);
1226 out[1] = mulAdd(r, vr, out[1]);
1227 out += 2;
1228 } while (--frameCount);
1229 }
1230}
1231
Andy Hung8ed196a2018-01-05 13:21:11 -08001232void AudioMixer::Track::track__16BitsStereo(
1233 int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001234{
Andy Hung296b7412014-06-17 15:25:47 -07001235 ALOGVV("track__16BitsStereo\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001236 const int16_t *in = static_cast<const int16_t *>(mIn);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001237
Glenn Kastenf6b16782011-12-15 09:51:17 -08001238 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001239 int32_t l;
1240 int32_t r;
1241 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001242 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
1243 int32_t vl = prevVolume[0];
1244 int32_t vr = prevVolume[1];
1245 int32_t va = prevAuxLevel;
1246 const int32_t vlInc = volumeInc[0];
1247 const int32_t vrInc = volumeInc[1];
1248 const int32_t vaInc = auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001249 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001250 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001251 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1252
1253 do {
1254 l = (int32_t)*in++;
1255 r = (int32_t)*in++;
1256 *out++ += (vl >> 16) * l;
1257 *out++ += (vr >> 16) * r;
1258 *aux++ += (va >> 17) * (l + r);
1259 vl += vlInc;
1260 vr += vrInc;
1261 va += vaInc;
1262 } while (--frameCount);
1263
Andy Hung8ed196a2018-01-05 13:21:11 -08001264 prevVolume[0] = vl;
1265 prevVolume[1] = vr;
1266 prevAuxLevel = va;
1267 adjustVolumeRamp(true);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001268 }
1269
1270 // constant gain
1271 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001272 const uint32_t vrl = volumeRL;
1273 const int16_t va = (int16_t)auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001274 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001275 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001276 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1277 in += 2;
1278 out[0] = mulAddRL(1, rl, vrl, out[0]);
1279 out[1] = mulAddRL(0, rl, vrl, out[1]);
1280 out += 2;
1281 aux[0] = mulAdd(a, va, aux[0]);
1282 aux++;
1283 } while (--frameCount);
1284 }
1285 } else {
1286 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001287 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
1288 int32_t vl = prevVolume[0];
1289 int32_t vr = prevVolume[1];
1290 const int32_t vlInc = volumeInc[0];
1291 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001292
Steve Blockb8a80522011-12-20 16:23:08 +00001293 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001294 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001295 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1296
1297 do {
1298 *out++ += (vl >> 16) * (int32_t) *in++;
1299 *out++ += (vr >> 16) * (int32_t) *in++;
1300 vl += vlInc;
1301 vr += vrInc;
1302 } while (--frameCount);
1303
Andy Hung8ed196a2018-01-05 13:21:11 -08001304 prevVolume[0] = vl;
1305 prevVolume[1] = vr;
1306 adjustVolumeRamp(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001307 }
1308
1309 // constant gain
1310 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001311 const uint32_t vrl = volumeRL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001312 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001313 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001314 in += 2;
1315 out[0] = mulAddRL(1, rl, vrl, out[0]);
1316 out[1] = mulAddRL(0, rl, vrl, out[1]);
1317 out += 2;
1318 } while (--frameCount);
1319 }
1320 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001321 mIn = in;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001322}
1323
Andy Hung8ed196a2018-01-05 13:21:11 -08001324void AudioMixer::Track::track__16BitsMono(
1325 int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001326{
Andy Hung296b7412014-06-17 15:25:47 -07001327 ALOGVV("track__16BitsMono\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001328 const int16_t *in = static_cast<int16_t const *>(mIn);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001329
Glenn Kastenf6b16782011-12-15 09:51:17 -08001330 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001331 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001332 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
1333 int32_t vl = prevVolume[0];
1334 int32_t vr = prevVolume[1];
1335 int32_t va = prevAuxLevel;
1336 const int32_t vlInc = volumeInc[0];
1337 const int32_t vrInc = volumeInc[1];
1338 const int32_t vaInc = auxInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001339
Steve Blockb8a80522011-12-20 16:23:08 +00001340 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001341 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001342 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1343
1344 do {
1345 int32_t l = *in++;
1346 *out++ += (vl >> 16) * l;
1347 *out++ += (vr >> 16) * l;
1348 *aux++ += (va >> 16) * l;
1349 vl += vlInc;
1350 vr += vrInc;
1351 va += vaInc;
1352 } while (--frameCount);
1353
Andy Hung8ed196a2018-01-05 13:21:11 -08001354 prevVolume[0] = vl;
1355 prevVolume[1] = vr;
1356 prevAuxLevel = va;
1357 adjustVolumeRamp(true);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001358 }
1359 // constant gain
1360 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001361 const int16_t vl = volume[0];
1362 const int16_t vr = volume[1];
1363 const int16_t va = (int16_t)auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001364 do {
1365 int16_t l = *in++;
1366 out[0] = mulAdd(l, vl, out[0]);
1367 out[1] = mulAdd(l, vr, out[1]);
1368 out += 2;
1369 aux[0] = mulAdd(l, va, aux[0]);
1370 aux++;
1371 } while (--frameCount);
1372 }
1373 } else {
1374 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001375 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
1376 int32_t vl = prevVolume[0];
1377 int32_t vr = prevVolume[1];
1378 const int32_t vlInc = volumeInc[0];
1379 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001380
Steve Blockb8a80522011-12-20 16:23:08 +00001381 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001382 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001383 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1384
1385 do {
1386 int32_t l = *in++;
1387 *out++ += (vl >> 16) * l;
1388 *out++ += (vr >> 16) * l;
1389 vl += vlInc;
1390 vr += vrInc;
1391 } while (--frameCount);
1392
Andy Hung8ed196a2018-01-05 13:21:11 -08001393 prevVolume[0] = vl;
1394 prevVolume[1] = vr;
1395 adjustVolumeRamp(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001396 }
1397 // constant gain
1398 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001399 const int16_t vl = volume[0];
1400 const int16_t vr = volume[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001401 do {
1402 int16_t l = *in++;
1403 out[0] = mulAdd(l, vl, out[0]);
1404 out[1] = mulAdd(l, vr, out[1]);
1405 out += 2;
1406 } while (--frameCount);
1407 }
1408 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001409 mIn = in;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001410}
1411
Mathias Agopian65ab4712010-07-14 17:59:35 -07001412// no-op case
Andy Hung8ed196a2018-01-05 13:21:11 -08001413void AudioMixer::process__nop()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001414{
Andy Hung296b7412014-06-17 15:25:47 -07001415 ALOGVV("process__nop\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001416
1417 for (const auto &pair : mGroups) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001418 // process by group of tracks with same output buffer to
1419 // avoid multiple memset() on same buffer
Andy Hung8ed196a2018-01-05 13:21:11 -08001420 const auto &group = pair.second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001421
Andy Hung8ed196a2018-01-05 13:21:11 -08001422 const std::shared_ptr<Track> &t = mTracks[group[0]];
1423 memset(t->mainBuffer, 0,
jiabin245cdd92018-12-07 17:55:15 -08001424 mFrameCount * audio_bytes_per_frame(
1425 t->mMixerChannelCount + t->mMixerHapticChannelCount, t->mMixerFormat));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001426
Andy Hung8ed196a2018-01-05 13:21:11 -08001427 // now consume data
1428 for (const int name : group) {
1429 const std::shared_ptr<Track> &t = mTracks[name];
1430 size_t outFrames = mFrameCount;
1431 while (outFrames) {
1432 t->buffer.frameCount = outFrames;
1433 t->bufferProvider->getNextBuffer(&t->buffer);
1434 if (t->buffer.raw == NULL) break;
1435 outFrames -= t->buffer.frameCount;
1436 t->bufferProvider->releaseBuffer(&t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001437 }
1438 }
1439 }
1440}
1441
1442// generic code without resampling
Andy Hung8ed196a2018-01-05 13:21:11 -08001443void AudioMixer::process__genericNoResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001444{
Andy Hung296b7412014-06-17 15:25:47 -07001445 ALOGVV("process__genericNoResampling\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001446 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1447
Andy Hung8ed196a2018-01-05 13:21:11 -08001448 for (const auto &pair : mGroups) {
1449 // process by group of tracks with same output main buffer to
1450 // avoid multiple memset() on same buffer
1451 const auto &group = pair.second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001452
Andy Hung8ed196a2018-01-05 13:21:11 -08001453 // acquire buffer
1454 for (const int name : group) {
1455 const std::shared_ptr<Track> &t = mTracks[name];
1456 t->buffer.frameCount = mFrameCount;
1457 t->bufferProvider->getNextBuffer(&t->buffer);
1458 t->frameCount = t->buffer.frameCount;
1459 t->mIn = t->buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001460 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001461
1462 int32_t *out = (int *)pair.first;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001463 size_t numFrames = 0;
1464 do {
Andy Hung8ed196a2018-01-05 13:21:11 -08001465 const size_t frameCount = std::min((size_t)BLOCKSIZE, mFrameCount - numFrames);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001466 memset(outTemp, 0, sizeof(outTemp));
Andy Hung8ed196a2018-01-05 13:21:11 -08001467 for (const int name : group) {
1468 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001469 int32_t *aux = NULL;
Andy Hung8ed196a2018-01-05 13:21:11 -08001470 if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
1471 aux = t->auxBuffer + numFrames;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001472 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001473 for (int outFrames = frameCount; outFrames > 0; ) {
1474 // t->in == nullptr can happen if the track was flushed just after having
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301475 // been enabled for mixing.
Andy Hung8ed196a2018-01-05 13:21:11 -08001476 if (t->mIn == nullptr) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301477 break;
1478 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001479 size_t inFrames = (t->frameCount > outFrames)?outFrames:t->frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001480 if (inFrames > 0) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001481 (t.get()->*t->hook)(
1482 outTemp + (frameCount - outFrames) * t->mMixerChannelCount,
1483 inFrames, mResampleTemp.get() /* naked ptr */, aux);
1484 t->frameCount -= inFrames;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001485 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001486 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001487 aux += inFrames;
1488 }
1489 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001490 if (t->frameCount == 0 && outFrames) {
1491 t->bufferProvider->releaseBuffer(&t->buffer);
1492 t->buffer.frameCount = (mFrameCount - numFrames) -
Yahan Zhouc1c11b42018-01-16 12:44:04 -08001493 (frameCount - outFrames);
Andy Hung8ed196a2018-01-05 13:21:11 -08001494 t->bufferProvider->getNextBuffer(&t->buffer);
1495 t->mIn = t->buffer.raw;
1496 if (t->mIn == nullptr) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001497 break;
1498 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001499 t->frameCount = t->buffer.frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001500 }
1501 }
1502 }
Andy Hung296b7412014-06-17 15:25:47 -07001503
Andy Hung8ed196a2018-01-05 13:21:11 -08001504 const std::shared_ptr<Track> &t1 = mTracks[group[0]];
1505 convertMixerFormat(out, t1->mMixerFormat, outTemp, t1->mMixerInFormat,
1506 frameCount * t1->mMixerChannelCount);
Andy Hung296b7412014-06-17 15:25:47 -07001507 // TODO: fix ugly casting due to choice of out pointer type
1508 out = reinterpret_cast<int32_t*>((uint8_t*)out
Andy Hung8ed196a2018-01-05 13:21:11 -08001509 + frameCount * t1->mMixerChannelCount
1510 * audio_bytes_per_sample(t1->mMixerFormat));
Yahan Zhouc1c11b42018-01-16 12:44:04 -08001511 numFrames += frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001512 } while (numFrames < mFrameCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001513
Andy Hung8ed196a2018-01-05 13:21:11 -08001514 // release each track's buffer
1515 for (const int name : group) {
1516 const std::shared_ptr<Track> &t = mTracks[name];
1517 t->bufferProvider->releaseBuffer(&t->buffer);
1518 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001519 }
1520}
1521
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001522// generic code with resampling
Andy Hung8ed196a2018-01-05 13:21:11 -08001523void AudioMixer::process__genericResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001524{
Andy Hung296b7412014-06-17 15:25:47 -07001525 ALOGVV("process__genericResampling\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001526 int32_t * const outTemp = mOutputTemp.get(); // naked ptr
1527 size_t numFrames = mFrameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001528
Andy Hung8ed196a2018-01-05 13:21:11 -08001529 for (const auto &pair : mGroups) {
1530 const auto &group = pair.second;
1531 const std::shared_ptr<Track> &t1 = mTracks[group[0]];
1532
1533 // clear temp buffer
1534 memset(outTemp, 0, sizeof(*outTemp) * t1->mMixerChannelCount * mFrameCount);
1535 for (const int name : group) {
1536 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001537 int32_t *aux = NULL;
Andy Hung8ed196a2018-01-05 13:21:11 -08001538 if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
1539 aux = t->auxBuffer;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001540 }
1541
1542 // this is a little goofy, on the resampling case we don't
1543 // acquire/release the buffers because it's done by
1544 // the resampler.
Andy Hung8ed196a2018-01-05 13:21:11 -08001545 if (t->needs & NEEDS_RESAMPLE) {
1546 (t.get()->*t->hook)(outTemp, numFrames, mResampleTemp.get() /* naked ptr */, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001547 } else {
1548
1549 size_t outFrames = 0;
1550
1551 while (outFrames < numFrames) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001552 t->buffer.frameCount = numFrames - outFrames;
1553 t->bufferProvider->getNextBuffer(&t->buffer);
1554 t->mIn = t->buffer.raw;
1555 // t->mIn == nullptr can happen if the track was flushed just after having
Mathias Agopian65ab4712010-07-14 17:59:35 -07001556 // been enabled for mixing.
Andy Hung8ed196a2018-01-05 13:21:11 -08001557 if (t->mIn == nullptr) break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001558
Andy Hung8ed196a2018-01-05 13:21:11 -08001559 (t.get()->*t->hook)(
1560 outTemp + outFrames * t->mMixerChannelCount, t->buffer.frameCount,
Andy Hunga6018892018-02-21 14:32:16 -08001561 mResampleTemp.get() /* naked ptr */,
1562 aux != nullptr ? aux + outFrames : nullptr);
Andy Hung8ed196a2018-01-05 13:21:11 -08001563 outFrames += t->buffer.frameCount;
Andy Hunga6018892018-02-21 14:32:16 -08001564
Andy Hung8ed196a2018-01-05 13:21:11 -08001565 t->bufferProvider->releaseBuffer(&t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001566 }
1567 }
1568 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001569 convertMixerFormat(t1->mainBuffer, t1->mMixerFormat,
1570 outTemp, t1->mMixerInFormat, numFrames * t1->mMixerChannelCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001571 }
1572}
1573
1574// one track, 16 bits stereo without resampling is the most common case
Andy Hung8ed196a2018-01-05 13:21:11 -08001575void AudioMixer::process__oneTrack16BitsStereoNoResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001576{
Andy Hung8ed196a2018-01-05 13:21:11 -08001577 ALOGVV("process__oneTrack16BitsStereoNoResampling\n");
1578 LOG_ALWAYS_FATAL_IF(mEnabled.size() != 0,
1579 "%zu != 1 tracks enabled", mEnabled.size());
1580 const int name = mEnabled[0];
1581 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001582
Andy Hung8ed196a2018-01-05 13:21:11 -08001583 AudioBufferProvider::Buffer& b(t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001584
Andy Hung8ed196a2018-01-05 13:21:11 -08001585 int32_t* out = t->mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001586 float *fout = reinterpret_cast<float*>(out);
Andy Hung8ed196a2018-01-05 13:21:11 -08001587 size_t numFrames = mFrameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001588
Andy Hung8ed196a2018-01-05 13:21:11 -08001589 const int16_t vl = t->volume[0];
1590 const int16_t vr = t->volume[1];
1591 const uint32_t vrl = t->volumeRL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001592 while (numFrames) {
1593 b.frameCount = numFrames;
Andy Hung8ed196a2018-01-05 13:21:11 -08001594 t->bufferProvider->getNextBuffer(&b);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001595 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001596
1597 // in == NULL can happen if the track was flushed just after having
1598 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001599 if (in == NULL || (((uintptr_t)in) & 3)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001600 if ( AUDIO_FORMAT_PCM_FLOAT == t->mMixerFormat ) {
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001601 memset((char*)fout, 0, numFrames
Andy Hung8ed196a2018-01-05 13:21:11 -08001602 * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001603 } else {
1604 memset((char*)out, 0, numFrames
Andy Hung8ed196a2018-01-05 13:21:11 -08001605 * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001606 }
Andy Hung395db4b2014-08-25 17:15:29 -07001607 ALOGE_IF((((uintptr_t)in) & 3),
Andy Hung8ed196a2018-01-05 13:21:11 -08001608 "process__oneTrack16BitsStereoNoResampling: misaligned buffer"
Andy Hung395db4b2014-08-25 17:15:29 -07001609 " %p track %d, channels %d, needs %08x, volume %08x vfl %f vfr %f",
Andy Hung8ed196a2018-01-05 13:21:11 -08001610 in, name, t->channelCount, t->needs, vrl, t->mVolume[0], t->mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001611 return;
1612 }
1613 size_t outFrames = b.frameCount;
1614
Andy Hung8ed196a2018-01-05 13:21:11 -08001615 switch (t->mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001616 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001617 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001618 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001619 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001620 int32_t l = mulRL(1, rl, vrl);
1621 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001622 *fout++ = float_from_q4_27(l);
1623 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001624 // Note: In case of later int16_t sink output,
1625 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001626 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001627 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001628 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung97ae8242014-05-30 10:35:47 -07001629 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001630 // volume is boosted, so we might need to clamp even though
1631 // we process only one track.
1632 do {
1633 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1634 in += 2;
1635 int32_t l = mulRL(1, rl, vrl) >> 12;
1636 int32_t r = mulRL(0, rl, vrl) >> 12;
1637 // clamping...
1638 l = clamp16(l);
1639 r = clamp16(r);
1640 *out++ = (r<<16) | (l & 0xFFFF);
1641 } while (--outFrames);
1642 } else {
1643 do {
1644 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1645 in += 2;
1646 int32_t l = mulRL(1, rl, vrl) >> 12;
1647 int32_t r = mulRL(0, rl, vrl) >> 12;
1648 *out++ = (r<<16) | (l & 0xFFFF);
1649 } while (--outFrames);
1650 }
1651 break;
1652 default:
Andy Hung8ed196a2018-01-05 13:21:11 -08001653 LOG_ALWAYS_FATAL("bad mixer format: %d", t->mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001654 }
1655 numFrames -= b.frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001656 t->bufferProvider->releaseBuffer(&b);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001657 }
1658}
1659
Glenn Kasten52008f82012-03-18 09:34:41 -07001660/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1661
1662/*static*/ void AudioMixer::sInitRoutine()
1663{
Andy Hung34803d52014-07-16 21:41:35 -07001664 DownmixerBufferProvider::init(); // for the downmixer
John Grossman4ff14ba2012-02-08 16:37:41 -08001665}
1666
Andy Hunge93b6b72014-07-17 21:30:53 -07001667/* TODO: consider whether this level of optimization is necessary.
1668 * Perhaps just stick with a single for loop.
1669 */
1670
1671// Needs to derive a compile time constant (constexpr). Could be targeted to go
1672// to a MONOVOL mixtype based on MAX_NUM_VOLUMES, but that's an unnecessary complication.
Chih-Hung Hsiehbf291732016-05-17 15:16:07 -07001673#define MIXTYPE_MONOVOL(mixtype) ((mixtype) == MIXTYPE_MULTI ? MIXTYPE_MULTI_MONOVOL : \
1674 (mixtype) == MIXTYPE_MULTI_SAVEONLY ? MIXTYPE_MULTI_SAVEONLY_MONOVOL : (mixtype))
Andy Hunge93b6b72014-07-17 21:30:53 -07001675
1676/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1677 * TO: int32_t (Q4.27) or float
1678 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001679 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001680 */
1681template <int MIXTYPE,
1682 typename TO, typename TI, typename TV, typename TA, typename TAV>
1683static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
1684 const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc)
1685{
1686 switch (channels) {
1687 case 1:
1688 volumeRampMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1689 break;
1690 case 2:
1691 volumeRampMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1692 break;
1693 case 3:
1694 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out,
1695 frameCount, in, aux, vol, volinc, vola, volainc);
1696 break;
1697 case 4:
1698 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out,
1699 frameCount, in, aux, vol, volinc, vola, volainc);
1700 break;
1701 case 5:
1702 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out,
1703 frameCount, in, aux, vol, volinc, vola, volainc);
1704 break;
1705 case 6:
1706 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out,
1707 frameCount, in, aux, vol, volinc, vola, volainc);
1708 break;
1709 case 7:
1710 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out,
1711 frameCount, in, aux, vol, volinc, vola, volainc);
1712 break;
1713 case 8:
1714 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out,
1715 frameCount, in, aux, vol, volinc, vola, volainc);
1716 break;
1717 }
1718}
1719
1720/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1721 * TO: int32_t (Q4.27) or float
1722 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001723 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001724 */
1725template <int MIXTYPE,
1726 typename TO, typename TI, typename TV, typename TA, typename TAV>
1727static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
1728 const TI* in, TA* aux, const TV *vol, TAV vola)
1729{
1730 switch (channels) {
1731 case 1:
1732 volumeMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, vola);
1733 break;
1734 case 2:
1735 volumeMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, vola);
1736 break;
1737 case 3:
1738 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out, frameCount, in, aux, vol, vola);
1739 break;
1740 case 4:
1741 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out, frameCount, in, aux, vol, vola);
1742 break;
1743 case 5:
1744 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out, frameCount, in, aux, vol, vola);
1745 break;
1746 case 6:
1747 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out, frameCount, in, aux, vol, vola);
1748 break;
1749 case 7:
1750 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out, frameCount, in, aux, vol, vola);
1751 break;
1752 case 8:
1753 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out, frameCount, in, aux, vol, vola);
1754 break;
1755 }
1756}
1757
1758/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1759 * USEFLOATVOL (set to true if float volume is used)
1760 * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards)
1761 * TO: int32_t (Q4.27) or float
1762 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001763 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001764 */
1765template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001766 typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001767void AudioMixer::Track::volumeMix(TO *out, size_t outFrames,
1768 const TI *in, TA *aux, bool ramp)
Andy Hung5e58b0a2014-06-23 19:07:29 -07001769{
1770 if (USEFLOATVOL) {
1771 if (ramp) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001772 volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1773 mPrevVolume, mVolumeInc,
Andy Hung116a4982017-11-30 10:15:08 -08001774#ifdef FLOAT_AUX
Andy Hung8ed196a2018-01-05 13:21:11 -08001775 &mPrevAuxLevel, mAuxInc
Andy Hung116a4982017-11-30 10:15:08 -08001776#else
Andy Hung8ed196a2018-01-05 13:21:11 -08001777 &prevAuxLevel, auxInc
Andy Hung116a4982017-11-30 10:15:08 -08001778#endif
1779 );
Andy Hung5e58b0a2014-06-23 19:07:29 -07001780 if (ADJUSTVOL) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001781 adjustVolumeRamp(aux != NULL, true);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001782 }
1783 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001784 volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1785 mVolume,
Andy Hung116a4982017-11-30 10:15:08 -08001786#ifdef FLOAT_AUX
Andy Hung8ed196a2018-01-05 13:21:11 -08001787 mAuxLevel
Andy Hung116a4982017-11-30 10:15:08 -08001788#else
Andy Hung8ed196a2018-01-05 13:21:11 -08001789 auxLevel
Andy Hung116a4982017-11-30 10:15:08 -08001790#endif
1791 );
Andy Hung5e58b0a2014-06-23 19:07:29 -07001792 }
1793 } else {
1794 if (ramp) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001795 volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1796 prevVolume, volumeInc, &prevAuxLevel, auxInc);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001797 if (ADJUSTVOL) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001798 adjustVolumeRamp(aux != NULL);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001799 }
1800 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001801 volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1802 volume, auxLevel);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001803 }
1804 }
1805}
1806
Andy Hung296b7412014-06-17 15:25:47 -07001807/* This process hook is called when there is a single track without
1808 * aux buffer, volume ramp, or resampling.
1809 * TODO: Update the hook selection: this can properly handle aux and ramp.
Andy Hunge93b6b72014-07-17 21:30:53 -07001810 *
1811 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1812 * TO: int32_t (Q4.27) or float
1813 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1814 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07001815 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001816template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001817void AudioMixer::process__noResampleOneTrack()
Andy Hung296b7412014-06-17 15:25:47 -07001818{
Andy Hung8ed196a2018-01-05 13:21:11 -08001819 ALOGVV("process__noResampleOneTrack\n");
1820 LOG_ALWAYS_FATAL_IF(mEnabled.size() != 1,
1821 "%zu != 1 tracks enabled", mEnabled.size());
1822 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
Andy Hunge93b6b72014-07-17 21:30:53 -07001823 const uint32_t channels = t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07001824 TO* out = reinterpret_cast<TO*>(t->mainBuffer);
1825 TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
1826 const bool ramp = t->needsRamp();
1827
Andy Hung8ed196a2018-01-05 13:21:11 -08001828 for (size_t numFrames = mFrameCount; numFrames > 0; ) {
Andy Hung296b7412014-06-17 15:25:47 -07001829 AudioBufferProvider::Buffer& b(t->buffer);
1830 // get input buffer
1831 b.frameCount = numFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001832 t->bufferProvider->getNextBuffer(&b);
Andy Hung296b7412014-06-17 15:25:47 -07001833 const TI *in = reinterpret_cast<TI*>(b.raw);
1834
1835 // in == NULL can happen if the track was flushed just after having
1836 // been enabled for mixing.
1837 if (in == NULL || (((uintptr_t)in) & 3)) {
1838 memset(out, 0, numFrames
Andy Hunge93b6b72014-07-17 21:30:53 -07001839 * channels * audio_bytes_per_sample(t->mMixerFormat));
Andy Hung8ed196a2018-01-05 13:21:11 -08001840 ALOGE_IF((((uintptr_t)in) & 3), "process__noResampleOneTrack: bus error: "
Andy Hung296b7412014-06-17 15:25:47 -07001841 "buffer %p track %p, channels %d, needs %#x",
Andy Hung8ed196a2018-01-05 13:21:11 -08001842 in, &t, t->channelCount, t->needs);
Andy Hung296b7412014-06-17 15:25:47 -07001843 return;
1844 }
1845
1846 const size_t outFrames = b.frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001847 t->volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, false /* ADJUSTVOL */> (
1848 out, outFrames, in, aux, ramp);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001849
Andy Hunge93b6b72014-07-17 21:30:53 -07001850 out += outFrames * channels;
Andy Hung296b7412014-06-17 15:25:47 -07001851 if (aux != NULL) {
Andy Hunga6018892018-02-21 14:32:16 -08001852 aux += outFrames;
Andy Hung296b7412014-06-17 15:25:47 -07001853 }
1854 numFrames -= b.frameCount;
1855
1856 // release buffer
1857 t->bufferProvider->releaseBuffer(&b);
1858 }
1859 if (ramp) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001860 t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
Andy Hung296b7412014-06-17 15:25:47 -07001861 }
1862}
1863
jiabin77270b82018-12-18 15:41:29 -08001864void AudioMixer::processHapticData()
1865{
1866 // Need to keep consistent with VibrationEffect.scale(int, float, int)
1867 for (const auto &pair : mGroups) {
1868 // process by group of tracks with same output main buffer.
1869 const auto &group = pair.second;
1870 for (const int name : group) {
1871 const std::shared_ptr<Track> &t = mTracks[name];
1872 if (t->mHapticPlaybackEnabled) {
1873 size_t sampleCount = mFrameCount * t->mMixerHapticChannelCount;
1874 float gamma = t->getHapticScaleGamma();
1875 float maxAmplitudeRatio = t->getHapticMaxAmplitudeRatio();
1876 uint8_t* buffer = (uint8_t*)pair.first + mFrameCount * audio_bytes_per_frame(
1877 t->mMixerChannelCount, t->mMixerFormat);
1878 switch (t->mMixerFormat) {
1879 // Mixer format should be AUDIO_FORMAT_PCM_FLOAT.
1880 case AUDIO_FORMAT_PCM_FLOAT: {
1881 float* fout = (float*) buffer;
1882 for (size_t i = 0; i < sampleCount; i++) {
1883 float mul = fout[i] >= 0 ? 1.0 : -1.0;
1884 fout[i] = powf(fabsf(fout[i] / HAPTIC_MAX_AMPLITUDE_FLOAT), gamma)
1885 * maxAmplitudeRatio * HAPTIC_MAX_AMPLITUDE_FLOAT * mul;
1886 }
1887 } break;
1888 default:
1889 LOG_ALWAYS_FATAL("bad mMixerFormat: %#x", t->mMixerFormat);
1890 break;
1891 }
1892 break;
1893 }
1894 }
1895 }
1896}
1897
Andy Hung296b7412014-06-17 15:25:47 -07001898/* This track hook is called to do resampling then mixing,
1899 * pulling from the track's upstream AudioBufferProvider.
Andy Hunge93b6b72014-07-17 21:30:53 -07001900 *
1901 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1902 * TO: int32_t (Q4.27) or float
1903 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001904 * TA: int32_t (Q4.27) or float
Andy Hung296b7412014-06-17 15:25:47 -07001905 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001906template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001907void AudioMixer::Track::track__Resample(TO* out, size_t outFrameCount, TO* temp, TA* aux)
Andy Hung296b7412014-06-17 15:25:47 -07001908{
1909 ALOGVV("track__Resample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001910 mResampler->setSampleRate(sampleRate);
1911 const bool ramp = needsRamp();
Andy Hung296b7412014-06-17 15:25:47 -07001912 if (ramp || aux != NULL) {
1913 // if ramp: resample with unity gain to temp buffer and scale/mix in 2nd step.
1914 // if aux != NULL: resample with unity gain to temp buffer then apply send level.
1915
Andy Hung8ed196a2018-01-05 13:21:11 -08001916 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
1917 memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(TO));
1918 mResampler->resample((int32_t*)temp, outFrameCount, bufferProvider);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001919
Andy Hung116a4982017-11-30 10:15:08 -08001920 volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
Andy Hung8ed196a2018-01-05 13:21:11 -08001921 out, outFrameCount, temp, aux, ramp);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001922
Andy Hung296b7412014-06-17 15:25:47 -07001923 } else { // constant volume gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001924 mResampler->setVolume(mVolume[0], mVolume[1]);
1925 mResampler->resample((int32_t*)out, outFrameCount, bufferProvider);
Andy Hung296b7412014-06-17 15:25:47 -07001926 }
1927}
1928
1929/* This track hook is called to mix a track, when no resampling is required.
Andy Hung8ed196a2018-01-05 13:21:11 -08001930 * The input buffer should be present in in.
Andy Hunge93b6b72014-07-17 21:30:53 -07001931 *
1932 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1933 * TO: int32_t (Q4.27) or float
1934 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001935 * TA: int32_t (Q4.27) or float
Andy Hung296b7412014-06-17 15:25:47 -07001936 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001937template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001938void AudioMixer::Track::track__NoResample(TO* out, size_t frameCount, TO* temp __unused, TA* aux)
Andy Hung296b7412014-06-17 15:25:47 -07001939{
1940 ALOGVV("track__NoResample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001941 const TI *in = static_cast<const TI *>(mIn);
Andy Hung296b7412014-06-17 15:25:47 -07001942
Andy Hung116a4982017-11-30 10:15:08 -08001943 volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
Andy Hung8ed196a2018-01-05 13:21:11 -08001944 out, frameCount, in, aux, needsRamp());
Andy Hung5e58b0a2014-06-23 19:07:29 -07001945
Andy Hung296b7412014-06-17 15:25:47 -07001946 // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
1947 // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
Andy Hung8ed196a2018-01-05 13:21:11 -08001948 in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * mMixerChannelCount;
1949 mIn = in;
Andy Hung296b7412014-06-17 15:25:47 -07001950}
1951
1952/* The Mixer engine generates either int32_t (Q4_27) or float data.
1953 * We use this function to convert the engine buffers
1954 * to the desired mixer output format, either int16_t (Q.15) or float.
1955 */
Andy Hung8ed196a2018-01-05 13:21:11 -08001956/* static */
Andy Hung296b7412014-06-17 15:25:47 -07001957void AudioMixer::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
1958 void *in, audio_format_t mixerInFormat, size_t sampleCount)
1959{
1960 switch (mixerInFormat) {
1961 case AUDIO_FORMAT_PCM_FLOAT:
1962 switch (mixerOutFormat) {
1963 case AUDIO_FORMAT_PCM_FLOAT:
1964 memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
1965 break;
1966 case AUDIO_FORMAT_PCM_16_BIT:
1967 memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
1968 break;
1969 default:
1970 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1971 break;
1972 }
1973 break;
1974 case AUDIO_FORMAT_PCM_16_BIT:
1975 switch (mixerOutFormat) {
1976 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung5effdf62017-11-27 13:51:40 -08001977 memcpy_to_float_from_q4_27((float*)out, (const int32_t*)in, sampleCount);
Andy Hung296b7412014-06-17 15:25:47 -07001978 break;
1979 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung5effdf62017-11-27 13:51:40 -08001980 memcpy_to_i16_from_q4_27((int16_t*)out, (const int32_t*)in, sampleCount);
Andy Hung296b7412014-06-17 15:25:47 -07001981 break;
1982 default:
1983 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1984 break;
1985 }
1986 break;
1987 default:
1988 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1989 break;
1990 }
1991}
1992
1993/* Returns the proper track hook to use for mixing the track into the output buffer.
1994 */
Andy Hung8ed196a2018-01-05 13:21:11 -08001995/* static */
1996AudioMixer::hook_t AudioMixer::Track::getTrackHook(int trackType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001997 audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
1998{
Andy Hunge93b6b72014-07-17 21:30:53 -07001999 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07002000 switch (trackType) {
2001 case TRACKTYPE_NOP:
Andy Hung8ed196a2018-01-05 13:21:11 -08002002 return &Track::track__nop;
Andy Hung296b7412014-06-17 15:25:47 -07002003 case TRACKTYPE_RESAMPLE:
Andy Hung8ed196a2018-01-05 13:21:11 -08002004 return &Track::track__genericResample;
Andy Hung296b7412014-06-17 15:25:47 -07002005 case TRACKTYPE_NORESAMPLEMONO:
Andy Hung8ed196a2018-01-05 13:21:11 -08002006 return &Track::track__16BitsMono;
Andy Hung296b7412014-06-17 15:25:47 -07002007 case TRACKTYPE_NORESAMPLE:
Andy Hung8ed196a2018-01-05 13:21:11 -08002008 return &Track::track__16BitsStereo;
Andy Hung296b7412014-06-17 15:25:47 -07002009 default:
2010 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
2011 break;
2012 }
2013 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002014 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07002015 switch (trackType) {
2016 case TRACKTYPE_NOP:
Andy Hung8ed196a2018-01-05 13:21:11 -08002017 return &Track::track__nop;
Andy Hung296b7412014-06-17 15:25:47 -07002018 case TRACKTYPE_RESAMPLE:
2019 switch (mixerInFormat) {
2020 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002021 return (AudioMixer::hook_t) &Track::track__Resample<
Andy Hung116a4982017-11-30 10:15:08 -08002022 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002023 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002024 return (AudioMixer::hook_t) &Track::track__Resample<
Andy Hung116a4982017-11-30 10:15:08 -08002025 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002026 default:
2027 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2028 break;
2029 }
2030 break;
2031 case TRACKTYPE_NORESAMPLEMONO:
2032 switch (mixerInFormat) {
2033 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002034 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08002035 MIXTYPE_MONOEXPAND, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002036 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002037 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08002038 MIXTYPE_MONOEXPAND, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002039 default:
2040 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2041 break;
2042 }
2043 break;
2044 case TRACKTYPE_NORESAMPLE:
2045 switch (mixerInFormat) {
2046 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002047 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08002048 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002049 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002050 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08002051 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002052 default:
2053 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2054 break;
2055 }
2056 break;
2057 default:
2058 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
2059 break;
2060 }
2061 return NULL;
2062}
2063
2064/* Returns the proper process hook for mixing tracks. Currently works only for
2065 * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
Andy Hung395db4b2014-08-25 17:15:29 -07002066 *
2067 * TODO: Due to the special mixing considerations of duplicating to
2068 * a stereo output track, the input track cannot be MONO. This should be
2069 * prevented by the caller.
Andy Hung296b7412014-06-17 15:25:47 -07002070 */
Andy Hung8ed196a2018-01-05 13:21:11 -08002071/* static */
2072AudioMixer::process_hook_t AudioMixer::getProcessHook(
2073 int processType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07002074 audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
2075{
2076 if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
2077 LOG_ALWAYS_FATAL("bad processType: %d", processType);
2078 return NULL;
2079 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002080 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung8ed196a2018-01-05 13:21:11 -08002081 return &AudioMixer::process__oneTrack16BitsStereoNoResampling;
Andy Hung296b7412014-06-17 15:25:47 -07002082 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002083 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07002084 switch (mixerInFormat) {
2085 case AUDIO_FORMAT_PCM_FLOAT:
2086 switch (mixerOutFormat) {
2087 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002088 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08002089 MIXTYPE_MULTI_SAVEONLY, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002090 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002091 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08002092 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002093 default:
2094 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2095 break;
2096 }
2097 break;
2098 case AUDIO_FORMAT_PCM_16_BIT:
2099 switch (mixerOutFormat) {
2100 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002101 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08002102 MIXTYPE_MULTI_SAVEONLY, float /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002103 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002104 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08002105 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002106 default:
2107 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2108 break;
2109 }
2110 break;
2111 default:
2112 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2113 break;
2114 }
2115 return NULL;
2116}
2117
Mathias Agopian65ab4712010-07-14 17:59:35 -07002118// ----------------------------------------------------------------------------
Glenn Kasten63238ef2015-03-02 15:50:29 -08002119} // namespace android