blob: af54b21986e85dfc083530d6f152b7beb8d33449 [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;
Andy Hung296b7412014-06-17 15:25:47 -0700165 // Check the downmixing (or upmixing) requirements.
Andy Hung0f451e92014-08-04 21:28:47 -0700166 status_t status = t->prepareForDownmix();
Andy Hung68112fc2014-05-14 14:13:23 -0700167 if (status != OK) {
168 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
Andy Hung1bc088a2018-02-09 15:57:31 -0800169 return BAD_VALUE;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700170 }
Andy Hung7f475492014-08-25 16:36:37 -0700171 // prepareForDownmix() may change mDownmixRequiresFormat
Andy Hung296b7412014-06-17 15:25:47 -0700172 ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
Andy Hung0f451e92014-08-04 21:28:47 -0700173 t->prepareForReformat();
Andy Hung1bc088a2018-02-09 15:57:31 -0800174
175 mTracks[name] = t;
176 return OK;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700177 }
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800178}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700179
Andy Hunge93b6b72014-07-17 21:30:53 -0700180// Called when channel masks have changed for a track name
Andy Hung7f475492014-08-25 16:36:37 -0700181// TODO: Fix DownmixerBufferProvider not to (possibly) change mixer input format,
Andy Hunge93b6b72014-07-17 21:30:53 -0700182// which will simplify this logic.
183bool AudioMixer::setChannelMasks(int name,
184 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) {
Andy Hung1bc088a2018-02-09 15:57:31 -0800185 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800186 const std::shared_ptr<Track> &track = mTracks[name];
Andy Hunge93b6b72014-07-17 21:30:53 -0700187
Andy Hung8ed196a2018-01-05 13:21:11 -0800188 if (trackChannelMask == track->channelMask
189 && mixerChannelMask == track->mMixerChannelMask) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700190 return false; // no need to change
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700191 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700192 // always recompute for both channel masks even if only one has changed.
193 const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
194 const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
Andy Hunge93b6b72014-07-17 21:30:53 -0700195
196 ALOG_ASSERT((trackChannelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX)
197 && trackChannelCount
198 && mixerChannelCount);
Andy Hung8ed196a2018-01-05 13:21:11 -0800199 track->channelMask = trackChannelMask;
200 track->channelCount = trackChannelCount;
201 track->mMixerChannelMask = mixerChannelMask;
202 track->mMixerChannelCount = mixerChannelCount;
Andy Hunge93b6b72014-07-17 21:30:53 -0700203
204 // channel masks have changed, does this track need a downmixer?
205 // update to try using our desired format (if we aren't already using it)
Andy Hung8ed196a2018-01-05 13:21:11 -0800206 const status_t status = track->prepareForDownmix();
Andy Hunge93b6b72014-07-17 21:30:53 -0700207 ALOGE_IF(status != OK,
Andy Hung0f451e92014-08-04 21:28:47 -0700208 "prepareForDownmix error %d, track channel mask %#x, mixer channel mask %#x",
Andy Hung8ed196a2018-01-05 13:21:11 -0800209 status, track->channelMask, track->mMixerChannelMask);
Andy Hunge93b6b72014-07-17 21:30:53 -0700210
Yung Ti Su1a0ecc32018-05-07 11:09:15 +0800211 // always do reformat since channel mask changed,
212 // do it after downmix since track format may change!
213 track->prepareForReformat();
Andy Hunge93b6b72014-07-17 21:30:53 -0700214
Yung Ti Sub5d11952018-05-22 22:31:14 +0800215 if (track->mResampler.get() != nullptr) {
Andy Hung7f475492014-08-25 16:36:37 -0700216 // resampler channels may have changed.
Andy Hung8ed196a2018-01-05 13:21:11 -0800217 const uint32_t resetToSampleRate = track->sampleRate;
218 track->mResampler.reset(nullptr);
219 track->sampleRate = mSampleRate; // without resampler, track rate is device sample rate.
Andy Hunge93b6b72014-07-17 21:30:53 -0700220 // recreate the resampler with updated format, channels, saved sampleRate.
Andy Hung8ed196a2018-01-05 13:21:11 -0800221 track->setResampler(resetToSampleRate /*trackSampleRate*/, mSampleRate /*devSampleRate*/);
Andy Hunge93b6b72014-07-17 21:30:53 -0700222 }
223 return true;
224}
225
Andy Hung8ed196a2018-01-05 13:21:11 -0800226void AudioMixer::Track::unprepareForDownmix() {
Andy Hung0f451e92014-08-04 21:28:47 -0700227 ALOGV("AudioMixer::unprepareForDownmix(%p)", this);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700228
Andy Hung8ed196a2018-01-05 13:21:11 -0800229 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
Andy Hung85395892017-04-25 16:47:52 -0700230 // release any buffers held by the mPostDownmixReformatBufferProvider
Andy Hung8ed196a2018-01-05 13:21:11 -0800231 // before deallocating the mDownmixerBufferProvider.
Andy Hung85395892017-04-25 16:47:52 -0700232 mPostDownmixReformatBufferProvider->reset();
233 }
234
Andy Hung7f475492014-08-25 16:36:37 -0700235 mDownmixRequiresFormat = AUDIO_FORMAT_INVALID;
Andy Hung8ed196a2018-01-05 13:21:11 -0800236 if (mDownmixerBufferProvider.get() != nullptr) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700237 // this track had previously been configured with a downmixer, delete it
Andy Hung8ed196a2018-01-05 13:21:11 -0800238 mDownmixerBufferProvider.reset(nullptr);
Andy Hung0f451e92014-08-04 21:28:47 -0700239 reconfigureBufferProviders();
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700240 } else {
241 ALOGV(" nothing to do, no downmixer to delete");
242 }
243}
244
Andy Hung8ed196a2018-01-05 13:21:11 -0800245status_t AudioMixer::Track::prepareForDownmix()
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700246{
Andy Hung0f451e92014-08-04 21:28:47 -0700247 ALOGV("AudioMixer::prepareForDownmix(%p) with mask 0x%x",
248 this, channelMask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700249
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700250 // discard the previous downmixer if there was one
Andy Hung0f451e92014-08-04 21:28:47 -0700251 unprepareForDownmix();
Andy Hung73e62e22015-04-20 12:06:38 -0700252 // MONO_HACK Only remix (upmix or downmix) if the track and mixer/device channel masks
Andy Hung0f451e92014-08-04 21:28:47 -0700253 // are not the same and not handled internally, as mono -> stereo currently is.
254 if (channelMask == mMixerChannelMask
255 || (channelMask == AUDIO_CHANNEL_OUT_MONO
256 && mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO)) {
257 return NO_ERROR;
258 }
Andy Hung650ceb92015-01-29 13:31:12 -0800259 // DownmixerBufferProvider is only used for position masks.
260 if (audio_channel_mask_get_representation(channelMask)
261 == AUDIO_CHANNEL_REPRESENTATION_POSITION
262 && DownmixerBufferProvider::isMultichannelCapable()) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800263 mDownmixerBufferProvider.reset(new DownmixerBufferProvider(channelMask,
Andy Hung0f451e92014-08-04 21:28:47 -0700264 mMixerChannelMask,
265 AUDIO_FORMAT_PCM_16_BIT /* TODO: use mMixerInFormat, now only PCM 16 */,
Andy Hung8ed196a2018-01-05 13:21:11 -0800266 sampleRate, sessionId, kCopyBufferFrameCount));
267 if (static_cast<DownmixerBufferProvider *>(mDownmixerBufferProvider.get())->isValid()) {
Andy Hung7f475492014-08-25 16:36:37 -0700268 mDownmixRequiresFormat = AUDIO_FORMAT_PCM_16_BIT; // PCM 16 bit required for downmix
Andy Hung0f451e92014-08-04 21:28:47 -0700269 reconfigureBufferProviders();
Andy Hung34803d52014-07-16 21:41:35 -0700270 return NO_ERROR;
271 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800272 // mDownmixerBufferProvider reset below.
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700273 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700274
275 // Effect downmixer does not accept the channel conversion. Let's use our remixer.
Andy Hung8ed196a2018-01-05 13:21:11 -0800276 mDownmixerBufferProvider.reset(new RemixBufferProvider(channelMask,
277 mMixerChannelMask, mMixerInFormat, kCopyBufferFrameCount));
Andy Hunge93b6b72014-07-17 21:30:53 -0700278 // Remix always finds a conversion whereas Downmixer effect above may fail.
Andy Hung0f451e92014-08-04 21:28:47 -0700279 reconfigureBufferProviders();
Andy Hunge93b6b72014-07-17 21:30:53 -0700280 return NO_ERROR;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700281}
282
Andy Hung8ed196a2018-01-05 13:21:11 -0800283void AudioMixer::Track::unprepareForReformat() {
Andy Hung0f451e92014-08-04 21:28:47 -0700284 ALOGV("AudioMixer::unprepareForReformat(%p)", this);
Andy Hung7f475492014-08-25 16:36:37 -0700285 bool requiresReconfigure = false;
Andy Hung8ed196a2018-01-05 13:21:11 -0800286 if (mReformatBufferProvider.get() != nullptr) {
287 mReformatBufferProvider.reset(nullptr);
Andy Hung7f475492014-08-25 16:36:37 -0700288 requiresReconfigure = true;
289 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800290 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
291 mPostDownmixReformatBufferProvider.reset(nullptr);
Andy Hung7f475492014-08-25 16:36:37 -0700292 requiresReconfigure = true;
293 }
294 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700295 reconfigureBufferProviders();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700296 }
297}
298
Andy Hung8ed196a2018-01-05 13:21:11 -0800299status_t AudioMixer::Track::prepareForReformat()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700300{
Andy Hung0f451e92014-08-04 21:28:47 -0700301 ALOGV("AudioMixer::prepareForReformat(%p) with format %#x", this, mFormat);
Andy Hung7f475492014-08-25 16:36:37 -0700302 // discard previous reformatters
Andy Hung0f451e92014-08-04 21:28:47 -0700303 unprepareForReformat();
Andy Hung7f475492014-08-25 16:36:37 -0700304 // only configure reformatters as needed
305 const audio_format_t targetFormat = mDownmixRequiresFormat != AUDIO_FORMAT_INVALID
306 ? mDownmixRequiresFormat : mMixerInFormat;
307 bool requiresReconfigure = false;
308 if (mFormat != targetFormat) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800309 mReformatBufferProvider.reset(new ReformatBufferProvider(
Andy Hung0f451e92014-08-04 21:28:47 -0700310 audio_channel_count_from_out_mask(channelMask),
Andy Hung7f475492014-08-25 16:36:37 -0700311 mFormat,
312 targetFormat,
Andy Hung8ed196a2018-01-05 13:21:11 -0800313 kCopyBufferFrameCount));
Andy Hung7f475492014-08-25 16:36:37 -0700314 requiresReconfigure = true;
Kevin Rocarde053bfa2017-11-09 22:07:34 -0800315 } else if (mFormat == AUDIO_FORMAT_PCM_FLOAT) {
316 // Input and output are floats, make sure application did not provide > 3db samples
317 // that would break volume application (b/68099072)
318 // TODO: add a trusted source flag to avoid the overhead
319 mReformatBufferProvider.reset(new ClampFloatBufferProvider(
320 audio_channel_count_from_out_mask(channelMask),
321 kCopyBufferFrameCount));
322 requiresReconfigure = true;
Andy Hung7f475492014-08-25 16:36:37 -0700323 }
324 if (targetFormat != mMixerInFormat) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800325 mPostDownmixReformatBufferProvider.reset(new ReformatBufferProvider(
Andy Hung7f475492014-08-25 16:36:37 -0700326 audio_channel_count_from_out_mask(mMixerChannelMask),
327 targetFormat,
328 mMixerInFormat,
Andy Hung8ed196a2018-01-05 13:21:11 -0800329 kCopyBufferFrameCount));
Andy Hung7f475492014-08-25 16:36:37 -0700330 requiresReconfigure = true;
331 }
332 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700333 reconfigureBufferProviders();
Andy Hung296b7412014-06-17 15:25:47 -0700334 }
335 return NO_ERROR;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700336}
337
Andy Hung8ed196a2018-01-05 13:21:11 -0800338void AudioMixer::Track::reconfigureBufferProviders()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700339{
Andy Hung3a34df92018-08-21 12:32:30 -0700340 // configure from upstream to downstream buffer providers.
Andy Hung0f451e92014-08-04 21:28:47 -0700341 bufferProvider = mInputBufferProvider;
Andy Hung8ed196a2018-01-05 13:21:11 -0800342 if (mReformatBufferProvider.get() != nullptr) {
Andy Hung0f451e92014-08-04 21:28:47 -0700343 mReformatBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800344 bufferProvider = mReformatBufferProvider.get();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700345 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800346 if (mDownmixerBufferProvider.get() != nullptr) {
347 mDownmixerBufferProvider->setBufferProvider(bufferProvider);
348 bufferProvider = mDownmixerBufferProvider.get();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700349 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800350 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
Andy Hung7f475492014-08-25 16:36:37 -0700351 mPostDownmixReformatBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800352 bufferProvider = mPostDownmixReformatBufferProvider.get();
Andy Hung7f475492014-08-25 16:36:37 -0700353 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800354 if (mTimestretchBufferProvider.get() != nullptr) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700355 mTimestretchBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800356 bufferProvider = mTimestretchBufferProvider.get();
Andy Hungc5656cc2015-03-26 19:04:33 -0700357 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700358}
359
Andy Hung1bc088a2018-02-09 15:57:31 -0800360void AudioMixer::destroy(int name)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800361{
Andy Hung1bc088a2018-02-09 15:57:31 -0800362 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800363 ALOGV("deleteTrackName(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800364
365 if (mTracks[name]->enabled) {
366 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700367 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800368 mTracks.erase(name); // deallocate track
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800369}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700370
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800371void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700372{
Andy Hung1bc088a2018-02-09 15:57:31 -0800373 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800374 const std::shared_ptr<Track> &track = mTracks[name];
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800375
Andy Hung8ed196a2018-01-05 13:21:11 -0800376 if (!track->enabled) {
377 track->enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800378 ALOGV("enable(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800379 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700380 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700381}
382
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800383void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700384{
Andy Hung1bc088a2018-02-09 15:57:31 -0800385 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800386 const std::shared_ptr<Track> &track = mTracks[name];
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800387
Andy Hung8ed196a2018-01-05 13:21:11 -0800388 if (track->enabled) {
389 track->enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800390 ALOGV("disable(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800391 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700392 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700393}
394
Andy Hung5866a3b2014-05-29 21:33:13 -0700395/* Sets the volume ramp variables for the AudioMixer.
396 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700397 * The volume ramp variables are used to transition from the previous
398 * volume to the set volume. ramp controls the duration of the transition.
399 * Its value is typically one state framecount period, but may also be 0,
400 * meaning "immediate."
Andy Hung5866a3b2014-05-29 21:33:13 -0700401 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700402 * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
403 * even if there is a nonzero floating point increment (in that case, the volume
404 * change is immediate). This restriction should be changed when the legacy mixer
405 * is removed (see #2).
406 * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
407 * when no longer needed.
408 *
409 * @param newVolume set volume target in floating point [0.0, 1.0].
410 * @param ramp number of frames to increment over. if ramp is 0, the volume
411 * should be set immediately. Currently ramp should not exceed 65535 (frames).
412 * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
413 * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
414 * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
415 * @param pSetVolume pointer to the float target volume, set on return.
416 * @param pPrevVolume pointer to the float previous volume, set on return.
417 * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
Andy Hung5866a3b2014-05-29 21:33:13 -0700418 * @return true if the volume has changed, false if volume is same.
419 */
Andy Hung5e58b0a2014-06-23 19:07:29 -0700420static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
421 int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
422 float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
Andy Hunge09c9942015-05-08 16:58:13 -0700423 // check floating point volume to see if it is identical to the previously
424 // set volume.
425 // We do not use a tolerance here (and reject changes too small)
426 // as it may be confusing to use a different value than the one set.
427 // If the resulting volume is too small to ramp, it is a direct set of the volume.
Andy Hung5e58b0a2014-06-23 19:07:29 -0700428 if (newVolume == *pSetVolume) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700429 return false;
430 }
Andy Hunge09c9942015-05-08 16:58:13 -0700431 if (newVolume < 0) {
432 newVolume = 0; // should not have negative volumes
Andy Hung5866a3b2014-05-29 21:33:13 -0700433 } else {
Andy Hunge09c9942015-05-08 16:58:13 -0700434 switch (fpclassify(newVolume)) {
435 case FP_SUBNORMAL:
436 case FP_NAN:
437 newVolume = 0;
438 break;
439 case FP_ZERO:
440 break; // zero volume is fine
441 case FP_INFINITE:
442 // Infinite volume could be handled consistently since
443 // floating point math saturates at infinities,
444 // but we limit volume to unity gain float.
445 // ramp = 0; break;
446 //
447 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
448 break;
449 case FP_NORMAL:
450 default:
451 // Floating point does not have problems with overflow wrap
452 // that integer has. However, we limit the volume to
453 // unity gain here.
454 // TODO: Revisit the volume limitation and perhaps parameterize.
455 if (newVolume > AudioMixer::UNITY_GAIN_FLOAT) {
456 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
457 }
458 break;
459 }
Andy Hung5866a3b2014-05-29 21:33:13 -0700460 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700461
Andy Hunge09c9942015-05-08 16:58:13 -0700462 // set floating point volume ramp
463 if (ramp != 0) {
464 // when the ramp completes, *pPrevVolume is set to *pSetVolume, so there
465 // is no computational mismatch; hence equality is checked here.
466 ALOGD_IF(*pPrevVolume != *pSetVolume, "previous float ramp hasn't finished,"
467 " prev:%f set_to:%f", *pPrevVolume, *pSetVolume);
468 const float inc = (newVolume - *pPrevVolume) / ramp; // could be inf, nan, subnormal
Andy Hung8ed196a2018-01-05 13:21:11 -0800469 // could be inf, cannot be nan, subnormal
470 const float maxv = std::max(newVolume, *pPrevVolume);
Andy Hunge09c9942015-05-08 16:58:13 -0700471
472 if (isnormal(inc) // inc must be a normal number (no subnormals, infinite, nan)
473 && maxv + inc != maxv) { // inc must make forward progress
474 *pVolumeInc = inc;
475 // ramp is set now.
476 // Note: if newVolume is 0, then near the end of the ramp,
477 // it may be possible that the ramped volume may be subnormal or
478 // temporarily negative by a small amount or subnormal due to floating
479 // point inaccuracies.
480 } else {
481 ramp = 0; // ramp not allowed
482 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700483 }
Andy Hunge09c9942015-05-08 16:58:13 -0700484
485 // compute and check integer volume, no need to check negative values
486 // The integer volume is limited to "unity_gain" to avoid wrapping and other
487 // audio artifacts, so it never reaches the range limit of U4.28.
488 // We safely use signed 16 and 32 bit integers here.
489 const float scaledVolume = newVolume * AudioMixer::UNITY_GAIN_INT; // not neg, subnormal, nan
490 const int32_t intVolume = (scaledVolume >= (float)AudioMixer::UNITY_GAIN_INT) ?
491 AudioMixer::UNITY_GAIN_INT : (int32_t)scaledVolume;
492
493 // set integer volume ramp
494 if (ramp != 0) {
495 // integer volume is U4.12 (to use 16 bit multiplies), but ramping uses U4.28.
496 // when the ramp completes, *pIntPrevVolume is set to *pIntSetVolume << 16, so there
497 // is no computational mismatch; hence equality is checked here.
498 ALOGD_IF(*pIntPrevVolume != *pIntSetVolume << 16, "previous int ramp hasn't finished,"
499 " prev:%d set_to:%d", *pIntPrevVolume, *pIntSetVolume << 16);
500 const int32_t inc = ((intVolume << 16) - *pIntPrevVolume) / ramp;
501
502 if (inc != 0) { // inc must make forward progress
503 *pIntVolumeInc = inc;
504 } else {
505 ramp = 0; // ramp not allowed
506 }
507 }
508
509 // if no ramp, or ramp not allowed, then clear float and integer increments
510 if (ramp == 0) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700511 *pVolumeInc = 0;
512 *pPrevVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700513 *pIntVolumeInc = 0;
514 *pIntPrevVolume = intVolume << 16;
515 }
Andy Hunge09c9942015-05-08 16:58:13 -0700516 *pSetVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700517 *pIntSetVolume = intVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700518 return true;
519}
520
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800521void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700522{
Andy Hung1bc088a2018-02-09 15:57:31 -0800523 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800524 const std::shared_ptr<Track> &track = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700525
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000526 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
527 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700528
529 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700530
Mathias Agopian65ab4712010-07-14 17:59:35 -0700531 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800532 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700533 case CHANNEL_MASK: {
Andy Hunge93b6b72014-07-17 21:30:53 -0700534 const audio_channel_mask_t trackChannelMask =
535 static_cast<audio_channel_mask_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800536 if (setChannelMasks(name, trackChannelMask, track->mMixerChannelMask)) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700537 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
Andy Hung8ed196a2018-01-05 13:21:11 -0800538 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700539 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700540 } break;
541 case MAIN_BUFFER:
Andy Hung8ed196a2018-01-05 13:21:11 -0800542 if (track->mainBuffer != valueBuf) {
543 track->mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100544 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Andy Hung8ed196a2018-01-05 13:21:11 -0800545 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700546 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700547 break;
548 case AUX_BUFFER:
Andy Hung8ed196a2018-01-05 13:21:11 -0800549 if (track->auxBuffer != valueBuf) {
550 track->auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100551 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Andy Hung8ed196a2018-01-05 13:21:11 -0800552 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700553 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700554 break;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700555 case FORMAT: {
556 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800557 if (track->mFormat != format) {
Andy Hungef7c7fb2014-05-12 16:51:41 -0700558 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
Andy Hung8ed196a2018-01-05 13:21:11 -0800559 track->mFormat = format;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700560 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
Andy Hung8ed196a2018-01-05 13:21:11 -0800561 track->prepareForReformat();
562 invalidate();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700563 }
564 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700565 // FIXME do we want to support setting the downmix type from AudioFlinger?
566 // for a specific track? or per mixer?
567 /* case DOWNMIX_TYPE:
568 break */
Andy Hung78820702014-02-28 16:23:02 -0800569 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800570 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800571 if (track->mMixerFormat != format) {
572 track->mMixerFormat = format;
Andy Hung78820702014-02-28 16:23:02 -0800573 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800574 }
575 } break;
Andy Hunge93b6b72014-07-17 21:30:53 -0700576 case MIXER_CHANNEL_MASK: {
577 const audio_channel_mask_t mixerChannelMask =
578 static_cast<audio_channel_mask_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800579 if (setChannelMasks(name, track->channelMask, mixerChannelMask)) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700580 ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
Andy Hung8ed196a2018-01-05 13:21:11 -0800581 invalidate();
Andy Hunge93b6b72014-07-17 21:30:53 -0700582 }
583 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700584 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800585 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700586 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700587 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700588
Mathias Agopian65ab4712010-07-14 17:59:35 -0700589 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800590 switch (param) {
591 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800592 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800593 if (track->setResampler(uint32_t(valueInt), mSampleRate)) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700594 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
595 uint32_t(valueInt));
Andy Hung8ed196a2018-01-05 13:21:11 -0800596 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700597 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800598 break;
599 case RESET:
Andy Hung8ed196a2018-01-05 13:21:11 -0800600 track->resetResampler();
601 invalidate();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800602 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700603 case REMOVE:
Andy Hung8ed196a2018-01-05 13:21:11 -0800604 track->mResampler.reset(nullptr);
605 track->sampleRate = mSampleRate;
606 invalidate();
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700607 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700608 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800609 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800610 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700611 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700612
Mathias Agopian65ab4712010-07-14 17:59:35 -0700613 case RAMP_VOLUME:
614 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800615 switch (param) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800616 case AUXLEVEL:
Andy Hung6be49402014-05-30 10:42:03 -0700617 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung8ed196a2018-01-05 13:21:11 -0800618 target == RAMP_VOLUME ? mFrameCount : 0,
619 &track->auxLevel, &track->prevAuxLevel, &track->auxInc,
620 &track->mAuxLevel, &track->mPrevAuxLevel, &track->mAuxInc)) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700621 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
Andy Hung8ed196a2018-01-05 13:21:11 -0800622 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track->auxLevel);
623 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700624 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800625 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700626 default:
Andy Hunge93b6b72014-07-17 21:30:53 -0700627 if ((unsigned)param >= VOLUME0 && (unsigned)param < VOLUME0 + MAX_NUM_VOLUMES) {
628 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung8ed196a2018-01-05 13:21:11 -0800629 target == RAMP_VOLUME ? mFrameCount : 0,
630 &track->volume[param - VOLUME0],
631 &track->prevVolume[param - VOLUME0],
632 &track->volumeInc[param - VOLUME0],
633 &track->mVolume[param - VOLUME0],
634 &track->mPrevVolume[param - VOLUME0],
635 &track->mVolumeInc[param - VOLUME0])) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700636 ALOGV("setParameter(%s, VOLUME%d: %04x)",
637 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
Andy Hung8ed196a2018-01-05 13:21:11 -0800638 track->volume[param - VOLUME0]);
639 invalidate();
Andy Hunge93b6b72014-07-17 21:30:53 -0700640 }
641 } else {
642 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
643 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700644 }
645 break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700646 case TIMESTRETCH:
647 switch (param) {
648 case PLAYBACK_RATE: {
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700649 const AudioPlaybackRate *playbackRate =
650 reinterpret_cast<AudioPlaybackRate*>(value);
Ricardo Garcia6c7f0622015-04-30 18:39:16 -0700651 ALOGW_IF(!isAudioPlaybackRateValid(*playbackRate),
Andy Hung8ed196a2018-01-05 13:21:11 -0800652 "bad parameters speed %f, pitch %f",
653 playbackRate->mSpeed, playbackRate->mPitch);
654 if (track->setPlaybackRate(*playbackRate)) {
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700655 ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE "
656 "%f %f %d %d",
657 playbackRate->mSpeed,
658 playbackRate->mPitch,
659 playbackRate->mStretchMode,
660 playbackRate->mFallbackMode);
Andy Hung8ed196a2018-01-05 13:21:11 -0800661 // invalidate(); (should not require reconfigure)
Andy Hungc5656cc2015-03-26 19:04:33 -0700662 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700663 } break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700664 default:
665 LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);
666 }
667 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700668
669 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800670 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700671 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700672}
673
Andy Hung8ed196a2018-01-05 13:21:11 -0800674bool AudioMixer::Track::setResampler(uint32_t trackSampleRate, uint32_t devSampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700675{
Andy Hung8ed196a2018-01-05 13:21:11 -0800676 if (trackSampleRate != devSampleRate || mResampler.get() != nullptr) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700677 if (sampleRate != trackSampleRate) {
678 sampleRate = trackSampleRate;
Andy Hung8ed196a2018-01-05 13:21:11 -0800679 if (mResampler.get() == nullptr) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700680 ALOGV("Creating resampler from track %d Hz to device %d Hz",
681 trackSampleRate, devSampleRate);
Glenn Kastenac602052012-10-01 14:04:31 -0700682 AudioResampler::src_quality quality;
683 // force lowest quality level resampler if use case isn't music or video
684 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
685 // quality level based on the initial ratio, but that could change later.
686 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
Andy Hungdb4c0312015-05-06 08:46:52 -0700687 if (isMusicRate(trackSampleRate)) {
Glenn Kastenac602052012-10-01 14:04:31 -0700688 quality = AudioResampler::DEFAULT_QUALITY;
Andy Hungdb4c0312015-05-06 08:46:52 -0700689 } else {
690 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700691 }
Andy Hung296b7412014-06-17 15:25:47 -0700692
Andy Hunge93b6b72014-07-17 21:30:53 -0700693 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
694 // but if none exists, it is the channel count (1 for mono).
Andy Hung8ed196a2018-01-05 13:21:11 -0800695 const int resamplerChannelCount = mDownmixerBufferProvider.get() != nullptr
Andy Hunge93b6b72014-07-17 21:30:53 -0700696 ? mMixerChannelCount : channelCount;
Andy Hung9a592762014-07-21 21:56:01 -0700697 ALOGVV("Creating resampler:"
698 " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
699 mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
Andy Hung8ed196a2018-01-05 13:21:11 -0800700 mResampler.reset(AudioResampler::create(
Andy Hung3348e362014-07-07 10:21:44 -0700701 mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -0700702 resamplerChannelCount,
Andy Hung8ed196a2018-01-05 13:21:11 -0800703 devSampleRate, quality));
Mathias Agopian65ab4712010-07-14 17:59:35 -0700704 }
705 return true;
706 }
707 }
708 return false;
709}
710
Andy Hung8ed196a2018-01-05 13:21:11 -0800711bool AudioMixer::Track::setPlaybackRate(const AudioPlaybackRate &playbackRate)
Andy Hungc5656cc2015-03-26 19:04:33 -0700712{
Andy Hung8ed196a2018-01-05 13:21:11 -0800713 if ((mTimestretchBufferProvider.get() == nullptr &&
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700714 fabs(playbackRate.mSpeed - mPlaybackRate.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
715 fabs(playbackRate.mPitch - mPlaybackRate.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA) ||
716 isAudioPlaybackRateEqual(playbackRate, mPlaybackRate)) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700717 return false;
718 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700719 mPlaybackRate = playbackRate;
Andy Hung8ed196a2018-01-05 13:21:11 -0800720 if (mTimestretchBufferProvider.get() == nullptr) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700721 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
722 // but if none exists, it is the channel count (1 for mono).
Andy Hung8ed196a2018-01-05 13:21:11 -0800723 const int timestretchChannelCount = mDownmixerBufferProvider.get() != nullptr
Andy Hungc5656cc2015-03-26 19:04:33 -0700724 ? mMixerChannelCount : channelCount;
Andy Hung8ed196a2018-01-05 13:21:11 -0800725 mTimestretchBufferProvider.reset(new TimestretchBufferProvider(timestretchChannelCount,
726 mMixerInFormat, sampleRate, playbackRate));
Andy Hungc5656cc2015-03-26 19:04:33 -0700727 reconfigureBufferProviders();
728 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -0800729 static_cast<TimestretchBufferProvider*>(mTimestretchBufferProvider.get())
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700730 ->setPlaybackRate(playbackRate);
Andy Hungc5656cc2015-03-26 19:04:33 -0700731 }
732 return true;
733}
734
Andy Hung5e58b0a2014-06-23 19:07:29 -0700735/* Checks to see if the volume ramp has completed and clears the increment
736 * variables appropriately.
737 *
738 * FIXME: There is code to handle int/float ramp variable switchover should it not
739 * complete within a mixer buffer processing call, but it is preferred to avoid switchover
740 * due to precision issues. The switchover code is included for legacy code purposes
741 * and can be removed once the integer volume is removed.
742 *
743 * It is not sufficient to clear only the volumeInc integer variable because
744 * if one channel requires ramping, all channels are ramped.
745 *
746 * There is a bit of duplicated code here, but it keeps backward compatibility.
747 */
Andy Hung8ed196a2018-01-05 13:21:11 -0800748inline void AudioMixer::Track::adjustVolumeRamp(bool aux, bool useFloat)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700749{
Andy Hung5e58b0a2014-06-23 19:07:29 -0700750 if (useFloat) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700751 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Eric Laurent43412fc2015-05-08 16:14:36 -0700752 if ((mVolumeInc[i] > 0 && mPrevVolume[i] + mVolumeInc[i] >= mVolume[i]) ||
753 (mVolumeInc[i] < 0 && mPrevVolume[i] + mVolumeInc[i] <= mVolume[i])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700754 volumeInc[i] = 0;
755 prevVolume[i] = volume[i] << 16;
756 mVolumeInc[i] = 0.;
757 mPrevVolume[i] = mVolume[i];
Andy Hung5e58b0a2014-06-23 19:07:29 -0700758 } else {
759 //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
760 prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
761 }
762 }
763 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -0700764 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700765 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
766 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
767 volumeInc[i] = 0;
768 prevVolume[i] = volume[i] << 16;
769 mVolumeInc[i] = 0.;
770 mPrevVolume[i] = mVolume[i];
771 } else {
772 //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
773 mPrevVolume[i] = float_from_u4_28(prevVolume[i]);
774 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700775 }
776 }
Andy Hung116a4982017-11-30 10:15:08 -0800777
Mathias Agopian65ab4712010-07-14 17:59:35 -0700778 if (aux) {
Andy Hung116a4982017-11-30 10:15:08 -0800779#ifdef FLOAT_AUX
780 if (useFloat) {
781 if ((mAuxInc > 0.f && mPrevAuxLevel + mAuxInc >= mAuxLevel) ||
782 (mAuxInc < 0.f && mPrevAuxLevel + mAuxInc <= mAuxLevel)) {
783 auxInc = 0;
784 prevAuxLevel = auxLevel << 16;
785 mAuxInc = 0.f;
786 mPrevAuxLevel = mAuxLevel;
787 }
788 } else
789#endif
790 if ((auxInc > 0 && ((prevAuxLevel + auxInc) >> 16) >= auxLevel) ||
791 (auxInc < 0 && ((prevAuxLevel + auxInc) >> 16) <= auxLevel)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700792 auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700793 prevAuxLevel = auxLevel << 16;
Andy Hung116a4982017-11-30 10:15:08 -0800794 mAuxInc = 0.f;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700795 mPrevAuxLevel = mAuxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700796 }
797 }
798}
799
Glenn Kastenc59c0042012-02-02 14:06:11 -0800800size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800801{
Andy Hung8ed196a2018-01-05 13:21:11 -0800802 const auto it = mTracks.find(name);
803 if (it != mTracks.end()) {
804 return it->second->getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800805 }
806 return 0;
807}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700808
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800809void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700810{
Andy Hung1bc088a2018-02-09 15:57:31 -0800811 LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800812 const std::shared_ptr<Track> &track = mTracks[name];
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700813
Andy Hung8ed196a2018-01-05 13:21:11 -0800814 if (track->mInputBufferProvider == bufferProvider) {
Andy Hung1d26ddf2014-05-29 15:53:09 -0700815 return; // don't reset any buffer providers if identical.
816 }
Andy Hung3a34df92018-08-21 12:32:30 -0700817 // reset order from downstream to upstream buffer providers.
818 if (track->mTimestretchBufferProvider.get() != nullptr) {
819 track->mTimestretchBufferProvider->reset();
Andy Hung8ed196a2018-01-05 13:21:11 -0800820 } else if (track->mPostDownmixReformatBufferProvider.get() != nullptr) {
821 track->mPostDownmixReformatBufferProvider->reset();
Andy Hung3a34df92018-08-21 12:32:30 -0700822 } else if (track->mDownmixerBufferProvider != nullptr) {
823 track->mDownmixerBufferProvider->reset();
824 } else if (track->mReformatBufferProvider.get() != nullptr) {
825 track->mReformatBufferProvider->reset();
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700826 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700827
Andy Hung8ed196a2018-01-05 13:21:11 -0800828 track->mInputBufferProvider = bufferProvider;
829 track->reconfigureBufferProviders();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700830}
831
Andy Hung8ed196a2018-01-05 13:21:11 -0800832void AudioMixer::process__validate()
Mathias Agopian65ab4712010-07-14 17:59:35 -0700833{
Andy Hung395db4b2014-08-25 17:15:29 -0700834 // TODO: fix all16BitsStereNoResample logic to
835 // either properly handle muted tracks (it should ignore them)
836 // or remove altogether as an obsolete optimization.
Glenn Kasten4c340c62012-01-27 12:33:54 -0800837 bool all16BitsStereoNoResample = true;
838 bool resampling = false;
839 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700840
Andy Hung8ed196a2018-01-05 13:21:11 -0800841 mEnabled.clear();
842 mGroups.clear();
843 for (const auto &pair : mTracks) {
844 const int name = pair.first;
845 const std::shared_ptr<Track> &t = pair.second;
846 if (!t->enabled) continue;
847
848 mEnabled.emplace_back(name); // we add to mEnabled in order of name.
849 mGroups[t->mainBuffer].emplace_back(name); // mGroups also in order of name.
850
Mathias Agopian65ab4712010-07-14 17:59:35 -0700851 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700852 // FIXME can overflow (mask is only 3 bits)
Andy Hung8ed196a2018-01-05 13:21:11 -0800853 n |= NEEDS_CHANNEL_1 + t->channelCount - 1;
854 if (t->doesResample()) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700855 n |= NEEDS_RESAMPLE;
856 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800857 if (t->auxLevel != 0 && t->auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700858 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700859 }
860
Andy Hung8ed196a2018-01-05 13:21:11 -0800861 if (t->volumeInc[0]|t->volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800862 volumeRamp = true;
Andy Hung8ed196a2018-01-05 13:21:11 -0800863 } else if (!t->doesResample() && t->volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700864 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700865 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800866 t->needs = n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700867
Glenn Kastend6fadf02013-10-30 14:37:29 -0700868 if (n & NEEDS_MUTE) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800869 t->hook = &Track::track__nop;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700870 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700871 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800872 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700873 }
Glenn Kastend6fadf02013-10-30 14:37:29 -0700874 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800875 all16BitsStereoNoResample = false;
876 resampling = true;
Andy Hung8ed196a2018-01-05 13:21:11 -0800877 t->hook = Track::getTrackHook(TRACKTYPE_RESAMPLE, t->mMixerChannelCount,
878 t->mMixerInFormat, t->mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700879 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Chih-Hung Hsieh09f9c022018-07-27 10:22:35 -0700880 "Track %d needs downmix + resample", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700881 } else {
882 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
Andy Hung8ed196a2018-01-05 13:21:11 -0800883 t->hook = Track::getTrackHook(
884 (t->mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO // TODO: MONO_HACK
885 && t->channelMask == AUDIO_CHANNEL_OUT_MONO)
Andy Hunge93b6b72014-07-17 21:30:53 -0700886 ? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,
Andy Hung8ed196a2018-01-05 13:21:11 -0800887 t->mMixerChannelCount,
888 t->mMixerInFormat, t->mMixerFormat);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800889 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700890 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700891 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Andy Hung8ed196a2018-01-05 13:21:11 -0800892 t->hook = Track::getTrackHook(TRACKTYPE_NORESAMPLE, t->mMixerChannelCount,
893 t->mMixerInFormat, t->mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700894 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Chih-Hung Hsieh09f9c022018-07-27 10:22:35 -0700895 "Track %d needs downmix", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700896 }
897 }
898 }
899 }
900
901 // select the processing hooks
Andy Hung8ed196a2018-01-05 13:21:11 -0800902 mHook = &AudioMixer::process__nop;
903 if (mEnabled.size() > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700904 if (resampling) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800905 if (mOutputTemp.get() == nullptr) {
906 mOutputTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700907 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800908 if (mResampleTemp.get() == nullptr) {
909 mResampleTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700910 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800911 mHook = &AudioMixer::process__genericResampling;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700912 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -0800913 // we keep temp arrays around.
914 mHook = &AudioMixer::process__genericNoResampling;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700915 if (all16BitsStereoNoResample && !volumeRamp) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800916 if (mEnabled.size() == 1) {
917 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
918 if ((t->needs & NEEDS_MUTE) == 0) {
Andy Hung395db4b2014-08-25 17:15:29 -0700919 // The check prevents a muted track from acquiring a process hook.
920 //
921 // This is dangerous if the track is MONO as that requires
922 // special case handling due to implicit channel duplication.
923 // Stereo or Multichannel should actually be fine here.
Andy Hung8ed196a2018-01-05 13:21:11 -0800924 mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
925 t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
Andy Hung395db4b2014-08-25 17:15:29 -0700926 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700927 }
928 }
929 }
930 }
931
Andy Hung8ed196a2018-01-05 13:21:11 -0800932 ALOGV("mixer configuration change: %zu "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700933 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -0800934 mEnabled.size(), all16BitsStereoNoResample, resampling, volumeRamp);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700935
Andy Hung8ed196a2018-01-05 13:21:11 -0800936 process();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700937
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800938 // Now that the volume ramp has been done, set optimal state and
939 // track hooks for subsequent mixer process
Andy Hung8ed196a2018-01-05 13:21:11 -0800940 if (mEnabled.size() > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800941 bool allMuted = true;
Andy Hung8ed196a2018-01-05 13:21:11 -0800942
943 for (const int name : mEnabled) {
944 const std::shared_ptr<Track> &t = mTracks[name];
945 if (!t->doesResample() && t->volumeRL == 0) {
946 t->needs |= NEEDS_MUTE;
947 t->hook = &Track::track__nop;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800948 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800949 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800950 }
951 }
952 if (allMuted) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800953 mHook = &AudioMixer::process__nop;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800954 } else if (all16BitsStereoNoResample) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800955 if (mEnabled.size() == 1) {
956 //const int i = 31 - __builtin_clz(enabledTracks);
957 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
Andy Hung395db4b2014-08-25 17:15:29 -0700958 // Muted single tracks handled by allMuted above.
Andy Hung8ed196a2018-01-05 13:21:11 -0800959 mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
960 t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800961 }
962 }
963 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700964}
965
Andy Hung8ed196a2018-01-05 13:21:11 -0800966void AudioMixer::Track::track__genericResample(
967 int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700968{
Andy Hung296b7412014-06-17 15:25:47 -0700969 ALOGVV("track__genericResample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -0800970 mResampler->setSampleRate(sampleRate);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700971
972 // ramp gain - resample to temp buffer and scale/mix in 2nd step
973 if (aux != NULL) {
974 // always resample with unity gain when sending to auxiliary buffer to be able
975 // to apply send level after resampling
Andy Hung8ed196a2018-01-05 13:21:11 -0800976 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
977 memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(int32_t));
978 mResampler->resample(temp, outFrameCount, bufferProvider);
979 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
980 volumeRampStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700981 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -0800982 volumeStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700983 }
984 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -0800985 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
986 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700987 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
Andy Hung8ed196a2018-01-05 13:21:11 -0800988 mResampler->resample(temp, outFrameCount, bufferProvider);
989 volumeRampStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700990 }
991
992 // constant gain
993 else {
Andy Hung8ed196a2018-01-05 13:21:11 -0800994 mResampler->setVolume(mVolume[0], mVolume[1]);
995 mResampler->resample(out, outFrameCount, bufferProvider);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700996 }
997 }
998}
999
Andy Hung8ed196a2018-01-05 13:21:11 -08001000void AudioMixer::Track::track__nop(int32_t* out __unused,
Andy Hungee931ff2014-01-28 13:44:14 -08001001 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001002{
1003}
1004
Andy Hung8ed196a2018-01-05 13:21:11 -08001005void AudioMixer::Track::volumeRampStereo(
1006 int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001007{
Andy Hung8ed196a2018-01-05 13:21:11 -08001008 int32_t vl = prevVolume[0];
1009 int32_t vr = prevVolume[1];
1010 const int32_t vlInc = volumeInc[0];
1011 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001012
Steve Blockb8a80522011-12-20 16:23:08 +00001013 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001014 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001015 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1016
1017 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -08001018 if (CC_UNLIKELY(aux != NULL)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001019 int32_t va = prevAuxLevel;
1020 const int32_t vaInc = auxInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001021 int32_t l;
1022 int32_t r;
1023
1024 do {
1025 l = (*temp++ >> 12);
1026 r = (*temp++ >> 12);
1027 *out++ += (vl >> 16) * l;
1028 *out++ += (vr >> 16) * r;
1029 *aux++ += (va >> 17) * (l + r);
1030 vl += vlInc;
1031 vr += vrInc;
1032 va += vaInc;
1033 } while (--frameCount);
Andy Hung8ed196a2018-01-05 13:21:11 -08001034 prevAuxLevel = va;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001035 } else {
1036 do {
1037 *out++ += (vl >> 16) * (*temp++ >> 12);
1038 *out++ += (vr >> 16) * (*temp++ >> 12);
1039 vl += vlInc;
1040 vr += vrInc;
1041 } while (--frameCount);
1042 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001043 prevVolume[0] = vl;
1044 prevVolume[1] = vr;
1045 adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001046}
1047
Andy Hung8ed196a2018-01-05 13:21:11 -08001048void AudioMixer::Track::volumeStereo(
1049 int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001050{
Andy Hung8ed196a2018-01-05 13:21:11 -08001051 const int16_t vl = volume[0];
1052 const int16_t vr = volume[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001053
Glenn Kastenf6b16782011-12-15 09:51:17 -08001054 if (CC_UNLIKELY(aux != NULL)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001055 const int16_t va = auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001056 do {
1057 int16_t l = (int16_t)(*temp++ >> 12);
1058 int16_t r = (int16_t)(*temp++ >> 12);
1059 out[0] = mulAdd(l, vl, out[0]);
1060 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1061 out[1] = mulAdd(r, vr, out[1]);
1062 out += 2;
1063 aux[0] = mulAdd(a, va, aux[0]);
1064 aux++;
1065 } while (--frameCount);
1066 } else {
1067 do {
1068 int16_t l = (int16_t)(*temp++ >> 12);
1069 int16_t r = (int16_t)(*temp++ >> 12);
1070 out[0] = mulAdd(l, vl, out[0]);
1071 out[1] = mulAdd(r, vr, out[1]);
1072 out += 2;
1073 } while (--frameCount);
1074 }
1075}
1076
Andy Hung8ed196a2018-01-05 13:21:11 -08001077void AudioMixer::Track::track__16BitsStereo(
1078 int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001079{
Andy Hung296b7412014-06-17 15:25:47 -07001080 ALOGVV("track__16BitsStereo\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001081 const int16_t *in = static_cast<const int16_t *>(mIn);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001082
Glenn Kastenf6b16782011-12-15 09:51:17 -08001083 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001084 int32_t l;
1085 int32_t r;
1086 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001087 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
1088 int32_t vl = prevVolume[0];
1089 int32_t vr = prevVolume[1];
1090 int32_t va = prevAuxLevel;
1091 const int32_t vlInc = volumeInc[0];
1092 const int32_t vrInc = volumeInc[1];
1093 const int32_t vaInc = auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001094 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001095 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001096 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1097
1098 do {
1099 l = (int32_t)*in++;
1100 r = (int32_t)*in++;
1101 *out++ += (vl >> 16) * l;
1102 *out++ += (vr >> 16) * r;
1103 *aux++ += (va >> 17) * (l + r);
1104 vl += vlInc;
1105 vr += vrInc;
1106 va += vaInc;
1107 } while (--frameCount);
1108
Andy Hung8ed196a2018-01-05 13:21:11 -08001109 prevVolume[0] = vl;
1110 prevVolume[1] = vr;
1111 prevAuxLevel = va;
1112 adjustVolumeRamp(true);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001113 }
1114
1115 // constant gain
1116 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001117 const uint32_t vrl = volumeRL;
1118 const int16_t va = (int16_t)auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001119 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001120 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001121 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1122 in += 2;
1123 out[0] = mulAddRL(1, rl, vrl, out[0]);
1124 out[1] = mulAddRL(0, rl, vrl, out[1]);
1125 out += 2;
1126 aux[0] = mulAdd(a, va, aux[0]);
1127 aux++;
1128 } while (--frameCount);
1129 }
1130 } else {
1131 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001132 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
1133 int32_t vl = prevVolume[0];
1134 int32_t vr = prevVolume[1];
1135 const int32_t vlInc = volumeInc[0];
1136 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001137
Steve Blockb8a80522011-12-20 16:23:08 +00001138 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001139 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001140 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1141
1142 do {
1143 *out++ += (vl >> 16) * (int32_t) *in++;
1144 *out++ += (vr >> 16) * (int32_t) *in++;
1145 vl += vlInc;
1146 vr += vrInc;
1147 } while (--frameCount);
1148
Andy Hung8ed196a2018-01-05 13:21:11 -08001149 prevVolume[0] = vl;
1150 prevVolume[1] = vr;
1151 adjustVolumeRamp(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001152 }
1153
1154 // constant gain
1155 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001156 const uint32_t vrl = volumeRL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001157 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001158 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001159 in += 2;
1160 out[0] = mulAddRL(1, rl, vrl, out[0]);
1161 out[1] = mulAddRL(0, rl, vrl, out[1]);
1162 out += 2;
1163 } while (--frameCount);
1164 }
1165 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001166 mIn = in;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001167}
1168
Andy Hung8ed196a2018-01-05 13:21:11 -08001169void AudioMixer::Track::track__16BitsMono(
1170 int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001171{
Andy Hung296b7412014-06-17 15:25:47 -07001172 ALOGVV("track__16BitsMono\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001173 const int16_t *in = static_cast<int16_t const *>(mIn);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001174
Glenn Kastenf6b16782011-12-15 09:51:17 -08001175 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001176 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001177 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
1178 int32_t vl = prevVolume[0];
1179 int32_t vr = prevVolume[1];
1180 int32_t va = prevAuxLevel;
1181 const int32_t vlInc = volumeInc[0];
1182 const int32_t vrInc = volumeInc[1];
1183 const int32_t vaInc = auxInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001184
Steve Blockb8a80522011-12-20 16:23:08 +00001185 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001186 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001187 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1188
1189 do {
1190 int32_t l = *in++;
1191 *out++ += (vl >> 16) * l;
1192 *out++ += (vr >> 16) * l;
1193 *aux++ += (va >> 16) * l;
1194 vl += vlInc;
1195 vr += vrInc;
1196 va += vaInc;
1197 } while (--frameCount);
1198
Andy Hung8ed196a2018-01-05 13:21:11 -08001199 prevVolume[0] = vl;
1200 prevVolume[1] = vr;
1201 prevAuxLevel = va;
1202 adjustVolumeRamp(true);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001203 }
1204 // constant gain
1205 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001206 const int16_t vl = volume[0];
1207 const int16_t vr = volume[1];
1208 const int16_t va = (int16_t)auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001209 do {
1210 int16_t l = *in++;
1211 out[0] = mulAdd(l, vl, out[0]);
1212 out[1] = mulAdd(l, vr, out[1]);
1213 out += 2;
1214 aux[0] = mulAdd(l, va, aux[0]);
1215 aux++;
1216 } while (--frameCount);
1217 }
1218 } else {
1219 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001220 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
1221 int32_t vl = prevVolume[0];
1222 int32_t vr = prevVolume[1];
1223 const int32_t vlInc = volumeInc[0];
1224 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001225
Steve Blockb8a80522011-12-20 16:23:08 +00001226 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001227 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001228 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1229
1230 do {
1231 int32_t l = *in++;
1232 *out++ += (vl >> 16) * l;
1233 *out++ += (vr >> 16) * l;
1234 vl += vlInc;
1235 vr += vrInc;
1236 } while (--frameCount);
1237
Andy Hung8ed196a2018-01-05 13:21:11 -08001238 prevVolume[0] = vl;
1239 prevVolume[1] = vr;
1240 adjustVolumeRamp(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001241 }
1242 // constant gain
1243 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001244 const int16_t vl = volume[0];
1245 const int16_t vr = volume[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001246 do {
1247 int16_t l = *in++;
1248 out[0] = mulAdd(l, vl, out[0]);
1249 out[1] = mulAdd(l, vr, out[1]);
1250 out += 2;
1251 } while (--frameCount);
1252 }
1253 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001254 mIn = in;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001255}
1256
Mathias Agopian65ab4712010-07-14 17:59:35 -07001257// no-op case
Andy Hung8ed196a2018-01-05 13:21:11 -08001258void AudioMixer::process__nop()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001259{
Andy Hung296b7412014-06-17 15:25:47 -07001260 ALOGVV("process__nop\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001261
1262 for (const auto &pair : mGroups) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001263 // process by group of tracks with same output buffer to
1264 // avoid multiple memset() on same buffer
Andy Hung8ed196a2018-01-05 13:21:11 -08001265 const auto &group = pair.second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001266
Andy Hung8ed196a2018-01-05 13:21:11 -08001267 const std::shared_ptr<Track> &t = mTracks[group[0]];
1268 memset(t->mainBuffer, 0,
1269 mFrameCount * t->mMixerChannelCount
1270 * audio_bytes_per_sample(t->mMixerFormat));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001271
Andy Hung8ed196a2018-01-05 13:21:11 -08001272 // now consume data
1273 for (const int name : group) {
1274 const std::shared_ptr<Track> &t = mTracks[name];
1275 size_t outFrames = mFrameCount;
1276 while (outFrames) {
1277 t->buffer.frameCount = outFrames;
1278 t->bufferProvider->getNextBuffer(&t->buffer);
1279 if (t->buffer.raw == NULL) break;
1280 outFrames -= t->buffer.frameCount;
1281 t->bufferProvider->releaseBuffer(&t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001282 }
1283 }
1284 }
1285}
1286
1287// generic code without resampling
Andy Hung8ed196a2018-01-05 13:21:11 -08001288void AudioMixer::process__genericNoResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001289{
Andy Hung296b7412014-06-17 15:25:47 -07001290 ALOGVV("process__genericNoResampling\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001291 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1292
Andy Hung8ed196a2018-01-05 13:21:11 -08001293 for (const auto &pair : mGroups) {
1294 // process by group of tracks with same output main buffer to
1295 // avoid multiple memset() on same buffer
1296 const auto &group = pair.second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001297
Andy Hung8ed196a2018-01-05 13:21:11 -08001298 // acquire buffer
1299 for (const int name : group) {
1300 const std::shared_ptr<Track> &t = mTracks[name];
1301 t->buffer.frameCount = mFrameCount;
1302 t->bufferProvider->getNextBuffer(&t->buffer);
1303 t->frameCount = t->buffer.frameCount;
1304 t->mIn = t->buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001305 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001306
1307 int32_t *out = (int *)pair.first;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001308 size_t numFrames = 0;
1309 do {
Andy Hung8ed196a2018-01-05 13:21:11 -08001310 const size_t frameCount = std::min((size_t)BLOCKSIZE, mFrameCount - numFrames);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001311 memset(outTemp, 0, sizeof(outTemp));
Andy Hung8ed196a2018-01-05 13:21:11 -08001312 for (const int name : group) {
1313 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001314 int32_t *aux = NULL;
Andy Hung8ed196a2018-01-05 13:21:11 -08001315 if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
1316 aux = t->auxBuffer + numFrames;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001317 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001318 for (int outFrames = frameCount; outFrames > 0; ) {
1319 // t->in == nullptr can happen if the track was flushed just after having
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301320 // been enabled for mixing.
Andy Hung8ed196a2018-01-05 13:21:11 -08001321 if (t->mIn == nullptr) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301322 break;
1323 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001324 size_t inFrames = (t->frameCount > outFrames)?outFrames:t->frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001325 if (inFrames > 0) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001326 (t.get()->*t->hook)(
1327 outTemp + (frameCount - outFrames) * t->mMixerChannelCount,
1328 inFrames, mResampleTemp.get() /* naked ptr */, aux);
1329 t->frameCount -= inFrames;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001330 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001331 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001332 aux += inFrames;
1333 }
1334 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001335 if (t->frameCount == 0 && outFrames) {
1336 t->bufferProvider->releaseBuffer(&t->buffer);
1337 t->buffer.frameCount = (mFrameCount - numFrames) -
Yahan Zhouc1c11b42018-01-16 12:44:04 -08001338 (frameCount - outFrames);
Andy Hung8ed196a2018-01-05 13:21:11 -08001339 t->bufferProvider->getNextBuffer(&t->buffer);
1340 t->mIn = t->buffer.raw;
1341 if (t->mIn == nullptr) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001342 break;
1343 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001344 t->frameCount = t->buffer.frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001345 }
1346 }
1347 }
Andy Hung296b7412014-06-17 15:25:47 -07001348
Andy Hung8ed196a2018-01-05 13:21:11 -08001349 const std::shared_ptr<Track> &t1 = mTracks[group[0]];
1350 convertMixerFormat(out, t1->mMixerFormat, outTemp, t1->mMixerInFormat,
1351 frameCount * t1->mMixerChannelCount);
Andy Hung296b7412014-06-17 15:25:47 -07001352 // TODO: fix ugly casting due to choice of out pointer type
1353 out = reinterpret_cast<int32_t*>((uint8_t*)out
Andy Hung8ed196a2018-01-05 13:21:11 -08001354 + frameCount * t1->mMixerChannelCount
1355 * audio_bytes_per_sample(t1->mMixerFormat));
Yahan Zhouc1c11b42018-01-16 12:44:04 -08001356 numFrames += frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001357 } while (numFrames < mFrameCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001358
Andy Hung8ed196a2018-01-05 13:21:11 -08001359 // release each track's buffer
1360 for (const int name : group) {
1361 const std::shared_ptr<Track> &t = mTracks[name];
1362 t->bufferProvider->releaseBuffer(&t->buffer);
1363 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001364 }
1365}
1366
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001367// generic code with resampling
Andy Hung8ed196a2018-01-05 13:21:11 -08001368void AudioMixer::process__genericResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001369{
Andy Hung296b7412014-06-17 15:25:47 -07001370 ALOGVV("process__genericResampling\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001371 int32_t * const outTemp = mOutputTemp.get(); // naked ptr
1372 size_t numFrames = mFrameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001373
Andy Hung8ed196a2018-01-05 13:21:11 -08001374 for (const auto &pair : mGroups) {
1375 const auto &group = pair.second;
1376 const std::shared_ptr<Track> &t1 = mTracks[group[0]];
1377
1378 // clear temp buffer
1379 memset(outTemp, 0, sizeof(*outTemp) * t1->mMixerChannelCount * mFrameCount);
1380 for (const int name : group) {
1381 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001382 int32_t *aux = NULL;
Andy Hung8ed196a2018-01-05 13:21:11 -08001383 if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
1384 aux = t->auxBuffer;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001385 }
1386
1387 // this is a little goofy, on the resampling case we don't
1388 // acquire/release the buffers because it's done by
1389 // the resampler.
Andy Hung8ed196a2018-01-05 13:21:11 -08001390 if (t->needs & NEEDS_RESAMPLE) {
1391 (t.get()->*t->hook)(outTemp, numFrames, mResampleTemp.get() /* naked ptr */, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001392 } else {
1393
1394 size_t outFrames = 0;
1395
1396 while (outFrames < numFrames) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001397 t->buffer.frameCount = numFrames - outFrames;
1398 t->bufferProvider->getNextBuffer(&t->buffer);
1399 t->mIn = t->buffer.raw;
1400 // t->mIn == nullptr can happen if the track was flushed just after having
Mathias Agopian65ab4712010-07-14 17:59:35 -07001401 // been enabled for mixing.
Andy Hung8ed196a2018-01-05 13:21:11 -08001402 if (t->mIn == nullptr) break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001403
Andy Hung8ed196a2018-01-05 13:21:11 -08001404 (t.get()->*t->hook)(
1405 outTemp + outFrames * t->mMixerChannelCount, t->buffer.frameCount,
Andy Hunga6018892018-02-21 14:32:16 -08001406 mResampleTemp.get() /* naked ptr */,
1407 aux != nullptr ? aux + outFrames : nullptr);
Andy Hung8ed196a2018-01-05 13:21:11 -08001408 outFrames += t->buffer.frameCount;
Andy Hunga6018892018-02-21 14:32:16 -08001409
Andy Hung8ed196a2018-01-05 13:21:11 -08001410 t->bufferProvider->releaseBuffer(&t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001411 }
1412 }
1413 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001414 convertMixerFormat(t1->mainBuffer, t1->mMixerFormat,
1415 outTemp, t1->mMixerInFormat, numFrames * t1->mMixerChannelCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001416 }
1417}
1418
1419// one track, 16 bits stereo without resampling is the most common case
Andy Hung8ed196a2018-01-05 13:21:11 -08001420void AudioMixer::process__oneTrack16BitsStereoNoResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001421{
Andy Hung8ed196a2018-01-05 13:21:11 -08001422 ALOGVV("process__oneTrack16BitsStereoNoResampling\n");
1423 LOG_ALWAYS_FATAL_IF(mEnabled.size() != 0,
1424 "%zu != 1 tracks enabled", mEnabled.size());
1425 const int name = mEnabled[0];
1426 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001427
Andy Hung8ed196a2018-01-05 13:21:11 -08001428 AudioBufferProvider::Buffer& b(t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001429
Andy Hung8ed196a2018-01-05 13:21:11 -08001430 int32_t* out = t->mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001431 float *fout = reinterpret_cast<float*>(out);
Andy Hung8ed196a2018-01-05 13:21:11 -08001432 size_t numFrames = mFrameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001433
Andy Hung8ed196a2018-01-05 13:21:11 -08001434 const int16_t vl = t->volume[0];
1435 const int16_t vr = t->volume[1];
1436 const uint32_t vrl = t->volumeRL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001437 while (numFrames) {
1438 b.frameCount = numFrames;
Andy Hung8ed196a2018-01-05 13:21:11 -08001439 t->bufferProvider->getNextBuffer(&b);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001440 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001441
1442 // in == NULL can happen if the track was flushed just after having
1443 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001444 if (in == NULL || (((uintptr_t)in) & 3)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001445 if ( AUDIO_FORMAT_PCM_FLOAT == t->mMixerFormat ) {
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001446 memset((char*)fout, 0, numFrames
Andy Hung8ed196a2018-01-05 13:21:11 -08001447 * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001448 } else {
1449 memset((char*)out, 0, numFrames
Andy Hung8ed196a2018-01-05 13:21:11 -08001450 * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001451 }
Andy Hung395db4b2014-08-25 17:15:29 -07001452 ALOGE_IF((((uintptr_t)in) & 3),
Andy Hung8ed196a2018-01-05 13:21:11 -08001453 "process__oneTrack16BitsStereoNoResampling: misaligned buffer"
Andy Hung395db4b2014-08-25 17:15:29 -07001454 " %p track %d, channels %d, needs %08x, volume %08x vfl %f vfr %f",
Andy Hung8ed196a2018-01-05 13:21:11 -08001455 in, name, t->channelCount, t->needs, vrl, t->mVolume[0], t->mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001456 return;
1457 }
1458 size_t outFrames = b.frameCount;
1459
Andy Hung8ed196a2018-01-05 13:21:11 -08001460 switch (t->mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001461 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001462 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001463 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001464 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001465 int32_t l = mulRL(1, rl, vrl);
1466 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001467 *fout++ = float_from_q4_27(l);
1468 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001469 // Note: In case of later int16_t sink output,
1470 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001471 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001472 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001473 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung97ae8242014-05-30 10:35:47 -07001474 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001475 // volume is boosted, so we might need to clamp even though
1476 // we process only one track.
1477 do {
1478 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1479 in += 2;
1480 int32_t l = mulRL(1, rl, vrl) >> 12;
1481 int32_t r = mulRL(0, rl, vrl) >> 12;
1482 // clamping...
1483 l = clamp16(l);
1484 r = clamp16(r);
1485 *out++ = (r<<16) | (l & 0xFFFF);
1486 } while (--outFrames);
1487 } else {
1488 do {
1489 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1490 in += 2;
1491 int32_t l = mulRL(1, rl, vrl) >> 12;
1492 int32_t r = mulRL(0, rl, vrl) >> 12;
1493 *out++ = (r<<16) | (l & 0xFFFF);
1494 } while (--outFrames);
1495 }
1496 break;
1497 default:
Andy Hung8ed196a2018-01-05 13:21:11 -08001498 LOG_ALWAYS_FATAL("bad mixer format: %d", t->mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001499 }
1500 numFrames -= b.frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001501 t->bufferProvider->releaseBuffer(&b);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001502 }
1503}
1504
Glenn Kasten52008f82012-03-18 09:34:41 -07001505/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1506
1507/*static*/ void AudioMixer::sInitRoutine()
1508{
Andy Hung34803d52014-07-16 21:41:35 -07001509 DownmixerBufferProvider::init(); // for the downmixer
John Grossman4ff14ba2012-02-08 16:37:41 -08001510}
1511
Andy Hunge93b6b72014-07-17 21:30:53 -07001512/* TODO: consider whether this level of optimization is necessary.
1513 * Perhaps just stick with a single for loop.
1514 */
1515
1516// Needs to derive a compile time constant (constexpr). Could be targeted to go
1517// to a MONOVOL mixtype based on MAX_NUM_VOLUMES, but that's an unnecessary complication.
Chih-Hung Hsiehbf291732016-05-17 15:16:07 -07001518#define MIXTYPE_MONOVOL(mixtype) ((mixtype) == MIXTYPE_MULTI ? MIXTYPE_MULTI_MONOVOL : \
1519 (mixtype) == MIXTYPE_MULTI_SAVEONLY ? MIXTYPE_MULTI_SAVEONLY_MONOVOL : (mixtype))
Andy Hunge93b6b72014-07-17 21:30:53 -07001520
1521/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1522 * TO: int32_t (Q4.27) or float
1523 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001524 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001525 */
1526template <int MIXTYPE,
1527 typename TO, typename TI, typename TV, typename TA, typename TAV>
1528static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
1529 const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc)
1530{
1531 switch (channels) {
1532 case 1:
1533 volumeRampMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1534 break;
1535 case 2:
1536 volumeRampMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1537 break;
1538 case 3:
1539 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out,
1540 frameCount, in, aux, vol, volinc, vola, volainc);
1541 break;
1542 case 4:
1543 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out,
1544 frameCount, in, aux, vol, volinc, vola, volainc);
1545 break;
1546 case 5:
1547 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out,
1548 frameCount, in, aux, vol, volinc, vola, volainc);
1549 break;
1550 case 6:
1551 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out,
1552 frameCount, in, aux, vol, volinc, vola, volainc);
1553 break;
1554 case 7:
1555 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out,
1556 frameCount, in, aux, vol, volinc, vola, volainc);
1557 break;
1558 case 8:
1559 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out,
1560 frameCount, in, aux, vol, volinc, vola, volainc);
1561 break;
1562 }
1563}
1564
1565/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1566 * TO: int32_t (Q4.27) or float
1567 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001568 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001569 */
1570template <int MIXTYPE,
1571 typename TO, typename TI, typename TV, typename TA, typename TAV>
1572static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
1573 const TI* in, TA* aux, const TV *vol, TAV vola)
1574{
1575 switch (channels) {
1576 case 1:
1577 volumeMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, vola);
1578 break;
1579 case 2:
1580 volumeMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, vola);
1581 break;
1582 case 3:
1583 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out, frameCount, in, aux, vol, vola);
1584 break;
1585 case 4:
1586 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out, frameCount, in, aux, vol, vola);
1587 break;
1588 case 5:
1589 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out, frameCount, in, aux, vol, vola);
1590 break;
1591 case 6:
1592 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out, frameCount, in, aux, vol, vola);
1593 break;
1594 case 7:
1595 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out, frameCount, in, aux, vol, vola);
1596 break;
1597 case 8:
1598 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out, frameCount, in, aux, vol, vola);
1599 break;
1600 }
1601}
1602
1603/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1604 * USEFLOATVOL (set to true if float volume is used)
1605 * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards)
1606 * TO: int32_t (Q4.27) or float
1607 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001608 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001609 */
1610template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001611 typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001612void AudioMixer::Track::volumeMix(TO *out, size_t outFrames,
1613 const TI *in, TA *aux, bool ramp)
Andy Hung5e58b0a2014-06-23 19:07:29 -07001614{
1615 if (USEFLOATVOL) {
1616 if (ramp) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001617 volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1618 mPrevVolume, mVolumeInc,
Andy Hung116a4982017-11-30 10:15:08 -08001619#ifdef FLOAT_AUX
Andy Hung8ed196a2018-01-05 13:21:11 -08001620 &mPrevAuxLevel, mAuxInc
Andy Hung116a4982017-11-30 10:15:08 -08001621#else
Andy Hung8ed196a2018-01-05 13:21:11 -08001622 &prevAuxLevel, auxInc
Andy Hung116a4982017-11-30 10:15:08 -08001623#endif
1624 );
Andy Hung5e58b0a2014-06-23 19:07:29 -07001625 if (ADJUSTVOL) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001626 adjustVolumeRamp(aux != NULL, true);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001627 }
1628 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001629 volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1630 mVolume,
Andy Hung116a4982017-11-30 10:15:08 -08001631#ifdef FLOAT_AUX
Andy Hung8ed196a2018-01-05 13:21:11 -08001632 mAuxLevel
Andy Hung116a4982017-11-30 10:15:08 -08001633#else
Andy Hung8ed196a2018-01-05 13:21:11 -08001634 auxLevel
Andy Hung116a4982017-11-30 10:15:08 -08001635#endif
1636 );
Andy Hung5e58b0a2014-06-23 19:07:29 -07001637 }
1638 } else {
1639 if (ramp) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001640 volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1641 prevVolume, volumeInc, &prevAuxLevel, auxInc);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001642 if (ADJUSTVOL) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001643 adjustVolumeRamp(aux != NULL);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001644 }
1645 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001646 volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1647 volume, auxLevel);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001648 }
1649 }
1650}
1651
Andy Hung296b7412014-06-17 15:25:47 -07001652/* This process hook is called when there is a single track without
1653 * aux buffer, volume ramp, or resampling.
1654 * TODO: Update the hook selection: this can properly handle aux and ramp.
Andy Hunge93b6b72014-07-17 21:30:53 -07001655 *
1656 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1657 * TO: int32_t (Q4.27) or float
1658 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1659 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07001660 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001661template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001662void AudioMixer::process__noResampleOneTrack()
Andy Hung296b7412014-06-17 15:25:47 -07001663{
Andy Hung8ed196a2018-01-05 13:21:11 -08001664 ALOGVV("process__noResampleOneTrack\n");
1665 LOG_ALWAYS_FATAL_IF(mEnabled.size() != 1,
1666 "%zu != 1 tracks enabled", mEnabled.size());
1667 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
Andy Hunge93b6b72014-07-17 21:30:53 -07001668 const uint32_t channels = t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07001669 TO* out = reinterpret_cast<TO*>(t->mainBuffer);
1670 TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
1671 const bool ramp = t->needsRamp();
1672
Andy Hung8ed196a2018-01-05 13:21:11 -08001673 for (size_t numFrames = mFrameCount; numFrames > 0; ) {
Andy Hung296b7412014-06-17 15:25:47 -07001674 AudioBufferProvider::Buffer& b(t->buffer);
1675 // get input buffer
1676 b.frameCount = numFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001677 t->bufferProvider->getNextBuffer(&b);
Andy Hung296b7412014-06-17 15:25:47 -07001678 const TI *in = reinterpret_cast<TI*>(b.raw);
1679
1680 // in == NULL can happen if the track was flushed just after having
1681 // been enabled for mixing.
1682 if (in == NULL || (((uintptr_t)in) & 3)) {
1683 memset(out, 0, numFrames
Andy Hunge93b6b72014-07-17 21:30:53 -07001684 * channels * audio_bytes_per_sample(t->mMixerFormat));
Andy Hung8ed196a2018-01-05 13:21:11 -08001685 ALOGE_IF((((uintptr_t)in) & 3), "process__noResampleOneTrack: bus error: "
Andy Hung296b7412014-06-17 15:25:47 -07001686 "buffer %p track %p, channels %d, needs %#x",
Andy Hung8ed196a2018-01-05 13:21:11 -08001687 in, &t, t->channelCount, t->needs);
Andy Hung296b7412014-06-17 15:25:47 -07001688 return;
1689 }
1690
1691 const size_t outFrames = b.frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001692 t->volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, false /* ADJUSTVOL */> (
1693 out, outFrames, in, aux, ramp);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001694
Andy Hunge93b6b72014-07-17 21:30:53 -07001695 out += outFrames * channels;
Andy Hung296b7412014-06-17 15:25:47 -07001696 if (aux != NULL) {
Andy Hunga6018892018-02-21 14:32:16 -08001697 aux += outFrames;
Andy Hung296b7412014-06-17 15:25:47 -07001698 }
1699 numFrames -= b.frameCount;
1700
1701 // release buffer
1702 t->bufferProvider->releaseBuffer(&b);
1703 }
1704 if (ramp) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001705 t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
Andy Hung296b7412014-06-17 15:25:47 -07001706 }
1707}
1708
1709/* This track hook is called to do resampling then mixing,
1710 * pulling from the track's upstream AudioBufferProvider.
Andy Hunge93b6b72014-07-17 21:30:53 -07001711 *
1712 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1713 * TO: int32_t (Q4.27) or float
1714 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001715 * TA: int32_t (Q4.27) or float
Andy Hung296b7412014-06-17 15:25:47 -07001716 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001717template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001718void AudioMixer::Track::track__Resample(TO* out, size_t outFrameCount, TO* temp, TA* aux)
Andy Hung296b7412014-06-17 15:25:47 -07001719{
1720 ALOGVV("track__Resample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001721 mResampler->setSampleRate(sampleRate);
1722 const bool ramp = needsRamp();
Andy Hung296b7412014-06-17 15:25:47 -07001723 if (ramp || aux != NULL) {
1724 // if ramp: resample with unity gain to temp buffer and scale/mix in 2nd step.
1725 // if aux != NULL: resample with unity gain to temp buffer then apply send level.
1726
Andy Hung8ed196a2018-01-05 13:21:11 -08001727 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
1728 memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(TO));
1729 mResampler->resample((int32_t*)temp, outFrameCount, bufferProvider);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001730
Andy Hung116a4982017-11-30 10:15:08 -08001731 volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
Andy Hung8ed196a2018-01-05 13:21:11 -08001732 out, outFrameCount, temp, aux, ramp);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001733
Andy Hung296b7412014-06-17 15:25:47 -07001734 } else { // constant volume gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001735 mResampler->setVolume(mVolume[0], mVolume[1]);
1736 mResampler->resample((int32_t*)out, outFrameCount, bufferProvider);
Andy Hung296b7412014-06-17 15:25:47 -07001737 }
1738}
1739
1740/* This track hook is called to mix a track, when no resampling is required.
Andy Hung8ed196a2018-01-05 13:21:11 -08001741 * The input buffer should be present in in.
Andy Hunge93b6b72014-07-17 21:30:53 -07001742 *
1743 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1744 * TO: int32_t (Q4.27) or float
1745 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001746 * TA: int32_t (Q4.27) or float
Andy Hung296b7412014-06-17 15:25:47 -07001747 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001748template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001749void AudioMixer::Track::track__NoResample(TO* out, size_t frameCount, TO* temp __unused, TA* aux)
Andy Hung296b7412014-06-17 15:25:47 -07001750{
1751 ALOGVV("track__NoResample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001752 const TI *in = static_cast<const TI *>(mIn);
Andy Hung296b7412014-06-17 15:25:47 -07001753
Andy Hung116a4982017-11-30 10:15:08 -08001754 volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
Andy Hung8ed196a2018-01-05 13:21:11 -08001755 out, frameCount, in, aux, needsRamp());
Andy Hung5e58b0a2014-06-23 19:07:29 -07001756
Andy Hung296b7412014-06-17 15:25:47 -07001757 // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
1758 // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
Andy Hung8ed196a2018-01-05 13:21:11 -08001759 in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * mMixerChannelCount;
1760 mIn = in;
Andy Hung296b7412014-06-17 15:25:47 -07001761}
1762
1763/* The Mixer engine generates either int32_t (Q4_27) or float data.
1764 * We use this function to convert the engine buffers
1765 * to the desired mixer output format, either int16_t (Q.15) or float.
1766 */
Andy Hung8ed196a2018-01-05 13:21:11 -08001767/* static */
Andy Hung296b7412014-06-17 15:25:47 -07001768void AudioMixer::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
1769 void *in, audio_format_t mixerInFormat, size_t sampleCount)
1770{
1771 switch (mixerInFormat) {
1772 case AUDIO_FORMAT_PCM_FLOAT:
1773 switch (mixerOutFormat) {
1774 case AUDIO_FORMAT_PCM_FLOAT:
1775 memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
1776 break;
1777 case AUDIO_FORMAT_PCM_16_BIT:
1778 memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
1779 break;
1780 default:
1781 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1782 break;
1783 }
1784 break;
1785 case AUDIO_FORMAT_PCM_16_BIT:
1786 switch (mixerOutFormat) {
1787 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung5effdf62017-11-27 13:51:40 -08001788 memcpy_to_float_from_q4_27((float*)out, (const int32_t*)in, sampleCount);
Andy Hung296b7412014-06-17 15:25:47 -07001789 break;
1790 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung5effdf62017-11-27 13:51:40 -08001791 memcpy_to_i16_from_q4_27((int16_t*)out, (const int32_t*)in, sampleCount);
Andy Hung296b7412014-06-17 15:25:47 -07001792 break;
1793 default:
1794 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1795 break;
1796 }
1797 break;
1798 default:
1799 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1800 break;
1801 }
1802}
1803
1804/* Returns the proper track hook to use for mixing the track into the output buffer.
1805 */
Andy Hung8ed196a2018-01-05 13:21:11 -08001806/* static */
1807AudioMixer::hook_t AudioMixer::Track::getTrackHook(int trackType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001808 audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
1809{
Andy Hunge93b6b72014-07-17 21:30:53 -07001810 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07001811 switch (trackType) {
1812 case TRACKTYPE_NOP:
Andy Hung8ed196a2018-01-05 13:21:11 -08001813 return &Track::track__nop;
Andy Hung296b7412014-06-17 15:25:47 -07001814 case TRACKTYPE_RESAMPLE:
Andy Hung8ed196a2018-01-05 13:21:11 -08001815 return &Track::track__genericResample;
Andy Hung296b7412014-06-17 15:25:47 -07001816 case TRACKTYPE_NORESAMPLEMONO:
Andy Hung8ed196a2018-01-05 13:21:11 -08001817 return &Track::track__16BitsMono;
Andy Hung296b7412014-06-17 15:25:47 -07001818 case TRACKTYPE_NORESAMPLE:
Andy Hung8ed196a2018-01-05 13:21:11 -08001819 return &Track::track__16BitsStereo;
Andy Hung296b7412014-06-17 15:25:47 -07001820 default:
1821 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1822 break;
1823 }
1824 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001825 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07001826 switch (trackType) {
1827 case TRACKTYPE_NOP:
Andy Hung8ed196a2018-01-05 13:21:11 -08001828 return &Track::track__nop;
Andy Hung296b7412014-06-17 15:25:47 -07001829 case TRACKTYPE_RESAMPLE:
1830 switch (mixerInFormat) {
1831 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001832 return (AudioMixer::hook_t) &Track::track__Resample<
Andy Hung116a4982017-11-30 10:15:08 -08001833 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001834 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001835 return (AudioMixer::hook_t) &Track::track__Resample<
Andy Hung116a4982017-11-30 10:15:08 -08001836 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001837 default:
1838 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1839 break;
1840 }
1841 break;
1842 case TRACKTYPE_NORESAMPLEMONO:
1843 switch (mixerInFormat) {
1844 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001845 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001846 MIXTYPE_MONOEXPAND, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001847 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001848 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001849 MIXTYPE_MONOEXPAND, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001850 default:
1851 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1852 break;
1853 }
1854 break;
1855 case TRACKTYPE_NORESAMPLE:
1856 switch (mixerInFormat) {
1857 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001858 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001859 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001860 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001861 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001862 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001863 default:
1864 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1865 break;
1866 }
1867 break;
1868 default:
1869 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1870 break;
1871 }
1872 return NULL;
1873}
1874
1875/* Returns the proper process hook for mixing tracks. Currently works only for
1876 * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
Andy Hung395db4b2014-08-25 17:15:29 -07001877 *
1878 * TODO: Due to the special mixing considerations of duplicating to
1879 * a stereo output track, the input track cannot be MONO. This should be
1880 * prevented by the caller.
Andy Hung296b7412014-06-17 15:25:47 -07001881 */
Andy Hung8ed196a2018-01-05 13:21:11 -08001882/* static */
1883AudioMixer::process_hook_t AudioMixer::getProcessHook(
1884 int processType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001885 audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
1886{
1887 if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
1888 LOG_ALWAYS_FATAL("bad processType: %d", processType);
1889 return NULL;
1890 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001891 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001892 return &AudioMixer::process__oneTrack16BitsStereoNoResampling;
Andy Hung296b7412014-06-17 15:25:47 -07001893 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001894 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07001895 switch (mixerInFormat) {
1896 case AUDIO_FORMAT_PCM_FLOAT:
1897 switch (mixerOutFormat) {
1898 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001899 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08001900 MIXTYPE_MULTI_SAVEONLY, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001901 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001902 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08001903 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001904 default:
1905 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1906 break;
1907 }
1908 break;
1909 case AUDIO_FORMAT_PCM_16_BIT:
1910 switch (mixerOutFormat) {
1911 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001912 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08001913 MIXTYPE_MULTI_SAVEONLY, float /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001914 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001915 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08001916 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001917 default:
1918 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1919 break;
1920 }
1921 break;
1922 default:
1923 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1924 break;
1925 }
1926 return NULL;
1927}
1928
Mathias Agopian65ab4712010-07-14 17:59:35 -07001929// ----------------------------------------------------------------------------
Glenn Kasten63238ef2015-03-02 15:50:29 -08001930} // namespace android