blob: 23513c9636295bbe6ec30554f74858e2fad3624b [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
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070030#include <cutils/bitops.h>
Glenn Kastenf6b16782011-12-15 09:51:17 -080031#include <cutils/compiler.h>
Glenn Kasten5798d4e2012-03-08 12:18:35 -080032#include <utils/Debug.h>
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070033
34#include <system/audio.h>
35
Glenn Kasten3b21c502011-12-15 09:52:39 -080036#include <audio_utils/primitives.h>
Andy Hungef7c7fb2014-05-12 16:51:41 -070037#include <audio_utils/format.h>
Andy Hung068561c2017-01-03 17:09:32 -080038#include <media/AudioMixer.h>
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070039
Andy Hung296b7412014-06-17 15:25:47 -070040#include "AudioMixerOps.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070041
Andy Hunge93b6b72014-07-17 21:30:53 -070042// The FCC_2 macro refers to the Fixed Channel Count of 2 for the legacy integer mixer.
Andy Hung296b7412014-06-17 15:25:47 -070043#ifndef FCC_2
44#define FCC_2 2
45#endif
46
Andy Hunge93b6b72014-07-17 21:30:53 -070047// Look for MONO_HACK for any Mono hack involving legacy mono channel to
48// stereo channel conversion.
49
Andy Hung296b7412014-06-17 15:25:47 -070050/* VERY_VERY_VERBOSE_LOGGING will show exactly which process hook and track hook is
51 * being used. This is a considerable amount of log spam, so don't enable unless you
52 * are verifying the hook based code.
53 */
54//#define VERY_VERY_VERBOSE_LOGGING
55#ifdef VERY_VERY_VERBOSE_LOGGING
56#define ALOGVV ALOGV
57//define ALOGVV printf // for test-mixer.cpp
58#else
59#define ALOGVV(a...) do { } while (0)
60#endif
61
Andy Hunga08810b2014-07-16 21:53:43 -070062#ifndef ARRAY_SIZE
63#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
64#endif
65
Andy Hunge09c9942015-05-08 16:58:13 -070066// TODO: Move these macro/inlines to a header file.
67template <typename T>
68static inline
69T max(const T& x, const T& y) {
70 return x > y ? x : y;
71}
72
Andy Hung5b8fde72014-09-02 21:14:34 -070073// Set kUseNewMixer to true to use the new mixer engine always. Otherwise the
74// original code will be used for stereo sinks, the new mixer for multichannel.
75static const bool kUseNewMixer = true;
Andy Hung296b7412014-06-17 15:25:47 -070076
77// Set kUseFloat to true to allow floating input into the mixer engine.
78// If kUseNewMixer is false, this is ignored or may be overridden internally
79// because of downmix/upmix support.
80static const bool kUseFloat = true;
81
Andy Hung1b2fdcb2014-07-16 17:44:34 -070082// Set to default copy buffer size in frames for input processing.
83static const size_t kCopyBufferFrameCount = 256;
84
Mathias Agopian65ab4712010-07-14 17:59:35 -070085namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070086
87// ----------------------------------------------------------------------------
Andy Hung1b2fdcb2014-07-16 17:44:34 -070088
89template <typename T>
90T min(const T& a, const T& b)
91{
92 return a < b ? a : b;
93}
94
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070095// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -070096
Paul Lind3c0a0e82012-08-01 18:49:49 -070097// Ensure mConfiguredNames bitmask is initialized properly on all architectures.
98// The value of 1 << x is undefined in C when x >= 32.
99
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700100AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks)
Paul Lind3c0a0e82012-08-01 18:49:49 -0700101 : mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1),
Glenn Kasten7f5d3352013-02-15 23:55:04 +0000102 mSampleRate(sampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700103{
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700104 ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
105 maxNumTracks, MAX_NUM_TRACKS);
106
Glenn Kasten599fabc2012-03-08 12:33:37 -0800107 // AudioMixer is not yet capable of more than 32 active track inputs
108 ALOG_ASSERT(32 >= MAX_NUM_TRACKS, "bad MAX_NUM_TRACKS %d", MAX_NUM_TRACKS);
109
Glenn Kasten52008f82012-03-18 09:34:41 -0700110 pthread_once(&sOnceControl, &sInitRoutine);
111
Mathias Agopian65ab4712010-07-14 17:59:35 -0700112 mState.enabledTracks= 0;
113 mState.needsChanged = 0;
114 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800115 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -0800116 mState.outputTemp = NULL;
117 mState.resampleTemp = NULL;
Glenn Kasten3ab8d662017-04-03 14:35:09 -0700118 mState.mNBLogWriter = &mDummyLogWriter;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800119 // mState.reserved
Glenn Kasten17a736c2012-02-14 08:52:15 -0800120
121 // FIXME Most of the following initialization is probably redundant since
122 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
123 // and mTrackNames is initially 0. However, leave it here until that's verified.
Mathias Agopian65ab4712010-07-14 17:59:35 -0700124 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800125 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Eric Laurenta5e82142012-04-16 13:47:17 -0700126 t->resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700127 t->downmixerBufferProvider = NULL;
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700128 t->mReformatBufferProvider = NULL;
Andy Hungc5656cc2015-03-26 19:04:33 -0700129 t->mTimestretchBufferProvider = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700130 t++;
131 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700132
Mathias Agopian65ab4712010-07-14 17:59:35 -0700133}
134
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800135AudioMixer::~AudioMixer()
136{
137 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800138 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800139 delete t->resampler;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700140 delete t->downmixerBufferProvider;
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700141 delete t->mReformatBufferProvider;
Andy Hungc5656cc2015-03-26 19:04:33 -0700142 delete t->mTimestretchBufferProvider;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800143 t++;
144 }
145 delete [] mState.outputTemp;
146 delete [] mState.resampleTemp;
147}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700148
Glenn Kasten3ab8d662017-04-03 14:35:09 -0700149void AudioMixer::setNBLogWriter(NBLog::Writer *logWriter)
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800150{
Glenn Kasten3ab8d662017-04-03 14:35:09 -0700151 mState.mNBLogWriter = logWriter;
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800152}
153
Andy Hung7f475492014-08-25 16:36:37 -0700154static inline audio_format_t selectMixerInFormat(audio_format_t inputFormat __unused) {
155 return kUseFloat && kUseNewMixer ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
156}
157
Andy Hunge8a1ced2014-05-09 15:02:21 -0700158int AudioMixer::getTrackName(audio_channel_mask_t channelMask,
159 audio_format_t format, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800160{
Andy Hunge8a1ced2014-05-09 15:02:21 -0700161 if (!isValidPcmTrackFormat(format)) {
162 ALOGE("AudioMixer::getTrackName invalid format (%#x)", format);
163 return -1;
164 }
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700165 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800166 if (names != 0) {
167 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100168 ALOGV("add track (%d)", n);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700169 // assume default parameters for the track, except where noted below
170 track_t* t = &mState.tracks[n];
171 t->needs = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700172
173 // Integer volume.
174 // Currently integer volume is kept for the legacy integer mixer.
175 // Will be removed when the legacy mixer path is removed.
Andy Hung97ae8242014-05-30 10:35:47 -0700176 t->volume[0] = UNITY_GAIN_INT;
177 t->volume[1] = UNITY_GAIN_INT;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700178 t->prevVolume[0] = UNITY_GAIN_INT << 16;
179 t->prevVolume[1] = UNITY_GAIN_INT << 16;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700180 t->volumeInc[0] = 0;
181 t->volumeInc[1] = 0;
182 t->auxLevel = 0;
183 t->auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700184 t->prevAuxLevel = 0;
185
186 // Floating point volume.
187 t->mVolume[0] = UNITY_GAIN_FLOAT;
188 t->mVolume[1] = UNITY_GAIN_FLOAT;
189 t->mPrevVolume[0] = UNITY_GAIN_FLOAT;
190 t->mPrevVolume[1] = UNITY_GAIN_FLOAT;
191 t->mVolumeInc[0] = 0.;
192 t->mVolumeInc[1] = 0.;
193 t->mAuxLevel = 0.;
194 t->mAuxInc = 0.;
195 t->mPrevAuxLevel = 0.;
196
Glenn Kastendeeb1282012-03-25 11:59:31 -0700197 // no initialization needed
Glenn Kastendeeb1282012-03-25 11:59:31 -0700198 // t->frameCount
Andy Hung68112fc2014-05-14 14:13:23 -0700199 t->channelCount = audio_channel_count_from_out_mask(channelMask);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700200 t->enabled = false;
Andy Hunge93b6b72014-07-17 21:30:53 -0700201 ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
Andy Hungef7c7fb2014-05-12 16:51:41 -0700202 "Non-stereo channel mask: %d\n", channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700203 t->channelMask = channelMask;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700204 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700205 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
206 t->bufferProvider = NULL;
207 t->buffer.raw = NULL;
208 // no initialization needed
209 // t->buffer.frameCount
210 t->hook = NULL;
211 t->in = NULL;
212 t->resampler = NULL;
213 t->sampleRate = mSampleRate;
214 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
215 t->mainBuffer = NULL;
216 t->auxBuffer = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700217 t->mInputBufferProvider = NULL;
218 t->mReformatBufferProvider = NULL;
Glenn Kasten52008f82012-03-18 09:34:41 -0700219 t->downmixerBufferProvider = NULL;
Andy Hung7f475492014-08-25 16:36:37 -0700220 t->mPostDownmixReformatBufferProvider = NULL;
Andy Hungc5656cc2015-03-26 19:04:33 -0700221 t->mTimestretchBufferProvider = NULL;
Andy Hung78820702014-02-28 16:23:02 -0800222 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700223 t->mFormat = format;
Andy Hung7f475492014-08-25 16:36:37 -0700224 t->mMixerInFormat = selectMixerInFormat(format);
225 t->mDownmixRequiresFormat = AUDIO_FORMAT_INVALID; // no format required
Andy Hunge93b6b72014-07-17 21:30:53 -0700226 t->mMixerChannelMask = audio_channel_mask_from_representation_and_bits(
227 AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
228 t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700229 t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
Andy Hung296b7412014-06-17 15:25:47 -0700230 // Check the downmixing (or upmixing) requirements.
Andy Hung0f451e92014-08-04 21:28:47 -0700231 status_t status = t->prepareForDownmix();
Andy Hung68112fc2014-05-14 14:13:23 -0700232 if (status != OK) {
233 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
234 return -1;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700235 }
Andy Hung7f475492014-08-25 16:36:37 -0700236 // prepareForDownmix() may change mDownmixRequiresFormat
Andy Hung296b7412014-06-17 15:25:47 -0700237 ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
Andy Hung0f451e92014-08-04 21:28:47 -0700238 t->prepareForReformat();
Andy Hung68112fc2014-05-14 14:13:23 -0700239 mTrackNames |= 1 << n;
240 return TRACK0 + n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700241 }
Andy Hung68112fc2014-05-14 14:13:23 -0700242 ALOGE("AudioMixer::getTrackName out of available tracks");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700243 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800244}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700245
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800246void AudioMixer::invalidateState(uint32_t mask)
247{
Glenn Kasten34fca342013-08-13 09:48:14 -0700248 if (mask != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700249 mState.needsChanged |= mask;
250 mState.hook = process__validate;
251 }
252 }
253
Andy Hunge93b6b72014-07-17 21:30:53 -0700254// Called when channel masks have changed for a track name
Andy Hung7f475492014-08-25 16:36:37 -0700255// TODO: Fix DownmixerBufferProvider not to (possibly) change mixer input format,
Andy Hunge93b6b72014-07-17 21:30:53 -0700256// which will simplify this logic.
257bool AudioMixer::setChannelMasks(int name,
258 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) {
259 track_t &track = mState.tracks[name];
260
261 if (trackChannelMask == track.channelMask
262 && mixerChannelMask == track.mMixerChannelMask) {
263 return false; // no need to change
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700264 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700265 // always recompute for both channel masks even if only one has changed.
266 const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
267 const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
268 const bool mixerChannelCountChanged = track.mMixerChannelCount != mixerChannelCount;
269
270 ALOG_ASSERT((trackChannelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX)
271 && trackChannelCount
272 && mixerChannelCount);
273 track.channelMask = trackChannelMask;
274 track.channelCount = trackChannelCount;
275 track.mMixerChannelMask = mixerChannelMask;
276 track.mMixerChannelCount = mixerChannelCount;
277
278 // channel masks have changed, does this track need a downmixer?
279 // update to try using our desired format (if we aren't already using it)
Andy Hung7f475492014-08-25 16:36:37 -0700280 const audio_format_t prevDownmixerFormat = track.mDownmixRequiresFormat;
Andy Hung0f451e92014-08-04 21:28:47 -0700281 const status_t status = mState.tracks[name].prepareForDownmix();
Andy Hunge93b6b72014-07-17 21:30:53 -0700282 ALOGE_IF(status != OK,
Andy Hung0f451e92014-08-04 21:28:47 -0700283 "prepareForDownmix error %d, track channel mask %#x, mixer channel mask %#x",
Andy Hunge93b6b72014-07-17 21:30:53 -0700284 status, track.channelMask, track.mMixerChannelMask);
285
Andy Hung7f475492014-08-25 16:36:37 -0700286 if (prevDownmixerFormat != track.mDownmixRequiresFormat) {
Andy Hung0f451e92014-08-04 21:28:47 -0700287 track.prepareForReformat(); // because of downmixer, track format may change!
Andy Hunge93b6b72014-07-17 21:30:53 -0700288 }
289
Andy Hung7f475492014-08-25 16:36:37 -0700290 if (track.resampler && mixerChannelCountChanged) {
291 // resampler channels may have changed.
Andy Hunge93b6b72014-07-17 21:30:53 -0700292 const uint32_t resetToSampleRate = track.sampleRate;
293 delete track.resampler;
294 track.resampler = NULL;
295 track.sampleRate = mSampleRate; // without resampler, track rate is device sample rate.
296 // recreate the resampler with updated format, channels, saved sampleRate.
297 track.setResampler(resetToSampleRate /*trackSampleRate*/, mSampleRate /*devSampleRate*/);
298 }
299 return true;
300}
301
Andy Hung0f451e92014-08-04 21:28:47 -0700302void AudioMixer::track_t::unprepareForDownmix() {
303 ALOGV("AudioMixer::unprepareForDownmix(%p)", this);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700304
Andy Hung7f475492014-08-25 16:36:37 -0700305 mDownmixRequiresFormat = AUDIO_FORMAT_INVALID;
Andy Hung0f451e92014-08-04 21:28:47 -0700306 if (downmixerBufferProvider != NULL) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700307 // this track had previously been configured with a downmixer, delete it
308 ALOGV(" deleting old downmixer");
Andy Hung0f451e92014-08-04 21:28:47 -0700309 delete downmixerBufferProvider;
310 downmixerBufferProvider = NULL;
311 reconfigureBufferProviders();
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700312 } else {
313 ALOGV(" nothing to do, no downmixer to delete");
314 }
315}
316
Andy Hung0f451e92014-08-04 21:28:47 -0700317status_t AudioMixer::track_t::prepareForDownmix()
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700318{
Andy Hung0f451e92014-08-04 21:28:47 -0700319 ALOGV("AudioMixer::prepareForDownmix(%p) with mask 0x%x",
320 this, channelMask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700321
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700322 // discard the previous downmixer if there was one
Andy Hung0f451e92014-08-04 21:28:47 -0700323 unprepareForDownmix();
Andy Hung73e62e22015-04-20 12:06:38 -0700324 // MONO_HACK Only remix (upmix or downmix) if the track and mixer/device channel masks
Andy Hung0f451e92014-08-04 21:28:47 -0700325 // are not the same and not handled internally, as mono -> stereo currently is.
326 if (channelMask == mMixerChannelMask
327 || (channelMask == AUDIO_CHANNEL_OUT_MONO
328 && mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO)) {
329 return NO_ERROR;
330 }
Andy Hung650ceb92015-01-29 13:31:12 -0800331 // DownmixerBufferProvider is only used for position masks.
332 if (audio_channel_mask_get_representation(channelMask)
333 == AUDIO_CHANNEL_REPRESENTATION_POSITION
334 && DownmixerBufferProvider::isMultichannelCapable()) {
Andy Hung0f451e92014-08-04 21:28:47 -0700335 DownmixerBufferProvider* pDbp = new DownmixerBufferProvider(channelMask,
336 mMixerChannelMask,
337 AUDIO_FORMAT_PCM_16_BIT /* TODO: use mMixerInFormat, now only PCM 16 */,
338 sampleRate, sessionId, kCopyBufferFrameCount);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700339
Andy Hung34803d52014-07-16 21:41:35 -0700340 if (pDbp->isValid()) { // if constructor completed properly
Andy Hung7f475492014-08-25 16:36:37 -0700341 mDownmixRequiresFormat = AUDIO_FORMAT_PCM_16_BIT; // PCM 16 bit required for downmix
Andy Hung0f451e92014-08-04 21:28:47 -0700342 downmixerBufferProvider = pDbp;
343 reconfigureBufferProviders();
Andy Hung34803d52014-07-16 21:41:35 -0700344 return NO_ERROR;
345 }
346 delete pDbp;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700347 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700348
349 // Effect downmixer does not accept the channel conversion. Let's use our remixer.
Andy Hung0f451e92014-08-04 21:28:47 -0700350 RemixBufferProvider* pRbp = new RemixBufferProvider(channelMask,
351 mMixerChannelMask, mMixerInFormat, kCopyBufferFrameCount);
Andy Hunge93b6b72014-07-17 21:30:53 -0700352 // Remix always finds a conversion whereas Downmixer effect above may fail.
Andy Hung0f451e92014-08-04 21:28:47 -0700353 downmixerBufferProvider = pRbp;
354 reconfigureBufferProviders();
Andy Hunge93b6b72014-07-17 21:30:53 -0700355 return NO_ERROR;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700356}
357
Andy Hung0f451e92014-08-04 21:28:47 -0700358void AudioMixer::track_t::unprepareForReformat() {
359 ALOGV("AudioMixer::unprepareForReformat(%p)", this);
Andy Hung7f475492014-08-25 16:36:37 -0700360 bool requiresReconfigure = false;
Andy Hung0f451e92014-08-04 21:28:47 -0700361 if (mReformatBufferProvider != NULL) {
362 delete mReformatBufferProvider;
363 mReformatBufferProvider = NULL;
Andy Hung7f475492014-08-25 16:36:37 -0700364 requiresReconfigure = true;
365 }
366 if (mPostDownmixReformatBufferProvider != NULL) {
367 delete mPostDownmixReformatBufferProvider;
368 mPostDownmixReformatBufferProvider = NULL;
369 requiresReconfigure = true;
370 }
371 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700372 reconfigureBufferProviders();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700373 }
374}
375
Andy Hung0f451e92014-08-04 21:28:47 -0700376status_t AudioMixer::track_t::prepareForReformat()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700377{
Andy Hung0f451e92014-08-04 21:28:47 -0700378 ALOGV("AudioMixer::prepareForReformat(%p) with format %#x", this, mFormat);
Andy Hung7f475492014-08-25 16:36:37 -0700379 // discard previous reformatters
Andy Hung0f451e92014-08-04 21:28:47 -0700380 unprepareForReformat();
Andy Hung7f475492014-08-25 16:36:37 -0700381 // only configure reformatters as needed
382 const audio_format_t targetFormat = mDownmixRequiresFormat != AUDIO_FORMAT_INVALID
383 ? mDownmixRequiresFormat : mMixerInFormat;
384 bool requiresReconfigure = false;
385 if (mFormat != targetFormat) {
Andy Hung0f451e92014-08-04 21:28:47 -0700386 mReformatBufferProvider = new ReformatBufferProvider(
387 audio_channel_count_from_out_mask(channelMask),
Andy Hung7f475492014-08-25 16:36:37 -0700388 mFormat,
389 targetFormat,
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700390 kCopyBufferFrameCount);
Andy Hung7f475492014-08-25 16:36:37 -0700391 requiresReconfigure = true;
392 }
393 if (targetFormat != mMixerInFormat) {
394 mPostDownmixReformatBufferProvider = new ReformatBufferProvider(
395 audio_channel_count_from_out_mask(mMixerChannelMask),
396 targetFormat,
397 mMixerInFormat,
398 kCopyBufferFrameCount);
399 requiresReconfigure = true;
400 }
401 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700402 reconfigureBufferProviders();
Andy Hung296b7412014-06-17 15:25:47 -0700403 }
404 return NO_ERROR;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700405}
406
Andy Hung0f451e92014-08-04 21:28:47 -0700407void AudioMixer::track_t::reconfigureBufferProviders()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700408{
Andy Hung0f451e92014-08-04 21:28:47 -0700409 bufferProvider = mInputBufferProvider;
410 if (mReformatBufferProvider) {
411 mReformatBufferProvider->setBufferProvider(bufferProvider);
412 bufferProvider = mReformatBufferProvider;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700413 }
Andy Hung0f451e92014-08-04 21:28:47 -0700414 if (downmixerBufferProvider) {
415 downmixerBufferProvider->setBufferProvider(bufferProvider);
416 bufferProvider = downmixerBufferProvider;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700417 }
Andy Hung7f475492014-08-25 16:36:37 -0700418 if (mPostDownmixReformatBufferProvider) {
419 mPostDownmixReformatBufferProvider->setBufferProvider(bufferProvider);
420 bufferProvider = mPostDownmixReformatBufferProvider;
421 }
Andy Hungc5656cc2015-03-26 19:04:33 -0700422 if (mTimestretchBufferProvider) {
423 mTimestretchBufferProvider->setBufferProvider(bufferProvider);
424 bufferProvider = mTimestretchBufferProvider;
425 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700426}
427
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800428void AudioMixer::deleteTrackName(int name)
429{
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700430 ALOGV("AudioMixer::deleteTrackName(%d)", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700431 name -= TRACK0;
Eric Laurentaf3ec7c2016-08-01 11:25:19 -0700432 LOG_ALWAYS_FATAL_IF(name < 0 || name >= (int)MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800433 ALOGV("deleteTrackName(%d)", name);
434 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800435 if (track.enabled) {
436 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800437 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700438 }
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700439 // delete the resampler
440 delete track.resampler;
441 track.resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700442 // delete the downmixer
Andy Hung0f451e92014-08-04 21:28:47 -0700443 mState.tracks[name].unprepareForDownmix();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700444 // delete the reformatter
Andy Hung0f451e92014-08-04 21:28:47 -0700445 mState.tracks[name].unprepareForReformat();
Andy Hungc5656cc2015-03-26 19:04:33 -0700446 // delete the timestretch provider
447 delete track.mTimestretchBufferProvider;
448 track.mTimestretchBufferProvider = NULL;
Glenn Kasten237a6242011-12-15 15:32:27 -0800449 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800450}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700451
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800452void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700453{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800454 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800455 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800456 track_t& track = mState.tracks[name];
457
Glenn Kasten4c340c62012-01-27 12:33:54 -0800458 if (!track.enabled) {
459 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800460 ALOGV("enable(%d)", name);
461 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700462 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700463}
464
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800465void AudioMixer::disable(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 = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800473 ALOGV("disable(%d)", name);
474 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700475 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700476}
477
Andy Hung5866a3b2014-05-29 21:33:13 -0700478/* Sets the volume ramp variables for the AudioMixer.
479 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700480 * The volume ramp variables are used to transition from the previous
481 * volume to the set volume. ramp controls the duration of the transition.
482 * Its value is typically one state framecount period, but may also be 0,
483 * meaning "immediate."
Andy Hung5866a3b2014-05-29 21:33:13 -0700484 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700485 * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
486 * even if there is a nonzero floating point increment (in that case, the volume
487 * change is immediate). This restriction should be changed when the legacy mixer
488 * is removed (see #2).
489 * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
490 * when no longer needed.
491 *
492 * @param newVolume set volume target in floating point [0.0, 1.0].
493 * @param ramp number of frames to increment over. if ramp is 0, the volume
494 * should be set immediately. Currently ramp should not exceed 65535 (frames).
495 * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
496 * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
497 * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
498 * @param pSetVolume pointer to the float target volume, set on return.
499 * @param pPrevVolume pointer to the float previous volume, set on return.
500 * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
Andy Hung5866a3b2014-05-29 21:33:13 -0700501 * @return true if the volume has changed, false if volume is same.
502 */
Andy Hung5e58b0a2014-06-23 19:07:29 -0700503static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
504 int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
505 float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
Andy Hunge09c9942015-05-08 16:58:13 -0700506 // check floating point volume to see if it is identical to the previously
507 // set volume.
508 // We do not use a tolerance here (and reject changes too small)
509 // as it may be confusing to use a different value than the one set.
510 // If the resulting volume is too small to ramp, it is a direct set of the volume.
Andy Hung5e58b0a2014-06-23 19:07:29 -0700511 if (newVolume == *pSetVolume) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700512 return false;
513 }
Andy Hunge09c9942015-05-08 16:58:13 -0700514 if (newVolume < 0) {
515 newVolume = 0; // should not have negative volumes
Andy Hung5866a3b2014-05-29 21:33:13 -0700516 } else {
Andy Hunge09c9942015-05-08 16:58:13 -0700517 switch (fpclassify(newVolume)) {
518 case FP_SUBNORMAL:
519 case FP_NAN:
520 newVolume = 0;
521 break;
522 case FP_ZERO:
523 break; // zero volume is fine
524 case FP_INFINITE:
525 // Infinite volume could be handled consistently since
526 // floating point math saturates at infinities,
527 // but we limit volume to unity gain float.
528 // ramp = 0; break;
529 //
530 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
531 break;
532 case FP_NORMAL:
533 default:
534 // Floating point does not have problems with overflow wrap
535 // that integer has. However, we limit the volume to
536 // unity gain here.
537 // TODO: Revisit the volume limitation and perhaps parameterize.
538 if (newVolume > AudioMixer::UNITY_GAIN_FLOAT) {
539 newVolume = AudioMixer::UNITY_GAIN_FLOAT;
540 }
541 break;
542 }
Andy Hung5866a3b2014-05-29 21:33:13 -0700543 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700544
Andy Hunge09c9942015-05-08 16:58:13 -0700545 // set floating point volume ramp
546 if (ramp != 0) {
547 // when the ramp completes, *pPrevVolume is set to *pSetVolume, so there
548 // is no computational mismatch; hence equality is checked here.
549 ALOGD_IF(*pPrevVolume != *pSetVolume, "previous float ramp hasn't finished,"
550 " prev:%f set_to:%f", *pPrevVolume, *pSetVolume);
551 const float inc = (newVolume - *pPrevVolume) / ramp; // could be inf, nan, subnormal
552 const float maxv = max(newVolume, *pPrevVolume); // could be inf, cannot be nan, subnormal
553
554 if (isnormal(inc) // inc must be a normal number (no subnormals, infinite, nan)
555 && maxv + inc != maxv) { // inc must make forward progress
556 *pVolumeInc = inc;
557 // ramp is set now.
558 // Note: if newVolume is 0, then near the end of the ramp,
559 // it may be possible that the ramped volume may be subnormal or
560 // temporarily negative by a small amount or subnormal due to floating
561 // point inaccuracies.
562 } else {
563 ramp = 0; // ramp not allowed
564 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700565 }
Andy Hunge09c9942015-05-08 16:58:13 -0700566
567 // compute and check integer volume, no need to check negative values
568 // The integer volume is limited to "unity_gain" to avoid wrapping and other
569 // audio artifacts, so it never reaches the range limit of U4.28.
570 // We safely use signed 16 and 32 bit integers here.
571 const float scaledVolume = newVolume * AudioMixer::UNITY_GAIN_INT; // not neg, subnormal, nan
572 const int32_t intVolume = (scaledVolume >= (float)AudioMixer::UNITY_GAIN_INT) ?
573 AudioMixer::UNITY_GAIN_INT : (int32_t)scaledVolume;
574
575 // set integer volume ramp
576 if (ramp != 0) {
577 // integer volume is U4.12 (to use 16 bit multiplies), but ramping uses U4.28.
578 // when the ramp completes, *pIntPrevVolume is set to *pIntSetVolume << 16, so there
579 // is no computational mismatch; hence equality is checked here.
580 ALOGD_IF(*pIntPrevVolume != *pIntSetVolume << 16, "previous int ramp hasn't finished,"
581 " prev:%d set_to:%d", *pIntPrevVolume, *pIntSetVolume << 16);
582 const int32_t inc = ((intVolume << 16) - *pIntPrevVolume) / ramp;
583
584 if (inc != 0) { // inc must make forward progress
585 *pIntVolumeInc = inc;
586 } else {
587 ramp = 0; // ramp not allowed
588 }
589 }
590
591 // if no ramp, or ramp not allowed, then clear float and integer increments
592 if (ramp == 0) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700593 *pVolumeInc = 0;
594 *pPrevVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700595 *pIntVolumeInc = 0;
596 *pIntPrevVolume = intVolume << 16;
597 }
Andy Hunge09c9942015-05-08 16:58:13 -0700598 *pSetVolume = newVolume;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700599 *pIntSetVolume = intVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700600 return true;
601}
602
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800603void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700604{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800605 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800606 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800607 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700608
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000609 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
610 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700611
612 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700613
Mathias Agopian65ab4712010-07-14 17:59:35 -0700614 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800615 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700616 case CHANNEL_MASK: {
Andy Hunge93b6b72014-07-17 21:30:53 -0700617 const audio_channel_mask_t trackChannelMask =
618 static_cast<audio_channel_mask_t>(valueInt);
619 if (setChannelMasks(name, trackChannelMask, track.mMixerChannelMask)) {
620 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800621 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700622 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700623 } break;
624 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800625 if (track.mainBuffer != valueBuf) {
626 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100627 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800628 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700629 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700630 break;
631 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800632 if (track.auxBuffer != valueBuf) {
633 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100634 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800635 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700636 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700637 break;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700638 case FORMAT: {
639 audio_format_t format = static_cast<audio_format_t>(valueInt);
640 if (track.mFormat != format) {
641 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
642 track.mFormat = format;
643 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
Andy Hung0f451e92014-08-04 21:28:47 -0700644 track.prepareForReformat();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700645 invalidateState(1 << name);
646 }
647 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700648 // FIXME do we want to support setting the downmix type from AudioFlinger?
649 // for a specific track? or per mixer?
650 /* case DOWNMIX_TYPE:
651 break */
Andy Hung78820702014-02-28 16:23:02 -0800652 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800653 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung78820702014-02-28 16:23:02 -0800654 if (track.mMixerFormat != format) {
655 track.mMixerFormat = format;
656 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800657 }
658 } break;
Andy Hunge93b6b72014-07-17 21:30:53 -0700659 case MIXER_CHANNEL_MASK: {
660 const audio_channel_mask_t mixerChannelMask =
661 static_cast<audio_channel_mask_t>(valueInt);
662 if (setChannelMasks(name, track.channelMask, mixerChannelMask)) {
663 ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
664 invalidateState(1 << name);
665 }
666 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700667 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800668 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700669 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700670 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700671
Mathias Agopian65ab4712010-07-14 17:59:35 -0700672 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800673 switch (param) {
674 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800675 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700676 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
677 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
678 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800679 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700680 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800681 break;
682 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800683 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800684 invalidateState(1 << name);
685 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700686 case REMOVE:
687 delete track.resampler;
688 track.resampler = NULL;
689 track.sampleRate = mSampleRate;
690 invalidateState(1 << name);
691 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700692 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800693 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800694 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700695 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700696
Mathias Agopian65ab4712010-07-14 17:59:35 -0700697 case RAMP_VOLUME:
698 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800699 switch (param) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800700 case AUXLEVEL:
Andy Hung6be49402014-05-30 10:42:03 -0700701 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung5866a3b2014-05-29 21:33:13 -0700702 target == RAMP_VOLUME ? mState.frameCount : 0,
Andy Hung5e58b0a2014-06-23 19:07:29 -0700703 &track.auxLevel, &track.prevAuxLevel, &track.auxInc,
704 &track.mAuxLevel, &track.mPrevAuxLevel, &track.mAuxInc)) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700705 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
Andy Hung6be49402014-05-30 10:42:03 -0700706 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track.auxLevel);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800707 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700708 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800709 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700710 default:
Andy Hunge93b6b72014-07-17 21:30:53 -0700711 if ((unsigned)param >= VOLUME0 && (unsigned)param < VOLUME0 + MAX_NUM_VOLUMES) {
712 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
713 target == RAMP_VOLUME ? mState.frameCount : 0,
714 &track.volume[param - VOLUME0], &track.prevVolume[param - VOLUME0],
715 &track.volumeInc[param - VOLUME0],
716 &track.mVolume[param - VOLUME0], &track.mPrevVolume[param - VOLUME0],
717 &track.mVolumeInc[param - VOLUME0])) {
718 ALOGV("setParameter(%s, VOLUME%d: %04x)",
719 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
720 track.volume[param - VOLUME0]);
721 invalidateState(1 << name);
722 }
723 } else {
724 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
725 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700726 }
727 break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700728 case TIMESTRETCH:
729 switch (param) {
730 case PLAYBACK_RATE: {
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700731 const AudioPlaybackRate *playbackRate =
732 reinterpret_cast<AudioPlaybackRate*>(value);
Ricardo Garcia6c7f0622015-04-30 18:39:16 -0700733 ALOGW_IF(!isAudioPlaybackRateValid(*playbackRate),
734 "bad parameters speed %f, pitch %f",playbackRate->mSpeed,
735 playbackRate->mPitch);
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700736 if (track.setPlaybackRate(*playbackRate)) {
737 ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE "
738 "%f %f %d %d",
739 playbackRate->mSpeed,
740 playbackRate->mPitch,
741 playbackRate->mStretchMode,
742 playbackRate->mFallbackMode);
Andy Hungc5656cc2015-03-26 19:04:33 -0700743 // invalidateState(1 << name);
744 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700745 } break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700746 default:
747 LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);
748 }
749 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700750
751 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800752 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700753 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700754}
755
Andy Hunge93b6b72014-07-17 21:30:53 -0700756bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700757{
Andy Hunge93b6b72014-07-17 21:30:53 -0700758 if (trackSampleRate != devSampleRate || resampler != NULL) {
759 if (sampleRate != trackSampleRate) {
760 sampleRate = trackSampleRate;
Glenn Kastene0feee32011-12-13 11:53:26 -0800761 if (resampler == NULL) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700762 ALOGV("Creating resampler from track %d Hz to device %d Hz",
763 trackSampleRate, devSampleRate);
Glenn Kastenac602052012-10-01 14:04:31 -0700764 AudioResampler::src_quality quality;
765 // force lowest quality level resampler if use case isn't music or video
766 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
767 // quality level based on the initial ratio, but that could change later.
768 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
Andy Hungdb4c0312015-05-06 08:46:52 -0700769 if (isMusicRate(trackSampleRate)) {
Glenn Kastenac602052012-10-01 14:04:31 -0700770 quality = AudioResampler::DEFAULT_QUALITY;
Andy Hungdb4c0312015-05-06 08:46:52 -0700771 } else {
772 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700773 }
Andy Hung296b7412014-06-17 15:25:47 -0700774
Andy Hunge93b6b72014-07-17 21:30:53 -0700775 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
776 // but if none exists, it is the channel count (1 for mono).
777 const int resamplerChannelCount = downmixerBufferProvider != NULL
778 ? mMixerChannelCount : channelCount;
Andy Hung9a592762014-07-21 21:56:01 -0700779 ALOGVV("Creating resampler:"
780 " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
781 mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700782 resampler = AudioResampler::create(
Andy Hung3348e362014-07-07 10:21:44 -0700783 mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -0700784 resamplerChannelCount,
Glenn Kastenac602052012-10-01 14:04:31 -0700785 devSampleRate, quality);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700786 }
787 return true;
788 }
789 }
790 return false;
791}
792
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700793bool AudioMixer::track_t::setPlaybackRate(const AudioPlaybackRate &playbackRate)
Andy Hungc5656cc2015-03-26 19:04:33 -0700794{
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700795 if ((mTimestretchBufferProvider == NULL &&
796 fabs(playbackRate.mSpeed - mPlaybackRate.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
797 fabs(playbackRate.mPitch - mPlaybackRate.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA) ||
798 isAudioPlaybackRateEqual(playbackRate, mPlaybackRate)) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700799 return false;
800 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700801 mPlaybackRate = playbackRate;
Andy Hungc5656cc2015-03-26 19:04:33 -0700802 if (mTimestretchBufferProvider == NULL) {
803 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
804 // but if none exists, it is the channel count (1 for mono).
805 const int timestretchChannelCount = downmixerBufferProvider != NULL
806 ? mMixerChannelCount : channelCount;
807 mTimestretchBufferProvider = new TimestretchBufferProvider(timestretchChannelCount,
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700808 mMixerInFormat, sampleRate, playbackRate);
Andy Hungc5656cc2015-03-26 19:04:33 -0700809 reconfigureBufferProviders();
810 } else {
811 reinterpret_cast<TimestretchBufferProvider*>(mTimestretchBufferProvider)
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700812 ->setPlaybackRate(playbackRate);
Andy Hungc5656cc2015-03-26 19:04:33 -0700813 }
814 return true;
815}
816
Andy Hung5e58b0a2014-06-23 19:07:29 -0700817/* Checks to see if the volume ramp has completed and clears the increment
818 * variables appropriately.
819 *
820 * FIXME: There is code to handle int/float ramp variable switchover should it not
821 * complete within a mixer buffer processing call, but it is preferred to avoid switchover
822 * due to precision issues. The switchover code is included for legacy code purposes
823 * and can be removed once the integer volume is removed.
824 *
825 * It is not sufficient to clear only the volumeInc integer variable because
826 * if one channel requires ramping, all channels are ramped.
827 *
828 * There is a bit of duplicated code here, but it keeps backward compatibility.
829 */
830inline void AudioMixer::track_t::adjustVolumeRamp(bool aux, bool useFloat)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700831{
Andy Hung5e58b0a2014-06-23 19:07:29 -0700832 if (useFloat) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700833 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Eric Laurent43412fc2015-05-08 16:14:36 -0700834 if ((mVolumeInc[i] > 0 && mPrevVolume[i] + mVolumeInc[i] >= mVolume[i]) ||
835 (mVolumeInc[i] < 0 && mPrevVolume[i] + mVolumeInc[i] <= mVolume[i])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700836 volumeInc[i] = 0;
837 prevVolume[i] = volume[i] << 16;
838 mVolumeInc[i] = 0.;
839 mPrevVolume[i] = mVolume[i];
Andy Hung5e58b0a2014-06-23 19:07:29 -0700840 } else {
841 //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
842 prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
843 }
844 }
845 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -0700846 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700847 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
848 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
849 volumeInc[i] = 0;
850 prevVolume[i] = volume[i] << 16;
851 mVolumeInc[i] = 0.;
852 mPrevVolume[i] = mVolume[i];
853 } else {
854 //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
855 mPrevVolume[i] = float_from_u4_28(prevVolume[i]);
856 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700857 }
858 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700859 /* TODO: aux is always integer regardless of output buffer type */
Mathias Agopian65ab4712010-07-14 17:59:35 -0700860 if (aux) {
861 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
Andy Hung5e58b0a2014-06-23 19:07:29 -0700862 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700863 auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700864 prevAuxLevel = auxLevel << 16;
865 mAuxInc = 0.;
866 mPrevAuxLevel = mAuxLevel;
867 } else {
868 //ALOGV("aux ramp: %d %d %d", auxLevel << 16, prevAuxLevel, auxInc);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700869 }
870 }
871}
872
Glenn Kastenc59c0042012-02-02 14:06:11 -0800873size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800874{
875 name -= TRACK0;
876 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800877 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800878 }
879 return 0;
880}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700881
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800882void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700883{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800884 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800885 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700886
Andy Hung1d26ddf2014-05-29 15:53:09 -0700887 if (mState.tracks[name].mInputBufferProvider == bufferProvider) {
888 return; // don't reset any buffer providers if identical.
889 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700890 if (mState.tracks[name].mReformatBufferProvider != NULL) {
891 mState.tracks[name].mReformatBufferProvider->reset();
892 } else if (mState.tracks[name].downmixerBufferProvider != NULL) {
Andy Hung7f475492014-08-25 16:36:37 -0700893 mState.tracks[name].downmixerBufferProvider->reset();
894 } else if (mState.tracks[name].mPostDownmixReformatBufferProvider != NULL) {
895 mState.tracks[name].mPostDownmixReformatBufferProvider->reset();
Andy Hungc5656cc2015-03-26 19:04:33 -0700896 } else if (mState.tracks[name].mTimestretchBufferProvider != NULL) {
897 mState.tracks[name].mTimestretchBufferProvider->reset();
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700898 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700899
900 mState.tracks[name].mInputBufferProvider = bufferProvider;
Andy Hung0f451e92014-08-04 21:28:47 -0700901 mState.tracks[name].reconfigureBufferProviders();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700902}
903
904
Glenn Kastend79072e2016-01-06 08:41:20 -0800905void AudioMixer::process()
Mathias Agopian65ab4712010-07-14 17:59:35 -0700906{
Glenn Kastend79072e2016-01-06 08:41:20 -0800907 mState.hook(&mState);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700908}
909
910
Glenn Kastend79072e2016-01-06 08:41:20 -0800911void AudioMixer::process__validate(state_t* state)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700912{
Steve Block5ff1dd52012-01-05 23:22:43 +0000913 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700914 "in process__validate() but nothing's invalid");
915
916 uint32_t changed = state->needsChanged;
917 state->needsChanged = 0; // clear the validation flag
918
919 // recompute which tracks are enabled / disabled
920 uint32_t enabled = 0;
921 uint32_t disabled = 0;
922 while (changed) {
923 const int i = 31 - __builtin_clz(changed);
924 const uint32_t mask = 1<<i;
925 changed &= ~mask;
926 track_t& t = state->tracks[i];
927 (t.enabled ? enabled : disabled) |= mask;
928 }
929 state->enabledTracks &= ~disabled;
930 state->enabledTracks |= enabled;
931
932 // compute everything we need...
933 int countActiveTracks = 0;
Andy Hung395db4b2014-08-25 17:15:29 -0700934 // TODO: fix all16BitsStereNoResample logic to
935 // either properly handle muted tracks (it should ignore them)
936 // or remove altogether as an obsolete optimization.
Glenn Kasten4c340c62012-01-27 12:33:54 -0800937 bool all16BitsStereoNoResample = true;
938 bool resampling = false;
939 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700940 uint32_t en = state->enabledTracks;
941 while (en) {
942 const int i = 31 - __builtin_clz(en);
943 en &= ~(1<<i);
944
945 countActiveTracks++;
946 track_t& t = state->tracks[i];
947 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700948 // FIXME can overflow (mask is only 3 bits)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700949 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700950 if (t.doesResample()) {
951 n |= NEEDS_RESAMPLE;
952 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700953 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700954 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700955 }
956
957 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800958 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700959 } else if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700960 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700961 }
962 t.needs = n;
963
Glenn Kastend6fadf02013-10-30 14:37:29 -0700964 if (n & NEEDS_MUTE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700965 t.hook = track__nop;
966 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700967 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800968 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700969 }
Glenn Kastend6fadf02013-10-30 14:37:29 -0700970 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800971 all16BitsStereoNoResample = false;
972 resampling = true;
Andy Hunge93b6b72014-07-17 21:30:53 -0700973 t.hook = getTrackHook(TRACKTYPE_RESAMPLE, t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -0700974 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700975 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700976 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700977 } else {
978 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
Andy Hunge93b6b72014-07-17 21:30:53 -0700979 t.hook = getTrackHook(
Andy Hung73e62e22015-04-20 12:06:38 -0700980 (t.mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO // TODO: MONO_HACK
981 && t.channelMask == AUDIO_CHANNEL_OUT_MONO)
Andy Hunge93b6b72014-07-17 21:30:53 -0700982 ? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,
983 t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -0700984 t.mMixerInFormat, t.mMixerFormat);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800985 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700986 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700987 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Andy Hunge93b6b72014-07-17 21:30:53 -0700988 t.hook = getTrackHook(TRACKTYPE_NORESAMPLE, t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -0700989 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700990 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700991 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700992 }
993 }
994 }
995 }
996
997 // select the processing hooks
998 state->hook = process__nop;
Glenn Kasten34fca342013-08-13 09:48:14 -0700999 if (countActiveTracks > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001000 if (resampling) {
1001 if (!state->outputTemp) {
1002 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
1003 }
1004 if (!state->resampleTemp) {
1005 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
1006 }
1007 state->hook = process__genericResampling;
1008 } else {
1009 if (state->outputTemp) {
1010 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -08001011 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001012 }
1013 if (state->resampleTemp) {
1014 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -08001015 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001016 }
1017 state->hook = process__genericNoResampling;
1018 if (all16BitsStereoNoResample && !volumeRamp) {
1019 if (countActiveTracks == 1) {
Andy Hung296b7412014-06-17 15:25:47 -07001020 const int i = 31 - __builtin_clz(state->enabledTracks);
1021 track_t& t = state->tracks[i];
Andy Hung395db4b2014-08-25 17:15:29 -07001022 if ((t.needs & NEEDS_MUTE) == 0) {
1023 // The check prevents a muted track from acquiring a process hook.
1024 //
1025 // This is dangerous if the track is MONO as that requires
1026 // special case handling due to implicit channel duplication.
1027 // Stereo or Multichannel should actually be fine here.
1028 state->hook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
1029 t.mMixerChannelCount, t.mMixerInFormat, t.mMixerFormat);
1030 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001031 }
1032 }
1033 }
1034 }
1035
Steve Block3856b092011-10-20 11:56:00 +01001036 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001037 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
1038 countActiveTracks, state->enabledTracks,
1039 all16BitsStereoNoResample, resampling, volumeRamp);
1040
Glenn Kastend79072e2016-01-06 08:41:20 -08001041 state->hook(state);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001042
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001043 // Now that the volume ramp has been done, set optimal state and
1044 // track hooks for subsequent mixer process
Glenn Kasten34fca342013-08-13 09:48:14 -07001045 if (countActiveTracks > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001046 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001047 uint32_t en = state->enabledTracks;
1048 while (en) {
1049 const int i = 31 - __builtin_clz(en);
1050 en &= ~(1<<i);
1051 track_t& t = state->tracks[i];
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001052 if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001053 t.needs |= NEEDS_MUTE;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001054 t.hook = track__nop;
1055 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001056 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001057 }
1058 }
1059 if (allMuted) {
1060 state->hook = process__nop;
1061 } else if (all16BitsStereoNoResample) {
1062 if (countActiveTracks == 1) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001063 const int i = 31 - __builtin_clz(state->enabledTracks);
1064 track_t& t = state->tracks[i];
Andy Hung395db4b2014-08-25 17:15:29 -07001065 // Muted single tracks handled by allMuted above.
Andy Hunge93b6b72014-07-17 21:30:53 -07001066 state->hook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
1067 t.mMixerChannelCount, t.mMixerInFormat, t.mMixerFormat);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001068 }
1069 }
1070 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001071}
1072
Mathias Agopian65ab4712010-07-14 17:59:35 -07001073
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001074void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
1075 int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001076{
Andy Hung296b7412014-06-17 15:25:47 -07001077 ALOGVV("track__genericResample\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001078 t->resampler->setSampleRate(t->sampleRate);
1079
1080 // ramp gain - resample to temp buffer and scale/mix in 2nd step
1081 if (aux != NULL) {
1082 // always resample with unity gain when sending to auxiliary buffer to be able
1083 // to apply send level after resampling
Andy Hung5e58b0a2014-06-23 19:07:29 -07001084 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Andy Hunge93b6b72014-07-17 21:30:53 -07001085 memset(temp, 0, outFrameCount * t->mMixerChannelCount * sizeof(int32_t));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001086 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -08001087 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001088 volumeRampStereo(t, out, outFrameCount, temp, aux);
1089 } else {
1090 volumeStereo(t, out, outFrameCount, temp, aux);
1091 }
1092 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -08001093 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001094 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001095 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
1096 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
1097 volumeRampStereo(t, out, outFrameCount, temp, aux);
1098 }
1099
1100 // constant gain
1101 else {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001102 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001103 t->resampler->resample(out, outFrameCount, t->bufferProvider);
1104 }
1105 }
1106}
1107
Andy Hungee931ff2014-01-28 13:44:14 -08001108void AudioMixer::track__nop(track_t* t __unused, int32_t* out __unused,
1109 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001110{
1111}
1112
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001113void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1114 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001115{
1116 int32_t vl = t->prevVolume[0];
1117 int32_t vr = t->prevVolume[1];
1118 const int32_t vlInc = t->volumeInc[0];
1119 const int32_t vrInc = t->volumeInc[1];
1120
Steve Blockb8a80522011-12-20 16:23:08 +00001121 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001122 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1123 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1124
1125 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -08001126 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001127 int32_t va = t->prevAuxLevel;
1128 const int32_t vaInc = t->auxInc;
1129 int32_t l;
1130 int32_t r;
1131
1132 do {
1133 l = (*temp++ >> 12);
1134 r = (*temp++ >> 12);
1135 *out++ += (vl >> 16) * l;
1136 *out++ += (vr >> 16) * r;
1137 *aux++ += (va >> 17) * (l + r);
1138 vl += vlInc;
1139 vr += vrInc;
1140 va += vaInc;
1141 } while (--frameCount);
1142 t->prevAuxLevel = va;
1143 } else {
1144 do {
1145 *out++ += (vl >> 16) * (*temp++ >> 12);
1146 *out++ += (vr >> 16) * (*temp++ >> 12);
1147 vl += vlInc;
1148 vr += vrInc;
1149 } while (--frameCount);
1150 }
1151 t->prevVolume[0] = vl;
1152 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -08001153 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001154}
1155
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001156void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1157 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001158{
1159 const int16_t vl = t->volume[0];
1160 const int16_t vr = t->volume[1];
1161
Glenn Kastenf6b16782011-12-15 09:51:17 -08001162 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -08001163 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001164 do {
1165 int16_t l = (int16_t)(*temp++ >> 12);
1166 int16_t r = (int16_t)(*temp++ >> 12);
1167 out[0] = mulAdd(l, vl, out[0]);
1168 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1169 out[1] = mulAdd(r, vr, out[1]);
1170 out += 2;
1171 aux[0] = mulAdd(a, va, aux[0]);
1172 aux++;
1173 } while (--frameCount);
1174 } else {
1175 do {
1176 int16_t l = (int16_t)(*temp++ >> 12);
1177 int16_t r = (int16_t)(*temp++ >> 12);
1178 out[0] = mulAdd(l, vl, out[0]);
1179 out[1] = mulAdd(r, vr, out[1]);
1180 out += 2;
1181 } while (--frameCount);
1182 }
1183}
1184
Andy Hungee931ff2014-01-28 13:44:14 -08001185void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount,
1186 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001187{
Andy Hung296b7412014-06-17 15:25:47 -07001188 ALOGVV("track__16BitsStereo\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001189 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001190
Glenn Kastenf6b16782011-12-15 09:51:17 -08001191 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001192 int32_t l;
1193 int32_t r;
1194 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001195 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001196 int32_t vl = t->prevVolume[0];
1197 int32_t vr = t->prevVolume[1];
1198 int32_t va = t->prevAuxLevel;
1199 const int32_t vlInc = t->volumeInc[0];
1200 const int32_t vrInc = t->volumeInc[1];
1201 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001202 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001203 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1204 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1205
1206 do {
1207 l = (int32_t)*in++;
1208 r = (int32_t)*in++;
1209 *out++ += (vl >> 16) * l;
1210 *out++ += (vr >> 16) * r;
1211 *aux++ += (va >> 17) * (l + r);
1212 vl += vlInc;
1213 vr += vrInc;
1214 va += vaInc;
1215 } while (--frameCount);
1216
1217 t->prevVolume[0] = vl;
1218 t->prevVolume[1] = vr;
1219 t->prevAuxLevel = va;
1220 t->adjustVolumeRamp(true);
1221 }
1222
1223 // constant gain
1224 else {
1225 const uint32_t vrl = t->volumeRL;
1226 const int16_t va = (int16_t)t->auxLevel;
1227 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001228 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001229 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1230 in += 2;
1231 out[0] = mulAddRL(1, rl, vrl, out[0]);
1232 out[1] = mulAddRL(0, rl, vrl, out[1]);
1233 out += 2;
1234 aux[0] = mulAdd(a, va, aux[0]);
1235 aux++;
1236 } while (--frameCount);
1237 }
1238 } else {
1239 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001240 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001241 int32_t vl = t->prevVolume[0];
1242 int32_t vr = t->prevVolume[1];
1243 const int32_t vlInc = t->volumeInc[0];
1244 const int32_t vrInc = t->volumeInc[1];
1245
Steve Blockb8a80522011-12-20 16:23:08 +00001246 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001247 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1248 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1249
1250 do {
1251 *out++ += (vl >> 16) * (int32_t) *in++;
1252 *out++ += (vr >> 16) * (int32_t) *in++;
1253 vl += vlInc;
1254 vr += vrInc;
1255 } while (--frameCount);
1256
1257 t->prevVolume[0] = vl;
1258 t->prevVolume[1] = vr;
1259 t->adjustVolumeRamp(false);
1260 }
1261
1262 // constant gain
1263 else {
1264 const uint32_t vrl = t->volumeRL;
1265 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001266 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001267 in += 2;
1268 out[0] = mulAddRL(1, rl, vrl, out[0]);
1269 out[1] = mulAddRL(0, rl, vrl, out[1]);
1270 out += 2;
1271 } while (--frameCount);
1272 }
1273 }
1274 t->in = in;
1275}
1276
Andy Hungee931ff2014-01-28 13:44:14 -08001277void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount,
1278 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001279{
Andy Hung296b7412014-06-17 15:25:47 -07001280 ALOGVV("track__16BitsMono\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001281 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001282
Glenn Kastenf6b16782011-12-15 09:51:17 -08001283 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001284 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001285 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001286 int32_t vl = t->prevVolume[0];
1287 int32_t vr = t->prevVolume[1];
1288 int32_t va = t->prevAuxLevel;
1289 const int32_t vlInc = t->volumeInc[0];
1290 const int32_t vrInc = t->volumeInc[1];
1291 const int32_t vaInc = t->auxInc;
1292
Steve Blockb8a80522011-12-20 16:23:08 +00001293 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001294 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1295 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1296
1297 do {
1298 int32_t l = *in++;
1299 *out++ += (vl >> 16) * l;
1300 *out++ += (vr >> 16) * l;
1301 *aux++ += (va >> 16) * l;
1302 vl += vlInc;
1303 vr += vrInc;
1304 va += vaInc;
1305 } while (--frameCount);
1306
1307 t->prevVolume[0] = vl;
1308 t->prevVolume[1] = vr;
1309 t->prevAuxLevel = va;
1310 t->adjustVolumeRamp(true);
1311 }
1312 // constant gain
1313 else {
1314 const int16_t vl = t->volume[0];
1315 const int16_t vr = t->volume[1];
1316 const int16_t va = (int16_t)t->auxLevel;
1317 do {
1318 int16_t l = *in++;
1319 out[0] = mulAdd(l, vl, out[0]);
1320 out[1] = mulAdd(l, vr, out[1]);
1321 out += 2;
1322 aux[0] = mulAdd(l, va, aux[0]);
1323 aux++;
1324 } while (--frameCount);
1325 }
1326 } else {
1327 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001328 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001329 int32_t vl = t->prevVolume[0];
1330 int32_t vr = t->prevVolume[1];
1331 const int32_t vlInc = t->volumeInc[0];
1332 const int32_t vrInc = t->volumeInc[1];
1333
Steve Blockb8a80522011-12-20 16:23:08 +00001334 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001335 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1336 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1337
1338 do {
1339 int32_t l = *in++;
1340 *out++ += (vl >> 16) * l;
1341 *out++ += (vr >> 16) * l;
1342 vl += vlInc;
1343 vr += vrInc;
1344 } while (--frameCount);
1345
1346 t->prevVolume[0] = vl;
1347 t->prevVolume[1] = vr;
1348 t->adjustVolumeRamp(false);
1349 }
1350 // constant gain
1351 else {
1352 const int16_t vl = t->volume[0];
1353 const int16_t vr = t->volume[1];
1354 do {
1355 int16_t l = *in++;
1356 out[0] = mulAdd(l, vl, out[0]);
1357 out[1] = mulAdd(l, vr, out[1]);
1358 out += 2;
1359 } while (--frameCount);
1360 }
1361 }
1362 t->in = in;
1363}
1364
Mathias Agopian65ab4712010-07-14 17:59:35 -07001365// no-op case
Glenn Kastend79072e2016-01-06 08:41:20 -08001366void AudioMixer::process__nop(state_t* state)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001367{
Andy Hung296b7412014-06-17 15:25:47 -07001368 ALOGVV("process__nop\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001369 uint32_t e0 = state->enabledTracks;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001370 while (e0) {
1371 // process by group of tracks with same output buffer to
1372 // avoid multiple memset() on same buffer
1373 uint32_t e1 = e0, e2 = e0;
1374 int i = 31 - __builtin_clz(e1);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001375 {
1376 track_t& t1 = state->tracks[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001377 e2 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001378 while (e2) {
1379 i = 31 - __builtin_clz(e2);
1380 e2 &= ~(1<<i);
1381 track_t& t2 = state->tracks[i];
1382 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1383 e1 &= ~(1<<i);
1384 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001385 }
Glenn Kastenfc900c92013-02-18 12:47:49 -08001386 e0 &= ~(e1);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001387
Andy Hunge93b6b72014-07-17 21:30:53 -07001388 memset(t1.mainBuffer, 0, state->frameCount * t1.mMixerChannelCount
Andy Hung78820702014-02-28 16:23:02 -08001389 * audio_bytes_per_sample(t1.mMixerFormat));
Glenn Kastenfc900c92013-02-18 12:47:49 -08001390 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001391
1392 while (e1) {
1393 i = 31 - __builtin_clz(e1);
1394 e1 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001395 {
1396 track_t& t3 = state->tracks[i];
1397 size_t outFrames = state->frameCount;
1398 while (outFrames) {
1399 t3.buffer.frameCount = outFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001400 t3.bufferProvider->getNextBuffer(&t3.buffer);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001401 if (t3.buffer.raw == NULL) break;
1402 outFrames -= t3.buffer.frameCount;
1403 t3.bufferProvider->releaseBuffer(&t3.buffer);
1404 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001405 }
1406 }
1407 }
1408}
1409
1410// generic code without resampling
Glenn Kastend79072e2016-01-06 08:41:20 -08001411void AudioMixer::process__genericNoResampling(state_t* state)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001412{
Andy Hung296b7412014-06-17 15:25:47 -07001413 ALOGVV("process__genericNoResampling\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001414 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1415
1416 // acquire each track's buffer
1417 uint32_t enabledTracks = state->enabledTracks;
1418 uint32_t e0 = enabledTracks;
1419 while (e0) {
1420 const int i = 31 - __builtin_clz(e0);
1421 e0 &= ~(1<<i);
1422 track_t& t = state->tracks[i];
1423 t.buffer.frameCount = state->frameCount;
Glenn Kastend79072e2016-01-06 08:41:20 -08001424 t.bufferProvider->getNextBuffer(&t.buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001425 t.frameCount = t.buffer.frameCount;
1426 t.in = t.buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001427 }
1428
1429 e0 = enabledTracks;
1430 while (e0) {
1431 // process by group of tracks with same output buffer to
1432 // optimize cache use
1433 uint32_t e1 = e0, e2 = e0;
1434 int j = 31 - __builtin_clz(e1);
1435 track_t& t1 = state->tracks[j];
1436 e2 &= ~(1<<j);
1437 while (e2) {
1438 j = 31 - __builtin_clz(e2);
1439 e2 &= ~(1<<j);
1440 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001441 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001442 e1 &= ~(1<<j);
1443 }
1444 }
1445 e0 &= ~(e1);
1446 // this assumes output 16 bits stereo, no resampling
1447 int32_t *out = t1.mainBuffer;
1448 size_t numFrames = 0;
1449 do {
1450 memset(outTemp, 0, sizeof(outTemp));
1451 e2 = e1;
1452 while (e2) {
1453 const int i = 31 - __builtin_clz(e2);
1454 e2 &= ~(1<<i);
1455 track_t& t = state->tracks[i];
1456 size_t outFrames = BLOCKSIZE;
1457 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001458 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001459 aux = t.auxBuffer + numFrames;
1460 }
1461 while (outFrames) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301462 // t.in == NULL can happen if the track was flushed just after having
1463 // been enabled for mixing.
1464 if (t.in == NULL) {
1465 enabledTracks &= ~(1<<i);
1466 e1 &= ~(1<<i);
1467 break;
1468 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001469 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001470 if (inFrames > 0) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001471 t.hook(&t, outTemp + (BLOCKSIZE - outFrames) * t.mMixerChannelCount,
1472 inFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001473 t.frameCount -= inFrames;
1474 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001475 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001476 aux += inFrames;
1477 }
1478 }
1479 if (t.frameCount == 0 && outFrames) {
1480 t.bufferProvider->releaseBuffer(&t.buffer);
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001481 t.buffer.frameCount = (state->frameCount - numFrames) -
1482 (BLOCKSIZE - outFrames);
Glenn Kastend79072e2016-01-06 08:41:20 -08001483 t.bufferProvider->getNextBuffer(&t.buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001484 t.in = t.buffer.raw;
1485 if (t.in == NULL) {
1486 enabledTracks &= ~(1<<i);
1487 e1 &= ~(1<<i);
1488 break;
1489 }
1490 t.frameCount = t.buffer.frameCount;
1491 }
1492 }
1493 }
Andy Hung296b7412014-06-17 15:25:47 -07001494
1495 convertMixerFormat(out, t1.mMixerFormat, outTemp, t1.mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -07001496 BLOCKSIZE * t1.mMixerChannelCount);
Andy Hung296b7412014-06-17 15:25:47 -07001497 // TODO: fix ugly casting due to choice of out pointer type
1498 out = reinterpret_cast<int32_t*>((uint8_t*)out
Andy Hunge93b6b72014-07-17 21:30:53 -07001499 + BLOCKSIZE * t1.mMixerChannelCount
1500 * audio_bytes_per_sample(t1.mMixerFormat));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001501 numFrames += BLOCKSIZE;
1502 } while (numFrames < state->frameCount);
1503 }
1504
1505 // release each track's buffer
1506 e0 = enabledTracks;
1507 while (e0) {
1508 const int i = 31 - __builtin_clz(e0);
1509 e0 &= ~(1<<i);
1510 track_t& t = state->tracks[i];
1511 t.bufferProvider->releaseBuffer(&t.buffer);
1512 }
1513}
1514
1515
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001516// generic code with resampling
Glenn Kastend79072e2016-01-06 08:41:20 -08001517void AudioMixer::process__genericResampling(state_t* state)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001518{
Andy Hung296b7412014-06-17 15:25:47 -07001519 ALOGVV("process__genericResampling\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001520 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -07001521 int32_t* const outTemp = state->outputTemp;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001522 size_t numFrames = state->frameCount;
1523
1524 uint32_t e0 = state->enabledTracks;
1525 while (e0) {
1526 // process by group of tracks with same output buffer
1527 // to optimize cache use
1528 uint32_t e1 = e0, e2 = e0;
1529 int j = 31 - __builtin_clz(e1);
1530 track_t& t1 = state->tracks[j];
1531 e2 &= ~(1<<j);
1532 while (e2) {
1533 j = 31 - __builtin_clz(e2);
1534 e2 &= ~(1<<j);
1535 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001536 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001537 e1 &= ~(1<<j);
1538 }
1539 }
1540 e0 &= ~(e1);
1541 int32_t *out = t1.mainBuffer;
Andy Hunge93b6b72014-07-17 21:30:53 -07001542 memset(outTemp, 0, sizeof(*outTemp) * t1.mMixerChannelCount * state->frameCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001543 while (e1) {
1544 const int i = 31 - __builtin_clz(e1);
1545 e1 &= ~(1<<i);
1546 track_t& t = state->tracks[i];
1547 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001548 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001549 aux = t.auxBuffer;
1550 }
1551
1552 // this is a little goofy, on the resampling case we don't
1553 // acquire/release the buffers because it's done by
1554 // the resampler.
Glenn Kastend6fadf02013-10-30 14:37:29 -07001555 if (t.needs & NEEDS_RESAMPLE) {
Glenn Kastena1117922012-01-26 10:53:32 -08001556 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001557 } else {
1558
1559 size_t outFrames = 0;
1560
1561 while (outFrames < numFrames) {
1562 t.buffer.frameCount = numFrames - outFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001563 t.bufferProvider->getNextBuffer(&t.buffer);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001564 t.in = t.buffer.raw;
1565 // t.in == NULL can happen if the track was flushed just after having
1566 // been enabled for mixing.
1567 if (t.in == NULL) break;
1568
Glenn Kastenf6b16782011-12-15 09:51:17 -08001569 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001570 aux += outFrames;
1571 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001572 t.hook(&t, outTemp + outFrames * t.mMixerChannelCount, t.buffer.frameCount,
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001573 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001574 outFrames += t.buffer.frameCount;
1575 t.bufferProvider->releaseBuffer(&t.buffer);
1576 }
1577 }
1578 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001579 convertMixerFormat(out, t1.mMixerFormat,
1580 outTemp, t1.mMixerInFormat, numFrames * t1.mMixerChannelCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001581 }
1582}
1583
1584// one track, 16 bits stereo without resampling is the most common case
Glenn Kastend79072e2016-01-06 08:41:20 -08001585void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001586{
Andy Hung296b7412014-06-17 15:25:47 -07001587 ALOGVV("process__OneTrack16BitsStereoNoResampling\n");
Glenn Kasten99e53b82012-01-19 08:59:58 -08001588 // This method is only called when state->enabledTracks has exactly
1589 // one bit set. The asserts below would verify this, but are commented out
1590 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001591 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001592 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001593 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001594 const track_t& t = state->tracks[i];
1595
1596 AudioBufferProvider::Buffer& b(t.buffer);
1597
1598 int32_t* out = t.mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001599 float *fout = reinterpret_cast<float*>(out);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001600 size_t numFrames = state->frameCount;
1601
1602 const int16_t vl = t.volume[0];
1603 const int16_t vr = t.volume[1];
1604 const uint32_t vrl = t.volumeRL;
1605 while (numFrames) {
1606 b.frameCount = numFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001607 t.bufferProvider->getNextBuffer(&b);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001608 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001609
1610 // in == NULL can happen if the track was flushed just after having
1611 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001612 if (in == NULL || (((uintptr_t)in) & 3)) {
Jinguang Dong7c5ec032016-11-14 19:57:14 +08001613 if ( AUDIO_FORMAT_PCM_FLOAT == t.mMixerFormat ) {
1614 memset((char*)fout, 0, numFrames
1615 * t.mMixerChannelCount * audio_bytes_per_sample(t.mMixerFormat));
1616 } else {
1617 memset((char*)out, 0, numFrames
1618 * t.mMixerChannelCount * audio_bytes_per_sample(t.mMixerFormat));
1619 }
Andy Hung395db4b2014-08-25 17:15:29 -07001620 ALOGE_IF((((uintptr_t)in) & 3),
1621 "process__OneTrack16BitsStereoNoResampling: misaligned buffer"
1622 " %p track %d, channels %d, needs %08x, volume %08x vfl %f vfr %f",
1623 in, i, t.channelCount, t.needs, vrl, t.mVolume[0], t.mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001624 return;
1625 }
1626 size_t outFrames = b.frameCount;
1627
Andy Hung78820702014-02-28 16:23:02 -08001628 switch (t.mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001629 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001630 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001631 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001632 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001633 int32_t l = mulRL(1, rl, vrl);
1634 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001635 *fout++ = float_from_q4_27(l);
1636 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001637 // Note: In case of later int16_t sink output,
1638 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001639 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001640 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001641 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung97ae8242014-05-30 10:35:47 -07001642 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001643 // volume is boosted, so we might need to clamp even though
1644 // we process only one track.
1645 do {
1646 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1647 in += 2;
1648 int32_t l = mulRL(1, rl, vrl) >> 12;
1649 int32_t r = mulRL(0, rl, vrl) >> 12;
1650 // clamping...
1651 l = clamp16(l);
1652 r = clamp16(r);
1653 *out++ = (r<<16) | (l & 0xFFFF);
1654 } while (--outFrames);
1655 } else {
1656 do {
1657 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1658 in += 2;
1659 int32_t l = mulRL(1, rl, vrl) >> 12;
1660 int32_t r = mulRL(0, rl, vrl) >> 12;
1661 *out++ = (r<<16) | (l & 0xFFFF);
1662 } while (--outFrames);
1663 }
1664 break;
1665 default:
Andy Hung78820702014-02-28 16:23:02 -08001666 LOG_ALWAYS_FATAL("bad mixer format: %d", t.mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001667 }
1668 numFrames -= b.frameCount;
1669 t.bufferProvider->releaseBuffer(&b);
1670 }
1671}
1672
Glenn Kasten52008f82012-03-18 09:34:41 -07001673/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1674
1675/*static*/ void AudioMixer::sInitRoutine()
1676{
Andy Hung34803d52014-07-16 21:41:35 -07001677 DownmixerBufferProvider::init(); // for the downmixer
John Grossman4ff14ba2012-02-08 16:37:41 -08001678}
1679
Andy Hunge93b6b72014-07-17 21:30:53 -07001680/* TODO: consider whether this level of optimization is necessary.
1681 * Perhaps just stick with a single for loop.
1682 */
1683
1684// Needs to derive a compile time constant (constexpr). Could be targeted to go
1685// to a MONOVOL mixtype based on MAX_NUM_VOLUMES, but that's an unnecessary complication.
Chih-Hung Hsiehbf291732016-05-17 15:16:07 -07001686#define MIXTYPE_MONOVOL(mixtype) ((mixtype) == MIXTYPE_MULTI ? MIXTYPE_MULTI_MONOVOL : \
1687 (mixtype) == MIXTYPE_MULTI_SAVEONLY ? MIXTYPE_MULTI_SAVEONLY_MONOVOL : (mixtype))
Andy Hunge93b6b72014-07-17 21:30:53 -07001688
1689/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1690 * TO: int32_t (Q4.27) or float
1691 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1692 * TA: int32_t (Q4.27)
1693 */
1694template <int MIXTYPE,
1695 typename TO, typename TI, typename TV, typename TA, typename TAV>
1696static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
1697 const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc)
1698{
1699 switch (channels) {
1700 case 1:
1701 volumeRampMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1702 break;
1703 case 2:
1704 volumeRampMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1705 break;
1706 case 3:
1707 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out,
1708 frameCount, in, aux, vol, volinc, vola, volainc);
1709 break;
1710 case 4:
1711 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out,
1712 frameCount, in, aux, vol, volinc, vola, volainc);
1713 break;
1714 case 5:
1715 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out,
1716 frameCount, in, aux, vol, volinc, vola, volainc);
1717 break;
1718 case 6:
1719 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out,
1720 frameCount, in, aux, vol, volinc, vola, volainc);
1721 break;
1722 case 7:
1723 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out,
1724 frameCount, in, aux, vol, volinc, vola, volainc);
1725 break;
1726 case 8:
1727 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out,
1728 frameCount, in, aux, vol, volinc, vola, volainc);
1729 break;
1730 }
1731}
1732
1733/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1734 * TO: int32_t (Q4.27) or float
1735 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1736 * TA: int32_t (Q4.27)
1737 */
1738template <int MIXTYPE,
1739 typename TO, typename TI, typename TV, typename TA, typename TAV>
1740static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
1741 const TI* in, TA* aux, const TV *vol, TAV vola)
1742{
1743 switch (channels) {
1744 case 1:
1745 volumeMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, vola);
1746 break;
1747 case 2:
1748 volumeMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, vola);
1749 break;
1750 case 3:
1751 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out, frameCount, in, aux, vol, vola);
1752 break;
1753 case 4:
1754 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out, frameCount, in, aux, vol, vola);
1755 break;
1756 case 5:
1757 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out, frameCount, in, aux, vol, vola);
1758 break;
1759 case 6:
1760 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out, frameCount, in, aux, vol, vola);
1761 break;
1762 case 7:
1763 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out, frameCount, in, aux, vol, vola);
1764 break;
1765 case 8:
1766 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out, frameCount, in, aux, vol, vola);
1767 break;
1768 }
1769}
1770
1771/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1772 * USEFLOATVOL (set to true if float volume is used)
1773 * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards)
1774 * TO: int32_t (Q4.27) or float
1775 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1776 * TA: int32_t (Q4.27)
1777 */
1778template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001779 typename TO, typename TI, typename TA>
1780void AudioMixer::volumeMix(TO *out, size_t outFrames,
1781 const TI *in, TA *aux, bool ramp, AudioMixer::track_t *t)
1782{
1783 if (USEFLOATVOL) {
1784 if (ramp) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001785 volumeRampMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001786 t->mPrevVolume, t->mVolumeInc, &t->prevAuxLevel, t->auxInc);
1787 if (ADJUSTVOL) {
1788 t->adjustVolumeRamp(aux != NULL, true);
1789 }
1790 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -07001791 volumeMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001792 t->mVolume, t->auxLevel);
1793 }
1794 } else {
1795 if (ramp) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001796 volumeRampMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001797 t->prevVolume, t->volumeInc, &t->prevAuxLevel, t->auxInc);
1798 if (ADJUSTVOL) {
1799 t->adjustVolumeRamp(aux != NULL);
1800 }
1801 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -07001802 volumeMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001803 t->volume, t->auxLevel);
1804 }
1805 }
1806}
1807
Andy Hung296b7412014-06-17 15:25:47 -07001808/* This process hook is called when there is a single track without
1809 * aux buffer, volume ramp, or resampling.
1810 * TODO: Update the hook selection: this can properly handle aux and ramp.
Andy Hunge93b6b72014-07-17 21:30:53 -07001811 *
1812 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1813 * TO: int32_t (Q4.27) or float
1814 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1815 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07001816 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001817template <int MIXTYPE, typename TO, typename TI, typename TA>
Glenn Kastend79072e2016-01-06 08:41:20 -08001818void AudioMixer::process_NoResampleOneTrack(state_t* state)
Andy Hung296b7412014-06-17 15:25:47 -07001819{
1820 ALOGVV("process_NoResampleOneTrack\n");
1821 // CLZ is faster than CTZ on ARM, though really not sure if true after 31 - clz.
1822 const int i = 31 - __builtin_clz(state->enabledTracks);
1823 ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
1824 track_t *t = &state->tracks[i];
Andy Hunge93b6b72014-07-17 21:30:53 -07001825 const uint32_t channels = t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07001826 TO* out = reinterpret_cast<TO*>(t->mainBuffer);
1827 TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
1828 const bool ramp = t->needsRamp();
1829
1830 for (size_t numFrames = state->frameCount; numFrames; ) {
1831 AudioBufferProvider::Buffer& b(t->buffer);
1832 // get input buffer
1833 b.frameCount = numFrames;
Glenn Kastend79072e2016-01-06 08:41:20 -08001834 t->bufferProvider->getNextBuffer(&b);
Andy Hung296b7412014-06-17 15:25:47 -07001835 const TI *in = reinterpret_cast<TI*>(b.raw);
1836
1837 // in == NULL can happen if the track was flushed just after having
1838 // been enabled for mixing.
1839 if (in == NULL || (((uintptr_t)in) & 3)) {
1840 memset(out, 0, numFrames
Andy Hunge93b6b72014-07-17 21:30:53 -07001841 * channels * audio_bytes_per_sample(t->mMixerFormat));
Andy Hung296b7412014-06-17 15:25:47 -07001842 ALOGE_IF((((uintptr_t)in) & 3), "process_NoResampleOneTrack: bus error: "
1843 "buffer %p track %p, channels %d, needs %#x",
1844 in, t, t->channelCount, t->needs);
1845 return;
1846 }
1847
1848 const size_t outFrames = b.frameCount;
Andy Hunge93b6b72014-07-17 21:30:53 -07001849 volumeMix<MIXTYPE, is_same<TI, float>::value, false> (
1850 out, outFrames, in, aux, ramp, t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001851
Andy Hunge93b6b72014-07-17 21:30:53 -07001852 out += outFrames * channels;
Andy Hung296b7412014-06-17 15:25:47 -07001853 if (aux != NULL) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001854 aux += channels;
Andy Hung296b7412014-06-17 15:25:47 -07001855 }
1856 numFrames -= b.frameCount;
1857
1858 // release buffer
1859 t->bufferProvider->releaseBuffer(&b);
1860 }
1861 if (ramp) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001862 t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
Andy Hung296b7412014-06-17 15:25:47 -07001863 }
1864}
1865
1866/* This track hook is called to do resampling then mixing,
1867 * pulling from the track's upstream AudioBufferProvider.
Andy Hunge93b6b72014-07-17 21:30:53 -07001868 *
1869 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1870 * TO: int32_t (Q4.27) or float
1871 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1872 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07001873 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001874template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung296b7412014-06-17 15:25:47 -07001875void AudioMixer::track__Resample(track_t* t, TO* out, size_t outFrameCount, TO* temp, TA* aux)
1876{
1877 ALOGVV("track__Resample\n");
1878 t->resampler->setSampleRate(t->sampleRate);
Andy Hung296b7412014-06-17 15:25:47 -07001879 const bool ramp = t->needsRamp();
1880 if (ramp || aux != NULL) {
1881 // if ramp: resample with unity gain to temp buffer and scale/mix in 2nd step.
1882 // if aux != NULL: resample with unity gain to temp buffer then apply send level.
1883
Andy Hung5e58b0a2014-06-23 19:07:29 -07001884 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Andy Hunge93b6b72014-07-17 21:30:53 -07001885 memset(temp, 0, outFrameCount * t->mMixerChannelCount * sizeof(TO));
Andy Hung296b7412014-06-17 15:25:47 -07001886 t->resampler->resample((int32_t*)temp, outFrameCount, t->bufferProvider);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001887
Andy Hunge93b6b72014-07-17 21:30:53 -07001888 volumeMix<MIXTYPE, is_same<TI, float>::value, true>(
1889 out, outFrameCount, temp, aux, ramp, t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001890
Andy Hung296b7412014-06-17 15:25:47 -07001891 } else { // constant volume gain
Andy Hung5e58b0a2014-06-23 19:07:29 -07001892 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Andy Hung296b7412014-06-17 15:25:47 -07001893 t->resampler->resample((int32_t*)out, outFrameCount, t->bufferProvider);
1894 }
1895}
1896
1897/* This track hook is called to mix a track, when no resampling is required.
1898 * The input buffer should be present in t->in.
Andy Hunge93b6b72014-07-17 21:30:53 -07001899 *
1900 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1901 * TO: int32_t (Q4.27) or float
1902 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1903 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07001904 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001905template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung296b7412014-06-17 15:25:47 -07001906void AudioMixer::track__NoResample(track_t* t, TO* out, size_t frameCount,
1907 TO* temp __unused, TA* aux)
1908{
1909 ALOGVV("track__NoResample\n");
1910 const TI *in = static_cast<const TI *>(t->in);
1911
Andy Hunge93b6b72014-07-17 21:30:53 -07001912 volumeMix<MIXTYPE, is_same<TI, float>::value, true>(
1913 out, frameCount, in, aux, t->needsRamp(), t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001914
Andy Hung296b7412014-06-17 15:25:47 -07001915 // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
1916 // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
Andy Hunge93b6b72014-07-17 21:30:53 -07001917 in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07001918 t->in = in;
1919}
1920
1921/* The Mixer engine generates either int32_t (Q4_27) or float data.
1922 * We use this function to convert the engine buffers
1923 * to the desired mixer output format, either int16_t (Q.15) or float.
1924 */
1925void AudioMixer::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
1926 void *in, audio_format_t mixerInFormat, size_t sampleCount)
1927{
1928 switch (mixerInFormat) {
1929 case AUDIO_FORMAT_PCM_FLOAT:
1930 switch (mixerOutFormat) {
1931 case AUDIO_FORMAT_PCM_FLOAT:
1932 memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
1933 break;
1934 case AUDIO_FORMAT_PCM_16_BIT:
1935 memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
1936 break;
1937 default:
1938 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1939 break;
1940 }
1941 break;
1942 case AUDIO_FORMAT_PCM_16_BIT:
1943 switch (mixerOutFormat) {
1944 case AUDIO_FORMAT_PCM_FLOAT:
1945 memcpy_to_float_from_q4_27((float*)out, (int32_t*)in, sampleCount);
1946 break;
1947 case AUDIO_FORMAT_PCM_16_BIT:
1948 // two int16_t are produced per iteration
1949 ditherAndClamp((int32_t*)out, (int32_t*)in, sampleCount >> 1);
1950 break;
1951 default:
1952 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1953 break;
1954 }
1955 break;
1956 default:
1957 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1958 break;
1959 }
1960}
1961
1962/* Returns the proper track hook to use for mixing the track into the output buffer.
1963 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001964AudioMixer::hook_t AudioMixer::getTrackHook(int trackType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001965 audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
1966{
Andy Hunge93b6b72014-07-17 21:30:53 -07001967 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07001968 switch (trackType) {
1969 case TRACKTYPE_NOP:
1970 return track__nop;
1971 case TRACKTYPE_RESAMPLE:
1972 return track__genericResample;
1973 case TRACKTYPE_NORESAMPLEMONO:
1974 return track__16BitsMono;
1975 case TRACKTYPE_NORESAMPLE:
1976 return track__16BitsStereo;
1977 default:
1978 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1979 break;
1980 }
1981 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001982 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07001983 switch (trackType) {
1984 case TRACKTYPE_NOP:
1985 return track__nop;
1986 case TRACKTYPE_RESAMPLE:
1987 switch (mixerInFormat) {
1988 case AUDIO_FORMAT_PCM_FLOAT:
1989 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07001990 track__Resample<MIXTYPE_MULTI, float /*TO*/, float /*TI*/, int32_t /*TA*/>;
Andy Hung296b7412014-06-17 15:25:47 -07001991 case AUDIO_FORMAT_PCM_16_BIT:
1992 return (AudioMixer::hook_t)\
Andy Hunge93b6b72014-07-17 21:30:53 -07001993 track__Resample<MIXTYPE_MULTI, int32_t, int16_t, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07001994 default:
1995 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1996 break;
1997 }
1998 break;
1999 case TRACKTYPE_NORESAMPLEMONO:
2000 switch (mixerInFormat) {
2001 case AUDIO_FORMAT_PCM_FLOAT:
2002 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07002003 track__NoResample<MIXTYPE_MONOEXPAND, float, float, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07002004 case AUDIO_FORMAT_PCM_16_BIT:
2005 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07002006 track__NoResample<MIXTYPE_MONOEXPAND, int32_t, int16_t, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07002007 default:
2008 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2009 break;
2010 }
2011 break;
2012 case TRACKTYPE_NORESAMPLE:
2013 switch (mixerInFormat) {
2014 case AUDIO_FORMAT_PCM_FLOAT:
2015 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07002016 track__NoResample<MIXTYPE_MULTI, float, float, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07002017 case AUDIO_FORMAT_PCM_16_BIT:
2018 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07002019 track__NoResample<MIXTYPE_MULTI, int32_t, int16_t, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07002020 default:
2021 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2022 break;
2023 }
2024 break;
2025 default:
2026 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
2027 break;
2028 }
2029 return NULL;
2030}
2031
2032/* Returns the proper process hook for mixing tracks. Currently works only for
2033 * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
Andy Hung395db4b2014-08-25 17:15:29 -07002034 *
2035 * TODO: Due to the special mixing considerations of duplicating to
2036 * a stereo output track, the input track cannot be MONO. This should be
2037 * prevented by the caller.
Andy Hung296b7412014-06-17 15:25:47 -07002038 */
Andy Hunge93b6b72014-07-17 21:30:53 -07002039AudioMixer::process_hook_t AudioMixer::getProcessHook(int processType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07002040 audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
2041{
2042 if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
2043 LOG_ALWAYS_FATAL("bad processType: %d", processType);
2044 return NULL;
2045 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002046 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07002047 return process__OneTrack16BitsStereoNoResampling;
2048 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002049 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07002050 switch (mixerInFormat) {
2051 case AUDIO_FORMAT_PCM_FLOAT:
2052 switch (mixerOutFormat) {
2053 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002054 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
2055 float /*TO*/, float /*TI*/, int32_t /*TA*/>;
Andy Hung296b7412014-06-17 15:25:47 -07002056 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002057 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
Andy Hung296b7412014-06-17 15:25:47 -07002058 int16_t, float, int32_t>;
2059 default:
2060 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2061 break;
2062 }
2063 break;
2064 case AUDIO_FORMAT_PCM_16_BIT:
2065 switch (mixerOutFormat) {
2066 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002067 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
Andy Hung296b7412014-06-17 15:25:47 -07002068 float, int16_t, int32_t>;
2069 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002070 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
Andy Hung296b7412014-06-17 15:25:47 -07002071 int16_t, int16_t, int32_t>;
2072 default:
2073 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2074 break;
2075 }
2076 break;
2077 default:
2078 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2079 break;
2080 }
2081 return NULL;
2082}
2083
Mathias Agopian65ab4712010-07-14 17:59:35 -07002084// ----------------------------------------------------------------------------
Glenn Kasten63238ef2015-03-02 15:50:29 -08002085} // namespace android