blob: f8e05e7cbb27773322e9edd8abeb5028d3edece2 [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 Hunge09c9942015-05-08 16:58:13 -070065// TODO: Move these macro/inlines to a header file.
66template <typename T>
67static inline
68T max(const T& x, const T& y) {
69 return x > y ? x : y;
70}
71
Andy Hung5b8fde72014-09-02 21:14:34 -070072// Set kUseNewMixer to true to use the new mixer engine always. Otherwise the
73// original code will be used for stereo sinks, the new mixer for multichannel.
Andy Hung116a4982017-11-30 10:15:08 -080074static constexpr bool kUseNewMixer = true;
Andy Hung296b7412014-06-17 15:25:47 -070075
76// Set kUseFloat to true to allow floating input into the mixer engine.
77// If kUseNewMixer is false, this is ignored or may be overridden internally
78// because of downmix/upmix support.
Andy Hung116a4982017-11-30 10:15:08 -080079static constexpr bool kUseFloat = true;
80
81#ifdef FLOAT_AUX
82using TYPE_AUX = float;
83static_assert(kUseNewMixer && kUseFloat,
84 "kUseNewMixer and kUseFloat must be true for FLOAT_AUX option");
85#else
86using TYPE_AUX = int32_t; // q4.27
87#endif
Andy Hung296b7412014-06-17 15:25:47 -070088
Andy Hung1b2fdcb2014-07-16 17:44:34 -070089// Set to default copy buffer size in frames for input processing.
90static const size_t kCopyBufferFrameCount = 256;
91
Mathias Agopian65ab4712010-07-14 17:59:35 -070092namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070093
94// ----------------------------------------------------------------------------
Andy Hung1b2fdcb2014-07-16 17:44:34 -070095
96template <typename T>
97T min(const T& a, const T& b)
98{
99 return a < b ? a : b;
100}
101
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700102// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -0700103
Paul Lind3c0a0e82012-08-01 18:49:49 -0700104// Ensure mConfiguredNames bitmask is initialized properly on all architectures.
105// The value of 1 << x is undefined in C when x >= 32.
106
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700107AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks)
Paul Lind3c0a0e82012-08-01 18:49:49 -0700108 : mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1),
Glenn Kasten7f5d3352013-02-15 23:55:04 +0000109 mSampleRate(sampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700110{
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700111 ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
112 maxNumTracks, MAX_NUM_TRACKS);
113
Glenn Kasten599fabc2012-03-08 12:33:37 -0800114 // AudioMixer is not yet capable of more than 32 active track inputs
115 ALOG_ASSERT(32 >= MAX_NUM_TRACKS, "bad MAX_NUM_TRACKS %d", MAX_NUM_TRACKS);
116
Glenn Kasten52008f82012-03-18 09:34:41 -0700117 pthread_once(&sOnceControl, &sInitRoutine);
118
Mathias Agopian65ab4712010-07-14 17:59:35 -0700119 mState.enabledTracks= 0;
120 mState.needsChanged = 0;
121 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800122 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -0800123 mState.outputTemp = NULL;
124 mState.resampleTemp = NULL;
Glenn Kasten3ab8d662017-04-03 14:35:09 -0700125 mState.mNBLogWriter = &mDummyLogWriter;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800126 // mState.reserved
Glenn Kasten17a736c2012-02-14 08:52:15 -0800127
128 // FIXME Most of the following initialization is probably redundant since
129 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
130 // and mTrackNames is initially 0. However, leave it here until that's verified.
Mathias Agopian65ab4712010-07-14 17:59:35 -0700131 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800132 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Eric Laurenta5e82142012-04-16 13:47:17 -0700133 t->resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700134 t->downmixerBufferProvider = NULL;
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700135 t->mReformatBufferProvider = NULL;
Andy Hungc5656cc2015-03-26 19:04:33 -0700136 t->mTimestretchBufferProvider = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700137 t++;
138 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700139
Mathias Agopian65ab4712010-07-14 17:59:35 -0700140}
141
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800142AudioMixer::~AudioMixer()
143{
144 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800145 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800146 delete t->resampler;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700147 delete t->downmixerBufferProvider;
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700148 delete t->mReformatBufferProvider;
Andy Hungc5656cc2015-03-26 19:04:33 -0700149 delete t->mTimestretchBufferProvider;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800150 t++;
151 }
152 delete [] mState.outputTemp;
153 delete [] mState.resampleTemp;
154}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700155
Glenn Kasten3ab8d662017-04-03 14:35:09 -0700156void AudioMixer::setNBLogWriter(NBLog::Writer *logWriter)
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800157{
Glenn Kasten3ab8d662017-04-03 14:35:09 -0700158 mState.mNBLogWriter = logWriter;
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800159}
160
Andy Hung7f475492014-08-25 16:36:37 -0700161static inline audio_format_t selectMixerInFormat(audio_format_t inputFormat __unused) {
162 return kUseFloat && kUseNewMixer ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
163}
164
Andy Hunge8a1ced2014-05-09 15:02:21 -0700165int AudioMixer::getTrackName(audio_channel_mask_t channelMask,
166 audio_format_t format, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800167{
Andy Hunge8a1ced2014-05-09 15:02:21 -0700168 if (!isValidPcmTrackFormat(format)) {
169 ALOGE("AudioMixer::getTrackName invalid format (%#x)", format);
170 return -1;
171 }
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700172 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800173 if (names != 0) {
174 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100175 ALOGV("add track (%d)", n);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700176 // assume default parameters for the track, except where noted below
177 track_t* t = &mState.tracks[n];
178 t->needs = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700179
180 // Integer volume.
181 // Currently integer volume is kept for the legacy integer mixer.
182 // Will be removed when the legacy mixer path is removed.
Andy Hung97ae8242014-05-30 10:35:47 -0700183 t->volume[0] = UNITY_GAIN_INT;
184 t->volume[1] = UNITY_GAIN_INT;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700185 t->prevVolume[0] = UNITY_GAIN_INT << 16;
186 t->prevVolume[1] = UNITY_GAIN_INT << 16;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700187 t->volumeInc[0] = 0;
188 t->volumeInc[1] = 0;
189 t->auxLevel = 0;
190 t->auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700191 t->prevAuxLevel = 0;
192
193 // Floating point volume.
194 t->mVolume[0] = UNITY_GAIN_FLOAT;
195 t->mVolume[1] = UNITY_GAIN_FLOAT;
196 t->mPrevVolume[0] = UNITY_GAIN_FLOAT;
197 t->mPrevVolume[1] = UNITY_GAIN_FLOAT;
198 t->mVolumeInc[0] = 0.;
199 t->mVolumeInc[1] = 0.;
200 t->mAuxLevel = 0.;
201 t->mAuxInc = 0.;
202 t->mPrevAuxLevel = 0.;
203
Glenn Kastendeeb1282012-03-25 11:59:31 -0700204 // no initialization needed
Glenn Kastendeeb1282012-03-25 11:59:31 -0700205 // t->frameCount
Andy Hung68112fc2014-05-14 14:13:23 -0700206 t->channelCount = audio_channel_count_from_out_mask(channelMask);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700207 t->enabled = false;
Andy Hunge93b6b72014-07-17 21:30:53 -0700208 ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
Andy Hungef7c7fb2014-05-12 16:51:41 -0700209 "Non-stereo channel mask: %d\n", channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700210 t->channelMask = channelMask;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700211 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700212 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
213 t->bufferProvider = NULL;
214 t->buffer.raw = NULL;
215 // no initialization needed
216 // t->buffer.frameCount
217 t->hook = NULL;
218 t->in = NULL;
219 t->resampler = NULL;
220 t->sampleRate = mSampleRate;
221 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
222 t->mainBuffer = NULL;
223 t->auxBuffer = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700224 t->mInputBufferProvider = NULL;
225 t->mReformatBufferProvider = NULL;
Glenn Kasten52008f82012-03-18 09:34:41 -0700226 t->downmixerBufferProvider = NULL;
Andy Hung7f475492014-08-25 16:36:37 -0700227 t->mPostDownmixReformatBufferProvider = NULL;
Andy Hungc5656cc2015-03-26 19:04:33 -0700228 t->mTimestretchBufferProvider = NULL;
Andy Hung78820702014-02-28 16:23:02 -0800229 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700230 t->mFormat = format;
Andy Hung7f475492014-08-25 16:36:37 -0700231 t->mMixerInFormat = selectMixerInFormat(format);
232 t->mDownmixRequiresFormat = AUDIO_FORMAT_INVALID; // no format required
Andy Hunge93b6b72014-07-17 21:30:53 -0700233 t->mMixerChannelMask = audio_channel_mask_from_representation_and_bits(
234 AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
235 t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700236 t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
Andy Hung296b7412014-06-17 15:25:47 -0700237 // Check the downmixing (or upmixing) requirements.
Andy Hung0f451e92014-08-04 21:28:47 -0700238 status_t status = t->prepareForDownmix();
Andy Hung68112fc2014-05-14 14:13:23 -0700239 if (status != OK) {
240 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
241 return -1;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700242 }
Andy Hung7f475492014-08-25 16:36:37 -0700243 // prepareForDownmix() may change mDownmixRequiresFormat
Andy Hung296b7412014-06-17 15:25:47 -0700244 ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
Andy Hung0f451e92014-08-04 21:28:47 -0700245 t->prepareForReformat();
Andy Hung68112fc2014-05-14 14:13:23 -0700246 mTrackNames |= 1 << n;
247 return TRACK0 + n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700248 }
Andy Hung68112fc2014-05-14 14:13:23 -0700249 ALOGE("AudioMixer::getTrackName out of available tracks");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700250 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800251}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700252
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800253void AudioMixer::invalidateState(uint32_t mask)
254{
Glenn Kasten34fca342013-08-13 09:48:14 -0700255 if (mask != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700256 mState.needsChanged |= mask;
257 mState.hook = process__validate;
258 }
259 }
260
Andy Hunge93b6b72014-07-17 21:30:53 -0700261// Called when channel masks have changed for a track name
Andy Hung7f475492014-08-25 16:36:37 -0700262// TODO: Fix DownmixerBufferProvider not to (possibly) change mixer input format,
Andy Hunge93b6b72014-07-17 21:30:53 -0700263// which will simplify this logic.
264bool AudioMixer::setChannelMasks(int name,
265 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) {
266 track_t &track = mState.tracks[name];
267
268 if (trackChannelMask == track.channelMask
269 && mixerChannelMask == track.mMixerChannelMask) {
270 return false; // no need to change
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700271 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700272 // always recompute for both channel masks even if only one has changed.
273 const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
274 const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
275 const bool mixerChannelCountChanged = track.mMixerChannelCount != mixerChannelCount;
276
277 ALOG_ASSERT((trackChannelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX)
278 && trackChannelCount
279 && mixerChannelCount);
280 track.channelMask = trackChannelMask;
281 track.channelCount = trackChannelCount;
282 track.mMixerChannelMask = mixerChannelMask;
283 track.mMixerChannelCount = mixerChannelCount;
284
285 // channel masks have changed, does this track need a downmixer?
286 // update to try using our desired format (if we aren't already using it)
Andy Hung7f475492014-08-25 16:36:37 -0700287 const audio_format_t prevDownmixerFormat = track.mDownmixRequiresFormat;
Andy Hung0f451e92014-08-04 21:28:47 -0700288 const status_t status = mState.tracks[name].prepareForDownmix();
Andy Hunge93b6b72014-07-17 21:30:53 -0700289 ALOGE_IF(status != OK,
Andy Hung0f451e92014-08-04 21:28:47 -0700290 "prepareForDownmix error %d, track channel mask %#x, mixer channel mask %#x",
Andy Hunge93b6b72014-07-17 21:30:53 -0700291 status, track.channelMask, track.mMixerChannelMask);
292
Andy Hung7f475492014-08-25 16:36:37 -0700293 if (prevDownmixerFormat != track.mDownmixRequiresFormat) {
Andy Hung0f451e92014-08-04 21:28:47 -0700294 track.prepareForReformat(); // because of downmixer, track format may change!
Andy Hunge93b6b72014-07-17 21:30:53 -0700295 }
296
Andy Hung7f475492014-08-25 16:36:37 -0700297 if (track.resampler && mixerChannelCountChanged) {
298 // resampler channels may have changed.
Andy Hunge93b6b72014-07-17 21:30:53 -0700299 const uint32_t resetToSampleRate = track.sampleRate;
300 delete track.resampler;
301 track.resampler = NULL;
302 track.sampleRate = mSampleRate; // without resampler, track rate is device sample rate.
303 // recreate the resampler with updated format, channels, saved sampleRate.
304 track.setResampler(resetToSampleRate /*trackSampleRate*/, mSampleRate /*devSampleRate*/);
305 }
306 return true;
307}
308
Andy Hung0f451e92014-08-04 21:28:47 -0700309void AudioMixer::track_t::unprepareForDownmix() {
310 ALOGV("AudioMixer::unprepareForDownmix(%p)", this);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700311
Andy Hung85395892017-04-25 16:47:52 -0700312 if (mPostDownmixReformatBufferProvider != nullptr) {
313 // release any buffers held by the mPostDownmixReformatBufferProvider
314 // before deallocating the downmixerBufferProvider.
315 mPostDownmixReformatBufferProvider->reset();
316 }
317
Andy Hung7f475492014-08-25 16:36:37 -0700318 mDownmixRequiresFormat = AUDIO_FORMAT_INVALID;
Andy Hung0f451e92014-08-04 21:28:47 -0700319 if (downmixerBufferProvider != NULL) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700320 // this track had previously been configured with a downmixer, delete it
321 ALOGV(" deleting old downmixer");
Andy Hung0f451e92014-08-04 21:28:47 -0700322 delete downmixerBufferProvider;
323 downmixerBufferProvider = NULL;
324 reconfigureBufferProviders();
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700325 } else {
326 ALOGV(" nothing to do, no downmixer to delete");
327 }
328}
329
Andy Hung0f451e92014-08-04 21:28:47 -0700330status_t AudioMixer::track_t::prepareForDownmix()
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700331{
Andy Hung0f451e92014-08-04 21:28:47 -0700332 ALOGV("AudioMixer::prepareForDownmix(%p) with mask 0x%x",
333 this, channelMask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700334
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700335 // discard the previous downmixer if there was one
Andy Hung0f451e92014-08-04 21:28:47 -0700336 unprepareForDownmix();
Andy Hung73e62e22015-04-20 12:06:38 -0700337 // MONO_HACK Only remix (upmix or downmix) if the track and mixer/device channel masks
Andy Hung0f451e92014-08-04 21:28:47 -0700338 // are not the same and not handled internally, as mono -> stereo currently is.
339 if (channelMask == mMixerChannelMask
340 || (channelMask == AUDIO_CHANNEL_OUT_MONO
341 && mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO)) {
342 return NO_ERROR;
343 }
Andy Hung650ceb92015-01-29 13:31:12 -0800344 // DownmixerBufferProvider is only used for position masks.
345 if (audio_channel_mask_get_representation(channelMask)
346 == AUDIO_CHANNEL_REPRESENTATION_POSITION
347 && DownmixerBufferProvider::isMultichannelCapable()) {
Andy Hung0f451e92014-08-04 21:28:47 -0700348 DownmixerBufferProvider* pDbp = new DownmixerBufferProvider(channelMask,
349 mMixerChannelMask,
350 AUDIO_FORMAT_PCM_16_BIT /* TODO: use mMixerInFormat, now only PCM 16 */,
351 sampleRate, sessionId, kCopyBufferFrameCount);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700352
Andy Hung34803d52014-07-16 21:41:35 -0700353 if (pDbp->isValid()) { // if constructor completed properly
Andy Hung7f475492014-08-25 16:36:37 -0700354 mDownmixRequiresFormat = AUDIO_FORMAT_PCM_16_BIT; // PCM 16 bit required for downmix
Andy Hung0f451e92014-08-04 21:28:47 -0700355 downmixerBufferProvider = pDbp;
356 reconfigureBufferProviders();
Andy Hung34803d52014-07-16 21:41:35 -0700357 return NO_ERROR;
358 }
359 delete pDbp;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700360 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700361
362 // Effect downmixer does not accept the channel conversion. Let's use our remixer.
Andy Hung0f451e92014-08-04 21:28:47 -0700363 RemixBufferProvider* pRbp = new RemixBufferProvider(channelMask,
364 mMixerChannelMask, mMixerInFormat, kCopyBufferFrameCount);
Andy Hunge93b6b72014-07-17 21:30:53 -0700365 // Remix always finds a conversion whereas Downmixer effect above may fail.
Andy Hung0f451e92014-08-04 21:28:47 -0700366 downmixerBufferProvider = pRbp;
367 reconfigureBufferProviders();
Andy Hunge93b6b72014-07-17 21:30:53 -0700368 return NO_ERROR;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700369}
370
Andy Hung0f451e92014-08-04 21:28:47 -0700371void AudioMixer::track_t::unprepareForReformat() {
372 ALOGV("AudioMixer::unprepareForReformat(%p)", this);
Andy Hung7f475492014-08-25 16:36:37 -0700373 bool requiresReconfigure = false;
Andy Hung0f451e92014-08-04 21:28:47 -0700374 if (mReformatBufferProvider != NULL) {
375 delete mReformatBufferProvider;
376 mReformatBufferProvider = NULL;
Andy Hung7f475492014-08-25 16:36:37 -0700377 requiresReconfigure = true;
378 }
379 if (mPostDownmixReformatBufferProvider != NULL) {
380 delete mPostDownmixReformatBufferProvider;
381 mPostDownmixReformatBufferProvider = NULL;
382 requiresReconfigure = true;
383 }
384 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700385 reconfigureBufferProviders();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700386 }
387}
388
Andy Hung0f451e92014-08-04 21:28:47 -0700389status_t AudioMixer::track_t::prepareForReformat()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700390{
Andy Hung0f451e92014-08-04 21:28:47 -0700391 ALOGV("AudioMixer::prepareForReformat(%p) with format %#x", this, mFormat);
Andy Hung7f475492014-08-25 16:36:37 -0700392 // discard previous reformatters
Andy Hung0f451e92014-08-04 21:28:47 -0700393 unprepareForReformat();
Andy Hung7f475492014-08-25 16:36:37 -0700394 // only configure reformatters as needed
395 const audio_format_t targetFormat = mDownmixRequiresFormat != AUDIO_FORMAT_INVALID
396 ? mDownmixRequiresFormat : mMixerInFormat;
397 bool requiresReconfigure = false;
398 if (mFormat != targetFormat) {
Andy Hung0f451e92014-08-04 21:28:47 -0700399 mReformatBufferProvider = new ReformatBufferProvider(
400 audio_channel_count_from_out_mask(channelMask),
Andy Hung7f475492014-08-25 16:36:37 -0700401 mFormat,
402 targetFormat,
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700403 kCopyBufferFrameCount);
Andy Hung7f475492014-08-25 16:36:37 -0700404 requiresReconfigure = true;
405 }
406 if (targetFormat != mMixerInFormat) {
407 mPostDownmixReformatBufferProvider = new ReformatBufferProvider(
408 audio_channel_count_from_out_mask(mMixerChannelMask),
409 targetFormat,
410 mMixerInFormat,
411 kCopyBufferFrameCount);
412 requiresReconfigure = true;
413 }
414 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700415 reconfigureBufferProviders();
Andy Hung296b7412014-06-17 15:25:47 -0700416 }
417 return NO_ERROR;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700418}
419
Andy Hung0f451e92014-08-04 21:28:47 -0700420void AudioMixer::track_t::reconfigureBufferProviders()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700421{
Andy Hung0f451e92014-08-04 21:28:47 -0700422 bufferProvider = mInputBufferProvider;
423 if (mReformatBufferProvider) {
424 mReformatBufferProvider->setBufferProvider(bufferProvider);
425 bufferProvider = mReformatBufferProvider;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700426 }
Andy Hung0f451e92014-08-04 21:28:47 -0700427 if (downmixerBufferProvider) {
428 downmixerBufferProvider->setBufferProvider(bufferProvider);
429 bufferProvider = downmixerBufferProvider;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700430 }
Andy Hung7f475492014-08-25 16:36:37 -0700431 if (mPostDownmixReformatBufferProvider) {
432 mPostDownmixReformatBufferProvider->setBufferProvider(bufferProvider);
433 bufferProvider = mPostDownmixReformatBufferProvider;
434 }
Andy Hungc5656cc2015-03-26 19:04:33 -0700435 if (mTimestretchBufferProvider) {
436 mTimestretchBufferProvider->setBufferProvider(bufferProvider);
437 bufferProvider = mTimestretchBufferProvider;
438 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700439}
440
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800441void AudioMixer::deleteTrackName(int name)
442{
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700443 ALOGV("AudioMixer::deleteTrackName(%d)", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700444 name -= TRACK0;
Eric Laurentaf3ec7c2016-08-01 11:25:19 -0700445 LOG_ALWAYS_FATAL_IF(name < 0 || name >= (int)MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800446 ALOGV("deleteTrackName(%d)", name);
447 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800448 if (track.enabled) {
449 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800450 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700451 }
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700452 // delete the resampler
453 delete track.resampler;
454 track.resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700455 // delete the downmixer
Andy Hung0f451e92014-08-04 21:28:47 -0700456 mState.tracks[name].unprepareForDownmix();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700457 // delete the reformatter
Andy Hung0f451e92014-08-04 21:28:47 -0700458 mState.tracks[name].unprepareForReformat();
Andy Hungc5656cc2015-03-26 19:04:33 -0700459 // delete the timestretch provider
460 delete track.mTimestretchBufferProvider;
461 track.mTimestretchBufferProvider = NULL;
Glenn Kasten237a6242011-12-15 15:32:27 -0800462 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800463}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700464
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800465void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700466{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800467 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800468 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800469 track_t& track = mState.tracks[name];
470
Glenn Kasten4c340c62012-01-27 12:33:54 -0800471 if (!track.enabled) {
472 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800473 ALOGV("enable(%d)", name);
474 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700475 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700476}
477
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800478void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700479{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800480 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800481 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800482 track_t& track = mState.tracks[name];
483
Glenn Kasten4c340c62012-01-27 12:33:54 -0800484 if (track.enabled) {
485 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800486 ALOGV("disable(%d)", name);
487 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700488 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700489}
490
Andy Hung5866a3b2014-05-29 21:33:13 -0700491/* Sets the volume ramp variables for the AudioMixer.
492 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700493 * The volume ramp variables are used to transition from the previous
494 * volume to the set volume. ramp controls the duration of the transition.
495 * Its value is typically one state framecount period, but may also be 0,
496 * meaning "immediate."
Andy Hung5866a3b2014-05-29 21:33:13 -0700497 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700498 * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
499 * even if there is a nonzero floating point increment (in that case, the volume
500 * change is immediate). This restriction should be changed when the legacy mixer
501 * is removed (see #2).
502 * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
503 * when no longer needed.
504 *
505 * @param newVolume set volume target in floating point [0.0, 1.0].
506 * @param ramp number of frames to increment over. if ramp is 0, the volume
507 * should be set immediately. Currently ramp should not exceed 65535 (frames).
508 * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
509 * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
510 * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
511 * @param pSetVolume pointer to the float target volume, set on return.
512 * @param pPrevVolume pointer to the float previous volume, set on return.
513 * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
Andy Hung5866a3b2014-05-29 21:33:13 -0700514 * @return true if the volume has changed, false if volume is same.
515 */
Andy Hung5e58b0a2014-06-23 19:07:29 -0700516static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
517 int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
518 float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
Andy Hunge09c9942015-05-08 16:58:13 -0700519 // check floating point volume to see if it is identical to the previously
520 // set volume.
521 // We do not use a tolerance here (and reject changes too small)
522 // as it may be confusing to use a different value than the one set.
523 // If the resulting volume is too small to ramp, it is a direct set of the volume.
Andy Hung5e58b0a2014-06-23 19:07:29 -0700524 if (newVolume == *pSetVolume) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700525 return false;
526 }
Andy Hunge09c9942015-05-08 16:58:13 -0700527 if (newVolume < 0) {
528 newVolume = 0; // should not have negative volumes
Andy Hung5866a3b2014-05-29 21:33:13 -0700529 } else {
Andy Hunge09c9942015-05-08 16:58:13 -0700530 switch (fpclassify(newVolume)) {
531 case FP_SUBNORMAL:
532 case FP_NAN:
533 newVolume = 0;
534 break;
535 case FP_ZERO:
536 break; // zero volume is fine
537 case FP_INFINITE:
538 // Infinite volume could be handled consistently since
539 // floating point math saturates at infinities,
540 // but we limit volume to unity gain float.
541 // ramp = 0; break;
542 //
543 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
544 break;
545 case FP_NORMAL:
546 default:
547 // Floating point does not have problems with overflow wrap
548 // that integer has. However, we limit the volume to
549 // unity gain here.
550 // TODO: Revisit the volume limitation and perhaps parameterize.
551 if (newVolume > AudioMixer::UNITY_GAIN_FLOAT) {
552 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
553 }
554 break;
555 }
Andy Hung5866a3b2014-05-29 21:33:13 -0700556 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700557
Andy Hunge09c9942015-05-08 16:58:13 -0700558 // set floating point volume ramp
559 if (ramp != 0) {
560 // when the ramp completes, *pPrevVolume is set to *pSetVolume, so there
561 // is no computational mismatch; hence equality is checked here.
562 ALOGD_IF(*pPrevVolume != *pSetVolume, "previous float ramp hasn't finished,"
563 " prev:%f set_to:%f", *pPrevVolume, *pSetVolume);
564 const float inc = (newVolume - *pPrevVolume) / ramp; // could be inf, nan, subnormal
565 const float maxv = max(newVolume, *pPrevVolume); // could be inf, cannot be nan, subnormal
566
567 if (isnormal(inc) // inc must be a normal number (no subnormals, infinite, nan)
568 && maxv + inc != maxv) { // inc must make forward progress
569 *pVolumeInc = inc;
570 // ramp is set now.
571 // Note: if newVolume is 0, then near the end of the ramp,
572 // it may be possible that the ramped volume may be subnormal or
573 // temporarily negative by a small amount or subnormal due to floating
574 // point inaccuracies.
575 } else {
576 ramp = 0; // ramp not allowed
577 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700578 }
Andy Hunge09c9942015-05-08 16:58:13 -0700579
580 // compute and check integer volume, no need to check negative values
581 // The integer volume is limited to "unity_gain" to avoid wrapping and other
582 // audio artifacts, so it never reaches the range limit of U4.28.
583 // We safely use signed 16 and 32 bit integers here.
584 const float scaledVolume = newVolume * AudioMixer::UNITY_GAIN_INT; // not neg, subnormal, nan
585 const int32_t intVolume = (scaledVolume >= (float)AudioMixer::UNITY_GAIN_INT) ?
586 AudioMixer::UNITY_GAIN_INT : (int32_t)scaledVolume;
587
588 // set integer volume ramp
589 if (ramp != 0) {
590 // integer volume is U4.12 (to use 16 bit multiplies), but ramping uses U4.28.
591 // when the ramp completes, *pIntPrevVolume is set to *pIntSetVolume << 16, so there
592 // is no computational mismatch; hence equality is checked here.
593 ALOGD_IF(*pIntPrevVolume != *pIntSetVolume << 16, "previous int ramp hasn't finished,"
594 " prev:%d set_to:%d", *pIntPrevVolume, *pIntSetVolume << 16);
595 const int32_t inc = ((intVolume << 16) - *pIntPrevVolume) / ramp;
596
597 if (inc != 0) { // inc must make forward progress
598 *pIntVolumeInc = inc;
599 } else {
600 ramp = 0; // ramp not allowed
601 }
602 }
603
604 // if no ramp, or ramp not allowed, then clear float and integer increments
605 if (ramp == 0) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700606 *pVolumeInc = 0;
607 *pPrevVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700608 *pIntVolumeInc = 0;
609 *pIntPrevVolume = intVolume << 16;
610 }
Andy Hunge09c9942015-05-08 16:58:13 -0700611 *pSetVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700612 *pIntSetVolume = intVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700613 return true;
614}
615
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800616void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700617{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800618 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800619 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800620 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700621
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000622 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
623 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700624
625 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700626
Mathias Agopian65ab4712010-07-14 17:59:35 -0700627 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800628 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700629 case CHANNEL_MASK: {
Andy Hunge93b6b72014-07-17 21:30:53 -0700630 const audio_channel_mask_t trackChannelMask =
631 static_cast<audio_channel_mask_t>(valueInt);
632 if (setChannelMasks(name, trackChannelMask, track.mMixerChannelMask)) {
633 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800634 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700635 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700636 } break;
637 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800638 if (track.mainBuffer != valueBuf) {
639 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100640 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800641 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700642 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700643 break;
644 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800645 if (track.auxBuffer != valueBuf) {
646 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100647 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800648 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700649 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700650 break;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700651 case FORMAT: {
652 audio_format_t format = static_cast<audio_format_t>(valueInt);
653 if (track.mFormat != format) {
654 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
655 track.mFormat = format;
656 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
Andy Hung0f451e92014-08-04 21:28:47 -0700657 track.prepareForReformat();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700658 invalidateState(1 << name);
659 }
660 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700661 // FIXME do we want to support setting the downmix type from AudioFlinger?
662 // for a specific track? or per mixer?
663 /* case DOWNMIX_TYPE:
664 break */
Andy Hung78820702014-02-28 16:23:02 -0800665 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800666 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung78820702014-02-28 16:23:02 -0800667 if (track.mMixerFormat != format) {
668 track.mMixerFormat = format;
669 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800670 }
671 } break;
Andy Hunge93b6b72014-07-17 21:30:53 -0700672 case MIXER_CHANNEL_MASK: {
673 const audio_channel_mask_t mixerChannelMask =
674 static_cast<audio_channel_mask_t>(valueInt);
675 if (setChannelMasks(name, track.channelMask, mixerChannelMask)) {
676 ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
677 invalidateState(1 << name);
678 }
679 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700680 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800681 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700682 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700683 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700684
Mathias Agopian65ab4712010-07-14 17:59:35 -0700685 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800686 switch (param) {
687 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800688 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700689 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
690 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
691 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800692 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700693 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800694 break;
695 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800696 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800697 invalidateState(1 << name);
698 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700699 case REMOVE:
700 delete track.resampler;
701 track.resampler = NULL;
702 track.sampleRate = mSampleRate;
703 invalidateState(1 << name);
704 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700705 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800706 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800707 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700708 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700709
Mathias Agopian65ab4712010-07-14 17:59:35 -0700710 case RAMP_VOLUME:
711 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800712 switch (param) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800713 case AUXLEVEL:
Andy Hung6be49402014-05-30 10:42:03 -0700714 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung5866a3b2014-05-29 21:33:13 -0700715 target == RAMP_VOLUME ? mState.frameCount : 0,
Andy Hung5e58b0a2014-06-23 19:07:29 -0700716 &track.auxLevel, &track.prevAuxLevel, &track.auxInc,
717 &track.mAuxLevel, &track.mPrevAuxLevel, &track.mAuxInc)) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700718 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
Andy Hung6be49402014-05-30 10:42:03 -0700719 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track.auxLevel);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800720 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700721 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800722 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700723 default:
Andy Hunge93b6b72014-07-17 21:30:53 -0700724 if ((unsigned)param >= VOLUME0 && (unsigned)param < VOLUME0 + MAX_NUM_VOLUMES) {
725 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
726 target == RAMP_VOLUME ? mState.frameCount : 0,
727 &track.volume[param - VOLUME0], &track.prevVolume[param - VOLUME0],
728 &track.volumeInc[param - VOLUME0],
729 &track.mVolume[param - VOLUME0], &track.mPrevVolume[param - VOLUME0],
730 &track.mVolumeInc[param - VOLUME0])) {
731 ALOGV("setParameter(%s, VOLUME%d: %04x)",
732 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
733 track.volume[param - VOLUME0]);
734 invalidateState(1 << name);
735 }
736 } else {
737 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
738 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700739 }
740 break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700741 case TIMESTRETCH:
742 switch (param) {
743 case PLAYBACK_RATE: {
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700744 const AudioPlaybackRate *playbackRate =
745 reinterpret_cast<AudioPlaybackRate*>(value);
Ricardo Garcia6c7f0622015-04-30 18:39:16 -0700746 ALOGW_IF(!isAudioPlaybackRateValid(*playbackRate),
747 "bad parameters speed %f, pitch %f",playbackRate->mSpeed,
748 playbackRate->mPitch);
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700749 if (track.setPlaybackRate(*playbackRate)) {
750 ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE "
751 "%f %f %d %d",
752 playbackRate->mSpeed,
753 playbackRate->mPitch,
754 playbackRate->mStretchMode,
755 playbackRate->mFallbackMode);
Andy Hungc5656cc2015-03-26 19:04:33 -0700756 // invalidateState(1 << name);
757 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700758 } break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700759 default:
760 LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);
761 }
762 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700763
764 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800765 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700766 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700767}
768
Andy Hunge93b6b72014-07-17 21:30:53 -0700769bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700770{
Andy Hunge93b6b72014-07-17 21:30:53 -0700771 if (trackSampleRate != devSampleRate || resampler != NULL) {
772 if (sampleRate != trackSampleRate) {
773 sampleRate = trackSampleRate;
Glenn Kastene0feee32011-12-13 11:53:26 -0800774 if (resampler == NULL) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700775 ALOGV("Creating resampler from track %d Hz to device %d Hz",
776 trackSampleRate, devSampleRate);
Glenn Kastenac602052012-10-01 14:04:31 -0700777 AudioResampler::src_quality quality;
778 // force lowest quality level resampler if use case isn't music or video
779 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
780 // quality level based on the initial ratio, but that could change later.
781 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
Andy Hungdb4c0312015-05-06 08:46:52 -0700782 if (isMusicRate(trackSampleRate)) {
Glenn Kastenac602052012-10-01 14:04:31 -0700783 quality = AudioResampler::DEFAULT_QUALITY;
Andy Hungdb4c0312015-05-06 08:46:52 -0700784 } else {
785 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700786 }
Andy Hung296b7412014-06-17 15:25:47 -0700787
Andy Hunge93b6b72014-07-17 21:30:53 -0700788 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
789 // but if none exists, it is the channel count (1 for mono).
790 const int resamplerChannelCount = downmixerBufferProvider != NULL
791 ? mMixerChannelCount : channelCount;
Andy Hung9a592762014-07-21 21:56:01 -0700792 ALOGVV("Creating resampler:"
793 " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
794 mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700795 resampler = AudioResampler::create(
Andy Hung3348e362014-07-07 10:21:44 -0700796 mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -0700797 resamplerChannelCount,
Glenn Kastenac602052012-10-01 14:04:31 -0700798 devSampleRate, quality);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700799 }
800 return true;
801 }
802 }
803 return false;
804}
805
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700806bool AudioMixer::track_t::setPlaybackRate(const AudioPlaybackRate &playbackRate)
Andy Hungc5656cc2015-03-26 19:04:33 -0700807{
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700808 if ((mTimestretchBufferProvider == NULL &&
809 fabs(playbackRate.mSpeed - mPlaybackRate.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
810 fabs(playbackRate.mPitch - mPlaybackRate.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA) ||
811 isAudioPlaybackRateEqual(playbackRate, mPlaybackRate)) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700812 return false;
813 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700814 mPlaybackRate = playbackRate;
Andy Hungc5656cc2015-03-26 19:04:33 -0700815 if (mTimestretchBufferProvider == NULL) {
816 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
817 // but if none exists, it is the channel count (1 for mono).
818 const int timestretchChannelCount = downmixerBufferProvider != NULL
819 ? mMixerChannelCount : channelCount;
820 mTimestretchBufferProvider = new TimestretchBufferProvider(timestretchChannelCount,
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700821 mMixerInFormat, sampleRate, playbackRate);
Andy Hungc5656cc2015-03-26 19:04:33 -0700822 reconfigureBufferProviders();
823 } else {
Kevin Rocard8da62462017-11-09 22:07:59 -0800824 static_cast<TimestretchBufferProvider*>(mTimestretchBufferProvider)
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700825 ->setPlaybackRate(playbackRate);
Andy Hungc5656cc2015-03-26 19:04:33 -0700826 }
827 return true;
828}
829
Andy Hung5e58b0a2014-06-23 19:07:29 -0700830/* Checks to see if the volume ramp has completed and clears the increment
831 * variables appropriately.
832 *
833 * FIXME: There is code to handle int/float ramp variable switchover should it not
834 * complete within a mixer buffer processing call, but it is preferred to avoid switchover
835 * due to precision issues. The switchover code is included for legacy code purposes
836 * and can be removed once the integer volume is removed.
837 *
838 * It is not sufficient to clear only the volumeInc integer variable because
839 * if one channel requires ramping, all channels are ramped.
840 *
841 * There is a bit of duplicated code here, but it keeps backward compatibility.
842 */
843inline void AudioMixer::track_t::adjustVolumeRamp(bool aux, bool useFloat)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700844{
Andy Hung5e58b0a2014-06-23 19:07:29 -0700845 if (useFloat) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700846 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Eric Laurent43412fc2015-05-08 16:14:36 -0700847 if ((mVolumeInc[i] > 0 && mPrevVolume[i] + mVolumeInc[i] >= mVolume[i]) ||
848 (mVolumeInc[i] < 0 && mPrevVolume[i] + mVolumeInc[i] <= mVolume[i])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700849 volumeInc[i] = 0;
850 prevVolume[i] = volume[i] << 16;
851 mVolumeInc[i] = 0.;
852 mPrevVolume[i] = mVolume[i];
Andy Hung5e58b0a2014-06-23 19:07:29 -0700853 } else {
854 //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
855 prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
856 }
857 }
858 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -0700859 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700860 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
861 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
862 volumeInc[i] = 0;
863 prevVolume[i] = volume[i] << 16;
864 mVolumeInc[i] = 0.;
865 mPrevVolume[i] = mVolume[i];
866 } else {
867 //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
868 mPrevVolume[i] = float_from_u4_28(prevVolume[i]);
869 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700870 }
871 }
Andy Hung116a4982017-11-30 10:15:08 -0800872
Mathias Agopian65ab4712010-07-14 17:59:35 -0700873 if (aux) {
Andy Hung116a4982017-11-30 10:15:08 -0800874#ifdef FLOAT_AUX
875 if (useFloat) {
876 if ((mAuxInc > 0.f && mPrevAuxLevel + mAuxInc >= mAuxLevel) ||
877 (mAuxInc < 0.f && mPrevAuxLevel + mAuxInc <= mAuxLevel)) {
878 auxInc = 0;
879 prevAuxLevel = auxLevel << 16;
880 mAuxInc = 0.f;
881 mPrevAuxLevel = mAuxLevel;
882 }
883 } else
884#endif
885 if ((auxInc > 0 && ((prevAuxLevel + auxInc) >> 16) >= auxLevel) ||
886 (auxInc < 0 && ((prevAuxLevel + auxInc) >> 16) <= auxLevel)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700887 auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700888 prevAuxLevel = auxLevel << 16;
Andy Hung116a4982017-11-30 10:15:08 -0800889 mAuxInc = 0.f;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700890 mPrevAuxLevel = mAuxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700891 }
892 }
893}
894
Glenn Kastenc59c0042012-02-02 14:06:11 -0800895size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800896{
897 name -= TRACK0;
898 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800899 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800900 }
901 return 0;
902}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700903
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800904void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700905{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800906 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800907 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700908
Andy Hung1d26ddf2014-05-29 15:53:09 -0700909 if (mState.tracks[name].mInputBufferProvider == bufferProvider) {
910 return; // don't reset any buffer providers if identical.
911 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700912 if (mState.tracks[name].mReformatBufferProvider != NULL) {
913 mState.tracks[name].mReformatBufferProvider->reset();
914 } else if (mState.tracks[name].downmixerBufferProvider != NULL) {
Andy Hung7f475492014-08-25 16:36:37 -0700915 mState.tracks[name].downmixerBufferProvider->reset();
916 } else if (mState.tracks[name].mPostDownmixReformatBufferProvider != NULL) {
917 mState.tracks[name].mPostDownmixReformatBufferProvider->reset();
Andy Hungc5656cc2015-03-26 19:04:33 -0700918 } else if (mState.tracks[name].mTimestretchBufferProvider != NULL) {
919 mState.tracks[name].mTimestretchBufferProvider->reset();
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700920 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700921
922 mState.tracks[name].mInputBufferProvider = bufferProvider;
Andy Hung0f451e92014-08-04 21:28:47 -0700923 mState.tracks[name].reconfigureBufferProviders();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700924}
925
926
Glenn Kastend79072e2016-01-06 08:41:20 -0800927void AudioMixer::process()
Mathias Agopian65ab4712010-07-14 17:59:35 -0700928{
Glenn Kastend79072e2016-01-06 08:41:20 -0800929 mState.hook(&mState);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700930}
931
932
Glenn Kastend79072e2016-01-06 08:41:20 -0800933void AudioMixer::process__validate(state_t* state)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700934{
Steve Block5ff1dd52012-01-05 23:22:43 +0000935 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700936 "in process__validate() but nothing's invalid");
937
938 uint32_t changed = state->needsChanged;
939 state->needsChanged = 0; // clear the validation flag
940
941 // recompute which tracks are enabled / disabled
942 uint32_t enabled = 0;
943 uint32_t disabled = 0;
944 while (changed) {
945 const int i = 31 - __builtin_clz(changed);
946 const uint32_t mask = 1<<i;
947 changed &= ~mask;
948 track_t& t = state->tracks[i];
949 (t.enabled ? enabled : disabled) |= mask;
950 }
951 state->enabledTracks &= ~disabled;
952 state->enabledTracks |= enabled;
953
954 // compute everything we need...
955 int countActiveTracks = 0;
Andy Hung395db4b2014-08-25 17:15:29 -0700956 // TODO: fix all16BitsStereNoResample logic to
957 // either properly handle muted tracks (it should ignore them)
958 // or remove altogether as an obsolete optimization.
Glenn Kasten4c340c62012-01-27 12:33:54 -0800959 bool all16BitsStereoNoResample = true;
960 bool resampling = false;
961 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700962 uint32_t en = state->enabledTracks;
963 while (en) {
964 const int i = 31 - __builtin_clz(en);
965 en &= ~(1<<i);
966
967 countActiveTracks++;
968 track_t& t = state->tracks[i];
969 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700970 // FIXME can overflow (mask is only 3 bits)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700971 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700972 if (t.doesResample()) {
973 n |= NEEDS_RESAMPLE;
974 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700975 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700976 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700977 }
978
979 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800980 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700981 } else if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700982 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700983 }
984 t.needs = n;
985
Glenn Kastend6fadf02013-10-30 14:37:29 -0700986 if (n & NEEDS_MUTE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700987 t.hook = track__nop;
988 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700989 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800990 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700991 }
Glenn Kastend6fadf02013-10-30 14:37:29 -0700992 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800993 all16BitsStereoNoResample = false;
994 resampling = true;
Andy Hunge93b6b72014-07-17 21:30:53 -0700995 t.hook = getTrackHook(TRACKTYPE_RESAMPLE, t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -0700996 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700997 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700998 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700999 } else {
1000 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
Andy Hunge93b6b72014-07-17 21:30:53 -07001001 t.hook = getTrackHook(
Andy Hung73e62e22015-04-20 12:06:38 -07001002 (t.mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO // TODO: MONO_HACK
1003 && t.channelMask == AUDIO_CHANNEL_OUT_MONO)
Andy Hunge93b6b72014-07-17 21:30:53 -07001004 ? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,
1005 t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001006 t.mMixerInFormat, t.mMixerFormat);
Glenn Kasten4c340c62012-01-27 12:33:54 -08001007 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001008 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001009 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Andy Hunge93b6b72014-07-17 21:30:53 -07001010 t.hook = getTrackHook(TRACKTYPE_NORESAMPLE, t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001011 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001012 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -07001013 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001014 }
1015 }
1016 }
1017 }
1018
1019 // select the processing hooks
1020 state->hook = process__nop;
Glenn Kasten34fca342013-08-13 09:48:14 -07001021 if (countActiveTracks > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001022 if (resampling) {
1023 if (!state->outputTemp) {
1024 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
1025 }
1026 if (!state->resampleTemp) {
1027 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
1028 }
1029 state->hook = process__genericResampling;
1030 } else {
1031 if (state->outputTemp) {
1032 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -08001033 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001034 }
1035 if (state->resampleTemp) {
1036 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -08001037 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001038 }
1039 state->hook = process__genericNoResampling;
1040 if (all16BitsStereoNoResample && !volumeRamp) {
1041 if (countActiveTracks == 1) {
Andy Hung296b7412014-06-17 15:25:47 -07001042 const int i = 31 - __builtin_clz(state->enabledTracks);
1043 track_t& t = state->tracks[i];
Andy Hung395db4b2014-08-25 17:15:29 -07001044 if ((t.needs & NEEDS_MUTE) == 0) {
1045 // The check prevents a muted track from acquiring a process hook.
1046 //
1047 // This is dangerous if the track is MONO as that requires
1048 // special case handling due to implicit channel duplication.
1049 // Stereo or Multichannel should actually be fine here.
1050 state->hook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
1051 t.mMixerChannelCount, t.mMixerInFormat, t.mMixerFormat);
1052 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001053 }
1054 }
1055 }
1056 }
1057
Steve Block3856b092011-10-20 11:56:00 +01001058 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001059 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
1060 countActiveTracks, state->enabledTracks,
1061 all16BitsStereoNoResample, resampling, volumeRamp);
1062
Glenn Kastend79072e2016-01-06 08:41:20 -08001063 state->hook(state);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001064
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001065 // Now that the volume ramp has been done, set optimal state and
1066 // track hooks for subsequent mixer process
Glenn Kasten34fca342013-08-13 09:48:14 -07001067 if (countActiveTracks > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001068 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001069 uint32_t en = state->enabledTracks;
1070 while (en) {
1071 const int i = 31 - __builtin_clz(en);
1072 en &= ~(1<<i);
1073 track_t& t = state->tracks[i];
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001074 if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001075 t.needs |= NEEDS_MUTE;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001076 t.hook = track__nop;
1077 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001078 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001079 }
1080 }
1081 if (allMuted) {
1082 state->hook = process__nop;
1083 } else if (all16BitsStereoNoResample) {
1084 if (countActiveTracks == 1) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001085 const int i = 31 - __builtin_clz(state->enabledTracks);
1086 track_t& t = state->tracks[i];
Andy Hung395db4b2014-08-25 17:15:29 -07001087 // Muted single tracks handled by allMuted above.
Andy Hunge93b6b72014-07-17 21:30:53 -07001088 state->hook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
1089 t.mMixerChannelCount, t.mMixerInFormat, t.mMixerFormat);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001090 }
1091 }
1092 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001093}
1094
Mathias Agopian65ab4712010-07-14 17:59:35 -07001095
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001096void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
1097 int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001098{
Andy Hung296b7412014-06-17 15:25:47 -07001099 ALOGVV("track__genericResample\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001100 t->resampler->setSampleRate(t->sampleRate);
1101
1102 // ramp gain - resample to temp buffer and scale/mix in 2nd step
1103 if (aux != NULL) {
1104 // always resample with unity gain when sending to auxiliary buffer to be able
1105 // to apply send level after resampling
Andy Hung5e58b0a2014-06-23 19:07:29 -07001106 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Andy Hunge93b6b72014-07-17 21:30:53 -07001107 memset(temp, 0, outFrameCount * t->mMixerChannelCount * sizeof(int32_t));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001108 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -08001109 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001110 volumeRampStereo(t, out, outFrameCount, temp, aux);
1111 } else {
1112 volumeStereo(t, out, outFrameCount, temp, aux);
1113 }
1114 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -08001115 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001116 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001117 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
1118 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
1119 volumeRampStereo(t, out, outFrameCount, temp, aux);
1120 }
1121
1122 // constant gain
1123 else {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001124 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001125 t->resampler->resample(out, outFrameCount, t->bufferProvider);
1126 }
1127 }
1128}
1129
Andy Hungee931ff2014-01-28 13:44:14 -08001130void AudioMixer::track__nop(track_t* t __unused, int32_t* out __unused,
1131 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001132{
1133}
1134
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001135void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1136 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001137{
1138 int32_t vl = t->prevVolume[0];
1139 int32_t vr = t->prevVolume[1];
1140 const int32_t vlInc = t->volumeInc[0];
1141 const int32_t vrInc = t->volumeInc[1];
1142
Steve Blockb8a80522011-12-20 16:23:08 +00001143 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001144 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1145 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1146
1147 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -08001148 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001149 int32_t va = t->prevAuxLevel;
1150 const int32_t vaInc = t->auxInc;
1151 int32_t l;
1152 int32_t r;
1153
1154 do {
1155 l = (*temp++ >> 12);
1156 r = (*temp++ >> 12);
1157 *out++ += (vl >> 16) * l;
1158 *out++ += (vr >> 16) * r;
1159 *aux++ += (va >> 17) * (l + r);
1160 vl += vlInc;
1161 vr += vrInc;
1162 va += vaInc;
1163 } while (--frameCount);
1164 t->prevAuxLevel = va;
1165 } else {
1166 do {
1167 *out++ += (vl >> 16) * (*temp++ >> 12);
1168 *out++ += (vr >> 16) * (*temp++ >> 12);
1169 vl += vlInc;
1170 vr += vrInc;
1171 } while (--frameCount);
1172 }
1173 t->prevVolume[0] = vl;
1174 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -08001175 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001176}
1177
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001178void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1179 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001180{
1181 const int16_t vl = t->volume[0];
1182 const int16_t vr = t->volume[1];
1183
Glenn Kastenf6b16782011-12-15 09:51:17 -08001184 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -08001185 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001186 do {
1187 int16_t l = (int16_t)(*temp++ >> 12);
1188 int16_t r = (int16_t)(*temp++ >> 12);
1189 out[0] = mulAdd(l, vl, out[0]);
1190 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1191 out[1] = mulAdd(r, vr, out[1]);
1192 out += 2;
1193 aux[0] = mulAdd(a, va, aux[0]);
1194 aux++;
1195 } while (--frameCount);
1196 } else {
1197 do {
1198 int16_t l = (int16_t)(*temp++ >> 12);
1199 int16_t r = (int16_t)(*temp++ >> 12);
1200 out[0] = mulAdd(l, vl, out[0]);
1201 out[1] = mulAdd(r, vr, out[1]);
1202 out += 2;
1203 } while (--frameCount);
1204 }
1205}
1206
Andy Hungee931ff2014-01-28 13:44:14 -08001207void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount,
1208 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001209{
Andy Hung296b7412014-06-17 15:25:47 -07001210 ALOGVV("track__16BitsStereo\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001211 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001212
Glenn Kastenf6b16782011-12-15 09:51:17 -08001213 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001214 int32_t l;
1215 int32_t r;
1216 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001217 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001218 int32_t vl = t->prevVolume[0];
1219 int32_t vr = t->prevVolume[1];
1220 int32_t va = t->prevAuxLevel;
1221 const int32_t vlInc = t->volumeInc[0];
1222 const int32_t vrInc = t->volumeInc[1];
1223 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001224 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001225 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1226 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1227
1228 do {
1229 l = (int32_t)*in++;
1230 r = (int32_t)*in++;
1231 *out++ += (vl >> 16) * l;
1232 *out++ += (vr >> 16) * r;
1233 *aux++ += (va >> 17) * (l + r);
1234 vl += vlInc;
1235 vr += vrInc;
1236 va += vaInc;
1237 } while (--frameCount);
1238
1239 t->prevVolume[0] = vl;
1240 t->prevVolume[1] = vr;
1241 t->prevAuxLevel = va;
1242 t->adjustVolumeRamp(true);
1243 }
1244
1245 // constant gain
1246 else {
1247 const uint32_t vrl = t->volumeRL;
1248 const int16_t va = (int16_t)t->auxLevel;
1249 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001250 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001251 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1252 in += 2;
1253 out[0] = mulAddRL(1, rl, vrl, out[0]);
1254 out[1] = mulAddRL(0, rl, vrl, out[1]);
1255 out += 2;
1256 aux[0] = mulAdd(a, va, aux[0]);
1257 aux++;
1258 } while (--frameCount);
1259 }
1260 } else {
1261 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001262 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001263 int32_t vl = t->prevVolume[0];
1264 int32_t vr = t->prevVolume[1];
1265 const int32_t vlInc = t->volumeInc[0];
1266 const int32_t vrInc = t->volumeInc[1];
1267
Steve Blockb8a80522011-12-20 16:23:08 +00001268 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001269 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1270 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1271
1272 do {
1273 *out++ += (vl >> 16) * (int32_t) *in++;
1274 *out++ += (vr >> 16) * (int32_t) *in++;
1275 vl += vlInc;
1276 vr += vrInc;
1277 } while (--frameCount);
1278
1279 t->prevVolume[0] = vl;
1280 t->prevVolume[1] = vr;
1281 t->adjustVolumeRamp(false);
1282 }
1283
1284 // constant gain
1285 else {
1286 const uint32_t vrl = t->volumeRL;
1287 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001288 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001289 in += 2;
1290 out[0] = mulAddRL(1, rl, vrl, out[0]);
1291 out[1] = mulAddRL(0, rl, vrl, out[1]);
1292 out += 2;
1293 } while (--frameCount);
1294 }
1295 }
1296 t->in = in;
1297}
1298
Andy Hungee931ff2014-01-28 13:44:14 -08001299void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount,
1300 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001301{
Andy Hung296b7412014-06-17 15:25:47 -07001302 ALOGVV("track__16BitsMono\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001303 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001304
Glenn Kastenf6b16782011-12-15 09:51:17 -08001305 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001306 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001307 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001308 int32_t vl = t->prevVolume[0];
1309 int32_t vr = t->prevVolume[1];
1310 int32_t va = t->prevAuxLevel;
1311 const int32_t vlInc = t->volumeInc[0];
1312 const int32_t vrInc = t->volumeInc[1];
1313 const int32_t vaInc = t->auxInc;
1314
Steve Blockb8a80522011-12-20 16:23:08 +00001315 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001316 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1317 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1318
1319 do {
1320 int32_t l = *in++;
1321 *out++ += (vl >> 16) * l;
1322 *out++ += (vr >> 16) * l;
1323 *aux++ += (va >> 16) * l;
1324 vl += vlInc;
1325 vr += vrInc;
1326 va += vaInc;
1327 } while (--frameCount);
1328
1329 t->prevVolume[0] = vl;
1330 t->prevVolume[1] = vr;
1331 t->prevAuxLevel = va;
1332 t->adjustVolumeRamp(true);
1333 }
1334 // constant gain
1335 else {
1336 const int16_t vl = t->volume[0];
1337 const int16_t vr = t->volume[1];
1338 const int16_t va = (int16_t)t->auxLevel;
1339 do {
1340 int16_t l = *in++;
1341 out[0] = mulAdd(l, vl, out[0]);
1342 out[1] = mulAdd(l, vr, out[1]);
1343 out += 2;
1344 aux[0] = mulAdd(l, va, aux[0]);
1345 aux++;
1346 } while (--frameCount);
1347 }
1348 } else {
1349 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001350 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001351 int32_t vl = t->prevVolume[0];
1352 int32_t vr = t->prevVolume[1];
1353 const int32_t vlInc = t->volumeInc[0];
1354 const int32_t vrInc = t->volumeInc[1];
1355
Steve Blockb8a80522011-12-20 16:23:08 +00001356 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001357 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1358 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1359
1360 do {
1361 int32_t l = *in++;
1362 *out++ += (vl >> 16) * l;
1363 *out++ += (vr >> 16) * l;
1364 vl += vlInc;
1365 vr += vrInc;
1366 } while (--frameCount);
1367
1368 t->prevVolume[0] = vl;
1369 t->prevVolume[1] = vr;
1370 t->adjustVolumeRamp(false);
1371 }
1372 // constant gain
1373 else {
1374 const int16_t vl = t->volume[0];
1375 const int16_t vr = t->volume[1];
1376 do {
1377 int16_t l = *in++;
1378 out[0] = mulAdd(l, vl, out[0]);
1379 out[1] = mulAdd(l, vr, out[1]);
1380 out += 2;
1381 } while (--frameCount);
1382 }
1383 }
1384 t->in = in;
1385}
1386
Mathias Agopian65ab4712010-07-14 17:59:35 -07001387// no-op case
Glenn Kastend79072e2016-01-06 08:41:20 -08001388void AudioMixer::process__nop(state_t* state)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001389{
Andy Hung296b7412014-06-17 15:25:47 -07001390 ALOGVV("process__nop\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001391 uint32_t e0 = state->enabledTracks;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001392 while (e0) {
1393 // process by group of tracks with same output buffer to
1394 // avoid multiple memset() on same buffer
1395 uint32_t e1 = e0, e2 = e0;
1396 int i = 31 - __builtin_clz(e1);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001397 {
1398 track_t& t1 = state->tracks[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001399 e2 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001400 while (e2) {
1401 i = 31 - __builtin_clz(e2);
1402 e2 &= ~(1<<i);
1403 track_t& t2 = state->tracks[i];
1404 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1405 e1 &= ~(1<<i);
1406 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001407 }
Glenn Kastenfc900c92013-02-18 12:47:49 -08001408 e0 &= ~(e1);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001409
Andy Hunge93b6b72014-07-17 21:30:53 -07001410 memset(t1.mainBuffer, 0, state->frameCount * t1.mMixerChannelCount
Andy Hung78820702014-02-28 16:23:02 -08001411 * audio_bytes_per_sample(t1.mMixerFormat));
Glenn Kastenfc900c92013-02-18 12:47:49 -08001412 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001413
1414 while (e1) {
1415 i = 31 - __builtin_clz(e1);
1416 e1 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001417 {
1418 track_t& t3 = state->tracks[i];
1419 size_t outFrames = state->frameCount;
1420 while (outFrames) {
1421 t3.buffer.frameCount = outFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001422 t3.bufferProvider->getNextBuffer(&t3.buffer);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001423 if (t3.buffer.raw == NULL) break;
1424 outFrames -= t3.buffer.frameCount;
1425 t3.bufferProvider->releaseBuffer(&t3.buffer);
1426 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001427 }
1428 }
1429 }
1430}
1431
1432// generic code without resampling
Glenn Kastend79072e2016-01-06 08:41:20 -08001433void AudioMixer::process__genericNoResampling(state_t* state)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001434{
Andy Hung296b7412014-06-17 15:25:47 -07001435 ALOGVV("process__genericNoResampling\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001436 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1437
1438 // acquire each track's buffer
1439 uint32_t enabledTracks = state->enabledTracks;
1440 uint32_t e0 = enabledTracks;
1441 while (e0) {
1442 const int i = 31 - __builtin_clz(e0);
1443 e0 &= ~(1<<i);
1444 track_t& t = state->tracks[i];
1445 t.buffer.frameCount = state->frameCount;
Glenn Kastend79072e2016-01-06 08:41:20 -08001446 t.bufferProvider->getNextBuffer(&t.buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001447 t.frameCount = t.buffer.frameCount;
1448 t.in = t.buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001449 }
1450
1451 e0 = enabledTracks;
1452 while (e0) {
1453 // process by group of tracks with same output buffer to
1454 // optimize cache use
1455 uint32_t e1 = e0, e2 = e0;
1456 int j = 31 - __builtin_clz(e1);
1457 track_t& t1 = state->tracks[j];
1458 e2 &= ~(1<<j);
1459 while (e2) {
1460 j = 31 - __builtin_clz(e2);
1461 e2 &= ~(1<<j);
1462 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001463 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001464 e1 &= ~(1<<j);
1465 }
1466 }
1467 e0 &= ~(e1);
1468 // this assumes output 16 bits stereo, no resampling
1469 int32_t *out = t1.mainBuffer;
1470 size_t numFrames = 0;
1471 do {
1472 memset(outTemp, 0, sizeof(outTemp));
1473 e2 = e1;
1474 while (e2) {
1475 const int i = 31 - __builtin_clz(e2);
1476 e2 &= ~(1<<i);
1477 track_t& t = state->tracks[i];
1478 size_t outFrames = BLOCKSIZE;
1479 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001480 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001481 aux = t.auxBuffer + numFrames;
1482 }
1483 while (outFrames) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301484 // t.in == NULL can happen if the track was flushed just after having
1485 // been enabled for mixing.
1486 if (t.in == NULL) {
1487 enabledTracks &= ~(1<<i);
1488 e1 &= ~(1<<i);
1489 break;
1490 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001491 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001492 if (inFrames > 0) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001493 t.hook(&t, outTemp + (BLOCKSIZE - outFrames) * t.mMixerChannelCount,
1494 inFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001495 t.frameCount -= inFrames;
1496 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001497 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001498 aux += inFrames;
1499 }
1500 }
1501 if (t.frameCount == 0 && outFrames) {
1502 t.bufferProvider->releaseBuffer(&t.buffer);
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001503 t.buffer.frameCount = (state->frameCount - numFrames) -
1504 (BLOCKSIZE - outFrames);
Glenn Kastend79072e2016-01-06 08:41:20 -08001505 t.bufferProvider->getNextBuffer(&t.buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001506 t.in = t.buffer.raw;
1507 if (t.in == NULL) {
1508 enabledTracks &= ~(1<<i);
1509 e1 &= ~(1<<i);
1510 break;
1511 }
1512 t.frameCount = t.buffer.frameCount;
1513 }
1514 }
1515 }
Andy Hung296b7412014-06-17 15:25:47 -07001516
1517 convertMixerFormat(out, t1.mMixerFormat, outTemp, t1.mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -07001518 BLOCKSIZE * t1.mMixerChannelCount);
Andy Hung296b7412014-06-17 15:25:47 -07001519 // TODO: fix ugly casting due to choice of out pointer type
1520 out = reinterpret_cast<int32_t*>((uint8_t*)out
Andy Hunge93b6b72014-07-17 21:30:53 -07001521 + BLOCKSIZE * t1.mMixerChannelCount
1522 * audio_bytes_per_sample(t1.mMixerFormat));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001523 numFrames += BLOCKSIZE;
1524 } while (numFrames < state->frameCount);
1525 }
1526
1527 // release each track's buffer
1528 e0 = enabledTracks;
1529 while (e0) {
1530 const int i = 31 - __builtin_clz(e0);
1531 e0 &= ~(1<<i);
1532 track_t& t = state->tracks[i];
1533 t.bufferProvider->releaseBuffer(&t.buffer);
1534 }
1535}
1536
1537
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001538// generic code with resampling
Glenn Kastend79072e2016-01-06 08:41:20 -08001539void AudioMixer::process__genericResampling(state_t* state)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001540{
Andy Hung296b7412014-06-17 15:25:47 -07001541 ALOGVV("process__genericResampling\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001542 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -07001543 int32_t* const outTemp = state->outputTemp;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001544 size_t numFrames = state->frameCount;
1545
1546 uint32_t e0 = state->enabledTracks;
1547 while (e0) {
1548 // process by group of tracks with same output buffer
1549 // to optimize cache use
1550 uint32_t e1 = e0, e2 = e0;
1551 int j = 31 - __builtin_clz(e1);
1552 track_t& t1 = state->tracks[j];
1553 e2 &= ~(1<<j);
1554 while (e2) {
1555 j = 31 - __builtin_clz(e2);
1556 e2 &= ~(1<<j);
1557 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001558 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001559 e1 &= ~(1<<j);
1560 }
1561 }
1562 e0 &= ~(e1);
1563 int32_t *out = t1.mainBuffer;
Andy Hunge93b6b72014-07-17 21:30:53 -07001564 memset(outTemp, 0, sizeof(*outTemp) * t1.mMixerChannelCount * state->frameCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001565 while (e1) {
1566 const int i = 31 - __builtin_clz(e1);
1567 e1 &= ~(1<<i);
1568 track_t& t = state->tracks[i];
1569 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001570 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001571 aux = t.auxBuffer;
1572 }
1573
1574 // this is a little goofy, on the resampling case we don't
1575 // acquire/release the buffers because it's done by
1576 // the resampler.
Glenn Kastend6fadf02013-10-30 14:37:29 -07001577 if (t.needs & NEEDS_RESAMPLE) {
Glenn Kastena1117922012-01-26 10:53:32 -08001578 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001579 } else {
1580
1581 size_t outFrames = 0;
1582
1583 while (outFrames < numFrames) {
1584 t.buffer.frameCount = numFrames - outFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001585 t.bufferProvider->getNextBuffer(&t.buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001586 t.in = t.buffer.raw;
1587 // t.in == NULL can happen if the track was flushed just after having
1588 // been enabled for mixing.
1589 if (t.in == NULL) break;
1590
Glenn Kastenf6b16782011-12-15 09:51:17 -08001591 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001592 aux += outFrames;
1593 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001594 t.hook(&t, outTemp + outFrames * t.mMixerChannelCount, t.buffer.frameCount,
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001595 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001596 outFrames += t.buffer.frameCount;
1597 t.bufferProvider->releaseBuffer(&t.buffer);
1598 }
1599 }
1600 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001601 convertMixerFormat(out, t1.mMixerFormat,
1602 outTemp, t1.mMixerInFormat, numFrames * t1.mMixerChannelCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001603 }
1604}
1605
1606// one track, 16 bits stereo without resampling is the most common case
Glenn Kastend79072e2016-01-06 08:41:20 -08001607void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001608{
Andy Hung296b7412014-06-17 15:25:47 -07001609 ALOGVV("process__OneTrack16BitsStereoNoResampling\n");
Glenn Kasten99e53b82012-01-19 08:59:58 -08001610 // This method is only called when state->enabledTracks has exactly
1611 // one bit set. The asserts below would verify this, but are commented out
1612 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001613 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001614 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001615 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001616 const track_t& t = state->tracks[i];
1617
1618 AudioBufferProvider::Buffer& b(t.buffer);
1619
1620 int32_t* out = t.mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001621 float *fout = reinterpret_cast<float*>(out);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001622 size_t numFrames = state->frameCount;
1623
1624 const int16_t vl = t.volume[0];
1625 const int16_t vr = t.volume[1];
1626 const uint32_t vrl = t.volumeRL;
1627 while (numFrames) {
1628 b.frameCount = numFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001629 t.bufferProvider->getNextBuffer(&b);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001630 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001631
1632 // in == NULL can happen if the track was flushed just after having
1633 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001634 if (in == NULL || (((uintptr_t)in) & 3)) {
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001635 if ( AUDIO_FORMAT_PCM_FLOAT == t.mMixerFormat ) {
1636 memset((char*)fout, 0, numFrames
1637 * t.mMixerChannelCount * audio_bytes_per_sample(t.mMixerFormat));
1638 } else {
1639 memset((char*)out, 0, numFrames
1640 * t.mMixerChannelCount * audio_bytes_per_sample(t.mMixerFormat));
1641 }
Andy Hung395db4b2014-08-25 17:15:29 -07001642 ALOGE_IF((((uintptr_t)in) & 3),
1643 "process__OneTrack16BitsStereoNoResampling: misaligned buffer"
1644 " %p track %d, channels %d, needs %08x, volume %08x vfl %f vfr %f",
1645 in, i, t.channelCount, t.needs, vrl, t.mVolume[0], t.mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001646 return;
1647 }
1648 size_t outFrames = b.frameCount;
1649
Andy Hung78820702014-02-28 16:23:02 -08001650 switch (t.mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001651 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001652 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001653 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001654 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001655 int32_t l = mulRL(1, rl, vrl);
1656 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001657 *fout++ = float_from_q4_27(l);
1658 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001659 // Note: In case of later int16_t sink output,
1660 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001661 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001662 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001663 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung97ae8242014-05-30 10:35:47 -07001664 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001665 // volume is boosted, so we might need to clamp even though
1666 // we process only one track.
1667 do {
1668 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1669 in += 2;
1670 int32_t l = mulRL(1, rl, vrl) >> 12;
1671 int32_t r = mulRL(0, rl, vrl) >> 12;
1672 // clamping...
1673 l = clamp16(l);
1674 r = clamp16(r);
1675 *out++ = (r<<16) | (l & 0xFFFF);
1676 } while (--outFrames);
1677 } else {
1678 do {
1679 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1680 in += 2;
1681 int32_t l = mulRL(1, rl, vrl) >> 12;
1682 int32_t r = mulRL(0, rl, vrl) >> 12;
1683 *out++ = (r<<16) | (l & 0xFFFF);
1684 } while (--outFrames);
1685 }
1686 break;
1687 default:
Andy Hung78820702014-02-28 16:23:02 -08001688 LOG_ALWAYS_FATAL("bad mixer format: %d", t.mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001689 }
1690 numFrames -= b.frameCount;
1691 t.bufferProvider->releaseBuffer(&b);
1692 }
1693}
1694
Glenn Kasten52008f82012-03-18 09:34:41 -07001695/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1696
1697/*static*/ void AudioMixer::sInitRoutine()
1698{
Andy Hung34803d52014-07-16 21:41:35 -07001699 DownmixerBufferProvider::init(); // for the downmixer
John Grossman4ff14ba2012-02-08 16:37:41 -08001700}
1701
Andy Hunge93b6b72014-07-17 21:30:53 -07001702/* TODO: consider whether this level of optimization is necessary.
1703 * Perhaps just stick with a single for loop.
1704 */
1705
1706// Needs to derive a compile time constant (constexpr). Could be targeted to go
1707// to a MONOVOL mixtype based on MAX_NUM_VOLUMES, but that's an unnecessary complication.
Chih-Hung Hsiehbf291732016-05-17 15:16:07 -07001708#define MIXTYPE_MONOVOL(mixtype) ((mixtype) == MIXTYPE_MULTI ? MIXTYPE_MULTI_MONOVOL : \
1709 (mixtype) == MIXTYPE_MULTI_SAVEONLY ? MIXTYPE_MULTI_SAVEONLY_MONOVOL : (mixtype))
Andy Hunge93b6b72014-07-17 21:30:53 -07001710
1711/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1712 * TO: int32_t (Q4.27) or float
1713 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001714 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001715 */
1716template <int MIXTYPE,
1717 typename TO, typename TI, typename TV, typename TA, typename TAV>
1718static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
1719 const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc)
1720{
1721 switch (channels) {
1722 case 1:
1723 volumeRampMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1724 break;
1725 case 2:
1726 volumeRampMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1727 break;
1728 case 3:
1729 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out,
1730 frameCount, in, aux, vol, volinc, vola, volainc);
1731 break;
1732 case 4:
1733 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out,
1734 frameCount, in, aux, vol, volinc, vola, volainc);
1735 break;
1736 case 5:
1737 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out,
1738 frameCount, in, aux, vol, volinc, vola, volainc);
1739 break;
1740 case 6:
1741 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out,
1742 frameCount, in, aux, vol, volinc, vola, volainc);
1743 break;
1744 case 7:
1745 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out,
1746 frameCount, in, aux, vol, volinc, vola, volainc);
1747 break;
1748 case 8:
1749 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out,
1750 frameCount, in, aux, vol, volinc, vola, volainc);
1751 break;
1752 }
1753}
1754
1755/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1756 * TO: int32_t (Q4.27) or float
1757 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001758 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001759 */
1760template <int MIXTYPE,
1761 typename TO, typename TI, typename TV, typename TA, typename TAV>
1762static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
1763 const TI* in, TA* aux, const TV *vol, TAV vola)
1764{
1765 switch (channels) {
1766 case 1:
1767 volumeMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, vola);
1768 break;
1769 case 2:
1770 volumeMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, vola);
1771 break;
1772 case 3:
1773 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out, frameCount, in, aux, vol, vola);
1774 break;
1775 case 4:
1776 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out, frameCount, in, aux, vol, vola);
1777 break;
1778 case 5:
1779 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out, frameCount, in, aux, vol, vola);
1780 break;
1781 case 6:
1782 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out, frameCount, in, aux, vol, vola);
1783 break;
1784 case 7:
1785 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out, frameCount, in, aux, vol, vola);
1786 break;
1787 case 8:
1788 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out, frameCount, in, aux, vol, vola);
1789 break;
1790 }
1791}
1792
1793/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1794 * USEFLOATVOL (set to true if float volume is used)
1795 * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards)
1796 * TO: int32_t (Q4.27) or float
1797 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001798 * TA: int32_t (Q4.27) or float
Andy Hunge93b6b72014-07-17 21:30:53 -07001799 */
1800template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001801 typename TO, typename TI, typename TA>
1802void AudioMixer::volumeMix(TO *out, size_t outFrames,
1803 const TI *in, TA *aux, bool ramp, AudioMixer::track_t *t)
1804{
1805 if (USEFLOATVOL) {
1806 if (ramp) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001807 volumeRampMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung116a4982017-11-30 10:15:08 -08001808 t->mPrevVolume, t->mVolumeInc,
1809#ifdef FLOAT_AUX
1810 &t->mPrevAuxLevel, t->mAuxInc
1811#else
1812 &t->prevAuxLevel, t->auxInc
1813#endif
1814 );
Andy Hung5e58b0a2014-06-23 19:07:29 -07001815 if (ADJUSTVOL) {
1816 t->adjustVolumeRamp(aux != NULL, true);
1817 }
1818 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -07001819 volumeMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung116a4982017-11-30 10:15:08 -08001820 t->mVolume,
1821#ifdef FLOAT_AUX
1822 t->mAuxLevel
1823#else
1824 t->auxLevel
1825#endif
1826 );
Andy Hung5e58b0a2014-06-23 19:07:29 -07001827 }
1828 } else {
1829 if (ramp) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001830 volumeRampMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001831 t->prevVolume, t->volumeInc, &t->prevAuxLevel, t->auxInc);
1832 if (ADJUSTVOL) {
1833 t->adjustVolumeRamp(aux != NULL);
1834 }
1835 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -07001836 volumeMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001837 t->volume, t->auxLevel);
1838 }
1839 }
1840}
1841
Andy Hung296b7412014-06-17 15:25:47 -07001842/* This process hook is called when there is a single track without
1843 * aux buffer, volume ramp, or resampling.
1844 * TODO: Update the hook selection: this can properly handle aux and ramp.
Andy Hunge93b6b72014-07-17 21:30:53 -07001845 *
1846 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1847 * TO: int32_t (Q4.27) or float
1848 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1849 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07001850 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001851template <int MIXTYPE, typename TO, typename TI, typename TA>
Glenn Kastend79072e2016-01-06 08:41:20 -08001852void AudioMixer::process_NoResampleOneTrack(state_t* state)
Andy Hung296b7412014-06-17 15:25:47 -07001853{
1854 ALOGVV("process_NoResampleOneTrack\n");
1855 // CLZ is faster than CTZ on ARM, though really not sure if true after 31 - clz.
1856 const int i = 31 - __builtin_clz(state->enabledTracks);
1857 ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
1858 track_t *t = &state->tracks[i];
Andy Hunge93b6b72014-07-17 21:30:53 -07001859 const uint32_t channels = t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07001860 TO* out = reinterpret_cast<TO*>(t->mainBuffer);
1861 TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
1862 const bool ramp = t->needsRamp();
1863
1864 for (size_t numFrames = state->frameCount; numFrames; ) {
1865 AudioBufferProvider::Buffer& b(t->buffer);
1866 // get input buffer
1867 b.frameCount = numFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001868 t->bufferProvider->getNextBuffer(&b);
Andy Hung296b7412014-06-17 15:25:47 -07001869 const TI *in = reinterpret_cast<TI*>(b.raw);
1870
1871 // in == NULL can happen if the track was flushed just after having
1872 // been enabled for mixing.
1873 if (in == NULL || (((uintptr_t)in) & 3)) {
1874 memset(out, 0, numFrames
Andy Hunge93b6b72014-07-17 21:30:53 -07001875 * channels * audio_bytes_per_sample(t->mMixerFormat));
Andy Hung296b7412014-06-17 15:25:47 -07001876 ALOGE_IF((((uintptr_t)in) & 3), "process_NoResampleOneTrack: bus error: "
1877 "buffer %p track %p, channels %d, needs %#x",
1878 in, t, t->channelCount, t->needs);
1879 return;
1880 }
1881
1882 const size_t outFrames = b.frameCount;
Andy Hung116a4982017-11-30 10:15:08 -08001883 volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, false /* ADJUSTVOL */> (
Andy Hunge93b6b72014-07-17 21:30:53 -07001884 out, outFrames, in, aux, ramp, t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001885
Andy Hunge93b6b72014-07-17 21:30:53 -07001886 out += outFrames * channels;
Andy Hung296b7412014-06-17 15:25:47 -07001887 if (aux != NULL) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001888 aux += channels;
Andy Hung296b7412014-06-17 15:25:47 -07001889 }
1890 numFrames -= b.frameCount;
1891
1892 // release buffer
1893 t->bufferProvider->releaseBuffer(&b);
1894 }
1895 if (ramp) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001896 t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
Andy Hung296b7412014-06-17 15:25:47 -07001897 }
1898}
1899
1900/* This track hook is called to do resampling then mixing,
1901 * pulling from the track's upstream AudioBufferProvider.
Andy Hunge93b6b72014-07-17 21:30:53 -07001902 *
1903 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1904 * TO: int32_t (Q4.27) or float
1905 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001906 * TA: int32_t (Q4.27) or float
Andy Hung296b7412014-06-17 15:25:47 -07001907 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001908template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung296b7412014-06-17 15:25:47 -07001909void AudioMixer::track__Resample(track_t* t, TO* out, size_t outFrameCount, TO* temp, TA* aux)
1910{
1911 ALOGVV("track__Resample\n");
1912 t->resampler->setSampleRate(t->sampleRate);
Andy Hung296b7412014-06-17 15:25:47 -07001913 const bool ramp = t->needsRamp();
1914 if (ramp || aux != NULL) {
1915 // if ramp: resample with unity gain to temp buffer and scale/mix in 2nd step.
1916 // if aux != NULL: resample with unity gain to temp buffer then apply send level.
1917
Andy Hung5e58b0a2014-06-23 19:07:29 -07001918 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Andy Hunge93b6b72014-07-17 21:30:53 -07001919 memset(temp, 0, outFrameCount * t->mMixerChannelCount * sizeof(TO));
Andy Hung296b7412014-06-17 15:25:47 -07001920 t->resampler->resample((int32_t*)temp, outFrameCount, t->bufferProvider);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001921
Andy Hung116a4982017-11-30 10:15:08 -08001922 volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
Andy Hunge93b6b72014-07-17 21:30:53 -07001923 out, outFrameCount, temp, aux, ramp, t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001924
Andy Hung296b7412014-06-17 15:25:47 -07001925 } else { // constant volume gain
Andy Hung5e58b0a2014-06-23 19:07:29 -07001926 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Andy Hung296b7412014-06-17 15:25:47 -07001927 t->resampler->resample((int32_t*)out, outFrameCount, t->bufferProvider);
1928 }
1929}
1930
1931/* This track hook is called to mix a track, when no resampling is required.
1932 * The input buffer should be present in t->in.
Andy Hunge93b6b72014-07-17 21:30:53 -07001933 *
1934 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1935 * TO: int32_t (Q4.27) or float
1936 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
Andy Hung116a4982017-11-30 10:15:08 -08001937 * TA: int32_t (Q4.27) or float
Andy Hung296b7412014-06-17 15:25:47 -07001938 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001939template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung296b7412014-06-17 15:25:47 -07001940void AudioMixer::track__NoResample(track_t* t, TO* out, size_t frameCount,
1941 TO* temp __unused, TA* aux)
1942{
1943 ALOGVV("track__NoResample\n");
1944 const TI *in = static_cast<const TI *>(t->in);
1945
Andy Hung116a4982017-11-30 10:15:08 -08001946 volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
Andy Hunge93b6b72014-07-17 21:30:53 -07001947 out, frameCount, in, aux, t->needsRamp(), t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001948
Andy Hung296b7412014-06-17 15:25:47 -07001949 // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
1950 // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
Andy Hunge93b6b72014-07-17 21:30:53 -07001951 in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07001952 t->in = in;
1953}
1954
1955/* The Mixer engine generates either int32_t (Q4_27) or float data.
1956 * We use this function to convert the engine buffers
1957 * to the desired mixer output format, either int16_t (Q.15) or float.
1958 */
1959void AudioMixer::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
1960 void *in, audio_format_t mixerInFormat, size_t sampleCount)
1961{
1962 switch (mixerInFormat) {
1963 case AUDIO_FORMAT_PCM_FLOAT:
1964 switch (mixerOutFormat) {
1965 case AUDIO_FORMAT_PCM_FLOAT:
1966 memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
1967 break;
1968 case AUDIO_FORMAT_PCM_16_BIT:
1969 memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
1970 break;
1971 default:
1972 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1973 break;
1974 }
1975 break;
1976 case AUDIO_FORMAT_PCM_16_BIT:
1977 switch (mixerOutFormat) {
1978 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung5effdf62017-11-27 13:51:40 -08001979 memcpy_to_float_from_q4_27((float*)out, (const int32_t*)in, sampleCount);
Andy Hung296b7412014-06-17 15:25:47 -07001980 break;
1981 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung5effdf62017-11-27 13:51:40 -08001982 memcpy_to_i16_from_q4_27((int16_t*)out, (const int32_t*)in, sampleCount);
Andy Hung296b7412014-06-17 15:25:47 -07001983 break;
1984 default:
1985 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1986 break;
1987 }
1988 break;
1989 default:
1990 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1991 break;
1992 }
1993}
1994
1995/* Returns the proper track hook to use for mixing the track into the output buffer.
1996 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001997AudioMixer::hook_t AudioMixer::getTrackHook(int trackType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001998 audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
1999{
Andy Hunge93b6b72014-07-17 21:30:53 -07002000 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07002001 switch (trackType) {
2002 case TRACKTYPE_NOP:
2003 return track__nop;
2004 case TRACKTYPE_RESAMPLE:
2005 return track__genericResample;
2006 case TRACKTYPE_NORESAMPLEMONO:
2007 return track__16BitsMono;
2008 case TRACKTYPE_NORESAMPLE:
2009 return track__16BitsStereo;
2010 default:
2011 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
2012 break;
2013 }
2014 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002015 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07002016 switch (trackType) {
2017 case TRACKTYPE_NOP:
2018 return track__nop;
2019 case TRACKTYPE_RESAMPLE:
2020 switch (mixerInFormat) {
2021 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung116a4982017-11-30 10:15:08 -08002022 return (AudioMixer::hook_t)track__Resample<
2023 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002024 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung116a4982017-11-30 10:15:08 -08002025 return (AudioMixer::hook_t)track__Resample<
2026 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002027 default:
2028 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2029 break;
2030 }
2031 break;
2032 case TRACKTYPE_NORESAMPLEMONO:
2033 switch (mixerInFormat) {
2034 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung116a4982017-11-30 10:15:08 -08002035 return (AudioMixer::hook_t)track__NoResample<
2036 MIXTYPE_MONOEXPAND, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002037 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung116a4982017-11-30 10:15:08 -08002038 return (AudioMixer::hook_t)track__NoResample<
2039 MIXTYPE_MONOEXPAND, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002040 default:
2041 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2042 break;
2043 }
2044 break;
2045 case TRACKTYPE_NORESAMPLE:
2046 switch (mixerInFormat) {
2047 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung116a4982017-11-30 10:15:08 -08002048 return (AudioMixer::hook_t)track__NoResample<
2049 MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002050 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung116a4982017-11-30 10:15:08 -08002051 return (AudioMixer::hook_t)track__NoResample<
2052 MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002053 default:
2054 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2055 break;
2056 }
2057 break;
2058 default:
2059 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
2060 break;
2061 }
2062 return NULL;
2063}
2064
2065/* Returns the proper process hook for mixing tracks. Currently works only for
2066 * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
Andy Hung395db4b2014-08-25 17:15:29 -07002067 *
2068 * TODO: Due to the special mixing considerations of duplicating to
2069 * a stereo output track, the input track cannot be MONO. This should be
2070 * prevented by the caller.
Andy Hung296b7412014-06-17 15:25:47 -07002071 */
Andy Hunge93b6b72014-07-17 21:30:53 -07002072AudioMixer::process_hook_t AudioMixer::getProcessHook(int processType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07002073 audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
2074{
2075 if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
2076 LOG_ALWAYS_FATAL("bad processType: %d", processType);
2077 return NULL;
2078 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002079 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07002080 return process__OneTrack16BitsStereoNoResampling;
2081 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002082 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07002083 switch (mixerInFormat) {
2084 case AUDIO_FORMAT_PCM_FLOAT:
2085 switch (mixerOutFormat) {
2086 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung116a4982017-11-30 10:15:08 -08002087 return process_NoResampleOneTrack<
2088 MIXTYPE_MULTI_SAVEONLY, float /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002089 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung116a4982017-11-30 10:15:08 -08002090 return process_NoResampleOneTrack<
2091 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, float /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002092 default:
2093 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2094 break;
2095 }
2096 break;
2097 case AUDIO_FORMAT_PCM_16_BIT:
2098 switch (mixerOutFormat) {
2099 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung116a4982017-11-30 10:15:08 -08002100 return process_NoResampleOneTrack<
2101 MIXTYPE_MULTI_SAVEONLY, float /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002102 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung116a4982017-11-30 10:15:08 -08002103 return process_NoResampleOneTrack<
2104 MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
Andy Hung296b7412014-06-17 15:25:47 -07002105 default:
2106 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2107 break;
2108 }
2109 break;
2110 default:
2111 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2112 break;
2113 }
2114 return NULL;
2115}
2116
Mathias Agopian65ab4712010-07-14 17:59:35 -07002117// ----------------------------------------------------------------------------
Glenn Kasten63238ef2015-03-02 15:50:29 -08002118} // namespace android