blob: 365af75c1ce34c8f6648fff3432b683b243d2447 [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
21#include <stdint.h>
22#include <string.h>
23#include <stdlib.h>
Andy Hung5e58b0a2014-06-23 19:07:29 -070024#include <math.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070025#include <sys/types.h>
26
27#include <utils/Errors.h>
28#include <utils/Log.h>
29
Glenn Kastenf6b16782011-12-15 09:51:17 -080030#include <cutils/compiler.h>
Glenn Kasten5798d4e2012-03-08 12:18:35 -080031#include <utils/Debug.h>
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070032
33#include <system/audio.h>
34
Glenn Kasten3b21c502011-12-15 09:52:39 -080035#include <audio_utils/primitives.h>
Andy Hungef7c7fb2014-05-12 16:51:41 -070036#include <audio_utils/format.h>
Andy Hung068561c2017-01-03 17:09:32 -080037#include <media/AudioMixer.h>
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070038
Andy Hung296b7412014-06-17 15:25:47 -070039#include "AudioMixerOps.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070040
Andy Hunge93b6b72014-07-17 21:30:53 -070041// The FCC_2 macro refers to the Fixed Channel Count of 2 for the legacy integer mixer.
Andy Hung296b7412014-06-17 15:25:47 -070042#ifndef FCC_2
43#define FCC_2 2
44#endif
45
Andy Hunge93b6b72014-07-17 21:30:53 -070046// Look for MONO_HACK for any Mono hack involving legacy mono channel to
47// stereo channel conversion.
48
Andy Hung296b7412014-06-17 15:25:47 -070049/* VERY_VERY_VERBOSE_LOGGING will show exactly which process hook and track hook is
50 * being used. This is a considerable amount of log spam, so don't enable unless you
51 * are verifying the hook based code.
52 */
53//#define VERY_VERY_VERBOSE_LOGGING
54#ifdef VERY_VERY_VERBOSE_LOGGING
55#define ALOGVV ALOGV
56//define ALOGVV printf // for test-mixer.cpp
57#else
58#define ALOGVV(a...) do { } while (0)
59#endif
60
Andy Hunga08810b2014-07-16 21:53:43 -070061#ifndef ARRAY_SIZE
62#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
63#endif
64
Andy Hung5b8fde72014-09-02 21:14:34 -070065// Set kUseNewMixer to true to use the new mixer engine always. Otherwise the
66// original code will be used for stereo sinks, the new mixer for multichannel.
Andy Hung116a4982017-11-30 10:15:08 -080067static constexpr bool kUseNewMixer = true;
Andy Hung296b7412014-06-17 15:25:47 -070068
69// Set kUseFloat to true to allow floating input into the mixer engine.
70// If kUseNewMixer is false, this is ignored or may be overridden internally
71// because of downmix/upmix support.
Andy Hung116a4982017-11-30 10:15:08 -080072static constexpr bool kUseFloat = true;
73
74#ifdef FLOAT_AUX
75using TYPE_AUX = float;
76static_assert(kUseNewMixer && kUseFloat,
77 "kUseNewMixer and kUseFloat must be true for FLOAT_AUX option");
78#else
79using TYPE_AUX = int32_t; // q4.27
80#endif
Andy Hung296b7412014-06-17 15:25:47 -070081
Andy Hung1b2fdcb2014-07-16 17:44:34 -070082// Set to default copy buffer size in frames for input processing.
83static const size_t kCopyBufferFrameCount = 256;
84
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 Hung97ae8242014-05-30 10:35:47 -0700116 t->volume[0] = UNITY_GAIN_INT;
117 t->volume[1] = UNITY_GAIN_INT;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700118 t->prevVolume[0] = UNITY_GAIN_INT << 16;
119 t->prevVolume[1] = UNITY_GAIN_INT << 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.
127 t->mVolume[0] = UNITY_GAIN_FLOAT;
128 t->mVolume[1] = UNITY_GAIN_FLOAT;
129 t->mPrevVolume[0] = UNITY_GAIN_FLOAT;
130 t->mPrevVolume[1] = UNITY_GAIN_FLOAT;
131 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
Andy Hung68112fc2014-05-14 14:13:23 -0700139 t->channelCount = audio_channel_count_from_out_mask(channelMask);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700140 t->enabled = false;
Andy Hunge93b6b72014-07-17 21:30:53 -0700141 ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
Andy Hungef7c7fb2014-05-12 16:51:41 -0700142 "Non-stereo channel mask: %d\n", channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700143 t->channelMask = channelMask;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700144 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700145 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
146 t->bufferProvider = NULL;
147 t->buffer.raw = NULL;
148 // no initialization needed
149 // t->buffer.frameCount
150 t->hook = NULL;
Andy Hung8ed196a2018-01-05 13:21:11 -0800151 t->mIn = NULL;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700152 t->sampleRate = mSampleRate;
153 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
154 t->mainBuffer = NULL;
155 t->auxBuffer = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700156 t->mInputBufferProvider = NULL;
Andy Hung78820702014-02-28 16:23:02 -0800157 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700158 t->mFormat = format;
Andy Hung7f475492014-08-25 16:36:37 -0700159 t->mMixerInFormat = selectMixerInFormat(format);
160 t->mDownmixRequiresFormat = AUDIO_FORMAT_INVALID; // no format required
Andy Hunge93b6b72014-07-17 21:30:53 -0700161 t->mMixerChannelMask = audio_channel_mask_from_representation_and_bits(
162 AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
163 t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700164 t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
jiabindce8f8c2018-12-10 17:49:31 -0800165 // haptic
166 t->mAdjustInChannelCount = 0;
167 t->mAdjustOutChannelCount = 0;
168 t->mAdjustNonDestructiveInChannelCount = 0;
169 t->mAdjustNonDestructiveOutChannelCount = 0;
170 t->mKeepContractedChannels = false;
Andy Hung296b7412014-06-17 15:25:47 -0700171 // Check the downmixing (or upmixing) requirements.
Andy Hung0f451e92014-08-04 21:28:47 -0700172 status_t status = t->prepareForDownmix();
Andy Hung68112fc2014-05-14 14:13:23 -0700173 if (status != OK) {
174 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
Andy Hung1bc088a2018-02-09 15:57:31 -0800175 return BAD_VALUE;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700176 }
Andy Hung7f475492014-08-25 16:36:37 -0700177 // prepareForDownmix() may change mDownmixRequiresFormat
Andy Hung296b7412014-06-17 15:25:47 -0700178 ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
Andy Hung0f451e92014-08-04 21:28:47 -0700179 t->prepareForReformat();
jiabindce8f8c2018-12-10 17:49:31 -0800180 t->prepareForAdjustChannelsNonDestructive(mFrameCount);
181 t->prepareForAdjustChannels();
Andy Hung1bc088a2018-02-09 15:57:31 -0800182
183 mTracks[name] = t;
184 return OK;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700185 }
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800186}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700187
Andy Hunge93b6b72014-07-17 21:30:53 -0700188// Called when channel masks have changed for a track name
Andy Hung7f475492014-08-25 16:36:37 -0700189// TODO: Fix DownmixerBufferProvider not to (possibly) change mixer input format,
Andy Hunge93b6b72014-07-17 21:30:53 -0700190// which will simplify this logic.
191bool AudioMixer::setChannelMasks(int name,
192 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) {
Andy Hung1bc088a2018-02-09 15:57:31 -0800193 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800194 const std::shared_ptr<Track> &track = mTracks[name];
Andy Hunge93b6b72014-07-17 21:30:53 -0700195
Andy Hung8ed196a2018-01-05 13:21:11 -0800196 if (trackChannelMask == track->channelMask
197 && mixerChannelMask == track->mMixerChannelMask) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700198 return false; // no need to change
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700199 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700200 // always recompute for both channel masks even if only one has changed.
201 const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
202 const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
Andy Hunge93b6b72014-07-17 21:30:53 -0700203
204 ALOG_ASSERT((trackChannelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX)
205 && trackChannelCount
206 && mixerChannelCount);
Andy Hung8ed196a2018-01-05 13:21:11 -0800207 track->channelMask = trackChannelMask;
208 track->channelCount = trackChannelCount;
209 track->mMixerChannelMask = mixerChannelMask;
210 track->mMixerChannelCount = mixerChannelCount;
Andy Hunge93b6b72014-07-17 21:30:53 -0700211
212 // channel masks have changed, does this track need a downmixer?
213 // update to try using our desired format (if we aren't already using it)
Andy Hung8ed196a2018-01-05 13:21:11 -0800214 const status_t status = track->prepareForDownmix();
Andy Hunge93b6b72014-07-17 21:30:53 -0700215 ALOGE_IF(status != OK,
Andy Hung0f451e92014-08-04 21:28:47 -0700216 "prepareForDownmix error %d, track channel mask %#x, mixer channel mask %#x",
Andy Hung8ed196a2018-01-05 13:21:11 -0800217 status, track->channelMask, track->mMixerChannelMask);
Andy Hunge93b6b72014-07-17 21:30:53 -0700218
Yung Ti Su1a0ecc32018-05-07 11:09:15 +0800219 // always do reformat since channel mask changed,
220 // do it after downmix since track format may change!
221 track->prepareForReformat();
Andy Hunge93b6b72014-07-17 21:30:53 -0700222
jiabindce8f8c2018-12-10 17:49:31 -0800223 track->prepareForAdjustChannelsNonDestructive(mFrameCount);
224 track->prepareForAdjustChannels();
225
Yung Ti Sub5d11952018-05-22 22:31:14 +0800226 if (track->mResampler.get() != nullptr) {
Andy Hung7f475492014-08-25 16:36:37 -0700227 // resampler channels may have changed.
Andy Hung8ed196a2018-01-05 13:21:11 -0800228 const uint32_t resetToSampleRate = track->sampleRate;
229 track->mResampler.reset(nullptr);
230 track->sampleRate = mSampleRate; // without resampler, track rate is device sample rate.
Andy Hunge93b6b72014-07-17 21:30:53 -0700231 // recreate the resampler with updated format, channels, saved sampleRate.
Andy Hung8ed196a2018-01-05 13:21:11 -0800232 track->setResampler(resetToSampleRate /*trackSampleRate*/, mSampleRate /*devSampleRate*/);
Andy Hunge93b6b72014-07-17 21:30:53 -0700233 }
234 return true;
235}
236
Andy Hung8ed196a2018-01-05 13:21:11 -0800237void AudioMixer::Track::unprepareForDownmix() {
Andy Hung0f451e92014-08-04 21:28:47 -0700238 ALOGV("AudioMixer::unprepareForDownmix(%p)", this);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700239
Andy Hung8ed196a2018-01-05 13:21:11 -0800240 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
Andy Hung85395892017-04-25 16:47:52 -0700241 // release any buffers held by the mPostDownmixReformatBufferProvider
Andy Hung8ed196a2018-01-05 13:21:11 -0800242 // before deallocating the mDownmixerBufferProvider.
Andy Hung85395892017-04-25 16:47:52 -0700243 mPostDownmixReformatBufferProvider->reset();
244 }
245
Andy Hung7f475492014-08-25 16:36:37 -0700246 mDownmixRequiresFormat = AUDIO_FORMAT_INVALID;
Andy Hung8ed196a2018-01-05 13:21:11 -0800247 if (mDownmixerBufferProvider.get() != nullptr) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700248 // this track had previously been configured with a downmixer, delete it
Andy Hung8ed196a2018-01-05 13:21:11 -0800249 mDownmixerBufferProvider.reset(nullptr);
Andy Hung0f451e92014-08-04 21:28:47 -0700250 reconfigureBufferProviders();
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700251 } else {
252 ALOGV(" nothing to do, no downmixer to delete");
253 }
254}
255
Andy Hung8ed196a2018-01-05 13:21:11 -0800256status_t AudioMixer::Track::prepareForDownmix()
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700257{
Andy Hung0f451e92014-08-04 21:28:47 -0700258 ALOGV("AudioMixer::prepareForDownmix(%p) with mask 0x%x",
259 this, channelMask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700260
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700261 // discard the previous downmixer if there was one
Andy Hung0f451e92014-08-04 21:28:47 -0700262 unprepareForDownmix();
Andy Hung73e62e22015-04-20 12:06:38 -0700263 // MONO_HACK Only remix (upmix or downmix) if the track and mixer/device channel masks
Andy Hung0f451e92014-08-04 21:28:47 -0700264 // are not the same and not handled internally, as mono -> stereo currently is.
265 if (channelMask == mMixerChannelMask
266 || (channelMask == AUDIO_CHANNEL_OUT_MONO
267 && mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO)) {
268 return NO_ERROR;
269 }
Andy Hung650ceb92015-01-29 13:31:12 -0800270 // DownmixerBufferProvider is only used for position masks.
271 if (audio_channel_mask_get_representation(channelMask)
272 == AUDIO_CHANNEL_REPRESENTATION_POSITION
273 && DownmixerBufferProvider::isMultichannelCapable()) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800274 mDownmixerBufferProvider.reset(new DownmixerBufferProvider(channelMask,
Andy Hung0f451e92014-08-04 21:28:47 -0700275 mMixerChannelMask,
276 AUDIO_FORMAT_PCM_16_BIT /* TODO: use mMixerInFormat, now only PCM 16 */,
Andy Hung8ed196a2018-01-05 13:21:11 -0800277 sampleRate, sessionId, kCopyBufferFrameCount));
278 if (static_cast<DownmixerBufferProvider *>(mDownmixerBufferProvider.get())->isValid()) {
Andy Hung7f475492014-08-25 16:36:37 -0700279 mDownmixRequiresFormat = AUDIO_FORMAT_PCM_16_BIT; // PCM 16 bit required for downmix
Andy Hung0f451e92014-08-04 21:28:47 -0700280 reconfigureBufferProviders();
Andy Hung34803d52014-07-16 21:41:35 -0700281 return NO_ERROR;
282 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800283 // mDownmixerBufferProvider reset below.
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700284 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700285
286 // Effect downmixer does not accept the channel conversion. Let's use our remixer.
Andy Hung8ed196a2018-01-05 13:21:11 -0800287 mDownmixerBufferProvider.reset(new RemixBufferProvider(channelMask,
288 mMixerChannelMask, mMixerInFormat, kCopyBufferFrameCount));
Andy Hunge93b6b72014-07-17 21:30:53 -0700289 // Remix always finds a conversion whereas Downmixer effect above may fail.
Andy Hung0f451e92014-08-04 21:28:47 -0700290 reconfigureBufferProviders();
Andy Hunge93b6b72014-07-17 21:30:53 -0700291 return NO_ERROR;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700292}
293
Andy Hung8ed196a2018-01-05 13:21:11 -0800294void AudioMixer::Track::unprepareForReformat() {
Andy Hung0f451e92014-08-04 21:28:47 -0700295 ALOGV("AudioMixer::unprepareForReformat(%p)", this);
Andy Hung7f475492014-08-25 16:36:37 -0700296 bool requiresReconfigure = false;
Andy Hung8ed196a2018-01-05 13:21:11 -0800297 if (mReformatBufferProvider.get() != nullptr) {
298 mReformatBufferProvider.reset(nullptr);
Andy Hung7f475492014-08-25 16:36:37 -0700299 requiresReconfigure = true;
300 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800301 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
302 mPostDownmixReformatBufferProvider.reset(nullptr);
Andy Hung7f475492014-08-25 16:36:37 -0700303 requiresReconfigure = true;
304 }
305 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700306 reconfigureBufferProviders();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700307 }
308}
309
Andy Hung8ed196a2018-01-05 13:21:11 -0800310status_t AudioMixer::Track::prepareForReformat()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700311{
Andy Hung0f451e92014-08-04 21:28:47 -0700312 ALOGV("AudioMixer::prepareForReformat(%p) with format %#x", this, mFormat);
Andy Hung7f475492014-08-25 16:36:37 -0700313 // discard previous reformatters
Andy Hung0f451e92014-08-04 21:28:47 -0700314 unprepareForReformat();
Andy Hung7f475492014-08-25 16:36:37 -0700315 // only configure reformatters as needed
316 const audio_format_t targetFormat = mDownmixRequiresFormat != AUDIO_FORMAT_INVALID
317 ? mDownmixRequiresFormat : mMixerInFormat;
318 bool requiresReconfigure = false;
319 if (mFormat != targetFormat) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800320 mReformatBufferProvider.reset(new ReformatBufferProvider(
Andy Hung0f451e92014-08-04 21:28:47 -0700321 audio_channel_count_from_out_mask(channelMask),
Andy Hung7f475492014-08-25 16:36:37 -0700322 mFormat,
323 targetFormat,
Andy Hung8ed196a2018-01-05 13:21:11 -0800324 kCopyBufferFrameCount));
Andy Hung7f475492014-08-25 16:36:37 -0700325 requiresReconfigure = true;
Kevin Rocarde053bfa2017-11-09 22:07:34 -0800326 } else if (mFormat == AUDIO_FORMAT_PCM_FLOAT) {
327 // Input and output are floats, make sure application did not provide > 3db samples
328 // that would break volume application (b/68099072)
329 // TODO: add a trusted source flag to avoid the overhead
330 mReformatBufferProvider.reset(new ClampFloatBufferProvider(
331 audio_channel_count_from_out_mask(channelMask),
332 kCopyBufferFrameCount));
333 requiresReconfigure = true;
Andy Hung7f475492014-08-25 16:36:37 -0700334 }
335 if (targetFormat != mMixerInFormat) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800336 mPostDownmixReformatBufferProvider.reset(new ReformatBufferProvider(
Andy Hung7f475492014-08-25 16:36:37 -0700337 audio_channel_count_from_out_mask(mMixerChannelMask),
338 targetFormat,
339 mMixerInFormat,
Andy Hung8ed196a2018-01-05 13:21:11 -0800340 kCopyBufferFrameCount));
Andy Hung7f475492014-08-25 16:36:37 -0700341 requiresReconfigure = true;
342 }
343 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700344 reconfigureBufferProviders();
Andy Hung296b7412014-06-17 15:25:47 -0700345 }
346 return NO_ERROR;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700347}
348
jiabindce8f8c2018-12-10 17:49:31 -0800349void AudioMixer::Track::unprepareForAdjustChannels()
350{
351 ALOGV("AUDIOMIXER::unprepareForAdjustChannels");
352 if (mAdjustChannelsBufferProvider.get() != nullptr) {
353 mAdjustChannelsBufferProvider.reset(nullptr);
354 reconfigureBufferProviders();
355 }
356}
357
358status_t AudioMixer::Track::prepareForAdjustChannels()
359{
360 ALOGV("AudioMixer::prepareForAdjustChannels(%p) with inChannelCount: %u, outChannelCount: %u",
361 this, mAdjustInChannelCount, mAdjustOutChannelCount);
362 unprepareForAdjustChannels();
363 if (mAdjustInChannelCount != mAdjustOutChannelCount) {
364 mAdjustChannelsBufferProvider.reset(new AdjustChannelsBufferProvider(
365 mFormat, mAdjustInChannelCount, mAdjustOutChannelCount, kCopyBufferFrameCount));
366 reconfigureBufferProviders();
367 }
368 return NO_ERROR;
369}
370
371void AudioMixer::Track::unprepareForAdjustChannelsNonDestructive()
372{
373 ALOGV("AUDIOMIXER::unprepareForAdjustChannelsNonDestructive");
374 if (mAdjustChannelsNonDestructiveBufferProvider.get() != nullptr) {
375 mAdjustChannelsNonDestructiveBufferProvider.reset(nullptr);
376 reconfigureBufferProviders();
377 }
378}
379
380status_t AudioMixer::Track::prepareForAdjustChannelsNonDestructive(size_t frames)
381{
382 ALOGV("AudioMixer::prepareForAdjustChannelsNonDestructive(%p) with inChannelCount: %u, "
383 "outChannelCount: %u, keepContractedChannels: %d",
384 this, mAdjustNonDestructiveInChannelCount, mAdjustNonDestructiveOutChannelCount,
385 mKeepContractedChannels);
386 unprepareForAdjustChannelsNonDestructive();
387 if (mAdjustNonDestructiveInChannelCount != mAdjustNonDestructiveOutChannelCount) {
388 uint8_t* buffer = mKeepContractedChannels
389 ? (uint8_t*)mainBuffer + frames * audio_bytes_per_frame(
390 mMixerChannelCount, mMixerFormat)
391 : NULL;
392 mAdjustChannelsNonDestructiveBufferProvider.reset(
393 new AdjustChannelsNonDestructiveBufferProvider(
394 mFormat,
395 mAdjustNonDestructiveInChannelCount,
396 mAdjustNonDestructiveOutChannelCount,
397 mKeepContractedChannels ? mMixerFormat : AUDIO_FORMAT_INVALID,
398 frames,
399 buffer));
400 reconfigureBufferProviders();
401 }
402 return NO_ERROR;
403}
404
405void AudioMixer::Track::clearContractedBuffer()
406{
407 if (mAdjustChannelsNonDestructiveBufferProvider.get() != nullptr) {
408 static_cast<AdjustChannelsNonDestructiveBufferProvider*>(
409 mAdjustChannelsNonDestructiveBufferProvider.get())->clearContractedFrames();
410 }
411}
412
Andy Hung8ed196a2018-01-05 13:21:11 -0800413void AudioMixer::Track::reconfigureBufferProviders()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700414{
Andy Hung3a34df92018-08-21 12:32:30 -0700415 // configure from upstream to downstream buffer providers.
Andy Hung0f451e92014-08-04 21:28:47 -0700416 bufferProvider = mInputBufferProvider;
jiabindce8f8c2018-12-10 17:49:31 -0800417 if (mAdjustChannelsBufferProvider.get() != nullptr) {
418 mAdjustChannelsBufferProvider->setBufferProvider(bufferProvider);
419 bufferProvider = mAdjustChannelsBufferProvider.get();
420 }
421 if (mAdjustChannelsNonDestructiveBufferProvider.get() != nullptr) {
422 mAdjustChannelsNonDestructiveBufferProvider->setBufferProvider(bufferProvider);
423 bufferProvider = mAdjustChannelsNonDestructiveBufferProvider.get();
424 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800425 if (mReformatBufferProvider.get() != nullptr) {
Andy Hung0f451e92014-08-04 21:28:47 -0700426 mReformatBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800427 bufferProvider = mReformatBufferProvider.get();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700428 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800429 if (mDownmixerBufferProvider.get() != nullptr) {
430 mDownmixerBufferProvider->setBufferProvider(bufferProvider);
431 bufferProvider = mDownmixerBufferProvider.get();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700432 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800433 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
Andy Hung7f475492014-08-25 16:36:37 -0700434 mPostDownmixReformatBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800435 bufferProvider = mPostDownmixReformatBufferProvider.get();
Andy Hung7f475492014-08-25 16:36:37 -0700436 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800437 if (mTimestretchBufferProvider.get() != nullptr) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700438 mTimestretchBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800439 bufferProvider = mTimestretchBufferProvider.get();
Andy Hungc5656cc2015-03-26 19:04:33 -0700440 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700441}
442
Andy Hung1bc088a2018-02-09 15:57:31 -0800443void AudioMixer::destroy(int name)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800444{
Andy Hung1bc088a2018-02-09 15:57:31 -0800445 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800446 ALOGV("deleteTrackName(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800447
448 if (mTracks[name]->enabled) {
449 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700450 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800451 mTracks.erase(name); // deallocate track
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800452}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700453
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800454void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700455{
Andy Hung1bc088a2018-02-09 15:57:31 -0800456 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800457 const std::shared_ptr<Track> &track = mTracks[name];
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800458
Andy Hung8ed196a2018-01-05 13:21:11 -0800459 if (!track->enabled) {
460 track->enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800461 ALOGV("enable(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800462 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700463 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700464}
465
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800466void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700467{
Andy Hung1bc088a2018-02-09 15:57:31 -0800468 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800469 const std::shared_ptr<Track> &track = mTracks[name];
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800470
Andy Hung8ed196a2018-01-05 13:21:11 -0800471 if (track->enabled) {
472 track->enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800473 ALOGV("disable(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800474 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700475 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700476}
477
Andy Hung5866a3b2014-05-29 21:33:13 -0700478/* Sets the volume ramp variables for the AudioMixer.
479 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700480 * The volume ramp variables are used to transition from the previous
481 * volume to the set volume. ramp controls the duration of the transition.
482 * Its value is typically one state framecount period, but may also be 0,
483 * meaning "immediate."
Andy Hung5866a3b2014-05-29 21:33:13 -0700484 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700485 * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
486 * even if there is a nonzero floating point increment (in that case, the volume
487 * change is immediate). This restriction should be changed when the legacy mixer
488 * is removed (see #2).
489 * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
490 * when no longer needed.
491 *
492 * @param newVolume set volume target in floating point [0.0, 1.0].
493 * @param ramp number of frames to increment over. if ramp is 0, the volume
494 * should be set immediately. Currently ramp should not exceed 65535 (frames).
495 * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
496 * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
497 * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
498 * @param pSetVolume pointer to the float target volume, set on return.
499 * @param pPrevVolume pointer to the float previous volume, set on return.
500 * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
Andy Hung5866a3b2014-05-29 21:33:13 -0700501 * @return true if the volume has changed, false if volume is same.
502 */
Andy Hung5e58b0a2014-06-23 19:07:29 -0700503static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
504 int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
505 float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
Andy Hunge09c9942015-05-08 16:58:13 -0700506 // check floating point volume to see if it is identical to the previously
507 // set volume.
508 // We do not use a tolerance here (and reject changes too small)
509 // as it may be confusing to use a different value than the one set.
510 // If the resulting volume is too small to ramp, it is a direct set of the volume.
Andy Hung5e58b0a2014-06-23 19:07:29 -0700511 if (newVolume == *pSetVolume) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700512 return false;
513 }
Andy Hunge09c9942015-05-08 16:58:13 -0700514 if (newVolume < 0) {
515 newVolume = 0; // should not have negative volumes
Andy Hung5866a3b2014-05-29 21:33:13 -0700516 } else {
Andy Hunge09c9942015-05-08 16:58:13 -0700517 switch (fpclassify(newVolume)) {
518 case FP_SUBNORMAL:
519 case FP_NAN:
520 newVolume = 0;
521 break;
522 case FP_ZERO:
523 break; // zero volume is fine
524 case FP_INFINITE:
525 // Infinite volume could be handled consistently since
526 // floating point math saturates at infinities,
527 // but we limit volume to unity gain float.
528 // ramp = 0; break;
529 //
530 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
531 break;
532 case FP_NORMAL:
533 default:
534 // Floating point does not have problems with overflow wrap
535 // that integer has. However, we limit the volume to
536 // unity gain here.
537 // TODO: Revisit the volume limitation and perhaps parameterize.
538 if (newVolume > AudioMixer::UNITY_GAIN_FLOAT) {
539 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
540 }
541 break;
542 }
Andy Hung5866a3b2014-05-29 21:33:13 -0700543 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700544
Andy Hunge09c9942015-05-08 16:58:13 -0700545 // set floating point volume ramp
546 if (ramp != 0) {
547 // when the ramp completes, *pPrevVolume is set to *pSetVolume, so there
548 // is no computational mismatch; hence equality is checked here.
549 ALOGD_IF(*pPrevVolume != *pSetVolume, "previous float ramp hasn't finished,"
550 " prev:%f set_to:%f", *pPrevVolume, *pSetVolume);
551 const float inc = (newVolume - *pPrevVolume) / ramp; // could be inf, nan, subnormal
Andy Hung8ed196a2018-01-05 13:21:11 -0800552 // could be inf, cannot be nan, subnormal
553 const float maxv = std::max(newVolume, *pPrevVolume);
Andy Hunge09c9942015-05-08 16:58:13 -0700554
555 if (isnormal(inc) // inc must be a normal number (no subnormals, infinite, nan)
556 && maxv + inc != maxv) { // inc must make forward progress
557 *pVolumeInc = inc;
558 // ramp is set now.
559 // Note: if newVolume is 0, then near the end of the ramp,
560 // it may be possible that the ramped volume may be subnormal or
561 // temporarily negative by a small amount or subnormal due to floating
562 // point inaccuracies.
563 } else {
564 ramp = 0; // ramp not allowed
565 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700566 }
Andy Hunge09c9942015-05-08 16:58:13 -0700567
568 // compute and check integer volume, no need to check negative values
569 // The integer volume is limited to "unity_gain" to avoid wrapping and other
570 // audio artifacts, so it never reaches the range limit of U4.28.
571 // We safely use signed 16 and 32 bit integers here.
572 const float scaledVolume = newVolume * AudioMixer::UNITY_GAIN_INT; // not neg, subnormal, nan
573 const int32_t intVolume = (scaledVolume >= (float)AudioMixer::UNITY_GAIN_INT) ?
574 AudioMixer::UNITY_GAIN_INT : (int32_t)scaledVolume;
575
576 // set integer volume ramp
577 if (ramp != 0) {
578 // integer volume is U4.12 (to use 16 bit multiplies), but ramping uses U4.28.
579 // when the ramp completes, *pIntPrevVolume is set to *pIntSetVolume << 16, so there
580 // is no computational mismatch; hence equality is checked here.
581 ALOGD_IF(*pIntPrevVolume != *pIntSetVolume << 16, "previous int ramp hasn't finished,"
582 " prev:%d set_to:%d", *pIntPrevVolume, *pIntSetVolume << 16);
583 const int32_t inc = ((intVolume << 16) - *pIntPrevVolume) / ramp;
584
585 if (inc != 0) { // inc must make forward progress
586 *pIntVolumeInc = inc;
587 } else {
588 ramp = 0; // ramp not allowed
589 }
590 }
591
592 // if no ramp, or ramp not allowed, then clear float and integer increments
593 if (ramp == 0) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700594 *pVolumeInc = 0;
595 *pPrevVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700596 *pIntVolumeInc = 0;
597 *pIntPrevVolume = intVolume << 16;
598 }
Andy Hunge09c9942015-05-08 16:58:13 -0700599 *pSetVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700600 *pIntSetVolume = intVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700601 return true;
602}
603
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800604void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700605{
Andy Hung1bc088a2018-02-09 15:57:31 -0800606 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800607 const std::shared_ptr<Track> &track = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700608
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000609 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
610 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700611
612 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700613
Mathias Agopian65ab4712010-07-14 17:59:35 -0700614 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800615 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700616 case CHANNEL_MASK: {
Andy Hunge93b6b72014-07-17 21:30:53 -0700617 const audio_channel_mask_t trackChannelMask =
618 static_cast<audio_channel_mask_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800619 if (setChannelMasks(name, trackChannelMask, track->mMixerChannelMask)) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700620 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
Andy Hung8ed196a2018-01-05 13:21:11 -0800621 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700622 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700623 } break;
624 case MAIN_BUFFER:
Andy Hung8ed196a2018-01-05 13:21:11 -0800625 if (track->mainBuffer != valueBuf) {
626 track->mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100627 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
jiabindce8f8c2018-12-10 17:49:31 -0800628 if (track->mKeepContractedChannels) {
629 track->prepareForAdjustChannelsNonDestructive(mFrameCount);
630 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800631 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700632 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700633 break;
634 case AUX_BUFFER:
Andy Hung8ed196a2018-01-05 13:21:11 -0800635 if (track->auxBuffer != valueBuf) {
636 track->auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100637 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Andy Hung8ed196a2018-01-05 13:21:11 -0800638 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700639 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700640 break;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700641 case FORMAT: {
642 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800643 if (track->mFormat != format) {
Andy Hungef7c7fb2014-05-12 16:51:41 -0700644 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
Andy Hung8ed196a2018-01-05 13:21:11 -0800645 track->mFormat = format;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700646 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
Andy Hung8ed196a2018-01-05 13:21:11 -0800647 track->prepareForReformat();
648 invalidate();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700649 }
650 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700651 // FIXME do we want to support setting the downmix type from AudioFlinger?
652 // for a specific track? or per mixer?
653 /* case DOWNMIX_TYPE:
654 break */
Andy Hung78820702014-02-28 16:23:02 -0800655 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800656 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800657 if (track->mMixerFormat != format) {
658 track->mMixerFormat = format;
Andy Hung78820702014-02-28 16:23:02 -0800659 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
jiabindce8f8c2018-12-10 17:49:31 -0800660 if (track->mKeepContractedChannels) {
661 track->prepareForAdjustChannelsNonDestructive(mFrameCount);
662 }
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800663 }
664 } break;
Andy Hunge93b6b72014-07-17 21:30:53 -0700665 case MIXER_CHANNEL_MASK: {
666 const audio_channel_mask_t mixerChannelMask =
667 static_cast<audio_channel_mask_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800668 if (setChannelMasks(name, track->channelMask, mixerChannelMask)) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700669 ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
Andy Hung8ed196a2018-01-05 13:21:11 -0800670 invalidate();
Andy Hunge93b6b72014-07-17 21:30:53 -0700671 }
672 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700673 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800674 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700675 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700676 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700677
Mathias Agopian65ab4712010-07-14 17:59:35 -0700678 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800679 switch (param) {
680 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800681 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800682 if (track->setResampler(uint32_t(valueInt), mSampleRate)) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700683 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
684 uint32_t(valueInt));
Andy Hung8ed196a2018-01-05 13:21:11 -0800685 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700686 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800687 break;
688 case RESET:
Andy Hung8ed196a2018-01-05 13:21:11 -0800689 track->resetResampler();
690 invalidate();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800691 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700692 case REMOVE:
Andy Hung8ed196a2018-01-05 13:21:11 -0800693 track->mResampler.reset(nullptr);
694 track->sampleRate = mSampleRate;
695 invalidate();
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700696 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700697 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800698 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800699 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700700 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700701
Mathias Agopian65ab4712010-07-14 17:59:35 -0700702 case RAMP_VOLUME:
703 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800704 switch (param) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800705 case AUXLEVEL:
Andy Hung6be49402014-05-30 10:42:03 -0700706 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung8ed196a2018-01-05 13:21:11 -0800707 target == RAMP_VOLUME ? mFrameCount : 0,
708 &track->auxLevel, &track->prevAuxLevel, &track->auxInc,
709 &track->mAuxLevel, &track->mPrevAuxLevel, &track->mAuxInc)) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700710 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
Andy Hung8ed196a2018-01-05 13:21:11 -0800711 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track->auxLevel);
712 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700713 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800714 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700715 default:
Andy Hunge93b6b72014-07-17 21:30:53 -0700716 if ((unsigned)param >= VOLUME0 && (unsigned)param < VOLUME0 + MAX_NUM_VOLUMES) {
717 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung8ed196a2018-01-05 13:21:11 -0800718 target == RAMP_VOLUME ? mFrameCount : 0,
719 &track->volume[param - VOLUME0],
720 &track->prevVolume[param - VOLUME0],
721 &track->volumeInc[param - VOLUME0],
722 &track->mVolume[param - VOLUME0],
723 &track->mPrevVolume[param - VOLUME0],
724 &track->mVolumeInc[param - VOLUME0])) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700725 ALOGV("setParameter(%s, VOLUME%d: %04x)",
726 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
Andy Hung8ed196a2018-01-05 13:21:11 -0800727 track->volume[param - VOLUME0]);
728 invalidate();
Andy Hunge93b6b72014-07-17 21:30:53 -0700729 }
730 } else {
731 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
732 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700733 }
734 break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700735 case TIMESTRETCH:
736 switch (param) {
737 case PLAYBACK_RATE: {
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700738 const AudioPlaybackRate *playbackRate =
739 reinterpret_cast<AudioPlaybackRate*>(value);
Ricardo Garcia6c7f0622015-04-30 18:39:16 -0700740 ALOGW_IF(!isAudioPlaybackRateValid(*playbackRate),
Andy Hung8ed196a2018-01-05 13:21:11 -0800741 "bad parameters speed %f, pitch %f",
742 playbackRate->mSpeed, playbackRate->mPitch);
743 if (track->setPlaybackRate(*playbackRate)) {
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700744 ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE "
745 "%f %f %d %d",
746 playbackRate->mSpeed,
747 playbackRate->mPitch,
748 playbackRate->mStretchMode,
749 playbackRate->mFallbackMode);
Andy Hung8ed196a2018-01-05 13:21:11 -0800750 // invalidate(); (should not require reconfigure)
Andy Hungc5656cc2015-03-26 19:04:33 -0700751 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700752 } break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700753 default:
754 LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);
755 }
756 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700757
758 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800759 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700760 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700761}
762
Andy Hung8ed196a2018-01-05 13:21:11 -0800763bool AudioMixer::Track::setResampler(uint32_t trackSampleRate, uint32_t devSampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700764{
Andy Hung8ed196a2018-01-05 13:21:11 -0800765 if (trackSampleRate != devSampleRate || mResampler.get() != nullptr) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700766 if (sampleRate != trackSampleRate) {
767 sampleRate = trackSampleRate;
Andy Hung8ed196a2018-01-05 13:21:11 -0800768 if (mResampler.get() == nullptr) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700769 ALOGV("Creating resampler from track %d Hz to device %d Hz",
770 trackSampleRate, devSampleRate);
Glenn Kastenac602052012-10-01 14:04:31 -0700771 AudioResampler::src_quality quality;
772 // force lowest quality level resampler if use case isn't music or video
773 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
774 // quality level based on the initial ratio, but that could change later.
775 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
Andy Hungdb4c0312015-05-06 08:46:52 -0700776 if (isMusicRate(trackSampleRate)) {
Glenn Kastenac602052012-10-01 14:04:31 -0700777 quality = AudioResampler::DEFAULT_QUALITY;
Andy Hungdb4c0312015-05-06 08:46:52 -0700778 } else {
779 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700780 }
Andy Hung296b7412014-06-17 15:25:47 -0700781
Andy Hunge93b6b72014-07-17 21:30:53 -0700782 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
783 // but if none exists, it is the channel count (1 for mono).
Andy Hung8ed196a2018-01-05 13:21:11 -0800784 const int resamplerChannelCount = mDownmixerBufferProvider.get() != nullptr
Andy Hunge93b6b72014-07-17 21:30:53 -0700785 ? mMixerChannelCount : channelCount;
Andy Hung9a592762014-07-21 21:56:01 -0700786 ALOGVV("Creating resampler:"
787 " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
788 mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
Andy Hung8ed196a2018-01-05 13:21:11 -0800789 mResampler.reset(AudioResampler::create(
Andy Hung3348e362014-07-07 10:21:44 -0700790 mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -0700791 resamplerChannelCount,
Andy Hung8ed196a2018-01-05 13:21:11 -0800792 devSampleRate, quality));
Mathias Agopian65ab4712010-07-14 17:59:35 -0700793 }
794 return true;
795 }
796 }
797 return false;
798}
799
Andy Hung8ed196a2018-01-05 13:21:11 -0800800bool AudioMixer::Track::setPlaybackRate(const AudioPlaybackRate &playbackRate)
Andy Hungc5656cc2015-03-26 19:04:33 -0700801{
Andy Hung8ed196a2018-01-05 13:21:11 -0800802 if ((mTimestretchBufferProvider.get() == nullptr &&
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700803 fabs(playbackRate.mSpeed - mPlaybackRate.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
804 fabs(playbackRate.mPitch - mPlaybackRate.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA) ||
805 isAudioPlaybackRateEqual(playbackRate, mPlaybackRate)) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700806 return false;
807 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700808 mPlaybackRate = playbackRate;
Andy Hung8ed196a2018-01-05 13:21:11 -0800809 if (mTimestretchBufferProvider.get() == nullptr) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700810 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
811 // but if none exists, it is the channel count (1 for mono).
Andy Hung8ed196a2018-01-05 13:21:11 -0800812 const int timestretchChannelCount = mDownmixerBufferProvider.get() != nullptr
Andy Hungc5656cc2015-03-26 19:04:33 -0700813 ? mMixerChannelCount : channelCount;
Andy Hung8ed196a2018-01-05 13:21:11 -0800814 mTimestretchBufferProvider.reset(new TimestretchBufferProvider(timestretchChannelCount,
815 mMixerInFormat, sampleRate, playbackRate));
Andy Hungc5656cc2015-03-26 19:04:33 -0700816 reconfigureBufferProviders();
817 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -0800818 static_cast<TimestretchBufferProvider*>(mTimestretchBufferProvider.get())
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700819 ->setPlaybackRate(playbackRate);
Andy Hungc5656cc2015-03-26 19:04:33 -0700820 }
821 return true;
822}
823
Andy Hung5e58b0a2014-06-23 19:07:29 -0700824/* Checks to see if the volume ramp has completed and clears the increment
825 * variables appropriately.
826 *
827 * FIXME: There is code to handle int/float ramp variable switchover should it not
828 * complete within a mixer buffer processing call, but it is preferred to avoid switchover
829 * due to precision issues. The switchover code is included for legacy code purposes
830 * and can be removed once the integer volume is removed.
831 *
832 * It is not sufficient to clear only the volumeInc integer variable because
833 * if one channel requires ramping, all channels are ramped.
834 *
835 * There is a bit of duplicated code here, but it keeps backward compatibility.
836 */
Andy Hung8ed196a2018-01-05 13:21:11 -0800837inline void AudioMixer::Track::adjustVolumeRamp(bool aux, bool useFloat)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700838{
Andy Hung5e58b0a2014-06-23 19:07:29 -0700839 if (useFloat) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700840 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Eric Laurent43412fc2015-05-08 16:14:36 -0700841 if ((mVolumeInc[i] > 0 && mPrevVolume[i] + mVolumeInc[i] >= mVolume[i]) ||
842 (mVolumeInc[i] < 0 && mPrevVolume[i] + mVolumeInc[i] <= mVolume[i])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700843 volumeInc[i] = 0;
844 prevVolume[i] = volume[i] << 16;
845 mVolumeInc[i] = 0.;
846 mPrevVolume[i] = mVolume[i];
Andy Hung5e58b0a2014-06-23 19:07:29 -0700847 } else {
848 //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
849 prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
850 }
851 }
852 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -0700853 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700854 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
855 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
856 volumeInc[i] = 0;
857 prevVolume[i] = volume[i] << 16;
858 mVolumeInc[i] = 0.;
859 mPrevVolume[i] = mVolume[i];
860 } else {
861 //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
862 mPrevVolume[i] = float_from_u4_28(prevVolume[i]);
863 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700864 }
865 }
Andy Hung116a4982017-11-30 10:15:08 -0800866
Mathias Agopian65ab4712010-07-14 17:59:35 -0700867 if (aux) {
Andy Hung116a4982017-11-30 10:15:08 -0800868#ifdef FLOAT_AUX
869 if (useFloat) {
870 if ((mAuxInc > 0.f && mPrevAuxLevel + mAuxInc >= mAuxLevel) ||
871 (mAuxInc < 0.f && mPrevAuxLevel + mAuxInc <= mAuxLevel)) {
872 auxInc = 0;
873 prevAuxLevel = auxLevel << 16;
874 mAuxInc = 0.f;
875 mPrevAuxLevel = mAuxLevel;
876 }
877 } else
878#endif
879 if ((auxInc > 0 && ((prevAuxLevel + auxInc) >> 16) >= auxLevel) ||
880 (auxInc < 0 && ((prevAuxLevel + auxInc) >> 16) <= auxLevel)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700881 auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700882 prevAuxLevel = auxLevel << 16;
Andy Hung116a4982017-11-30 10:15:08 -0800883 mAuxInc = 0.f;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700884 mPrevAuxLevel = mAuxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700885 }
886 }
887}
888
Glenn Kastenc59c0042012-02-02 14:06:11 -0800889size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800890{
Andy Hung8ed196a2018-01-05 13:21:11 -0800891 const auto it = mTracks.find(name);
892 if (it != mTracks.end()) {
893 return it->second->getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800894 }
895 return 0;
896}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700897
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800898void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700899{
Andy Hung1bc088a2018-02-09 15:57:31 -0800900 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800901 const std::shared_ptr<Track> &track = mTracks[name];
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700902
Andy Hung8ed196a2018-01-05 13:21:11 -0800903 if (track->mInputBufferProvider == bufferProvider) {
Andy Hung1d26ddf2014-05-29 15:53:09 -0700904 return; // don't reset any buffer providers if identical.
905 }
Andy Hung3a34df92018-08-21 12:32:30 -0700906 // reset order from downstream to upstream buffer providers.
907 if (track->mTimestretchBufferProvider.get() != nullptr) {
908 track->mTimestretchBufferProvider->reset();
Andy Hung8ed196a2018-01-05 13:21:11 -0800909 } else if (track->mPostDownmixReformatBufferProvider.get() != nullptr) {
910 track->mPostDownmixReformatBufferProvider->reset();
Andy Hung3a34df92018-08-21 12:32:30 -0700911 } else if (track->mDownmixerBufferProvider != nullptr) {
912 track->mDownmixerBufferProvider->reset();
913 } else if (track->mReformatBufferProvider.get() != nullptr) {
914 track->mReformatBufferProvider->reset();
jiabindce8f8c2018-12-10 17:49:31 -0800915 } else if (track->mAdjustChannelsNonDestructiveBufferProvider.get() != nullptr) {
916 track->mAdjustChannelsNonDestructiveBufferProvider->reset();
917 } else if (track->mAdjustChannelsBufferProvider.get() != nullptr) {
918 track->mAdjustChannelsBufferProvider->reset();
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700919 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700920
Andy Hung8ed196a2018-01-05 13:21:11 -0800921 track->mInputBufferProvider = bufferProvider;
922 track->reconfigureBufferProviders();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700923}
924
Andy Hung8ed196a2018-01-05 13:21:11 -0800925void AudioMixer::process__validate()
Mathias Agopian65ab4712010-07-14 17:59:35 -0700926{
Andy Hung395db4b2014-08-25 17:15:29 -0700927 // TODO: fix all16BitsStereNoResample logic to
928 // either properly handle muted tracks (it should ignore them)
929 // or remove altogether as an obsolete optimization.
Glenn Kasten4c340c62012-01-27 12:33:54 -0800930 bool all16BitsStereoNoResample = true;
931 bool resampling = false;
932 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700933
Andy Hung8ed196a2018-01-05 13:21:11 -0800934 mEnabled.clear();
935 mGroups.clear();
936 for (const auto &pair : mTracks) {
937 const int name = pair.first;
938 const std::shared_ptr<Track> &t = pair.second;
939 if (!t->enabled) continue;
940
941 mEnabled.emplace_back(name); // we add to mEnabled in order of name.
942 mGroups[t->mainBuffer].emplace_back(name); // mGroups also in order of name.
943
Mathias Agopian65ab4712010-07-14 17:59:35 -0700944 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700945 // FIXME can overflow (mask is only 3 bits)
Andy Hung8ed196a2018-01-05 13:21:11 -0800946 n |= NEEDS_CHANNEL_1 + t->channelCount - 1;
947 if (t->doesResample()) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700948 n |= NEEDS_RESAMPLE;
949 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800950 if (t->auxLevel != 0 && t->auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700951 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700952 }
953
Andy Hung8ed196a2018-01-05 13:21:11 -0800954 if (t->volumeInc[0]|t->volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800955 volumeRamp = true;
Andy Hung8ed196a2018-01-05 13:21:11 -0800956 } else if (!t->doesResample() && t->volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700957 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700958 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800959 t->needs = n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700960
Glenn Kastend6fadf02013-10-30 14:37:29 -0700961 if (n & NEEDS_MUTE) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800962 t->hook = &Track::track__nop;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700963 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700964 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800965 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700966 }
Glenn Kastend6fadf02013-10-30 14:37:29 -0700967 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800968 all16BitsStereoNoResample = false;
969 resampling = true;
Andy Hung8ed196a2018-01-05 13:21:11 -0800970 t->hook = Track::getTrackHook(TRACKTYPE_RESAMPLE, t->mMixerChannelCount,
971 t->mMixerInFormat, t->mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700972 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Chih-Hung Hsieh09f9c022018-07-27 10:22:35 -0700973 "Track %d needs downmix + resample", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700974 } else {
975 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
Andy Hung8ed196a2018-01-05 13:21:11 -0800976 t->hook = Track::getTrackHook(
977 (t->mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO // TODO: MONO_HACK
978 && t->channelMask == AUDIO_CHANNEL_OUT_MONO)
Andy Hunge93b6b72014-07-17 21:30:53 -0700979 ? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,
Andy Hung8ed196a2018-01-05 13:21:11 -0800980 t->mMixerChannelCount,
981 t->mMixerInFormat, t->mMixerFormat);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800982 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700983 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700984 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Andy Hung8ed196a2018-01-05 13:21:11 -0800985 t->hook = Track::getTrackHook(TRACKTYPE_NORESAMPLE, t->mMixerChannelCount,
986 t->mMixerInFormat, t->mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700987 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Chih-Hung Hsieh09f9c022018-07-27 10:22:35 -0700988 "Track %d needs downmix", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700989 }
990 }
991 }
992 }
993
994 // select the processing hooks
Andy Hung8ed196a2018-01-05 13:21:11 -0800995 mHook = &AudioMixer::process__nop;
996 if (mEnabled.size() > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700997 if (resampling) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800998 if (mOutputTemp.get() == nullptr) {
999 mOutputTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001000 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001001 if (mResampleTemp.get() == nullptr) {
1002 mResampleTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001003 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001004 mHook = &AudioMixer::process__genericResampling;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001005 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001006 // we keep temp arrays around.
1007 mHook = &AudioMixer::process__genericNoResampling;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001008 if (all16BitsStereoNoResample && !volumeRamp) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001009 if (mEnabled.size() == 1) {
1010 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
1011 if ((t->needs & NEEDS_MUTE) == 0) {
Andy Hung395db4b2014-08-25 17:15:29 -07001012 // The check prevents a muted track from acquiring a process hook.
1013 //
1014 // This is dangerous if the track is MONO as that requires
1015 // special case handling due to implicit channel duplication.
1016 // Stereo or Multichannel should actually be fine here.
Andy Hung8ed196a2018-01-05 13:21:11 -08001017 mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
1018 t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
Andy Hung395db4b2014-08-25 17:15:29 -07001019 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001020 }
1021 }
1022 }
1023 }
1024
Andy Hung8ed196a2018-01-05 13:21:11 -08001025 ALOGV("mixer configuration change: %zu "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001026 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001027 mEnabled.size(), all16BitsStereoNoResample, resampling, volumeRamp);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001028
Andy Hung8ed196a2018-01-05 13:21:11 -08001029 process();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001030
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001031 // Now that the volume ramp has been done, set optimal state and
1032 // track hooks for subsequent mixer process
Andy Hung8ed196a2018-01-05 13:21:11 -08001033 if (mEnabled.size() > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001034 bool allMuted = true;
Andy Hung8ed196a2018-01-05 13:21:11 -08001035
1036 for (const int name : mEnabled) {
1037 const std::shared_ptr<Track> &t = mTracks[name];
1038 if (!t->doesResample() && t->volumeRL == 0) {
1039 t->needs |= NEEDS_MUTE;
1040 t->hook = &Track::track__nop;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001041 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001042 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001043 }
1044 }
1045 if (allMuted) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001046 mHook = &AudioMixer::process__nop;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001047 } else if (all16BitsStereoNoResample) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001048 if (mEnabled.size() == 1) {
1049 //const int i = 31 - __builtin_clz(enabledTracks);
1050 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
Andy Hung395db4b2014-08-25 17:15:29 -07001051 // Muted single tracks handled by allMuted above.
Andy Hung8ed196a2018-01-05 13:21:11 -08001052 mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
1053 t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001054 }
1055 }
1056 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001057}
1058
Andy Hung8ed196a2018-01-05 13:21:11 -08001059void AudioMixer::Track::track__genericResample(
1060 int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001061{
Andy Hung296b7412014-06-17 15:25:47 -07001062 ALOGVV("track__genericResample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001063 mResampler->setSampleRate(sampleRate);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001064
1065 // ramp gain - resample to temp buffer and scale/mix in 2nd step
1066 if (aux != NULL) {
1067 // always resample with unity gain when sending to auxiliary buffer to be able
1068 // to apply send level after resampling
Andy Hung8ed196a2018-01-05 13:21:11 -08001069 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
1070 memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(int32_t));
1071 mResampler->resample(temp, outFrameCount, bufferProvider);
1072 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
1073 volumeRampStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001074 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001075 volumeStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001076 }
1077 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001078 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
1079 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001080 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
Andy Hung8ed196a2018-01-05 13:21:11 -08001081 mResampler->resample(temp, outFrameCount, bufferProvider);
1082 volumeRampStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001083 }
1084
1085 // constant gain
1086 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001087 mResampler->setVolume(mVolume[0], mVolume[1]);
1088 mResampler->resample(out, outFrameCount, bufferProvider);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001089 }
1090 }
1091}
1092
Andy Hung8ed196a2018-01-05 13:21:11 -08001093void AudioMixer::Track::track__nop(int32_t* out __unused,
Andy Hungee931ff2014-01-28 13:44:14 -08001094 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001095{
1096}
1097
Andy Hung8ed196a2018-01-05 13:21:11 -08001098void AudioMixer::Track::volumeRampStereo(
1099 int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001100{
Andy Hung8ed196a2018-01-05 13:21:11 -08001101 int32_t vl = prevVolume[0];
1102 int32_t vr = prevVolume[1];
1103 const int32_t vlInc = volumeInc[0];
1104 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001105
Steve Blockb8a80522011-12-20 16:23:08 +00001106 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001107 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001108 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1109
1110 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -08001111 if (CC_UNLIKELY(aux != NULL)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001112 int32_t va = prevAuxLevel;
1113 const int32_t vaInc = auxInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001114 int32_t l;
1115 int32_t r;
1116
1117 do {
1118 l = (*temp++ >> 12);
1119 r = (*temp++ >> 12);
1120 *out++ += (vl >> 16) * l;
1121 *out++ += (vr >> 16) * r;
1122 *aux++ += (va >> 17) * (l + r);
1123 vl += vlInc;
1124 vr += vrInc;
1125 va += vaInc;
1126 } while (--frameCount);
Andy Hung8ed196a2018-01-05 13:21:11 -08001127 prevAuxLevel = va;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001128 } else {
1129 do {
1130 *out++ += (vl >> 16) * (*temp++ >> 12);
1131 *out++ += (vr >> 16) * (*temp++ >> 12);
1132 vl += vlInc;
1133 vr += vrInc;
1134 } while (--frameCount);
1135 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001136 prevVolume[0] = vl;
1137 prevVolume[1] = vr;
1138 adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001139}
1140
Andy Hung8ed196a2018-01-05 13:21:11 -08001141void AudioMixer::Track::volumeStereo(
1142 int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001143{
Andy Hung8ed196a2018-01-05 13:21:11 -08001144 const int16_t vl = volume[0];
1145 const int16_t vr = volume[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001146
Glenn Kastenf6b16782011-12-15 09:51:17 -08001147 if (CC_UNLIKELY(aux != NULL)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001148 const int16_t va = auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001149 do {
1150 int16_t l = (int16_t)(*temp++ >> 12);
1151 int16_t r = (int16_t)(*temp++ >> 12);
1152 out[0] = mulAdd(l, vl, out[0]);
1153 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1154 out[1] = mulAdd(r, vr, out[1]);
1155 out += 2;
1156 aux[0] = mulAdd(a, va, aux[0]);
1157 aux++;
1158 } while (--frameCount);
1159 } else {
1160 do {
1161 int16_t l = (int16_t)(*temp++ >> 12);
1162 int16_t r = (int16_t)(*temp++ >> 12);
1163 out[0] = mulAdd(l, vl, out[0]);
1164 out[1] = mulAdd(r, vr, out[1]);
1165 out += 2;
1166 } while (--frameCount);
1167 }
1168}
1169
Andy Hung8ed196a2018-01-05 13:21:11 -08001170void AudioMixer::Track::track__16BitsStereo(
1171 int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001172{
Andy Hung296b7412014-06-17 15:25:47 -07001173 ALOGVV("track__16BitsStereo\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001174 const int16_t *in = static_cast<const int16_t *>(mIn);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001175
Glenn Kastenf6b16782011-12-15 09:51:17 -08001176 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001177 int32_t l;
1178 int32_t r;
1179 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001180 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
1181 int32_t vl = prevVolume[0];
1182 int32_t vr = prevVolume[1];
1183 int32_t va = prevAuxLevel;
1184 const int32_t vlInc = volumeInc[0];
1185 const int32_t vrInc = volumeInc[1];
1186 const int32_t vaInc = auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001187 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001188 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001189 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1190
1191 do {
1192 l = (int32_t)*in++;
1193 r = (int32_t)*in++;
1194 *out++ += (vl >> 16) * l;
1195 *out++ += (vr >> 16) * r;
1196 *aux++ += (va >> 17) * (l + r);
1197 vl += vlInc;
1198 vr += vrInc;
1199 va += vaInc;
1200 } while (--frameCount);
1201
Andy Hung8ed196a2018-01-05 13:21:11 -08001202 prevVolume[0] = vl;
1203 prevVolume[1] = vr;
1204 prevAuxLevel = va;
1205 adjustVolumeRamp(true);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001206 }
1207
1208 // constant gain
1209 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001210 const uint32_t vrl = volumeRL;
1211 const int16_t va = (int16_t)auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001212 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001213 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001214 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1215 in += 2;
1216 out[0] = mulAddRL(1, rl, vrl, out[0]);
1217 out[1] = mulAddRL(0, rl, vrl, out[1]);
1218 out += 2;
1219 aux[0] = mulAdd(a, va, aux[0]);
1220 aux++;
1221 } while (--frameCount);
1222 }
1223 } else {
1224 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001225 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
1226 int32_t vl = prevVolume[0];
1227 int32_t vr = prevVolume[1];
1228 const int32_t vlInc = volumeInc[0];
1229 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001230
Steve Blockb8a80522011-12-20 16:23:08 +00001231 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001232 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001233 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1234
1235 do {
1236 *out++ += (vl >> 16) * (int32_t) *in++;
1237 *out++ += (vr >> 16) * (int32_t) *in++;
1238 vl += vlInc;
1239 vr += vrInc;
1240 } while (--frameCount);
1241
Andy Hung8ed196a2018-01-05 13:21:11 -08001242 prevVolume[0] = vl;
1243 prevVolume[1] = vr;
1244 adjustVolumeRamp(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001245 }
1246
1247 // constant gain
1248 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001249 const uint32_t vrl = volumeRL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001250 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001251 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001252 in += 2;
1253 out[0] = mulAddRL(1, rl, vrl, out[0]);
1254 out[1] = mulAddRL(0, rl, vrl, out[1]);
1255 out += 2;
1256 } while (--frameCount);
1257 }
1258 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001259 mIn = in;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001260}
1261
Andy Hung8ed196a2018-01-05 13:21:11 -08001262void AudioMixer::Track::track__16BitsMono(
1263 int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001264{
Andy Hung296b7412014-06-17 15:25:47 -07001265 ALOGVV("track__16BitsMono\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001266 const int16_t *in = static_cast<int16_t const *>(mIn);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001267
Glenn Kastenf6b16782011-12-15 09:51:17 -08001268 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001269 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001270 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
1271 int32_t vl = prevVolume[0];
1272 int32_t vr = prevVolume[1];
1273 int32_t va = prevAuxLevel;
1274 const int32_t vlInc = volumeInc[0];
1275 const int32_t vrInc = volumeInc[1];
1276 const int32_t vaInc = auxInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001277
Steve Blockb8a80522011-12-20 16:23:08 +00001278 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001279 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001280 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1281
1282 do {
1283 int32_t l = *in++;
1284 *out++ += (vl >> 16) * l;
1285 *out++ += (vr >> 16) * l;
1286 *aux++ += (va >> 16) * l;
1287 vl += vlInc;
1288 vr += vrInc;
1289 va += vaInc;
1290 } while (--frameCount);
1291
Andy Hung8ed196a2018-01-05 13:21:11 -08001292 prevVolume[0] = vl;
1293 prevVolume[1] = vr;
1294 prevAuxLevel = va;
1295 adjustVolumeRamp(true);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001296 }
1297 // constant gain
1298 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001299 const int16_t vl = volume[0];
1300 const int16_t vr = volume[1];
1301 const int16_t va = (int16_t)auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001302 do {
1303 int16_t l = *in++;
1304 out[0] = mulAdd(l, vl, out[0]);
1305 out[1] = mulAdd(l, vr, out[1]);
1306 out += 2;
1307 aux[0] = mulAdd(l, va, aux[0]);
1308 aux++;
1309 } while (--frameCount);
1310 }
1311 } else {
1312 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001313 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
1314 int32_t vl = prevVolume[0];
1315 int32_t vr = prevVolume[1];
1316 const int32_t vlInc = volumeInc[0];
1317 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001318
Steve Blockb8a80522011-12-20 16:23:08 +00001319 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001320 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001321 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1322
1323 do {
1324 int32_t l = *in++;
1325 *out++ += (vl >> 16) * l;
1326 *out++ += (vr >> 16) * l;
1327 vl += vlInc;
1328 vr += vrInc;
1329 } while (--frameCount);
1330
Andy Hung8ed196a2018-01-05 13:21:11 -08001331 prevVolume[0] = vl;
1332 prevVolume[1] = vr;
1333 adjustVolumeRamp(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001334 }
1335 // constant gain
1336 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001337 const int16_t vl = volume[0];
1338 const int16_t vr = volume[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001339 do {
1340 int16_t l = *in++;
1341 out[0] = mulAdd(l, vl, out[0]);
1342 out[1] = mulAdd(l, vr, out[1]);
1343 out += 2;
1344 } while (--frameCount);
1345 }
1346 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001347 mIn = in;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001348}
1349
Mathias Agopian65ab4712010-07-14 17:59:35 -07001350// no-op case
Andy Hung8ed196a2018-01-05 13:21:11 -08001351void AudioMixer::process__nop()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001352{
Andy Hung296b7412014-06-17 15:25:47 -07001353 ALOGVV("process__nop\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001354
1355 for (const auto &pair : mGroups) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001356 // process by group of tracks with same output buffer to
1357 // avoid multiple memset() on same buffer
Andy Hung8ed196a2018-01-05 13:21:11 -08001358 const auto &group = pair.second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001359
Andy Hung8ed196a2018-01-05 13:21:11 -08001360 const std::shared_ptr<Track> &t = mTracks[group[0]];
1361 memset(t->mainBuffer, 0,
1362 mFrameCount * t->mMixerChannelCount
1363 * audio_bytes_per_sample(t->mMixerFormat));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001364
Andy Hung8ed196a2018-01-05 13:21:11 -08001365 // now consume data
1366 for (const int name : group) {
1367 const std::shared_ptr<Track> &t = mTracks[name];
1368 size_t outFrames = mFrameCount;
1369 while (outFrames) {
1370 t->buffer.frameCount = outFrames;
1371 t->bufferProvider->getNextBuffer(&t->buffer);
1372 if (t->buffer.raw == NULL) break;
1373 outFrames -= t->buffer.frameCount;
1374 t->bufferProvider->releaseBuffer(&t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001375 }
1376 }
1377 }
1378}
1379
1380// generic code without resampling
Andy Hung8ed196a2018-01-05 13:21:11 -08001381void AudioMixer::process__genericNoResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001382{
Andy Hung296b7412014-06-17 15:25:47 -07001383 ALOGVV("process__genericNoResampling\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001384 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1385
Andy Hung8ed196a2018-01-05 13:21:11 -08001386 for (const auto &pair : mGroups) {
1387 // process by group of tracks with same output main buffer to
1388 // avoid multiple memset() on same buffer
1389 const auto &group = pair.second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001390
Andy Hung8ed196a2018-01-05 13:21:11 -08001391 // acquire buffer
1392 for (const int name : group) {
1393 const std::shared_ptr<Track> &t = mTracks[name];
1394 t->buffer.frameCount = mFrameCount;
1395 t->bufferProvider->getNextBuffer(&t->buffer);
1396 t->frameCount = t->buffer.frameCount;
1397 t->mIn = t->buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001398 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001399
1400 int32_t *out = (int *)pair.first;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001401 size_t numFrames = 0;
1402 do {
Andy Hung8ed196a2018-01-05 13:21:11 -08001403 const size_t frameCount = std::min((size_t)BLOCKSIZE, mFrameCount - numFrames);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001404 memset(outTemp, 0, sizeof(outTemp));
Andy Hung8ed196a2018-01-05 13:21:11 -08001405 for (const int name : group) {
1406 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001407 int32_t *aux = NULL;
Andy Hung8ed196a2018-01-05 13:21:11 -08001408 if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
1409 aux = t->auxBuffer + numFrames;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001410 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001411 for (int outFrames = frameCount; outFrames > 0; ) {
1412 // t->in == nullptr can happen if the track was flushed just after having
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301413 // been enabled for mixing.
Andy Hung8ed196a2018-01-05 13:21:11 -08001414 if (t->mIn == nullptr) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301415 break;
1416 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001417 size_t inFrames = (t->frameCount > outFrames)?outFrames:t->frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001418 if (inFrames > 0) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001419 (t.get()->*t->hook)(
1420 outTemp + (frameCount - outFrames) * t->mMixerChannelCount,
1421 inFrames, mResampleTemp.get() /* naked ptr */, aux);
1422 t->frameCount -= inFrames;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001423 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001424 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001425 aux += inFrames;
1426 }
1427 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001428 if (t->frameCount == 0 && outFrames) {
1429 t->bufferProvider->releaseBuffer(&t->buffer);
1430 t->buffer.frameCount = (mFrameCount - numFrames) -
Yahan Zhouc1c11b42018-01-16 12:44:04 -08001431 (frameCount - outFrames);
Andy Hung8ed196a2018-01-05 13:21:11 -08001432 t->bufferProvider->getNextBuffer(&t->buffer);
1433 t->mIn = t->buffer.raw;
1434 if (t->mIn == nullptr) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001435 break;
1436 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001437 t->frameCount = t->buffer.frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001438 }
1439 }
1440 }
Andy Hung296b7412014-06-17 15:25:47 -07001441
Andy Hung8ed196a2018-01-05 13:21:11 -08001442 const std::shared_ptr<Track> &t1 = mTracks[group[0]];
1443 convertMixerFormat(out, t1->mMixerFormat, outTemp, t1->mMixerInFormat,
1444 frameCount * t1->mMixerChannelCount);
Andy Hung296b7412014-06-17 15:25:47 -07001445 // TODO: fix ugly casting due to choice of out pointer type
1446 out = reinterpret_cast<int32_t*>((uint8_t*)out
Andy Hung8ed196a2018-01-05 13:21:11 -08001447 + frameCount * t1->mMixerChannelCount
1448 * audio_bytes_per_sample(t1->mMixerFormat));
Yahan Zhouc1c11b42018-01-16 12:44:04 -08001449 numFrames += frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001450 } while (numFrames < mFrameCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001451
Andy Hung8ed196a2018-01-05 13:21:11 -08001452 // release each track's buffer
1453 for (const int name : group) {
1454 const std::shared_ptr<Track> &t = mTracks[name];
1455 t->bufferProvider->releaseBuffer(&t->buffer);
1456 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001457 }
1458}
1459
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001460// generic code with resampling
Andy Hung8ed196a2018-01-05 13:21:11 -08001461void AudioMixer::process__genericResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001462{
Andy Hung296b7412014-06-17 15:25:47 -07001463 ALOGVV("process__genericResampling\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001464 int32_t * const outTemp = mOutputTemp.get(); // naked ptr
1465 size_t numFrames = mFrameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001466
Andy Hung8ed196a2018-01-05 13:21:11 -08001467 for (const auto &pair : mGroups) {
1468 const auto &group = pair.second;
1469 const std::shared_ptr<Track> &t1 = mTracks[group[0]];
1470
1471 // clear temp buffer
1472 memset(outTemp, 0, sizeof(*outTemp) * t1->mMixerChannelCount * mFrameCount);
1473 for (const int name : group) {
1474 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001475 int32_t *aux = NULL;
Andy Hung8ed196a2018-01-05 13:21:11 -08001476 if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
1477 aux = t->auxBuffer;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001478 }
1479
1480 // this is a little goofy, on the resampling case we don't
1481 // acquire/release the buffers because it's done by
1482 // the resampler.
Andy Hung8ed196a2018-01-05 13:21:11 -08001483 if (t->needs & NEEDS_RESAMPLE) {
1484 (t.get()->*t->hook)(outTemp, numFrames, mResampleTemp.get() /* naked ptr */, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001485 } else {
1486
1487 size_t outFrames = 0;
1488
1489 while (outFrames < numFrames) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001490 t->buffer.frameCount = numFrames - outFrames;
1491 t->bufferProvider->getNextBuffer(&t->buffer);
1492 t->mIn = t->buffer.raw;
1493 // t->mIn == nullptr can happen if the track was flushed just after having
Mathias Agopian65ab4712010-07-14 17:59:35 -07001494 // been enabled for mixing.
Andy Hung8ed196a2018-01-05 13:21:11 -08001495 if (t->mIn == nullptr) break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001496
Andy Hung8ed196a2018-01-05 13:21:11 -08001497 (t.get()->*t->hook)(
1498 outTemp + outFrames * t->mMixerChannelCount, t->buffer.frameCount,
Andy Hunga6018892018-02-21 14:32:16 -08001499 mResampleTemp.get() /* naked ptr */,
1500 aux != nullptr ? aux + outFrames : nullptr);
Andy Hung8ed196a2018-01-05 13:21:11 -08001501 outFrames += t->buffer.frameCount;
Andy Hunga6018892018-02-21 14:32:16 -08001502
Andy Hung8ed196a2018-01-05 13:21:11 -08001503 t->bufferProvider->releaseBuffer(&t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001504 }
1505 }
1506 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001507 convertMixerFormat(t1->mainBuffer, t1->mMixerFormat,
1508 outTemp, t1->mMixerInFormat, numFrames * t1->mMixerChannelCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001509 }
1510}
1511
1512// one track, 16 bits stereo without resampling is the most common case
Andy Hung8ed196a2018-01-05 13:21:11 -08001513void AudioMixer::process__oneTrack16BitsStereoNoResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001514{
Andy Hung8ed196a2018-01-05 13:21:11 -08001515 ALOGVV("process__oneTrack16BitsStereoNoResampling\n");
1516 LOG_ALWAYS_FATAL_IF(mEnabled.size() != 0,
1517 "%zu != 1 tracks enabled", mEnabled.size());
1518 const int name = mEnabled[0];
1519 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001520
Andy Hung8ed196a2018-01-05 13:21:11 -08001521 AudioBufferProvider::Buffer& b(t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001522
Andy Hung8ed196a2018-01-05 13:21:11 -08001523 int32_t* out = t->mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001524 float *fout = reinterpret_cast<float*>(out);
Andy Hung8ed196a2018-01-05 13:21:11 -08001525 size_t numFrames = mFrameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001526
Andy Hung8ed196a2018-01-05 13:21:11 -08001527 const int16_t vl = t->volume[0];
1528 const int16_t vr = t->volume[1];
1529 const uint32_t vrl = t->volumeRL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001530 while (numFrames) {
1531 b.frameCount = numFrames;
Andy Hung8ed196a2018-01-05 13:21:11 -08001532 t->bufferProvider->getNextBuffer(&b);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001533 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001534
1535 // in == NULL can happen if the track was flushed just after having
1536 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001537 if (in == NULL || (((uintptr_t)in) & 3)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001538 if ( AUDIO_FORMAT_PCM_FLOAT == t->mMixerFormat ) {
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001539 memset((char*)fout, 0, numFrames
Andy Hung8ed196a2018-01-05 13:21:11 -08001540 * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001541 } else {
1542 memset((char*)out, 0, numFrames
Andy Hung8ed196a2018-01-05 13:21:11 -08001543 * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001544 }
Andy Hung395db4b2014-08-25 17:15:29 -07001545 ALOGE_IF((((uintptr_t)in) & 3),
Andy Hung8ed196a2018-01-05 13:21:11 -08001546 "process__oneTrack16BitsStereoNoResampling: misaligned buffer"
Andy Hung395db4b2014-08-25 17:15:29 -07001547 " %p track %d, channels %d, needs %08x, volume %08x vfl %f vfr %f",
Andy Hung8ed196a2018-01-05 13:21:11 -08001548 in, name, t->channelCount, t->needs, vrl, t->mVolume[0], t->mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001549 return;
1550 }
1551 size_t outFrames = b.frameCount;
1552
Andy Hung8ed196a2018-01-05 13:21:11 -08001553 switch (t->mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001554 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001555 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001556 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001557 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001558 int32_t l = mulRL(1, rl, vrl);
1559 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001560 *fout++ = float_from_q4_27(l);
1561 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001562 // Note: In case of later int16_t sink output,
1563 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001564 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001565 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001566 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung97ae8242014-05-30 10:35:47 -07001567 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001568 // volume is boosted, so we might need to clamp even though
1569 // we process only one track.
1570 do {
1571 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1572 in += 2;
1573 int32_t l = mulRL(1, rl, vrl) >> 12;
1574 int32_t r = mulRL(0, rl, vrl) >> 12;
1575 // clamping...
1576 l = clamp16(l);
1577 r = clamp16(r);
1578 *out++ = (r<<16) | (l & 0xFFFF);
1579 } while (--outFrames);
1580 } else {
1581 do {
1582 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1583 in += 2;
1584 int32_t l = mulRL(1, rl, vrl) >> 12;
1585 int32_t r = mulRL(0, rl, vrl) >> 12;
1586 *out++ = (r<<16) | (l & 0xFFFF);
1587 } while (--outFrames);
1588 }
1589 break;
1590 default:
Andy Hung8ed196a2018-01-05 13:21:11 -08001591 LOG_ALWAYS_FATAL("bad mixer format: %d", t->mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001592 }
1593 numFrames -= b.frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001594 t->bufferProvider->releaseBuffer(&b);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001595 }
1596}
1597
Glenn Kasten52008f82012-03-18 09:34:41 -07001598/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1599
1600/*static*/ void AudioMixer::sInitRoutine()
1601{
Andy Hung34803d52014-07-16 21:41:35 -07001602 DownmixerBufferProvider::init(); // for the downmixer
John Grossman4ff14ba2012-02-08 16:37:41 -08001603}
1604
Andy Hunge93b6b72014-07-17 21:30:53 -07001605/* TODO: consider whether this level of optimization is necessary.
1606 * Perhaps just stick with a single for loop.
1607 */
1608
1609// Needs to derive a compile time constant (constexpr). Could be targeted to go
1610// to a MONOVOL mixtype based on MAX_NUM_VOLUMES, but that's an unnecessary complication.
Chih-Hung Hsiehbf291732016-05-17 15:16:07 -07001611#define MIXTYPE_MONOVOL(mixtype) ((mixtype) == MIXTYPE_MULTI ? MIXTYPE_MULTI_MONOVOL : \
1612 (mixtype) == MIXTYPE_MULTI_SAVEONLY ? MIXTYPE_MULTI_SAVEONLY_MONOVOL : (mixtype))
Andy Hunge93b6b72014-07-17 21:30:53 -07001613
1614/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1615 * TO: int32_t (Q4.27) or float
1616 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001617 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001618 */
1619template <int MIXTYPE,
1620 typename TO, typename TI, typename TV, typename TA, typename TAV>
1621static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
1622 const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc)
1623{
1624 switch (channels) {
1625 case 1:
1626 volumeRampMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1627 break;
1628 case 2:
1629 volumeRampMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1630 break;
1631 case 3:
1632 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out,
1633 frameCount, in, aux, vol, volinc, vola, volainc);
1634 break;
1635 case 4:
1636 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out,
1637 frameCount, in, aux, vol, volinc, vola, volainc);
1638 break;
1639 case 5:
1640 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out,
1641 frameCount, in, aux, vol, volinc, vola, volainc);
1642 break;
1643 case 6:
1644 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out,
1645 frameCount, in, aux, vol, volinc, vola, volainc);
1646 break;
1647 case 7:
1648 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out,
1649 frameCount, in, aux, vol, volinc, vola, volainc);
1650 break;
1651 case 8:
1652 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out,
1653 frameCount, in, aux, vol, volinc, vola, volainc);
1654 break;
1655 }
1656}
1657
1658/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1659 * TO: int32_t (Q4.27) or float
1660 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001661 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001662 */
1663template <int MIXTYPE,
1664 typename TO, typename TI, typename TV, typename TA, typename TAV>
1665static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
1666 const TI* in, TA* aux, const TV *vol, TAV vola)
1667{
1668 switch (channels) {
1669 case 1:
1670 volumeMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, vola);
1671 break;
1672 case 2:
1673 volumeMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, vola);
1674 break;
1675 case 3:
1676 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out, frameCount, in, aux, vol, vola);
1677 break;
1678 case 4:
1679 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out, frameCount, in, aux, vol, vola);
1680 break;
1681 case 5:
1682 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out, frameCount, in, aux, vol, vola);
1683 break;
1684 case 6:
1685 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out, frameCount, in, aux, vol, vola);
1686 break;
1687 case 7:
1688 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out, frameCount, in, aux, vol, vola);
1689 break;
1690 case 8:
1691 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out, frameCount, in, aux, vol, vola);
1692 break;
1693 }
1694}
1695
1696/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1697 * USEFLOATVOL (set to true if float volume is used)
1698 * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards)
1699 * TO: int32_t (Q4.27) or float
1700 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001701 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001702 */
1703template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001704 typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001705void AudioMixer::Track::volumeMix(TO *out, size_t outFrames,
1706 const TI *in, TA *aux, bool ramp)
Andy Hung5e58b0a2014-06-23 19:07:29 -07001707{
1708 if (USEFLOATVOL) {
1709 if (ramp) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001710 volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1711 mPrevVolume, mVolumeInc,
Andy Hung116a4982017-11-30 10:15:08 -08001712#ifdef FLOAT_AUX
Andy Hung8ed196a2018-01-05 13:21:11 -08001713 &mPrevAuxLevel, mAuxInc
Andy Hung116a4982017-11-30 10:15:08 -08001714#else
Andy Hung8ed196a2018-01-05 13:21:11 -08001715 &prevAuxLevel, auxInc
Andy Hung116a4982017-11-30 10:15:08 -08001716#endif
1717 );
Andy Hung5e58b0a2014-06-23 19:07:29 -07001718 if (ADJUSTVOL) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001719 adjustVolumeRamp(aux != NULL, true);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001720 }
1721 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001722 volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1723 mVolume,
Andy Hung116a4982017-11-30 10:15:08 -08001724#ifdef FLOAT_AUX
Andy Hung8ed196a2018-01-05 13:21:11 -08001725 mAuxLevel
Andy Hung116a4982017-11-30 10:15:08 -08001726#else
Andy Hung8ed196a2018-01-05 13:21:11 -08001727 auxLevel
Andy Hung116a4982017-11-30 10:15:08 -08001728#endif
1729 );
Andy Hung5e58b0a2014-06-23 19:07:29 -07001730 }
1731 } else {
1732 if (ramp) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001733 volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1734 prevVolume, volumeInc, &prevAuxLevel, auxInc);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001735 if (ADJUSTVOL) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001736 adjustVolumeRamp(aux != NULL);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001737 }
1738 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001739 volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1740 volume, auxLevel);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001741 }
1742 }
1743}
1744
Andy Hung296b7412014-06-17 15:25:47 -07001745/* This process hook is called when there is a single track without
1746 * aux buffer, volume ramp, or resampling.
1747 * TODO: Update the hook selection: this can properly handle aux and ramp.
Andy Hunge93b6b72014-07-17 21:30:53 -07001748 *
1749 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1750 * TO: int32_t (Q4.27) or float
1751 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1752 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07001753 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001754template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001755void AudioMixer::process__noResampleOneTrack()
Andy Hung296b7412014-06-17 15:25:47 -07001756{
Andy Hung8ed196a2018-01-05 13:21:11 -08001757 ALOGVV("process__noResampleOneTrack\n");
1758 LOG_ALWAYS_FATAL_IF(mEnabled.size() != 1,
1759 "%zu != 1 tracks enabled", mEnabled.size());
1760 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
Andy Hunge93b6b72014-07-17 21:30:53 -07001761 const uint32_t channels = t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07001762 TO* out = reinterpret_cast<TO*>(t->mainBuffer);
1763 TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
1764 const bool ramp = t->needsRamp();
1765
Andy Hung8ed196a2018-01-05 13:21:11 -08001766 for (size_t numFrames = mFrameCount; numFrames > 0; ) {
Andy Hung296b7412014-06-17 15:25:47 -07001767 AudioBufferProvider::Buffer& b(t->buffer);
1768 // get input buffer
1769 b.frameCount = numFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001770 t->bufferProvider->getNextBuffer(&b);
Andy Hung296b7412014-06-17 15:25:47 -07001771 const TI *in = reinterpret_cast<TI*>(b.raw);
1772
1773 // in == NULL can happen if the track was flushed just after having
1774 // been enabled for mixing.
1775 if (in == NULL || (((uintptr_t)in) & 3)) {
1776 memset(out, 0, numFrames
Andy Hunge93b6b72014-07-17 21:30:53 -07001777 * channels * audio_bytes_per_sample(t->mMixerFormat));
Andy Hung8ed196a2018-01-05 13:21:11 -08001778 ALOGE_IF((((uintptr_t)in) & 3), "process__noResampleOneTrack: bus error: "
Andy Hung296b7412014-06-17 15:25:47 -07001779 "buffer %p track %p, channels %d, needs %#x",
Andy Hung8ed196a2018-01-05 13:21:11 -08001780 in, &t, t->channelCount, t->needs);
Andy Hung296b7412014-06-17 15:25:47 -07001781 return;
1782 }
1783
1784 const size_t outFrames = b.frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001785 t->volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, false /* ADJUSTVOL */> (
1786 out, outFrames, in, aux, ramp);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001787
Andy Hunge93b6b72014-07-17 21:30:53 -07001788 out += outFrames * channels;
Andy Hung296b7412014-06-17 15:25:47 -07001789 if (aux != NULL) {
Andy Hunga6018892018-02-21 14:32:16 -08001790 aux += outFrames;
Andy Hung296b7412014-06-17 15:25:47 -07001791 }
1792 numFrames -= b.frameCount;
1793
1794 // release buffer
1795 t->bufferProvider->releaseBuffer(&b);
1796 }
1797 if (ramp) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001798 t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
Andy Hung296b7412014-06-17 15:25:47 -07001799 }
1800}
1801
1802/* This track hook is called to do resampling then mixing,
1803 * pulling from the track's upstream AudioBufferProvider.
Andy Hunge93b6b72014-07-17 21:30:53 -07001804 *
1805 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1806 * TO: int32_t (Q4.27) or float
1807 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001808 * TA: int32_t (Q4.27) or float
Andy Hung296b7412014-06-17 15:25:47 -07001809 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001810template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001811void AudioMixer::Track::track__Resample(TO* out, size_t outFrameCount, TO* temp, TA* aux)
Andy Hung296b7412014-06-17 15:25:47 -07001812{
1813 ALOGVV("track__Resample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001814 mResampler->setSampleRate(sampleRate);
1815 const bool ramp = needsRamp();
Andy Hung296b7412014-06-17 15:25:47 -07001816 if (ramp || aux != NULL) {
1817 // if ramp: resample with unity gain to temp buffer and scale/mix in 2nd step.
1818 // if aux != NULL: resample with unity gain to temp buffer then apply send level.
1819
Andy Hung8ed196a2018-01-05 13:21:11 -08001820 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
1821 memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(TO));
1822 mResampler->resample((int32_t*)temp, outFrameCount, bufferProvider);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001823
Andy Hung116a4982017-11-30 10:15:08 -08001824 volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
Andy Hung8ed196a2018-01-05 13:21:11 -08001825 out, outFrameCount, temp, aux, ramp);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001826
Andy Hung296b7412014-06-17 15:25:47 -07001827 } else { // constant volume gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001828 mResampler->setVolume(mVolume[0], mVolume[1]);
1829 mResampler->resample((int32_t*)out, outFrameCount, bufferProvider);
Andy Hung296b7412014-06-17 15:25:47 -07001830 }
1831}
1832
1833/* This track hook is called to mix a track, when no resampling is required.
Andy Hung8ed196a2018-01-05 13:21:11 -08001834 * The input buffer should be present in in.
Andy Hunge93b6b72014-07-17 21:30:53 -07001835 *
1836 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1837 * TO: int32_t (Q4.27) or float
1838 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001839 * TA: int32_t (Q4.27) or float
Andy Hung296b7412014-06-17 15:25:47 -07001840 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001841template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001842void AudioMixer::Track::track__NoResample(TO* out, size_t frameCount, TO* temp __unused, TA* aux)
Andy Hung296b7412014-06-17 15:25:47 -07001843{
1844 ALOGVV("track__NoResample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001845 const TI *in = static_cast<const TI *>(mIn);
Andy Hung296b7412014-06-17 15:25:47 -07001846
Andy Hung116a4982017-11-30 10:15:08 -08001847 volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
Andy Hung8ed196a2018-01-05 13:21:11 -08001848 out, frameCount, in, aux, needsRamp());
Andy Hung5e58b0a2014-06-23 19:07:29 -07001849
Andy Hung296b7412014-06-17 15:25:47 -07001850 // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
1851 // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
Andy Hung8ed196a2018-01-05 13:21:11 -08001852 in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * mMixerChannelCount;
1853 mIn = in;
Andy Hung296b7412014-06-17 15:25:47 -07001854}
1855
1856/* The Mixer engine generates either int32_t (Q4_27) or float data.
1857 * We use this function to convert the engine buffers
1858 * to the desired mixer output format, either int16_t (Q.15) or float.
1859 */
Andy Hung8ed196a2018-01-05 13:21:11 -08001860/* static */
Andy Hung296b7412014-06-17 15:25:47 -07001861void AudioMixer::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
1862 void *in, audio_format_t mixerInFormat, size_t sampleCount)
1863{
1864 switch (mixerInFormat) {
1865 case AUDIO_FORMAT_PCM_FLOAT:
1866 switch (mixerOutFormat) {
1867 case AUDIO_FORMAT_PCM_FLOAT:
1868 memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
1869 break;
1870 case AUDIO_FORMAT_PCM_16_BIT:
1871 memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
1872 break;
1873 default:
1874 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1875 break;
1876 }
1877 break;
1878 case AUDIO_FORMAT_PCM_16_BIT:
1879 switch (mixerOutFormat) {
1880 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung5effdf62017-11-27 13:51:40 -08001881 memcpy_to_float_from_q4_27((float*)out, (const int32_t*)in, sampleCount);
Andy Hung296b7412014-06-17 15:25:47 -07001882 break;
1883 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung5effdf62017-11-27 13:51:40 -08001884 memcpy_to_i16_from_q4_27((int16_t*)out, (const int32_t*)in, sampleCount);
Andy Hung296b7412014-06-17 15:25:47 -07001885 break;
1886 default:
1887 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1888 break;
1889 }
1890 break;
1891 default:
1892 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1893 break;
1894 }
1895}
1896
1897/* Returns the proper track hook to use for mixing the track into the output buffer.
1898 */
Andy Hung8ed196a2018-01-05 13:21:11 -08001899/* static */
1900AudioMixer::hook_t AudioMixer::Track::getTrackHook(int trackType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001901 audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
1902{
Andy Hunge93b6b72014-07-17 21:30:53 -07001903 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07001904 switch (trackType) {
1905 case TRACKTYPE_NOP:
Andy Hung8ed196a2018-01-05 13:21:11 -08001906 return &Track::track__nop;
Andy Hung296b7412014-06-17 15:25:47 -07001907 case TRACKTYPE_RESAMPLE:
Andy Hung8ed196a2018-01-05 13:21:11 -08001908 return &Track::track__genericResample;
Andy Hung296b7412014-06-17 15:25:47 -07001909 case TRACKTYPE_NORESAMPLEMONO:
Andy Hung8ed196a2018-01-05 13:21:11 -08001910 return &Track::track__16BitsMono;
Andy Hung296b7412014-06-17 15:25:47 -07001911 case TRACKTYPE_NORESAMPLE:
Andy Hung8ed196a2018-01-05 13:21:11 -08001912 return &Track::track__16BitsStereo;
Andy Hung296b7412014-06-17 15:25:47 -07001913 default:
1914 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1915 break;
1916 }
1917 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001918 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07001919 switch (trackType) {
1920 case TRACKTYPE_NOP:
Andy Hung8ed196a2018-01-05 13:21:11 -08001921 return &Track::track__nop;
Andy Hung296b7412014-06-17 15:25:47 -07001922 case TRACKTYPE_RESAMPLE:
1923 switch (mixerInFormat) {
1924 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001925 return (AudioMixer::hook_t) &Track::track__Resample<
Andy Hung116a4982017-11-30 10:15:08 -08001926 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001927 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001928 return (AudioMixer::hook_t) &Track::track__Resample<
Andy Hung116a4982017-11-30 10:15:08 -08001929 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001930 default:
1931 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1932 break;
1933 }
1934 break;
1935 case TRACKTYPE_NORESAMPLEMONO:
1936 switch (mixerInFormat) {
1937 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001938 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001939 MIXTYPE_MONOEXPAND, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001940 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001941 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001942 MIXTYPE_MONOEXPAND, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001943 default:
1944 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1945 break;
1946 }
1947 break;
1948 case TRACKTYPE_NORESAMPLE:
1949 switch (mixerInFormat) {
1950 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001951 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001952 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001953 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001954 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001955 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001956 default:
1957 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1958 break;
1959 }
1960 break;
1961 default:
1962 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1963 break;
1964 }
1965 return NULL;
1966}
1967
1968/* Returns the proper process hook for mixing tracks. Currently works only for
1969 * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
Andy Hung395db4b2014-08-25 17:15:29 -07001970 *
1971 * TODO: Due to the special mixing considerations of duplicating to
1972 * a stereo output track, the input track cannot be MONO. This should be
1973 * prevented by the caller.
Andy Hung296b7412014-06-17 15:25:47 -07001974 */
Andy Hung8ed196a2018-01-05 13:21:11 -08001975/* static */
1976AudioMixer::process_hook_t AudioMixer::getProcessHook(
1977 int processType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001978 audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
1979{
1980 if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
1981 LOG_ALWAYS_FATAL("bad processType: %d", processType);
1982 return NULL;
1983 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001984 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001985 return &AudioMixer::process__oneTrack16BitsStereoNoResampling;
Andy Hung296b7412014-06-17 15:25:47 -07001986 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001987 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07001988 switch (mixerInFormat) {
1989 case AUDIO_FORMAT_PCM_FLOAT:
1990 switch (mixerOutFormat) {
1991 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001992 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08001993 MIXTYPE_MULTI_SAVEONLY, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001994 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001995 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08001996 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001997 default:
1998 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1999 break;
2000 }
2001 break;
2002 case AUDIO_FORMAT_PCM_16_BIT:
2003 switch (mixerOutFormat) {
2004 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002005 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08002006 MIXTYPE_MULTI_SAVEONLY, float /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002007 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08002008 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08002009 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002010 default:
2011 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2012 break;
2013 }
2014 break;
2015 default:
2016 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2017 break;
2018 }
2019 return NULL;
2020}
2021
Mathias Agopian65ab4712010-07-14 17:59:35 -07002022// ----------------------------------------------------------------------------
Glenn Kasten63238ef2015-03-02 15:50:29 -08002023} // namespace android