blob: f1daeb4a4ed5fbbf4444e27e7d127b5c1cdee0d4 [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 Hung8ed196a2018-01-05 13:21:11 -080093int AudioMixer::getTrackName(
94 audio_channel_mask_t channelMask, audio_format_t format, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080095{
Andy Hunge8a1ced2014-05-09 15:02:21 -070096 if (!isValidPcmTrackFormat(format)) {
97 ALOGE("AudioMixer::getTrackName invalid format (%#x)", format);
98 return -1;
99 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800100 if (mTracks.size() >= (size_t)mMaxNumTracks) {
101 ALOGE("%s: out of track names (max = %d)", __func__, mMaxNumTracks);
102 return -1;
103 }
104
105 // get a new name for the track.
106 int name;
107 if (mUnusedNames.size() != 0) {
108 // reuse first name for deleted track.
109 auto it = mUnusedNames.begin();
110 name = *it;
111 (void)mUnusedNames.erase(it);
112 } else {
113 // we're fully populated, so create a new name.
114 name = mTracks.size();
115 }
116 ALOGV("add track (%d)", name);
117
118 auto t = std::make_shared<Track>();
119 mTracks[name] = t;
120
121 {
122 // TODO: move initialization to the Track constructor.
Glenn Kastendeeb1282012-03-25 11:59:31 -0700123 // assume default parameters for the track, except where noted below
Glenn Kastendeeb1282012-03-25 11:59:31 -0700124 t->needs = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700125
126 // Integer volume.
127 // Currently integer volume is kept for the legacy integer mixer.
128 // Will be removed when the legacy mixer path is removed.
Andy Hung97ae8242014-05-30 10:35:47 -0700129 t->volume[0] = UNITY_GAIN_INT;
130 t->volume[1] = UNITY_GAIN_INT;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700131 t->prevVolume[0] = UNITY_GAIN_INT << 16;
132 t->prevVolume[1] = UNITY_GAIN_INT << 16;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700133 t->volumeInc[0] = 0;
134 t->volumeInc[1] = 0;
135 t->auxLevel = 0;
136 t->auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700137 t->prevAuxLevel = 0;
138
139 // Floating point volume.
140 t->mVolume[0] = UNITY_GAIN_FLOAT;
141 t->mVolume[1] = UNITY_GAIN_FLOAT;
142 t->mPrevVolume[0] = UNITY_GAIN_FLOAT;
143 t->mPrevVolume[1] = UNITY_GAIN_FLOAT;
144 t->mVolumeInc[0] = 0.;
145 t->mVolumeInc[1] = 0.;
146 t->mAuxLevel = 0.;
147 t->mAuxInc = 0.;
148 t->mPrevAuxLevel = 0.;
149
Glenn Kastendeeb1282012-03-25 11:59:31 -0700150 // no initialization needed
Glenn Kastendeeb1282012-03-25 11:59:31 -0700151 // t->frameCount
Andy Hung68112fc2014-05-14 14:13:23 -0700152 t->channelCount = audio_channel_count_from_out_mask(channelMask);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700153 t->enabled = false;
Andy Hunge93b6b72014-07-17 21:30:53 -0700154 ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
Andy Hungef7c7fb2014-05-12 16:51:41 -0700155 "Non-stereo channel mask: %d\n", channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700156 t->channelMask = channelMask;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700157 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700158 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
159 t->bufferProvider = NULL;
160 t->buffer.raw = NULL;
161 // no initialization needed
162 // t->buffer.frameCount
163 t->hook = NULL;
Andy Hung8ed196a2018-01-05 13:21:11 -0800164 t->mIn = NULL;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700165 t->sampleRate = mSampleRate;
166 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
167 t->mainBuffer = NULL;
168 t->auxBuffer = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700169 t->mInputBufferProvider = NULL;
Andy Hung78820702014-02-28 16:23:02 -0800170 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700171 t->mFormat = format;
Andy Hung7f475492014-08-25 16:36:37 -0700172 t->mMixerInFormat = selectMixerInFormat(format);
173 t->mDownmixRequiresFormat = AUDIO_FORMAT_INVALID; // no format required
Andy Hunge93b6b72014-07-17 21:30:53 -0700174 t->mMixerChannelMask = audio_channel_mask_from_representation_and_bits(
175 AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
176 t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700177 t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
Andy Hung296b7412014-06-17 15:25:47 -0700178 // Check the downmixing (or upmixing) requirements.
Andy Hung0f451e92014-08-04 21:28:47 -0700179 status_t status = t->prepareForDownmix();
Andy Hung68112fc2014-05-14 14:13:23 -0700180 if (status != OK) {
181 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
182 return -1;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700183 }
Andy Hung7f475492014-08-25 16:36:37 -0700184 // prepareForDownmix() may change mDownmixRequiresFormat
Andy Hung296b7412014-06-17 15:25:47 -0700185 ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
Andy Hung0f451e92014-08-04 21:28:47 -0700186 t->prepareForReformat();
Andy Hung8ed196a2018-01-05 13:21:11 -0800187 return TRACK0 + name;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700188 }
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800189}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700190
Andy Hunge93b6b72014-07-17 21:30:53 -0700191// Called when channel masks have changed for a track name
Andy Hung7f475492014-08-25 16:36:37 -0700192// TODO: Fix DownmixerBufferProvider not to (possibly) change mixer input format,
Andy Hunge93b6b72014-07-17 21:30:53 -0700193// which will simplify this logic.
194bool AudioMixer::setChannelMasks(int name,
195 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800196 LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name);
197 const std::shared_ptr<Track> &track = mTracks[name];
Andy Hunge93b6b72014-07-17 21:30:53 -0700198
Andy Hung8ed196a2018-01-05 13:21:11 -0800199 if (trackChannelMask == track->channelMask
200 && mixerChannelMask == track->mMixerChannelMask) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700201 return false; // no need to change
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700202 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700203 // always recompute for both channel masks even if only one has changed.
204 const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
205 const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
Andy Hung8ed196a2018-01-05 13:21:11 -0800206 const bool mixerChannelCountChanged = track->mMixerChannelCount != mixerChannelCount;
Andy Hunge93b6b72014-07-17 21:30:53 -0700207
208 ALOG_ASSERT((trackChannelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX)
209 && trackChannelCount
210 && mixerChannelCount);
Andy Hung8ed196a2018-01-05 13:21:11 -0800211 track->channelMask = trackChannelMask;
212 track->channelCount = trackChannelCount;
213 track->mMixerChannelMask = mixerChannelMask;
214 track->mMixerChannelCount = mixerChannelCount;
Andy Hunge93b6b72014-07-17 21:30:53 -0700215
216 // channel masks have changed, does this track need a downmixer?
217 // update to try using our desired format (if we aren't already using it)
Andy Hung8ed196a2018-01-05 13:21:11 -0800218 const audio_format_t prevDownmixerFormat = track->mDownmixRequiresFormat;
219 const status_t status = track->prepareForDownmix();
Andy Hunge93b6b72014-07-17 21:30:53 -0700220 ALOGE_IF(status != OK,
Andy Hung0f451e92014-08-04 21:28:47 -0700221 "prepareForDownmix error %d, track channel mask %#x, mixer channel mask %#x",
Andy Hung8ed196a2018-01-05 13:21:11 -0800222 status, track->channelMask, track->mMixerChannelMask);
Andy Hunge93b6b72014-07-17 21:30:53 -0700223
Andy Hung8ed196a2018-01-05 13:21:11 -0800224 if (prevDownmixerFormat != track->mDownmixRequiresFormat) {
225 track->prepareForReformat(); // because of downmixer, track format may change!
Andy Hunge93b6b72014-07-17 21:30:53 -0700226 }
227
Andy Hung8ed196a2018-01-05 13:21:11 -0800228 if (track->mResampler.get() != nullptr && mixerChannelCountChanged) {
Andy Hung7f475492014-08-25 16:36:37 -0700229 // resampler channels may have changed.
Andy Hung8ed196a2018-01-05 13:21:11 -0800230 const uint32_t resetToSampleRate = track->sampleRate;
231 track->mResampler.reset(nullptr);
232 track->sampleRate = mSampleRate; // without resampler, track rate is device sample rate.
Andy Hunge93b6b72014-07-17 21:30:53 -0700233 // recreate the resampler with updated format, channels, saved sampleRate.
Andy Hung8ed196a2018-01-05 13:21:11 -0800234 track->setResampler(resetToSampleRate /*trackSampleRate*/, mSampleRate /*devSampleRate*/);
Andy Hunge93b6b72014-07-17 21:30:53 -0700235 }
236 return true;
237}
238
Andy Hung8ed196a2018-01-05 13:21:11 -0800239void AudioMixer::Track::unprepareForDownmix() {
Andy Hung0f451e92014-08-04 21:28:47 -0700240 ALOGV("AudioMixer::unprepareForDownmix(%p)", this);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700241
Andy Hung8ed196a2018-01-05 13:21:11 -0800242 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
Andy Hung85395892017-04-25 16:47:52 -0700243 // release any buffers held by the mPostDownmixReformatBufferProvider
Andy Hung8ed196a2018-01-05 13:21:11 -0800244 // before deallocating the mDownmixerBufferProvider.
Andy Hung85395892017-04-25 16:47:52 -0700245 mPostDownmixReformatBufferProvider->reset();
246 }
247
Andy Hung7f475492014-08-25 16:36:37 -0700248 mDownmixRequiresFormat = AUDIO_FORMAT_INVALID;
Andy Hung8ed196a2018-01-05 13:21:11 -0800249 if (mDownmixerBufferProvider.get() != nullptr) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700250 // this track had previously been configured with a downmixer, delete it
Andy Hung8ed196a2018-01-05 13:21:11 -0800251 mDownmixerBufferProvider.reset(nullptr);
Andy Hung0f451e92014-08-04 21:28:47 -0700252 reconfigureBufferProviders();
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700253 } else {
254 ALOGV(" nothing to do, no downmixer to delete");
255 }
256}
257
Andy Hung8ed196a2018-01-05 13:21:11 -0800258status_t AudioMixer::Track::prepareForDownmix()
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700259{
Andy Hung0f451e92014-08-04 21:28:47 -0700260 ALOGV("AudioMixer::prepareForDownmix(%p) with mask 0x%x",
261 this, channelMask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700262
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700263 // discard the previous downmixer if there was one
Andy Hung0f451e92014-08-04 21:28:47 -0700264 unprepareForDownmix();
Andy Hung73e62e22015-04-20 12:06:38 -0700265 // MONO_HACK Only remix (upmix or downmix) if the track and mixer/device channel masks
Andy Hung0f451e92014-08-04 21:28:47 -0700266 // are not the same and not handled internally, as mono -> stereo currently is.
267 if (channelMask == mMixerChannelMask
268 || (channelMask == AUDIO_CHANNEL_OUT_MONO
269 && mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO)) {
270 return NO_ERROR;
271 }
Andy Hung650ceb92015-01-29 13:31:12 -0800272 // DownmixerBufferProvider is only used for position masks.
273 if (audio_channel_mask_get_representation(channelMask)
274 == AUDIO_CHANNEL_REPRESENTATION_POSITION
275 && DownmixerBufferProvider::isMultichannelCapable()) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800276 mDownmixerBufferProvider.reset(new DownmixerBufferProvider(channelMask,
Andy Hung0f451e92014-08-04 21:28:47 -0700277 mMixerChannelMask,
278 AUDIO_FORMAT_PCM_16_BIT /* TODO: use mMixerInFormat, now only PCM 16 */,
Andy Hung8ed196a2018-01-05 13:21:11 -0800279 sampleRate, sessionId, kCopyBufferFrameCount));
280 if (static_cast<DownmixerBufferProvider *>(mDownmixerBufferProvider.get())->isValid()) {
Andy Hung7f475492014-08-25 16:36:37 -0700281 mDownmixRequiresFormat = AUDIO_FORMAT_PCM_16_BIT; // PCM 16 bit required for downmix
Andy Hung0f451e92014-08-04 21:28:47 -0700282 reconfigureBufferProviders();
Andy Hung34803d52014-07-16 21:41:35 -0700283 return NO_ERROR;
284 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800285 // mDownmixerBufferProvider reset below.
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700286 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700287
288 // Effect downmixer does not accept the channel conversion. Let's use our remixer.
Andy Hung8ed196a2018-01-05 13:21:11 -0800289 mDownmixerBufferProvider.reset(new RemixBufferProvider(channelMask,
290 mMixerChannelMask, mMixerInFormat, kCopyBufferFrameCount));
Andy Hunge93b6b72014-07-17 21:30:53 -0700291 // Remix always finds a conversion whereas Downmixer effect above may fail.
Andy Hung0f451e92014-08-04 21:28:47 -0700292 reconfigureBufferProviders();
Andy Hunge93b6b72014-07-17 21:30:53 -0700293 return NO_ERROR;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700294}
295
Andy Hung8ed196a2018-01-05 13:21:11 -0800296void AudioMixer::Track::unprepareForReformat() {
Andy Hung0f451e92014-08-04 21:28:47 -0700297 ALOGV("AudioMixer::unprepareForReformat(%p)", this);
Andy Hung7f475492014-08-25 16:36:37 -0700298 bool requiresReconfigure = false;
Andy Hung8ed196a2018-01-05 13:21:11 -0800299 if (mReformatBufferProvider.get() != nullptr) {
300 mReformatBufferProvider.reset(nullptr);
Andy Hung7f475492014-08-25 16:36:37 -0700301 requiresReconfigure = true;
302 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800303 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
304 mPostDownmixReformatBufferProvider.reset(nullptr);
Andy Hung7f475492014-08-25 16:36:37 -0700305 requiresReconfigure = true;
306 }
307 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700308 reconfigureBufferProviders();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700309 }
310}
311
Andy Hung8ed196a2018-01-05 13:21:11 -0800312status_t AudioMixer::Track::prepareForReformat()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700313{
Andy Hung0f451e92014-08-04 21:28:47 -0700314 ALOGV("AudioMixer::prepareForReformat(%p) with format %#x", this, mFormat);
Andy Hung7f475492014-08-25 16:36:37 -0700315 // discard previous reformatters
Andy Hung0f451e92014-08-04 21:28:47 -0700316 unprepareForReformat();
Andy Hung7f475492014-08-25 16:36:37 -0700317 // only configure reformatters as needed
318 const audio_format_t targetFormat = mDownmixRequiresFormat != AUDIO_FORMAT_INVALID
319 ? mDownmixRequiresFormat : mMixerInFormat;
320 bool requiresReconfigure = false;
321 if (mFormat != targetFormat) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800322 mReformatBufferProvider.reset(new ReformatBufferProvider(
Andy Hung0f451e92014-08-04 21:28:47 -0700323 audio_channel_count_from_out_mask(channelMask),
Andy Hung7f475492014-08-25 16:36:37 -0700324 mFormat,
325 targetFormat,
Andy Hung8ed196a2018-01-05 13:21:11 -0800326 kCopyBufferFrameCount));
Andy Hung7f475492014-08-25 16:36:37 -0700327 requiresReconfigure = true;
328 }
329 if (targetFormat != mMixerInFormat) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800330 mPostDownmixReformatBufferProvider.reset(new ReformatBufferProvider(
Andy Hung7f475492014-08-25 16:36:37 -0700331 audio_channel_count_from_out_mask(mMixerChannelMask),
332 targetFormat,
333 mMixerInFormat,
Andy Hung8ed196a2018-01-05 13:21:11 -0800334 kCopyBufferFrameCount));
Andy Hung7f475492014-08-25 16:36:37 -0700335 requiresReconfigure = true;
336 }
337 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700338 reconfigureBufferProviders();
Andy Hung296b7412014-06-17 15:25:47 -0700339 }
340 return NO_ERROR;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700341}
342
Andy Hung8ed196a2018-01-05 13:21:11 -0800343void AudioMixer::Track::reconfigureBufferProviders()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700344{
Andy Hung0f451e92014-08-04 21:28:47 -0700345 bufferProvider = mInputBufferProvider;
Andy Hung8ed196a2018-01-05 13:21:11 -0800346 if (mReformatBufferProvider.get() != nullptr) {
Andy Hung0f451e92014-08-04 21:28:47 -0700347 mReformatBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800348 bufferProvider = mReformatBufferProvider.get();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700349 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800350 if (mDownmixerBufferProvider.get() != nullptr) {
351 mDownmixerBufferProvider->setBufferProvider(bufferProvider);
352 bufferProvider = mDownmixerBufferProvider.get();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700353 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800354 if (mPostDownmixReformatBufferProvider.get() != nullptr) {
Andy Hung7f475492014-08-25 16:36:37 -0700355 mPostDownmixReformatBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800356 bufferProvider = mPostDownmixReformatBufferProvider.get();
Andy Hung7f475492014-08-25 16:36:37 -0700357 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800358 if (mTimestretchBufferProvider.get() != nullptr) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700359 mTimestretchBufferProvider->setBufferProvider(bufferProvider);
Andy Hung8ed196a2018-01-05 13:21:11 -0800360 bufferProvider = mTimestretchBufferProvider.get();
Andy Hungc5656cc2015-03-26 19:04:33 -0700361 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700362}
363
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800364void AudioMixer::deleteTrackName(int name)
365{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700366 name -= TRACK0;
Andy Hung8ed196a2018-01-05 13:21:11 -0800367 LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800368 ALOGV("deleteTrackName(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800369
370 if (mTracks[name]->enabled) {
371 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700372 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800373 mTracks.erase(name); // deallocate track
374 mUnusedNames.emplace(name); // recycle name
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800375}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700376
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800377void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700378{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800379 name -= TRACK0;
Andy Hung8ed196a2018-01-05 13:21:11 -0800380 LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name);
381 const std::shared_ptr<Track> &track = mTracks[name];
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800382
Andy Hung8ed196a2018-01-05 13:21:11 -0800383 if (!track->enabled) {
384 track->enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800385 ALOGV("enable(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800386 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700387 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700388}
389
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800390void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700391{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800392 name -= TRACK0;
Andy Hung8ed196a2018-01-05 13:21:11 -0800393 LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name);
394 const std::shared_ptr<Track> &track = mTracks[name];
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800395
Andy Hung8ed196a2018-01-05 13:21:11 -0800396 if (track->enabled) {
397 track->enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800398 ALOGV("disable(%d)", name);
Andy Hung8ed196a2018-01-05 13:21:11 -0800399 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700400 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700401}
402
Andy Hung5866a3b2014-05-29 21:33:13 -0700403/* Sets the volume ramp variables for the AudioMixer.
404 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700405 * The volume ramp variables are used to transition from the previous
406 * volume to the set volume. ramp controls the duration of the transition.
407 * Its value is typically one state framecount period, but may also be 0,
408 * meaning "immediate."
Andy Hung5866a3b2014-05-29 21:33:13 -0700409 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700410 * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
411 * even if there is a nonzero floating point increment (in that case, the volume
412 * change is immediate). This restriction should be changed when the legacy mixer
413 * is removed (see #2).
414 * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
415 * when no longer needed.
416 *
417 * @param newVolume set volume target in floating point [0.0, 1.0].
418 * @param ramp number of frames to increment over. if ramp is 0, the volume
419 * should be set immediately. Currently ramp should not exceed 65535 (frames).
420 * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
421 * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
422 * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
423 * @param pSetVolume pointer to the float target volume, set on return.
424 * @param pPrevVolume pointer to the float previous volume, set on return.
425 * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
Andy Hung5866a3b2014-05-29 21:33:13 -0700426 * @return true if the volume has changed, false if volume is same.
427 */
Andy Hung5e58b0a2014-06-23 19:07:29 -0700428static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
429 int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
430 float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
Andy Hunge09c9942015-05-08 16:58:13 -0700431 // check floating point volume to see if it is identical to the previously
432 // set volume.
433 // We do not use a tolerance here (and reject changes too small)
434 // as it may be confusing to use a different value than the one set.
435 // If the resulting volume is too small to ramp, it is a direct set of the volume.
Andy Hung5e58b0a2014-06-23 19:07:29 -0700436 if (newVolume == *pSetVolume) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700437 return false;
438 }
Andy Hunge09c9942015-05-08 16:58:13 -0700439 if (newVolume < 0) {
440 newVolume = 0; // should not have negative volumes
Andy Hung5866a3b2014-05-29 21:33:13 -0700441 } else {
Andy Hunge09c9942015-05-08 16:58:13 -0700442 switch (fpclassify(newVolume)) {
443 case FP_SUBNORMAL:
444 case FP_NAN:
445 newVolume = 0;
446 break;
447 case FP_ZERO:
448 break; // zero volume is fine
449 case FP_INFINITE:
450 // Infinite volume could be handled consistently since
451 // floating point math saturates at infinities,
452 // but we limit volume to unity gain float.
453 // ramp = 0; break;
454 //
455 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
456 break;
457 case FP_NORMAL:
458 default:
459 // Floating point does not have problems with overflow wrap
460 // that integer has. However, we limit the volume to
461 // unity gain here.
462 // TODO: Revisit the volume limitation and perhaps parameterize.
463 if (newVolume > AudioMixer::UNITY_GAIN_FLOAT) {
464 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
465 }
466 break;
467 }
Andy Hung5866a3b2014-05-29 21:33:13 -0700468 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700469
Andy Hunge09c9942015-05-08 16:58:13 -0700470 // set floating point volume ramp
471 if (ramp != 0) {
472 // when the ramp completes, *pPrevVolume is set to *pSetVolume, so there
473 // is no computational mismatch; hence equality is checked here.
474 ALOGD_IF(*pPrevVolume != *pSetVolume, "previous float ramp hasn't finished,"
475 " prev:%f set_to:%f", *pPrevVolume, *pSetVolume);
476 const float inc = (newVolume - *pPrevVolume) / ramp; // could be inf, nan, subnormal
Andy Hung8ed196a2018-01-05 13:21:11 -0800477 // could be inf, cannot be nan, subnormal
478 const float maxv = std::max(newVolume, *pPrevVolume);
Andy Hunge09c9942015-05-08 16:58:13 -0700479
480 if (isnormal(inc) // inc must be a normal number (no subnormals, infinite, nan)
481 && maxv + inc != maxv) { // inc must make forward progress
482 *pVolumeInc = inc;
483 // ramp is set now.
484 // Note: if newVolume is 0, then near the end of the ramp,
485 // it may be possible that the ramped volume may be subnormal or
486 // temporarily negative by a small amount or subnormal due to floating
487 // point inaccuracies.
488 } else {
489 ramp = 0; // ramp not allowed
490 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700491 }
Andy Hunge09c9942015-05-08 16:58:13 -0700492
493 // compute and check integer volume, no need to check negative values
494 // The integer volume is limited to "unity_gain" to avoid wrapping and other
495 // audio artifacts, so it never reaches the range limit of U4.28.
496 // We safely use signed 16 and 32 bit integers here.
497 const float scaledVolume = newVolume * AudioMixer::UNITY_GAIN_INT; // not neg, subnormal, nan
498 const int32_t intVolume = (scaledVolume >= (float)AudioMixer::UNITY_GAIN_INT) ?
499 AudioMixer::UNITY_GAIN_INT : (int32_t)scaledVolume;
500
501 // set integer volume ramp
502 if (ramp != 0) {
503 // integer volume is U4.12 (to use 16 bit multiplies), but ramping uses U4.28.
504 // when the ramp completes, *pIntPrevVolume is set to *pIntSetVolume << 16, so there
505 // is no computational mismatch; hence equality is checked here.
506 ALOGD_IF(*pIntPrevVolume != *pIntSetVolume << 16, "previous int ramp hasn't finished,"
507 " prev:%d set_to:%d", *pIntPrevVolume, *pIntSetVolume << 16);
508 const int32_t inc = ((intVolume << 16) - *pIntPrevVolume) / ramp;
509
510 if (inc != 0) { // inc must make forward progress
511 *pIntVolumeInc = inc;
512 } else {
513 ramp = 0; // ramp not allowed
514 }
515 }
516
517 // if no ramp, or ramp not allowed, then clear float and integer increments
518 if (ramp == 0) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700519 *pVolumeInc = 0;
520 *pPrevVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700521 *pIntVolumeInc = 0;
522 *pIntPrevVolume = intVolume << 16;
523 }
Andy Hunge09c9942015-05-08 16:58:13 -0700524 *pSetVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700525 *pIntSetVolume = intVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700526 return true;
527}
528
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800529void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700530{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800531 name -= TRACK0;
Andy Hung8ed196a2018-01-05 13:21:11 -0800532 LOG_ALWAYS_FATAL_IF(mTracks.find(name) == mTracks.end(), "invalid name: %d", name);
533 const std::shared_ptr<Track> &track = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700534
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000535 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
536 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700537
538 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700539
Mathias Agopian65ab4712010-07-14 17:59:35 -0700540 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800541 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700542 case CHANNEL_MASK: {
Andy Hunge93b6b72014-07-17 21:30:53 -0700543 const audio_channel_mask_t trackChannelMask =
544 static_cast<audio_channel_mask_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800545 if (setChannelMasks(name, trackChannelMask, track->mMixerChannelMask)) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700546 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
Andy Hung8ed196a2018-01-05 13:21:11 -0800547 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700548 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700549 } break;
550 case MAIN_BUFFER:
Andy Hung8ed196a2018-01-05 13:21:11 -0800551 if (track->mainBuffer != valueBuf) {
552 track->mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100553 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Andy Hung8ed196a2018-01-05 13:21:11 -0800554 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700555 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700556 break;
557 case AUX_BUFFER:
Andy Hung8ed196a2018-01-05 13:21:11 -0800558 if (track->auxBuffer != valueBuf) {
559 track->auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100560 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Andy Hung8ed196a2018-01-05 13:21:11 -0800561 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700562 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700563 break;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700564 case FORMAT: {
565 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800566 if (track->mFormat != format) {
Andy Hungef7c7fb2014-05-12 16:51:41 -0700567 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
Andy Hung8ed196a2018-01-05 13:21:11 -0800568 track->mFormat = format;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700569 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
Andy Hung8ed196a2018-01-05 13:21:11 -0800570 track->prepareForReformat();
571 invalidate();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700572 }
573 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700574 // FIXME do we want to support setting the downmix type from AudioFlinger?
575 // for a specific track? or per mixer?
576 /* case DOWNMIX_TYPE:
577 break */
Andy Hung78820702014-02-28 16:23:02 -0800578 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800579 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800580 if (track->mMixerFormat != format) {
581 track->mMixerFormat = format;
Andy Hung78820702014-02-28 16:23:02 -0800582 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800583 }
584 } break;
Andy Hunge93b6b72014-07-17 21:30:53 -0700585 case MIXER_CHANNEL_MASK: {
586 const audio_channel_mask_t mixerChannelMask =
587 static_cast<audio_channel_mask_t>(valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800588 if (setChannelMasks(name, track->channelMask, mixerChannelMask)) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700589 ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
Andy Hung8ed196a2018-01-05 13:21:11 -0800590 invalidate();
Andy Hunge93b6b72014-07-17 21:30:53 -0700591 }
592 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700593 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800594 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700595 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700596 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700597
Mathias Agopian65ab4712010-07-14 17:59:35 -0700598 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800599 switch (param) {
600 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800601 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Andy Hung8ed196a2018-01-05 13:21:11 -0800602 if (track->setResampler(uint32_t(valueInt), mSampleRate)) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700603 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
604 uint32_t(valueInt));
Andy Hung8ed196a2018-01-05 13:21:11 -0800605 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700606 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800607 break;
608 case RESET:
Andy Hung8ed196a2018-01-05 13:21:11 -0800609 track->resetResampler();
610 invalidate();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800611 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700612 case REMOVE:
Andy Hung8ed196a2018-01-05 13:21:11 -0800613 track->mResampler.reset(nullptr);
614 track->sampleRate = mSampleRate;
615 invalidate();
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700616 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700617 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800618 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800619 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700620 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700621
Mathias Agopian65ab4712010-07-14 17:59:35 -0700622 case RAMP_VOLUME:
623 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800624 switch (param) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800625 case AUXLEVEL:
Andy Hung6be49402014-05-30 10:42:03 -0700626 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung8ed196a2018-01-05 13:21:11 -0800627 target == RAMP_VOLUME ? mFrameCount : 0,
628 &track->auxLevel, &track->prevAuxLevel, &track->auxInc,
629 &track->mAuxLevel, &track->mPrevAuxLevel, &track->mAuxInc)) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700630 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
Andy Hung8ed196a2018-01-05 13:21:11 -0800631 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track->auxLevel);
632 invalidate();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700633 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800634 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700635 default:
Andy Hunge93b6b72014-07-17 21:30:53 -0700636 if ((unsigned)param >= VOLUME0 && (unsigned)param < VOLUME0 + MAX_NUM_VOLUMES) {
637 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung8ed196a2018-01-05 13:21:11 -0800638 target == RAMP_VOLUME ? mFrameCount : 0,
639 &track->volume[param - VOLUME0],
640 &track->prevVolume[param - VOLUME0],
641 &track->volumeInc[param - VOLUME0],
642 &track->mVolume[param - VOLUME0],
643 &track->mPrevVolume[param - VOLUME0],
644 &track->mVolumeInc[param - VOLUME0])) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700645 ALOGV("setParameter(%s, VOLUME%d: %04x)",
646 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
Andy Hung8ed196a2018-01-05 13:21:11 -0800647 track->volume[param - VOLUME0]);
648 invalidate();
Andy Hunge93b6b72014-07-17 21:30:53 -0700649 }
650 } else {
651 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
652 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700653 }
654 break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700655 case TIMESTRETCH:
656 switch (param) {
657 case PLAYBACK_RATE: {
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700658 const AudioPlaybackRate *playbackRate =
659 reinterpret_cast<AudioPlaybackRate*>(value);
Ricardo Garcia6c7f0622015-04-30 18:39:16 -0700660 ALOGW_IF(!isAudioPlaybackRateValid(*playbackRate),
Andy Hung8ed196a2018-01-05 13:21:11 -0800661 "bad parameters speed %f, pitch %f",
662 playbackRate->mSpeed, playbackRate->mPitch);
663 if (track->setPlaybackRate(*playbackRate)) {
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700664 ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE "
665 "%f %f %d %d",
666 playbackRate->mSpeed,
667 playbackRate->mPitch,
668 playbackRate->mStretchMode,
669 playbackRate->mFallbackMode);
Andy Hung8ed196a2018-01-05 13:21:11 -0800670 // invalidate(); (should not require reconfigure)
Andy Hungc5656cc2015-03-26 19:04:33 -0700671 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700672 } break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700673 default:
674 LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);
675 }
676 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700677
678 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800679 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700680 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700681}
682
Andy Hung8ed196a2018-01-05 13:21:11 -0800683bool AudioMixer::Track::setResampler(uint32_t trackSampleRate, uint32_t devSampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700684{
Andy Hung8ed196a2018-01-05 13:21:11 -0800685 if (trackSampleRate != devSampleRate || mResampler.get() != nullptr) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700686 if (sampleRate != trackSampleRate) {
687 sampleRate = trackSampleRate;
Andy Hung8ed196a2018-01-05 13:21:11 -0800688 if (mResampler.get() == nullptr) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700689 ALOGV("Creating resampler from track %d Hz to device %d Hz",
690 trackSampleRate, devSampleRate);
Glenn Kastenac602052012-10-01 14:04:31 -0700691 AudioResampler::src_quality quality;
692 // force lowest quality level resampler if use case isn't music or video
693 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
694 // quality level based on the initial ratio, but that could change later.
695 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
Andy Hungdb4c0312015-05-06 08:46:52 -0700696 if (isMusicRate(trackSampleRate)) {
Glenn Kastenac602052012-10-01 14:04:31 -0700697 quality = AudioResampler::DEFAULT_QUALITY;
Andy Hungdb4c0312015-05-06 08:46:52 -0700698 } else {
699 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700700 }
Andy Hung296b7412014-06-17 15:25:47 -0700701
Andy Hunge93b6b72014-07-17 21:30:53 -0700702 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
703 // but if none exists, it is the channel count (1 for mono).
Andy Hung8ed196a2018-01-05 13:21:11 -0800704 const int resamplerChannelCount = mDownmixerBufferProvider.get() != nullptr
Andy Hunge93b6b72014-07-17 21:30:53 -0700705 ? mMixerChannelCount : channelCount;
Andy Hung9a592762014-07-21 21:56:01 -0700706 ALOGVV("Creating resampler:"
707 " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
708 mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
Andy Hung8ed196a2018-01-05 13:21:11 -0800709 mResampler.reset(AudioResampler::create(
Andy Hung3348e362014-07-07 10:21:44 -0700710 mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -0700711 resamplerChannelCount,
Andy Hung8ed196a2018-01-05 13:21:11 -0800712 devSampleRate, quality));
Mathias Agopian65ab4712010-07-14 17:59:35 -0700713 }
714 return true;
715 }
716 }
717 return false;
718}
719
Andy Hung8ed196a2018-01-05 13:21:11 -0800720bool AudioMixer::Track::setPlaybackRate(const AudioPlaybackRate &playbackRate)
Andy Hungc5656cc2015-03-26 19:04:33 -0700721{
Andy Hung8ed196a2018-01-05 13:21:11 -0800722 if ((mTimestretchBufferProvider.get() == nullptr &&
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700723 fabs(playbackRate.mSpeed - mPlaybackRate.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
724 fabs(playbackRate.mPitch - mPlaybackRate.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA) ||
725 isAudioPlaybackRateEqual(playbackRate, mPlaybackRate)) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700726 return false;
727 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700728 mPlaybackRate = playbackRate;
Andy Hung8ed196a2018-01-05 13:21:11 -0800729 if (mTimestretchBufferProvider.get() == nullptr) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700730 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
731 // but if none exists, it is the channel count (1 for mono).
Andy Hung8ed196a2018-01-05 13:21:11 -0800732 const int timestretchChannelCount = mDownmixerBufferProvider.get() != nullptr
Andy Hungc5656cc2015-03-26 19:04:33 -0700733 ? mMixerChannelCount : channelCount;
Andy Hung8ed196a2018-01-05 13:21:11 -0800734 mTimestretchBufferProvider.reset(new TimestretchBufferProvider(timestretchChannelCount,
735 mMixerInFormat, sampleRate, playbackRate));
Andy Hungc5656cc2015-03-26 19:04:33 -0700736 reconfigureBufferProviders();
737 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -0800738 static_cast<TimestretchBufferProvider*>(mTimestretchBufferProvider.get())
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700739 ->setPlaybackRate(playbackRate);
Andy Hungc5656cc2015-03-26 19:04:33 -0700740 }
741 return true;
742}
743
Andy Hung5e58b0a2014-06-23 19:07:29 -0700744/* Checks to see if the volume ramp has completed and clears the increment
745 * variables appropriately.
746 *
747 * FIXME: There is code to handle int/float ramp variable switchover should it not
748 * complete within a mixer buffer processing call, but it is preferred to avoid switchover
749 * due to precision issues. The switchover code is included for legacy code purposes
750 * and can be removed once the integer volume is removed.
751 *
752 * It is not sufficient to clear only the volumeInc integer variable because
753 * if one channel requires ramping, all channels are ramped.
754 *
755 * There is a bit of duplicated code here, but it keeps backward compatibility.
756 */
Andy Hung8ed196a2018-01-05 13:21:11 -0800757inline void AudioMixer::Track::adjustVolumeRamp(bool aux, bool useFloat)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700758{
Andy Hung5e58b0a2014-06-23 19:07:29 -0700759 if (useFloat) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700760 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Eric Laurent43412fc2015-05-08 16:14:36 -0700761 if ((mVolumeInc[i] > 0 && mPrevVolume[i] + mVolumeInc[i] >= mVolume[i]) ||
762 (mVolumeInc[i] < 0 && mPrevVolume[i] + mVolumeInc[i] <= mVolume[i])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700763 volumeInc[i] = 0;
764 prevVolume[i] = volume[i] << 16;
765 mVolumeInc[i] = 0.;
766 mPrevVolume[i] = mVolume[i];
Andy Hung5e58b0a2014-06-23 19:07:29 -0700767 } else {
768 //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
769 prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
770 }
771 }
772 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -0700773 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700774 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
775 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
776 volumeInc[i] = 0;
777 prevVolume[i] = volume[i] << 16;
778 mVolumeInc[i] = 0.;
779 mPrevVolume[i] = mVolume[i];
780 } else {
781 //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
782 mPrevVolume[i] = float_from_u4_28(prevVolume[i]);
783 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700784 }
785 }
Andy Hung116a4982017-11-30 10:15:08 -0800786
Mathias Agopian65ab4712010-07-14 17:59:35 -0700787 if (aux) {
Andy Hung116a4982017-11-30 10:15:08 -0800788#ifdef FLOAT_AUX
789 if (useFloat) {
790 if ((mAuxInc > 0.f && mPrevAuxLevel + mAuxInc >= mAuxLevel) ||
791 (mAuxInc < 0.f && mPrevAuxLevel + mAuxInc <= mAuxLevel)) {
792 auxInc = 0;
793 prevAuxLevel = auxLevel << 16;
794 mAuxInc = 0.f;
795 mPrevAuxLevel = mAuxLevel;
796 }
797 } else
798#endif
799 if ((auxInc > 0 && ((prevAuxLevel + auxInc) >> 16) >= auxLevel) ||
800 (auxInc < 0 && ((prevAuxLevel + auxInc) >> 16) <= auxLevel)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700801 auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700802 prevAuxLevel = auxLevel << 16;
Andy Hung116a4982017-11-30 10:15:08 -0800803 mAuxInc = 0.f;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700804 mPrevAuxLevel = mAuxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700805 }
806 }
807}
808
Glenn Kastenc59c0042012-02-02 14:06:11 -0800809size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800810{
811 name -= TRACK0;
Andy Hung8ed196a2018-01-05 13:21:11 -0800812 const auto it = mTracks.find(name);
813 if (it != mTracks.end()) {
814 return it->second->getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800815 }
816 return 0;
817}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700818
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800819void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700820{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800821 name -= TRACK0;
Andy Hung8ed196a2018-01-05 13:21:11 -0800822 const std::shared_ptr<Track> &track = mTracks[name];
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700823
Andy Hung8ed196a2018-01-05 13:21:11 -0800824 if (track->mInputBufferProvider == bufferProvider) {
Andy Hung1d26ddf2014-05-29 15:53:09 -0700825 return; // don't reset any buffer providers if identical.
826 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800827 if (track->mReformatBufferProvider.get() != nullptr) {
828 track->mReformatBufferProvider->reset();
829 } else if (track->mDownmixerBufferProvider != nullptr) {
830 track->mDownmixerBufferProvider->reset();
831 } else if (track->mPostDownmixReformatBufferProvider.get() != nullptr) {
832 track->mPostDownmixReformatBufferProvider->reset();
833 } else if (track->mTimestretchBufferProvider.get() != nullptr) {
834 track->mTimestretchBufferProvider->reset();
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700835 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700836
Andy Hung8ed196a2018-01-05 13:21:11 -0800837 track->mInputBufferProvider = bufferProvider;
838 track->reconfigureBufferProviders();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700839}
840
Andy Hung8ed196a2018-01-05 13:21:11 -0800841void AudioMixer::process__validate()
Mathias Agopian65ab4712010-07-14 17:59:35 -0700842{
Andy Hung395db4b2014-08-25 17:15:29 -0700843 // TODO: fix all16BitsStereNoResample logic to
844 // either properly handle muted tracks (it should ignore them)
845 // or remove altogether as an obsolete optimization.
Glenn Kasten4c340c62012-01-27 12:33:54 -0800846 bool all16BitsStereoNoResample = true;
847 bool resampling = false;
848 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700849
Andy Hung8ed196a2018-01-05 13:21:11 -0800850 mEnabled.clear();
851 mGroups.clear();
852 for (const auto &pair : mTracks) {
853 const int name = pair.first;
854 const std::shared_ptr<Track> &t = pair.second;
855 if (!t->enabled) continue;
856
857 mEnabled.emplace_back(name); // we add to mEnabled in order of name.
858 mGroups[t->mainBuffer].emplace_back(name); // mGroups also in order of name.
859
Mathias Agopian65ab4712010-07-14 17:59:35 -0700860 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700861 // FIXME can overflow (mask is only 3 bits)
Andy Hung8ed196a2018-01-05 13:21:11 -0800862 n |= NEEDS_CHANNEL_1 + t->channelCount - 1;
863 if (t->doesResample()) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700864 n |= NEEDS_RESAMPLE;
865 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800866 if (t->auxLevel != 0 && t->auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700867 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700868 }
869
Andy Hung8ed196a2018-01-05 13:21:11 -0800870 if (t->volumeInc[0]|t->volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800871 volumeRamp = true;
Andy Hung8ed196a2018-01-05 13:21:11 -0800872 } else if (!t->doesResample() && t->volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700873 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700874 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800875 t->needs = n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700876
Glenn Kastend6fadf02013-10-30 14:37:29 -0700877 if (n & NEEDS_MUTE) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800878 t->hook = &Track::track__nop;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700879 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700880 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800881 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700882 }
Glenn Kastend6fadf02013-10-30 14:37:29 -0700883 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800884 all16BitsStereoNoResample = false;
885 resampling = true;
Andy Hung8ed196a2018-01-05 13:21:11 -0800886 t->hook = Track::getTrackHook(TRACKTYPE_RESAMPLE, t->mMixerChannelCount,
887 t->mMixerInFormat, t->mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700888 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700889 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700890 } else {
891 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
Andy Hung8ed196a2018-01-05 13:21:11 -0800892 t->hook = Track::getTrackHook(
893 (t->mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO // TODO: MONO_HACK
894 && t->channelMask == AUDIO_CHANNEL_OUT_MONO)
Andy Hunge93b6b72014-07-17 21:30:53 -0700895 ? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,
Andy Hung8ed196a2018-01-05 13:21:11 -0800896 t->mMixerChannelCount,
897 t->mMixerInFormat, t->mMixerFormat);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800898 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700899 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700900 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Andy Hung8ed196a2018-01-05 13:21:11 -0800901 t->hook = Track::getTrackHook(TRACKTYPE_NORESAMPLE, t->mMixerChannelCount,
902 t->mMixerInFormat, t->mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700903 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700904 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700905 }
906 }
907 }
908 }
909
910 // select the processing hooks
Andy Hung8ed196a2018-01-05 13:21:11 -0800911 mHook = &AudioMixer::process__nop;
912 if (mEnabled.size() > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700913 if (resampling) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800914 if (mOutputTemp.get() == nullptr) {
915 mOutputTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700916 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800917 if (mResampleTemp.get() == nullptr) {
918 mResampleTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700919 }
Andy Hung8ed196a2018-01-05 13:21:11 -0800920 mHook = &AudioMixer::process__genericResampling;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700921 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -0800922 // we keep temp arrays around.
923 mHook = &AudioMixer::process__genericNoResampling;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700924 if (all16BitsStereoNoResample && !volumeRamp) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800925 if (mEnabled.size() == 1) {
926 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
927 if ((t->needs & NEEDS_MUTE) == 0) {
Andy Hung395db4b2014-08-25 17:15:29 -0700928 // The check prevents a muted track from acquiring a process hook.
929 //
930 // This is dangerous if the track is MONO as that requires
931 // special case handling due to implicit channel duplication.
932 // Stereo or Multichannel should actually be fine here.
Andy Hung8ed196a2018-01-05 13:21:11 -0800933 mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
934 t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
Andy Hung395db4b2014-08-25 17:15:29 -0700935 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700936 }
937 }
938 }
939 }
940
Andy Hung8ed196a2018-01-05 13:21:11 -0800941 ALOGV("mixer configuration change: %zu "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700942 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -0800943 mEnabled.size(), all16BitsStereoNoResample, resampling, volumeRamp);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700944
Andy Hung8ed196a2018-01-05 13:21:11 -0800945 process();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700946
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800947 // Now that the volume ramp has been done, set optimal state and
948 // track hooks for subsequent mixer process
Andy Hung8ed196a2018-01-05 13:21:11 -0800949 if (mEnabled.size() > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800950 bool allMuted = true;
Andy Hung8ed196a2018-01-05 13:21:11 -0800951
952 for (const int name : mEnabled) {
953 const std::shared_ptr<Track> &t = mTracks[name];
954 if (!t->doesResample() && t->volumeRL == 0) {
955 t->needs |= NEEDS_MUTE;
956 t->hook = &Track::track__nop;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800957 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800958 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800959 }
960 }
961 if (allMuted) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800962 mHook = &AudioMixer::process__nop;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800963 } else if (all16BitsStereoNoResample) {
Andy Hung8ed196a2018-01-05 13:21:11 -0800964 if (mEnabled.size() == 1) {
965 //const int i = 31 - __builtin_clz(enabledTracks);
966 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
Andy Hung395db4b2014-08-25 17:15:29 -0700967 // Muted single tracks handled by allMuted above.
Andy Hung8ed196a2018-01-05 13:21:11 -0800968 mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
969 t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800970 }
971 }
972 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700973}
974
Andy Hung8ed196a2018-01-05 13:21:11 -0800975void AudioMixer::Track::track__genericResample(
976 int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700977{
Andy Hung296b7412014-06-17 15:25:47 -0700978 ALOGVV("track__genericResample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -0800979 mResampler->setSampleRate(sampleRate);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700980
981 // ramp gain - resample to temp buffer and scale/mix in 2nd step
982 if (aux != NULL) {
983 // always resample with unity gain when sending to auxiliary buffer to be able
984 // to apply send level after resampling
Andy Hung8ed196a2018-01-05 13:21:11 -0800985 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
986 memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(int32_t));
987 mResampler->resample(temp, outFrameCount, bufferProvider);
988 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
989 volumeRampStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700990 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -0800991 volumeStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700992 }
993 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -0800994 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
995 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700996 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
Andy Hung8ed196a2018-01-05 13:21:11 -0800997 mResampler->resample(temp, outFrameCount, bufferProvider);
998 volumeRampStereo(out, outFrameCount, temp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700999 }
1000
1001 // constant gain
1002 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001003 mResampler->setVolume(mVolume[0], mVolume[1]);
1004 mResampler->resample(out, outFrameCount, bufferProvider);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001005 }
1006 }
1007}
1008
Andy Hung8ed196a2018-01-05 13:21:11 -08001009void AudioMixer::Track::track__nop(int32_t* out __unused,
Andy Hungee931ff2014-01-28 13:44:14 -08001010 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001011{
1012}
1013
Andy Hung8ed196a2018-01-05 13:21:11 -08001014void AudioMixer::Track::volumeRampStereo(
1015 int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001016{
Andy Hung8ed196a2018-01-05 13:21:11 -08001017 int32_t vl = prevVolume[0];
1018 int32_t vr = prevVolume[1];
1019 const int32_t vlInc = volumeInc[0];
1020 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001021
Steve Blockb8a80522011-12-20 16:23:08 +00001022 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001023 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001024 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1025
1026 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -08001027 if (CC_UNLIKELY(aux != NULL)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001028 int32_t va = prevAuxLevel;
1029 const int32_t vaInc = auxInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001030 int32_t l;
1031 int32_t r;
1032
1033 do {
1034 l = (*temp++ >> 12);
1035 r = (*temp++ >> 12);
1036 *out++ += (vl >> 16) * l;
1037 *out++ += (vr >> 16) * r;
1038 *aux++ += (va >> 17) * (l + r);
1039 vl += vlInc;
1040 vr += vrInc;
1041 va += vaInc;
1042 } while (--frameCount);
Andy Hung8ed196a2018-01-05 13:21:11 -08001043 prevAuxLevel = va;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001044 } else {
1045 do {
1046 *out++ += (vl >> 16) * (*temp++ >> 12);
1047 *out++ += (vr >> 16) * (*temp++ >> 12);
1048 vl += vlInc;
1049 vr += vrInc;
1050 } while (--frameCount);
1051 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001052 prevVolume[0] = vl;
1053 prevVolume[1] = vr;
1054 adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001055}
1056
Andy Hung8ed196a2018-01-05 13:21:11 -08001057void AudioMixer::Track::volumeStereo(
1058 int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001059{
Andy Hung8ed196a2018-01-05 13:21:11 -08001060 const int16_t vl = volume[0];
1061 const int16_t vr = volume[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001062
Glenn Kastenf6b16782011-12-15 09:51:17 -08001063 if (CC_UNLIKELY(aux != NULL)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001064 const int16_t va = auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001065 do {
1066 int16_t l = (int16_t)(*temp++ >> 12);
1067 int16_t r = (int16_t)(*temp++ >> 12);
1068 out[0] = mulAdd(l, vl, out[0]);
1069 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1070 out[1] = mulAdd(r, vr, out[1]);
1071 out += 2;
1072 aux[0] = mulAdd(a, va, aux[0]);
1073 aux++;
1074 } while (--frameCount);
1075 } else {
1076 do {
1077 int16_t l = (int16_t)(*temp++ >> 12);
1078 int16_t r = (int16_t)(*temp++ >> 12);
1079 out[0] = mulAdd(l, vl, out[0]);
1080 out[1] = mulAdd(r, vr, out[1]);
1081 out += 2;
1082 } while (--frameCount);
1083 }
1084}
1085
Andy Hung8ed196a2018-01-05 13:21:11 -08001086void AudioMixer::Track::track__16BitsStereo(
1087 int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001088{
Andy Hung296b7412014-06-17 15:25:47 -07001089 ALOGVV("track__16BitsStereo\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001090 const int16_t *in = static_cast<const int16_t *>(mIn);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001091
Glenn Kastenf6b16782011-12-15 09:51:17 -08001092 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001093 int32_t l;
1094 int32_t r;
1095 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001096 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
1097 int32_t vl = prevVolume[0];
1098 int32_t vr = prevVolume[1];
1099 int32_t va = prevAuxLevel;
1100 const int32_t vlInc = volumeInc[0];
1101 const int32_t vrInc = volumeInc[1];
1102 const int32_t vaInc = auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001103 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001104 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001105 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1106
1107 do {
1108 l = (int32_t)*in++;
1109 r = (int32_t)*in++;
1110 *out++ += (vl >> 16) * l;
1111 *out++ += (vr >> 16) * r;
1112 *aux++ += (va >> 17) * (l + r);
1113 vl += vlInc;
1114 vr += vrInc;
1115 va += vaInc;
1116 } while (--frameCount);
1117
Andy Hung8ed196a2018-01-05 13:21:11 -08001118 prevVolume[0] = vl;
1119 prevVolume[1] = vr;
1120 prevAuxLevel = va;
1121 adjustVolumeRamp(true);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001122 }
1123
1124 // constant gain
1125 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001126 const uint32_t vrl = volumeRL;
1127 const int16_t va = (int16_t)auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001128 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001129 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001130 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1131 in += 2;
1132 out[0] = mulAddRL(1, rl, vrl, out[0]);
1133 out[1] = mulAddRL(0, rl, vrl, out[1]);
1134 out += 2;
1135 aux[0] = mulAdd(a, va, aux[0]);
1136 aux++;
1137 } while (--frameCount);
1138 }
1139 } else {
1140 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001141 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
1142 int32_t vl = prevVolume[0];
1143 int32_t vr = prevVolume[1];
1144 const int32_t vlInc = volumeInc[0];
1145 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001146
Steve Blockb8a80522011-12-20 16:23:08 +00001147 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001148 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001149 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1150
1151 do {
1152 *out++ += (vl >> 16) * (int32_t) *in++;
1153 *out++ += (vr >> 16) * (int32_t) *in++;
1154 vl += vlInc;
1155 vr += vrInc;
1156 } while (--frameCount);
1157
Andy Hung8ed196a2018-01-05 13:21:11 -08001158 prevVolume[0] = vl;
1159 prevVolume[1] = vr;
1160 adjustVolumeRamp(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001161 }
1162
1163 // constant gain
1164 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001165 const uint32_t vrl = volumeRL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001166 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001167 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001168 in += 2;
1169 out[0] = mulAddRL(1, rl, vrl, out[0]);
1170 out[1] = mulAddRL(0, rl, vrl, out[1]);
1171 out += 2;
1172 } while (--frameCount);
1173 }
1174 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001175 mIn = in;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001176}
1177
Andy Hung8ed196a2018-01-05 13:21:11 -08001178void AudioMixer::Track::track__16BitsMono(
1179 int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001180{
Andy Hung296b7412014-06-17 15:25:47 -07001181 ALOGVV("track__16BitsMono\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001182 const int16_t *in = static_cast<int16_t const *>(mIn);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001183
Glenn Kastenf6b16782011-12-15 09:51:17 -08001184 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001185 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001186 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
1187 int32_t vl = prevVolume[0];
1188 int32_t vr = prevVolume[1];
1189 int32_t va = prevAuxLevel;
1190 const int32_t vlInc = volumeInc[0];
1191 const int32_t vrInc = volumeInc[1];
1192 const int32_t vaInc = auxInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001193
Steve Blockb8a80522011-12-20 16:23:08 +00001194 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001195 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001196 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1197
1198 do {
1199 int32_t l = *in++;
1200 *out++ += (vl >> 16) * l;
1201 *out++ += (vr >> 16) * l;
1202 *aux++ += (va >> 16) * l;
1203 vl += vlInc;
1204 vr += vrInc;
1205 va += vaInc;
1206 } while (--frameCount);
1207
Andy Hung8ed196a2018-01-05 13:21:11 -08001208 prevVolume[0] = vl;
1209 prevVolume[1] = vr;
1210 prevAuxLevel = va;
1211 adjustVolumeRamp(true);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001212 }
1213 // constant gain
1214 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001215 const int16_t vl = volume[0];
1216 const int16_t vr = volume[1];
1217 const int16_t va = (int16_t)auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001218 do {
1219 int16_t l = *in++;
1220 out[0] = mulAdd(l, vl, out[0]);
1221 out[1] = mulAdd(l, vr, out[1]);
1222 out += 2;
1223 aux[0] = mulAdd(l, va, aux[0]);
1224 aux++;
1225 } while (--frameCount);
1226 }
1227 } else {
1228 // ramp gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001229 if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
1230 int32_t vl = prevVolume[0];
1231 int32_t vr = prevVolume[1];
1232 const int32_t vlInc = volumeInc[0];
1233 const int32_t vrInc = volumeInc[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001234
Steve Blockb8a80522011-12-20 16:23:08 +00001235 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Andy Hung8ed196a2018-01-05 13:21:11 -08001236 // t, vlInc/65536.0f, vl/65536.0f, volume[0],
Mathias Agopian65ab4712010-07-14 17:59:35 -07001237 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1238
1239 do {
1240 int32_t l = *in++;
1241 *out++ += (vl >> 16) * l;
1242 *out++ += (vr >> 16) * l;
1243 vl += vlInc;
1244 vr += vrInc;
1245 } while (--frameCount);
1246
Andy Hung8ed196a2018-01-05 13:21:11 -08001247 prevVolume[0] = vl;
1248 prevVolume[1] = vr;
1249 adjustVolumeRamp(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001250 }
1251 // constant gain
1252 else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001253 const int16_t vl = volume[0];
1254 const int16_t vr = volume[1];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001255 do {
1256 int16_t l = *in++;
1257 out[0] = mulAdd(l, vl, out[0]);
1258 out[1] = mulAdd(l, vr, out[1]);
1259 out += 2;
1260 } while (--frameCount);
1261 }
1262 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001263 mIn = in;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001264}
1265
Mathias Agopian65ab4712010-07-14 17:59:35 -07001266// no-op case
Andy Hung8ed196a2018-01-05 13:21:11 -08001267void AudioMixer::process__nop()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001268{
Andy Hung296b7412014-06-17 15:25:47 -07001269 ALOGVV("process__nop\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001270
1271 for (const auto &pair : mGroups) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001272 // process by group of tracks with same output buffer to
1273 // avoid multiple memset() on same buffer
Andy Hung8ed196a2018-01-05 13:21:11 -08001274 const auto &group = pair.second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001275
Andy Hung8ed196a2018-01-05 13:21:11 -08001276 const std::shared_ptr<Track> &t = mTracks[group[0]];
1277 memset(t->mainBuffer, 0,
1278 mFrameCount * t->mMixerChannelCount
1279 * audio_bytes_per_sample(t->mMixerFormat));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001280
Andy Hung8ed196a2018-01-05 13:21:11 -08001281 // now consume data
1282 for (const int name : group) {
1283 const std::shared_ptr<Track> &t = mTracks[name];
1284 size_t outFrames = mFrameCount;
1285 while (outFrames) {
1286 t->buffer.frameCount = outFrames;
1287 t->bufferProvider->getNextBuffer(&t->buffer);
1288 if (t->buffer.raw == NULL) break;
1289 outFrames -= t->buffer.frameCount;
1290 t->bufferProvider->releaseBuffer(&t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001291 }
1292 }
1293 }
1294}
1295
1296// generic code without resampling
Andy Hung8ed196a2018-01-05 13:21:11 -08001297void AudioMixer::process__genericNoResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001298{
Andy Hung296b7412014-06-17 15:25:47 -07001299 ALOGVV("process__genericNoResampling\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001300 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1301
Andy Hung8ed196a2018-01-05 13:21:11 -08001302 for (const auto &pair : mGroups) {
1303 // process by group of tracks with same output main buffer to
1304 // avoid multiple memset() on same buffer
1305 const auto &group = pair.second;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001306
Andy Hung8ed196a2018-01-05 13:21:11 -08001307 // acquire buffer
1308 for (const int name : group) {
1309 const std::shared_ptr<Track> &t = mTracks[name];
1310 t->buffer.frameCount = mFrameCount;
1311 t->bufferProvider->getNextBuffer(&t->buffer);
1312 t->frameCount = t->buffer.frameCount;
1313 t->mIn = t->buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001314 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001315
1316 int32_t *out = (int *)pair.first;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001317 size_t numFrames = 0;
1318 do {
Andy Hung8ed196a2018-01-05 13:21:11 -08001319 const size_t frameCount = std::min((size_t)BLOCKSIZE, mFrameCount - numFrames);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001320 memset(outTemp, 0, sizeof(outTemp));
Andy Hung8ed196a2018-01-05 13:21:11 -08001321 for (const int name : group) {
1322 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001323 int32_t *aux = NULL;
Andy Hung8ed196a2018-01-05 13:21:11 -08001324 if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
1325 aux = t->auxBuffer + numFrames;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001326 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001327 for (int outFrames = frameCount; outFrames > 0; ) {
1328 // t->in == nullptr can happen if the track was flushed just after having
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301329 // been enabled for mixing.
Andy Hung8ed196a2018-01-05 13:21:11 -08001330 if (t->mIn == nullptr) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301331 break;
1332 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001333 size_t inFrames = (t->frameCount > outFrames)?outFrames:t->frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001334 if (inFrames > 0) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001335 (t.get()->*t->hook)(
1336 outTemp + (frameCount - outFrames) * t->mMixerChannelCount,
1337 inFrames, mResampleTemp.get() /* naked ptr */, aux);
1338 t->frameCount -= inFrames;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001339 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001340 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001341 aux += inFrames;
1342 }
1343 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001344 if (t->frameCount == 0 && outFrames) {
1345 t->bufferProvider->releaseBuffer(&t->buffer);
1346 t->buffer.frameCount = (mFrameCount - numFrames) -
Yahan Zhouc1c11b42018-01-16 12:44:04 -08001347 (frameCount - outFrames);
Andy Hung8ed196a2018-01-05 13:21:11 -08001348 t->bufferProvider->getNextBuffer(&t->buffer);
1349 t->mIn = t->buffer.raw;
1350 if (t->mIn == nullptr) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001351 break;
1352 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001353 t->frameCount = t->buffer.frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001354 }
1355 }
1356 }
Andy Hung296b7412014-06-17 15:25:47 -07001357
Andy Hung8ed196a2018-01-05 13:21:11 -08001358 const std::shared_ptr<Track> &t1 = mTracks[group[0]];
1359 convertMixerFormat(out, t1->mMixerFormat, outTemp, t1->mMixerInFormat,
1360 frameCount * t1->mMixerChannelCount);
Andy Hung296b7412014-06-17 15:25:47 -07001361 // TODO: fix ugly casting due to choice of out pointer type
1362 out = reinterpret_cast<int32_t*>((uint8_t*)out
Andy Hung8ed196a2018-01-05 13:21:11 -08001363 + frameCount * t1->mMixerChannelCount
1364 * audio_bytes_per_sample(t1->mMixerFormat));
Yahan Zhouc1c11b42018-01-16 12:44:04 -08001365 numFrames += frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001366 } while (numFrames < mFrameCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001367
Andy Hung8ed196a2018-01-05 13:21:11 -08001368 // release each track's buffer
1369 for (const int name : group) {
1370 const std::shared_ptr<Track> &t = mTracks[name];
1371 t->bufferProvider->releaseBuffer(&t->buffer);
1372 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001373 }
1374}
1375
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001376// generic code with resampling
Andy Hung8ed196a2018-01-05 13:21:11 -08001377void AudioMixer::process__genericResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001378{
Andy Hung296b7412014-06-17 15:25:47 -07001379 ALOGVV("process__genericResampling\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001380 int32_t * const outTemp = mOutputTemp.get(); // naked ptr
1381 size_t numFrames = mFrameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001382
Andy Hung8ed196a2018-01-05 13:21:11 -08001383 for (const auto &pair : mGroups) {
1384 const auto &group = pair.second;
1385 const std::shared_ptr<Track> &t1 = mTracks[group[0]];
1386
1387 // clear temp buffer
1388 memset(outTemp, 0, sizeof(*outTemp) * t1->mMixerChannelCount * mFrameCount);
1389 for (const int name : group) {
1390 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001391 int32_t *aux = NULL;
Andy Hung8ed196a2018-01-05 13:21:11 -08001392 if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
1393 aux = t->auxBuffer;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001394 }
1395
1396 // this is a little goofy, on the resampling case we don't
1397 // acquire/release the buffers because it's done by
1398 // the resampler.
Andy Hung8ed196a2018-01-05 13:21:11 -08001399 if (t->needs & NEEDS_RESAMPLE) {
1400 (t.get()->*t->hook)(outTemp, numFrames, mResampleTemp.get() /* naked ptr */, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001401 } else {
1402
1403 size_t outFrames = 0;
1404
1405 while (outFrames < numFrames) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001406 t->buffer.frameCount = numFrames - outFrames;
1407 t->bufferProvider->getNextBuffer(&t->buffer);
1408 t->mIn = t->buffer.raw;
1409 // t->mIn == nullptr can happen if the track was flushed just after having
Mathias Agopian65ab4712010-07-14 17:59:35 -07001410 // been enabled for mixing.
Andy Hung8ed196a2018-01-05 13:21:11 -08001411 if (t->mIn == nullptr) break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001412
Glenn Kastenf6b16782011-12-15 09:51:17 -08001413 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001414 aux += outFrames;
1415 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001416 (t.get()->*t->hook)(
1417 outTemp + outFrames * t->mMixerChannelCount, t->buffer.frameCount,
1418 mResampleTemp.get() /* naked ptr */, aux);
1419 outFrames += t->buffer.frameCount;
1420 t->bufferProvider->releaseBuffer(&t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001421 }
1422 }
1423 }
Andy Hung8ed196a2018-01-05 13:21:11 -08001424 convertMixerFormat(t1->mainBuffer, t1->mMixerFormat,
1425 outTemp, t1->mMixerInFormat, numFrames * t1->mMixerChannelCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001426 }
1427}
1428
1429// one track, 16 bits stereo without resampling is the most common case
Andy Hung8ed196a2018-01-05 13:21:11 -08001430void AudioMixer::process__oneTrack16BitsStereoNoResampling()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001431{
Andy Hung8ed196a2018-01-05 13:21:11 -08001432 ALOGVV("process__oneTrack16BitsStereoNoResampling\n");
1433 LOG_ALWAYS_FATAL_IF(mEnabled.size() != 0,
1434 "%zu != 1 tracks enabled", mEnabled.size());
1435 const int name = mEnabled[0];
1436 const std::shared_ptr<Track> &t = mTracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001437
Andy Hung8ed196a2018-01-05 13:21:11 -08001438 AudioBufferProvider::Buffer& b(t->buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001439
Andy Hung8ed196a2018-01-05 13:21:11 -08001440 int32_t* out = t->mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001441 float *fout = reinterpret_cast<float*>(out);
Andy Hung8ed196a2018-01-05 13:21:11 -08001442 size_t numFrames = mFrameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001443
Andy Hung8ed196a2018-01-05 13:21:11 -08001444 const int16_t vl = t->volume[0];
1445 const int16_t vr = t->volume[1];
1446 const uint32_t vrl = t->volumeRL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001447 while (numFrames) {
1448 b.frameCount = numFrames;
Andy Hung8ed196a2018-01-05 13:21:11 -08001449 t->bufferProvider->getNextBuffer(&b);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001450 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001451
1452 // in == NULL can happen if the track was flushed just after having
1453 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001454 if (in == NULL || (((uintptr_t)in) & 3)) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001455 if ( AUDIO_FORMAT_PCM_FLOAT == t->mMixerFormat ) {
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001456 memset((char*)fout, 0, numFrames
Andy Hung8ed196a2018-01-05 13:21:11 -08001457 * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001458 } else {
1459 memset((char*)out, 0, numFrames
Andy Hung8ed196a2018-01-05 13:21:11 -08001460 * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001461 }
Andy Hung395db4b2014-08-25 17:15:29 -07001462 ALOGE_IF((((uintptr_t)in) & 3),
Andy Hung8ed196a2018-01-05 13:21:11 -08001463 "process__oneTrack16BitsStereoNoResampling: misaligned buffer"
Andy Hung395db4b2014-08-25 17:15:29 -07001464 " %p track %d, channels %d, needs %08x, volume %08x vfl %f vfr %f",
Andy Hung8ed196a2018-01-05 13:21:11 -08001465 in, name, t->channelCount, t->needs, vrl, t->mVolume[0], t->mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001466 return;
1467 }
1468 size_t outFrames = b.frameCount;
1469
Andy Hung8ed196a2018-01-05 13:21:11 -08001470 switch (t->mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001471 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001472 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001473 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001474 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001475 int32_t l = mulRL(1, rl, vrl);
1476 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001477 *fout++ = float_from_q4_27(l);
1478 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001479 // Note: In case of later int16_t sink output,
1480 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001481 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001482 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001483 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung97ae8242014-05-30 10:35:47 -07001484 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001485 // volume is boosted, so we might need to clamp even though
1486 // we process only one track.
1487 do {
1488 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1489 in += 2;
1490 int32_t l = mulRL(1, rl, vrl) >> 12;
1491 int32_t r = mulRL(0, rl, vrl) >> 12;
1492 // clamping...
1493 l = clamp16(l);
1494 r = clamp16(r);
1495 *out++ = (r<<16) | (l & 0xFFFF);
1496 } while (--outFrames);
1497 } else {
1498 do {
1499 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1500 in += 2;
1501 int32_t l = mulRL(1, rl, vrl) >> 12;
1502 int32_t r = mulRL(0, rl, vrl) >> 12;
1503 *out++ = (r<<16) | (l & 0xFFFF);
1504 } while (--outFrames);
1505 }
1506 break;
1507 default:
Andy Hung8ed196a2018-01-05 13:21:11 -08001508 LOG_ALWAYS_FATAL("bad mixer format: %d", t->mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001509 }
1510 numFrames -= b.frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001511 t->bufferProvider->releaseBuffer(&b);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001512 }
1513}
1514
Glenn Kasten52008f82012-03-18 09:34:41 -07001515/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1516
1517/*static*/ void AudioMixer::sInitRoutine()
1518{
Andy Hung34803d52014-07-16 21:41:35 -07001519 DownmixerBufferProvider::init(); // for the downmixer
John Grossman4ff14ba2012-02-08 16:37:41 -08001520}
1521
Andy Hunge93b6b72014-07-17 21:30:53 -07001522/* TODO: consider whether this level of optimization is necessary.
1523 * Perhaps just stick with a single for loop.
1524 */
1525
1526// Needs to derive a compile time constant (constexpr). Could be targeted to go
1527// to a MONOVOL mixtype based on MAX_NUM_VOLUMES, but that's an unnecessary complication.
Chih-Hung Hsiehbf291732016-05-17 15:16:07 -07001528#define MIXTYPE_MONOVOL(mixtype) ((mixtype) == MIXTYPE_MULTI ? MIXTYPE_MULTI_MONOVOL : \
1529 (mixtype) == MIXTYPE_MULTI_SAVEONLY ? MIXTYPE_MULTI_SAVEONLY_MONOVOL : (mixtype))
Andy Hunge93b6b72014-07-17 21:30:53 -07001530
1531/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1532 * TO: int32_t (Q4.27) or float
1533 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001534 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001535 */
1536template <int MIXTYPE,
1537 typename TO, typename TI, typename TV, typename TA, typename TAV>
1538static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
1539 const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc)
1540{
1541 switch (channels) {
1542 case 1:
1543 volumeRampMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1544 break;
1545 case 2:
1546 volumeRampMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1547 break;
1548 case 3:
1549 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out,
1550 frameCount, in, aux, vol, volinc, vola, volainc);
1551 break;
1552 case 4:
1553 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out,
1554 frameCount, in, aux, vol, volinc, vola, volainc);
1555 break;
1556 case 5:
1557 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out,
1558 frameCount, in, aux, vol, volinc, vola, volainc);
1559 break;
1560 case 6:
1561 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out,
1562 frameCount, in, aux, vol, volinc, vola, volainc);
1563 break;
1564 case 7:
1565 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out,
1566 frameCount, in, aux, vol, volinc, vola, volainc);
1567 break;
1568 case 8:
1569 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out,
1570 frameCount, in, aux, vol, volinc, vola, volainc);
1571 break;
1572 }
1573}
1574
1575/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1576 * TO: int32_t (Q4.27) or float
1577 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001578 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001579 */
1580template <int MIXTYPE,
1581 typename TO, typename TI, typename TV, typename TA, typename TAV>
1582static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
1583 const TI* in, TA* aux, const TV *vol, TAV vola)
1584{
1585 switch (channels) {
1586 case 1:
1587 volumeMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, vola);
1588 break;
1589 case 2:
1590 volumeMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, vola);
1591 break;
1592 case 3:
1593 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out, frameCount, in, aux, vol, vola);
1594 break;
1595 case 4:
1596 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out, frameCount, in, aux, vol, vola);
1597 break;
1598 case 5:
1599 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out, frameCount, in, aux, vol, vola);
1600 break;
1601 case 6:
1602 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out, frameCount, in, aux, vol, vola);
1603 break;
1604 case 7:
1605 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out, frameCount, in, aux, vol, vola);
1606 break;
1607 case 8:
1608 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out, frameCount, in, aux, vol, vola);
1609 break;
1610 }
1611}
1612
1613/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1614 * USEFLOATVOL (set to true if float volume is used)
1615 * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards)
1616 * TO: int32_t (Q4.27) or float
1617 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001618 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001619 */
1620template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001621 typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001622void AudioMixer::Track::volumeMix(TO *out, size_t outFrames,
1623 const TI *in, TA *aux, bool ramp)
Andy Hung5e58b0a2014-06-23 19:07:29 -07001624{
1625 if (USEFLOATVOL) {
1626 if (ramp) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001627 volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1628 mPrevVolume, mVolumeInc,
Andy Hung116a4982017-11-30 10:15:08 -08001629#ifdef FLOAT_AUX
Andy Hung8ed196a2018-01-05 13:21:11 -08001630 &mPrevAuxLevel, mAuxInc
Andy Hung116a4982017-11-30 10:15:08 -08001631#else
Andy Hung8ed196a2018-01-05 13:21:11 -08001632 &prevAuxLevel, auxInc
Andy Hung116a4982017-11-30 10:15:08 -08001633#endif
1634 );
Andy Hung5e58b0a2014-06-23 19:07:29 -07001635 if (ADJUSTVOL) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001636 adjustVolumeRamp(aux != NULL, true);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001637 }
1638 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001639 volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1640 mVolume,
Andy Hung116a4982017-11-30 10:15:08 -08001641#ifdef FLOAT_AUX
Andy Hung8ed196a2018-01-05 13:21:11 -08001642 mAuxLevel
Andy Hung116a4982017-11-30 10:15:08 -08001643#else
Andy Hung8ed196a2018-01-05 13:21:11 -08001644 auxLevel
Andy Hung116a4982017-11-30 10:15:08 -08001645#endif
1646 );
Andy Hung5e58b0a2014-06-23 19:07:29 -07001647 }
1648 } else {
1649 if (ramp) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001650 volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1651 prevVolume, volumeInc, &prevAuxLevel, auxInc);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001652 if (ADJUSTVOL) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001653 adjustVolumeRamp(aux != NULL);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001654 }
1655 } else {
Andy Hung8ed196a2018-01-05 13:21:11 -08001656 volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
1657 volume, auxLevel);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001658 }
1659 }
1660}
1661
Andy Hung296b7412014-06-17 15:25:47 -07001662/* This process hook is called when there is a single track without
1663 * aux buffer, volume ramp, or resampling.
1664 * TODO: Update the hook selection: this can properly handle aux and ramp.
Andy Hunge93b6b72014-07-17 21:30:53 -07001665 *
1666 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1667 * TO: int32_t (Q4.27) or float
1668 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1669 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07001670 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001671template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001672void AudioMixer::process__noResampleOneTrack()
Andy Hung296b7412014-06-17 15:25:47 -07001673{
Andy Hung8ed196a2018-01-05 13:21:11 -08001674 ALOGVV("process__noResampleOneTrack\n");
1675 LOG_ALWAYS_FATAL_IF(mEnabled.size() != 1,
1676 "%zu != 1 tracks enabled", mEnabled.size());
1677 const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
Andy Hunge93b6b72014-07-17 21:30:53 -07001678 const uint32_t channels = t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07001679 TO* out = reinterpret_cast<TO*>(t->mainBuffer);
1680 TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
1681 const bool ramp = t->needsRamp();
1682
Andy Hung8ed196a2018-01-05 13:21:11 -08001683 for (size_t numFrames = mFrameCount; numFrames > 0; ) {
Andy Hung296b7412014-06-17 15:25:47 -07001684 AudioBufferProvider::Buffer& b(t->buffer);
1685 // get input buffer
1686 b.frameCount = numFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001687 t->bufferProvider->getNextBuffer(&b);
Andy Hung296b7412014-06-17 15:25:47 -07001688 const TI *in = reinterpret_cast<TI*>(b.raw);
1689
1690 // in == NULL can happen if the track was flushed just after having
1691 // been enabled for mixing.
1692 if (in == NULL || (((uintptr_t)in) & 3)) {
1693 memset(out, 0, numFrames
Andy Hunge93b6b72014-07-17 21:30:53 -07001694 * channels * audio_bytes_per_sample(t->mMixerFormat));
Andy Hung8ed196a2018-01-05 13:21:11 -08001695 ALOGE_IF((((uintptr_t)in) & 3), "process__noResampleOneTrack: bus error: "
Andy Hung296b7412014-06-17 15:25:47 -07001696 "buffer %p track %p, channels %d, needs %#x",
Andy Hung8ed196a2018-01-05 13:21:11 -08001697 in, &t, t->channelCount, t->needs);
Andy Hung296b7412014-06-17 15:25:47 -07001698 return;
1699 }
1700
1701 const size_t outFrames = b.frameCount;
Andy Hung8ed196a2018-01-05 13:21:11 -08001702 t->volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, false /* ADJUSTVOL */> (
1703 out, outFrames, in, aux, ramp);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001704
Andy Hunge93b6b72014-07-17 21:30:53 -07001705 out += outFrames * channels;
Andy Hung296b7412014-06-17 15:25:47 -07001706 if (aux != NULL) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001707 aux += channels;
Andy Hung296b7412014-06-17 15:25:47 -07001708 }
1709 numFrames -= b.frameCount;
1710
1711 // release buffer
1712 t->bufferProvider->releaseBuffer(&b);
1713 }
1714 if (ramp) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001715 t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
Andy Hung296b7412014-06-17 15:25:47 -07001716 }
1717}
1718
1719/* This track hook is called to do resampling then mixing,
1720 * pulling from the track's upstream AudioBufferProvider.
Andy Hunge93b6b72014-07-17 21:30:53 -07001721 *
1722 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1723 * TO: int32_t (Q4.27) or float
1724 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001725 * TA: int32_t (Q4.27) or float
Andy Hung296b7412014-06-17 15:25:47 -07001726 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001727template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001728void AudioMixer::Track::track__Resample(TO* out, size_t outFrameCount, TO* temp, TA* aux)
Andy Hung296b7412014-06-17 15:25:47 -07001729{
1730 ALOGVV("track__Resample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001731 mResampler->setSampleRate(sampleRate);
1732 const bool ramp = needsRamp();
Andy Hung296b7412014-06-17 15:25:47 -07001733 if (ramp || aux != NULL) {
1734 // if ramp: resample with unity gain to temp buffer and scale/mix in 2nd step.
1735 // if aux != NULL: resample with unity gain to temp buffer then apply send level.
1736
Andy Hung8ed196a2018-01-05 13:21:11 -08001737 mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
1738 memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(TO));
1739 mResampler->resample((int32_t*)temp, outFrameCount, bufferProvider);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001740
Andy Hung116a4982017-11-30 10:15:08 -08001741 volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
Andy Hung8ed196a2018-01-05 13:21:11 -08001742 out, outFrameCount, temp, aux, ramp);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001743
Andy Hung296b7412014-06-17 15:25:47 -07001744 } else { // constant volume gain
Andy Hung8ed196a2018-01-05 13:21:11 -08001745 mResampler->setVolume(mVolume[0], mVolume[1]);
1746 mResampler->resample((int32_t*)out, outFrameCount, bufferProvider);
Andy Hung296b7412014-06-17 15:25:47 -07001747 }
1748}
1749
1750/* This track hook is called to mix a track, when no resampling is required.
Andy Hung8ed196a2018-01-05 13:21:11 -08001751 * The input buffer should be present in in.
Andy Hunge93b6b72014-07-17 21:30:53 -07001752 *
1753 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1754 * TO: int32_t (Q4.27) or float
1755 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001756 * TA: int32_t (Q4.27) or float
Andy Hung296b7412014-06-17 15:25:47 -07001757 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001758template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung8ed196a2018-01-05 13:21:11 -08001759void AudioMixer::Track::track__NoResample(TO* out, size_t frameCount, TO* temp __unused, TA* aux)
Andy Hung296b7412014-06-17 15:25:47 -07001760{
1761 ALOGVV("track__NoResample\n");
Andy Hung8ed196a2018-01-05 13:21:11 -08001762 const TI *in = static_cast<const TI *>(mIn);
Andy Hung296b7412014-06-17 15:25:47 -07001763
Andy Hung116a4982017-11-30 10:15:08 -08001764 volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
Andy Hung8ed196a2018-01-05 13:21:11 -08001765 out, frameCount, in, aux, needsRamp());
Andy Hung5e58b0a2014-06-23 19:07:29 -07001766
Andy Hung296b7412014-06-17 15:25:47 -07001767 // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
1768 // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
Andy Hung8ed196a2018-01-05 13:21:11 -08001769 in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * mMixerChannelCount;
1770 mIn = in;
Andy Hung296b7412014-06-17 15:25:47 -07001771}
1772
1773/* The Mixer engine generates either int32_t (Q4_27) or float data.
1774 * We use this function to convert the engine buffers
1775 * to the desired mixer output format, either int16_t (Q.15) or float.
1776 */
Andy Hung8ed196a2018-01-05 13:21:11 -08001777/* static */
Andy Hung296b7412014-06-17 15:25:47 -07001778void AudioMixer::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
1779 void *in, audio_format_t mixerInFormat, size_t sampleCount)
1780{
1781 switch (mixerInFormat) {
1782 case AUDIO_FORMAT_PCM_FLOAT:
1783 switch (mixerOutFormat) {
1784 case AUDIO_FORMAT_PCM_FLOAT:
1785 memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
1786 break;
1787 case AUDIO_FORMAT_PCM_16_BIT:
1788 memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
1789 break;
1790 default:
1791 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1792 break;
1793 }
1794 break;
1795 case AUDIO_FORMAT_PCM_16_BIT:
1796 switch (mixerOutFormat) {
1797 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung5effdf62017-11-27 13:51:40 -08001798 memcpy_to_float_from_q4_27((float*)out, (const int32_t*)in, sampleCount);
Andy Hung296b7412014-06-17 15:25:47 -07001799 break;
1800 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung5effdf62017-11-27 13:51:40 -08001801 memcpy_to_i16_from_q4_27((int16_t*)out, (const int32_t*)in, sampleCount);
Andy Hung296b7412014-06-17 15:25:47 -07001802 break;
1803 default:
1804 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1805 break;
1806 }
1807 break;
1808 default:
1809 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1810 break;
1811 }
1812}
1813
1814/* Returns the proper track hook to use for mixing the track into the output buffer.
1815 */
Andy Hung8ed196a2018-01-05 13:21:11 -08001816/* static */
1817AudioMixer::hook_t AudioMixer::Track::getTrackHook(int trackType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001818 audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
1819{
Andy Hunge93b6b72014-07-17 21:30:53 -07001820 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07001821 switch (trackType) {
1822 case TRACKTYPE_NOP:
Andy Hung8ed196a2018-01-05 13:21:11 -08001823 return &Track::track__nop;
Andy Hung296b7412014-06-17 15:25:47 -07001824 case TRACKTYPE_RESAMPLE:
Andy Hung8ed196a2018-01-05 13:21:11 -08001825 return &Track::track__genericResample;
Andy Hung296b7412014-06-17 15:25:47 -07001826 case TRACKTYPE_NORESAMPLEMONO:
Andy Hung8ed196a2018-01-05 13:21:11 -08001827 return &Track::track__16BitsMono;
Andy Hung296b7412014-06-17 15:25:47 -07001828 case TRACKTYPE_NORESAMPLE:
Andy Hung8ed196a2018-01-05 13:21:11 -08001829 return &Track::track__16BitsStereo;
Andy Hung296b7412014-06-17 15:25:47 -07001830 default:
1831 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1832 break;
1833 }
1834 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001835 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07001836 switch (trackType) {
1837 case TRACKTYPE_NOP:
Andy Hung8ed196a2018-01-05 13:21:11 -08001838 return &Track::track__nop;
Andy Hung296b7412014-06-17 15:25:47 -07001839 case TRACKTYPE_RESAMPLE:
1840 switch (mixerInFormat) {
1841 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001842 return (AudioMixer::hook_t) &Track::track__Resample<
Andy Hung116a4982017-11-30 10:15:08 -08001843 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001844 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001845 return (AudioMixer::hook_t) &Track::track__Resample<
Andy Hung116a4982017-11-30 10:15:08 -08001846 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001847 default:
1848 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1849 break;
1850 }
1851 break;
1852 case TRACKTYPE_NORESAMPLEMONO:
1853 switch (mixerInFormat) {
1854 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001855 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001856 MIXTYPE_MONOEXPAND, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001857 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001858 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001859 MIXTYPE_MONOEXPAND, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001860 default:
1861 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1862 break;
1863 }
1864 break;
1865 case TRACKTYPE_NORESAMPLE:
1866 switch (mixerInFormat) {
1867 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001868 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001869 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001870 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001871 return (AudioMixer::hook_t) &Track::track__NoResample<
Andy Hung116a4982017-11-30 10:15:08 -08001872 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001873 default:
1874 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1875 break;
1876 }
1877 break;
1878 default:
1879 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1880 break;
1881 }
1882 return NULL;
1883}
1884
1885/* Returns the proper process hook for mixing tracks. Currently works only for
1886 * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
Andy Hung395db4b2014-08-25 17:15:29 -07001887 *
1888 * TODO: Due to the special mixing considerations of duplicating to
1889 * a stereo output track, the input track cannot be MONO. This should be
1890 * prevented by the caller.
Andy Hung296b7412014-06-17 15:25:47 -07001891 */
Andy Hung8ed196a2018-01-05 13:21:11 -08001892/* static */
1893AudioMixer::process_hook_t AudioMixer::getProcessHook(
1894 int processType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001895 audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
1896{
1897 if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
1898 LOG_ALWAYS_FATAL("bad processType: %d", processType);
1899 return NULL;
1900 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001901 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung8ed196a2018-01-05 13:21:11 -08001902 return &AudioMixer::process__oneTrack16BitsStereoNoResampling;
Andy Hung296b7412014-06-17 15:25:47 -07001903 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001904 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07001905 switch (mixerInFormat) {
1906 case AUDIO_FORMAT_PCM_FLOAT:
1907 switch (mixerOutFormat) {
1908 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001909 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08001910 MIXTYPE_MULTI_SAVEONLY, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001911 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001912 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08001913 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001914 default:
1915 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1916 break;
1917 }
1918 break;
1919 case AUDIO_FORMAT_PCM_16_BIT:
1920 switch (mixerOutFormat) {
1921 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001922 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08001923 MIXTYPE_MULTI_SAVEONLY, float /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001924 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung8ed196a2018-01-05 13:21:11 -08001925 return &AudioMixer::process__noResampleOneTrack<
Andy Hung116a4982017-11-30 10:15:08 -08001926 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07001927 default:
1928 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1929 break;
1930 }
1931 break;
1932 default:
1933 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1934 break;
1935 }
1936 return NULL;
1937}
1938
Mathias Agopian65ab4712010-07-14 17:59:35 -07001939// ----------------------------------------------------------------------------
Glenn Kasten63238ef2015-03-02 15:50:29 -08001940} // namespace android