blob: 1348d088c6715d91afa85bce6b04d2ba1249eeff [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
Glenn Kasten153b9fe2013-07-15 11:23:36 -070021#include "Configuration.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070022#include <stdint.h>
23#include <string.h>
24#include <stdlib.h>
Andy Hung5e58b0a2014-06-23 19:07:29 -070025#include <math.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070026#include <sys/types.h>
27
28#include <utils/Errors.h>
29#include <utils/Log.h>
30
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070031#include <cutils/bitops.h>
Glenn Kastenf6b16782011-12-15 09:51:17 -080032#include <cutils/compiler.h>
Glenn Kasten5798d4e2012-03-08 12:18:35 -080033#include <utils/Debug.h>
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070034
35#include <system/audio.h>
36
Glenn Kasten3b21c502011-12-15 09:52:39 -080037#include <audio_utils/primitives.h>
Andy Hungef7c7fb2014-05-12 16:51:41 -070038#include <audio_utils/format.h>
John Grossman4ff14ba2012-02-08 16:37:41 -080039#include <common_time/local_clock.h>
40#include <common_time/cc_helper.h>
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070041
Andy Hung296b7412014-06-17 15:25:47 -070042#include "AudioMixerOps.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070043#include "AudioMixer.h"
44
Andy Hunge93b6b72014-07-17 21:30:53 -070045// The FCC_2 macro refers to the Fixed Channel Count of 2 for the legacy integer mixer.
Andy Hung296b7412014-06-17 15:25:47 -070046#ifndef FCC_2
47#define FCC_2 2
48#endif
49
Andy Hunge93b6b72014-07-17 21:30:53 -070050// Look for MONO_HACK for any Mono hack involving legacy mono channel to
51// stereo channel conversion.
52
Andy Hung296b7412014-06-17 15:25:47 -070053/* VERY_VERY_VERBOSE_LOGGING will show exactly which process hook and track hook is
54 * being used. This is a considerable amount of log spam, so don't enable unless you
55 * are verifying the hook based code.
56 */
57//#define VERY_VERY_VERBOSE_LOGGING
58#ifdef VERY_VERY_VERBOSE_LOGGING
59#define ALOGVV ALOGV
60//define ALOGVV printf // for test-mixer.cpp
61#else
62#define ALOGVV(a...) do { } while (0)
63#endif
64
Andy Hunga08810b2014-07-16 21:53:43 -070065#ifndef ARRAY_SIZE
66#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
67#endif
68
Andy Hung5b8fde72014-09-02 21:14:34 -070069// Set kUseNewMixer to true to use the new mixer engine always. Otherwise the
70// original code will be used for stereo sinks, the new mixer for multichannel.
71static const bool kUseNewMixer = true;
Andy Hung296b7412014-06-17 15:25:47 -070072
73// Set kUseFloat to true to allow floating input into the mixer engine.
74// If kUseNewMixer is false, this is ignored or may be overridden internally
75// because of downmix/upmix support.
76static const bool kUseFloat = true;
77
Andy Hung1b2fdcb2014-07-16 17:44:34 -070078// Set to default copy buffer size in frames for input processing.
79static const size_t kCopyBufferFrameCount = 256;
80
Mathias Agopian65ab4712010-07-14 17:59:35 -070081namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070082
83// ----------------------------------------------------------------------------
Andy Hung1b2fdcb2014-07-16 17:44:34 -070084
85template <typename T>
86T min(const T& a, const T& b)
87{
88 return a < b ? a : b;
89}
90
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070091// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -070092
Paul Lind3c0a0e82012-08-01 18:49:49 -070093// Ensure mConfiguredNames bitmask is initialized properly on all architectures.
94// The value of 1 << x is undefined in C when x >= 32.
95
Glenn Kasten5c94b6c2012-03-20 17:01:29 -070096AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks)
Paul Lind3c0a0e82012-08-01 18:49:49 -070097 : mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1),
Glenn Kasten7f5d3352013-02-15 23:55:04 +000098 mSampleRate(sampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -070099{
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700100 ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
101 maxNumTracks, MAX_NUM_TRACKS);
102
Glenn Kasten599fabc2012-03-08 12:33:37 -0800103 // AudioMixer is not yet capable of more than 32 active track inputs
104 ALOG_ASSERT(32 >= MAX_NUM_TRACKS, "bad MAX_NUM_TRACKS %d", MAX_NUM_TRACKS);
105
Glenn Kasten52008f82012-03-18 09:34:41 -0700106 pthread_once(&sOnceControl, &sInitRoutine);
107
Mathias Agopian65ab4712010-07-14 17:59:35 -0700108 mState.enabledTracks= 0;
109 mState.needsChanged = 0;
110 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800111 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -0800112 mState.outputTemp = NULL;
113 mState.resampleTemp = NULL;
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800114 mState.mLog = &mDummyLog;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800115 // mState.reserved
Glenn Kasten17a736c2012-02-14 08:52:15 -0800116
117 // FIXME Most of the following initialization is probably redundant since
118 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
119 // and mTrackNames is initially 0. However, leave it here until that's verified.
Mathias Agopian65ab4712010-07-14 17:59:35 -0700120 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800121 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Eric Laurenta5e82142012-04-16 13:47:17 -0700122 t->resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700123 t->downmixerBufferProvider = NULL;
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700124 t->mReformatBufferProvider = NULL;
Andy Hungc5656cc2015-03-26 19:04:33 -0700125 t->mTimestretchBufferProvider = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700126 t++;
127 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700128
Mathias Agopian65ab4712010-07-14 17:59:35 -0700129}
130
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800131AudioMixer::~AudioMixer()
132{
133 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800134 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800135 delete t->resampler;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700136 delete t->downmixerBufferProvider;
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700137 delete t->mReformatBufferProvider;
Andy Hungc5656cc2015-03-26 19:04:33 -0700138 delete t->mTimestretchBufferProvider;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800139 t++;
140 }
141 delete [] mState.outputTemp;
142 delete [] mState.resampleTemp;
143}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700144
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800145void AudioMixer::setLog(NBLog::Writer *log)
146{
147 mState.mLog = log;
148}
149
Andy Hung7f475492014-08-25 16:36:37 -0700150static inline audio_format_t selectMixerInFormat(audio_format_t inputFormat __unused) {
151 return kUseFloat && kUseNewMixer ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
152}
153
Andy Hunge8a1ced2014-05-09 15:02:21 -0700154int AudioMixer::getTrackName(audio_channel_mask_t channelMask,
155 audio_format_t format, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800156{
Andy Hunge8a1ced2014-05-09 15:02:21 -0700157 if (!isValidPcmTrackFormat(format)) {
158 ALOGE("AudioMixer::getTrackName invalid format (%#x)", format);
159 return -1;
160 }
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700161 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800162 if (names != 0) {
163 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100164 ALOGV("add track (%d)", n);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700165 // assume default parameters for the track, except where noted below
166 track_t* t = &mState.tracks[n];
167 t->needs = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700168
169 // Integer volume.
170 // Currently integer volume is kept for the legacy integer mixer.
171 // Will be removed when the legacy mixer path is removed.
Andy Hung97ae8242014-05-30 10:35:47 -0700172 t->volume[0] = UNITY_GAIN_INT;
173 t->volume[1] = UNITY_GAIN_INT;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700174 t->prevVolume[0] = UNITY_GAIN_INT << 16;
175 t->prevVolume[1] = UNITY_GAIN_INT << 16;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700176 t->volumeInc[0] = 0;
177 t->volumeInc[1] = 0;
178 t->auxLevel = 0;
179 t->auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700180 t->prevAuxLevel = 0;
181
182 // Floating point volume.
183 t->mVolume[0] = UNITY_GAIN_FLOAT;
184 t->mVolume[1] = UNITY_GAIN_FLOAT;
185 t->mPrevVolume[0] = UNITY_GAIN_FLOAT;
186 t->mPrevVolume[1] = UNITY_GAIN_FLOAT;
187 t->mVolumeInc[0] = 0.;
188 t->mVolumeInc[1] = 0.;
189 t->mAuxLevel = 0.;
190 t->mAuxInc = 0.;
191 t->mPrevAuxLevel = 0.;
192
Glenn Kastendeeb1282012-03-25 11:59:31 -0700193 // no initialization needed
Glenn Kastendeeb1282012-03-25 11:59:31 -0700194 // t->frameCount
Andy Hung68112fc2014-05-14 14:13:23 -0700195 t->channelCount = audio_channel_count_from_out_mask(channelMask);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700196 t->enabled = false;
Andy Hunge93b6b72014-07-17 21:30:53 -0700197 ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
Andy Hungef7c7fb2014-05-12 16:51:41 -0700198 "Non-stereo channel mask: %d\n", channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700199 t->channelMask = channelMask;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700200 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700201 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
202 t->bufferProvider = NULL;
203 t->buffer.raw = NULL;
204 // no initialization needed
205 // t->buffer.frameCount
206 t->hook = NULL;
207 t->in = NULL;
208 t->resampler = NULL;
209 t->sampleRate = mSampleRate;
210 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
211 t->mainBuffer = NULL;
212 t->auxBuffer = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700213 t->mInputBufferProvider = NULL;
214 t->mReformatBufferProvider = NULL;
Glenn Kasten52008f82012-03-18 09:34:41 -0700215 t->downmixerBufferProvider = NULL;
Andy Hung7f475492014-08-25 16:36:37 -0700216 t->mPostDownmixReformatBufferProvider = NULL;
Andy Hungc5656cc2015-03-26 19:04:33 -0700217 t->mTimestretchBufferProvider = NULL;
Andy Hung78820702014-02-28 16:23:02 -0800218 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700219 t->mFormat = format;
Andy Hung7f475492014-08-25 16:36:37 -0700220 t->mMixerInFormat = selectMixerInFormat(format);
221 t->mDownmixRequiresFormat = AUDIO_FORMAT_INVALID; // no format required
Andy Hunge93b6b72014-07-17 21:30:53 -0700222 t->mMixerChannelMask = audio_channel_mask_from_representation_and_bits(
223 AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
224 t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700225 t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
Andy Hung296b7412014-06-17 15:25:47 -0700226 // Check the downmixing (or upmixing) requirements.
Andy Hung0f451e92014-08-04 21:28:47 -0700227 status_t status = t->prepareForDownmix();
Andy Hung68112fc2014-05-14 14:13:23 -0700228 if (status != OK) {
229 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
230 return -1;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700231 }
Andy Hung7f475492014-08-25 16:36:37 -0700232 // prepareForDownmix() may change mDownmixRequiresFormat
Andy Hung296b7412014-06-17 15:25:47 -0700233 ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
Andy Hung0f451e92014-08-04 21:28:47 -0700234 t->prepareForReformat();
Andy Hung68112fc2014-05-14 14:13:23 -0700235 mTrackNames |= 1 << n;
236 return TRACK0 + n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700237 }
Andy Hung68112fc2014-05-14 14:13:23 -0700238 ALOGE("AudioMixer::getTrackName out of available tracks");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700239 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800240}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700241
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800242void AudioMixer::invalidateState(uint32_t mask)
243{
Glenn Kasten34fca342013-08-13 09:48:14 -0700244 if (mask != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700245 mState.needsChanged |= mask;
246 mState.hook = process__validate;
247 }
248 }
249
Andy Hunge93b6b72014-07-17 21:30:53 -0700250// Called when channel masks have changed for a track name
Andy Hung7f475492014-08-25 16:36:37 -0700251// TODO: Fix DownmixerBufferProvider not to (possibly) change mixer input format,
Andy Hunge93b6b72014-07-17 21:30:53 -0700252// which will simplify this logic.
253bool AudioMixer::setChannelMasks(int name,
254 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) {
255 track_t &track = mState.tracks[name];
256
257 if (trackChannelMask == track.channelMask
258 && mixerChannelMask == track.mMixerChannelMask) {
259 return false; // no need to change
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700260 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700261 // always recompute for both channel masks even if only one has changed.
262 const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
263 const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
264 const bool mixerChannelCountChanged = track.mMixerChannelCount != mixerChannelCount;
265
266 ALOG_ASSERT((trackChannelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX)
267 && trackChannelCount
268 && mixerChannelCount);
269 track.channelMask = trackChannelMask;
270 track.channelCount = trackChannelCount;
271 track.mMixerChannelMask = mixerChannelMask;
272 track.mMixerChannelCount = mixerChannelCount;
273
274 // channel masks have changed, does this track need a downmixer?
275 // update to try using our desired format (if we aren't already using it)
Andy Hung7f475492014-08-25 16:36:37 -0700276 const audio_format_t prevDownmixerFormat = track.mDownmixRequiresFormat;
Andy Hung0f451e92014-08-04 21:28:47 -0700277 const status_t status = mState.tracks[name].prepareForDownmix();
Andy Hunge93b6b72014-07-17 21:30:53 -0700278 ALOGE_IF(status != OK,
Andy Hung0f451e92014-08-04 21:28:47 -0700279 "prepareForDownmix error %d, track channel mask %#x, mixer channel mask %#x",
Andy Hunge93b6b72014-07-17 21:30:53 -0700280 status, track.channelMask, track.mMixerChannelMask);
281
Andy Hung7f475492014-08-25 16:36:37 -0700282 if (prevDownmixerFormat != track.mDownmixRequiresFormat) {
Andy Hung0f451e92014-08-04 21:28:47 -0700283 track.prepareForReformat(); // because of downmixer, track format may change!
Andy Hunge93b6b72014-07-17 21:30:53 -0700284 }
285
Andy Hung7f475492014-08-25 16:36:37 -0700286 if (track.resampler && mixerChannelCountChanged) {
287 // resampler channels may have changed.
Andy Hunge93b6b72014-07-17 21:30:53 -0700288 const uint32_t resetToSampleRate = track.sampleRate;
289 delete track.resampler;
290 track.resampler = NULL;
291 track.sampleRate = mSampleRate; // without resampler, track rate is device sample rate.
292 // recreate the resampler with updated format, channels, saved sampleRate.
293 track.setResampler(resetToSampleRate /*trackSampleRate*/, mSampleRate /*devSampleRate*/);
294 }
295 return true;
296}
297
Andy Hung0f451e92014-08-04 21:28:47 -0700298void AudioMixer::track_t::unprepareForDownmix() {
299 ALOGV("AudioMixer::unprepareForDownmix(%p)", this);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700300
Andy Hung7f475492014-08-25 16:36:37 -0700301 mDownmixRequiresFormat = AUDIO_FORMAT_INVALID;
Andy Hung0f451e92014-08-04 21:28:47 -0700302 if (downmixerBufferProvider != NULL) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700303 // this track had previously been configured with a downmixer, delete it
304 ALOGV(" deleting old downmixer");
Andy Hung0f451e92014-08-04 21:28:47 -0700305 delete downmixerBufferProvider;
306 downmixerBufferProvider = NULL;
307 reconfigureBufferProviders();
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700308 } else {
309 ALOGV(" nothing to do, no downmixer to delete");
310 }
311}
312
Andy Hung0f451e92014-08-04 21:28:47 -0700313status_t AudioMixer::track_t::prepareForDownmix()
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700314{
Andy Hung0f451e92014-08-04 21:28:47 -0700315 ALOGV("AudioMixer::prepareForDownmix(%p) with mask 0x%x",
316 this, channelMask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700317
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700318 // discard the previous downmixer if there was one
Andy Hung0f451e92014-08-04 21:28:47 -0700319 unprepareForDownmix();
Andy Hung73e62e22015-04-20 12:06:38 -0700320 // MONO_HACK Only remix (upmix or downmix) if the track and mixer/device channel masks
Andy Hung0f451e92014-08-04 21:28:47 -0700321 // are not the same and not handled internally, as mono -> stereo currently is.
322 if (channelMask == mMixerChannelMask
323 || (channelMask == AUDIO_CHANNEL_OUT_MONO
324 && mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO)) {
325 return NO_ERROR;
326 }
Andy Hung650ceb92015-01-29 13:31:12 -0800327 // DownmixerBufferProvider is only used for position masks.
328 if (audio_channel_mask_get_representation(channelMask)
329 == AUDIO_CHANNEL_REPRESENTATION_POSITION
330 && DownmixerBufferProvider::isMultichannelCapable()) {
Andy Hung0f451e92014-08-04 21:28:47 -0700331 DownmixerBufferProvider* pDbp = new DownmixerBufferProvider(channelMask,
332 mMixerChannelMask,
333 AUDIO_FORMAT_PCM_16_BIT /* TODO: use mMixerInFormat, now only PCM 16 */,
334 sampleRate, sessionId, kCopyBufferFrameCount);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700335
Andy Hung34803d52014-07-16 21:41:35 -0700336 if (pDbp->isValid()) { // if constructor completed properly
Andy Hung7f475492014-08-25 16:36:37 -0700337 mDownmixRequiresFormat = AUDIO_FORMAT_PCM_16_BIT; // PCM 16 bit required for downmix
Andy Hung0f451e92014-08-04 21:28:47 -0700338 downmixerBufferProvider = pDbp;
339 reconfigureBufferProviders();
Andy Hung34803d52014-07-16 21:41:35 -0700340 return NO_ERROR;
341 }
342 delete pDbp;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700343 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700344
345 // Effect downmixer does not accept the channel conversion. Let's use our remixer.
Andy Hung0f451e92014-08-04 21:28:47 -0700346 RemixBufferProvider* pRbp = new RemixBufferProvider(channelMask,
347 mMixerChannelMask, mMixerInFormat, kCopyBufferFrameCount);
Andy Hunge93b6b72014-07-17 21:30:53 -0700348 // Remix always finds a conversion whereas Downmixer effect above may fail.
Andy Hung0f451e92014-08-04 21:28:47 -0700349 downmixerBufferProvider = pRbp;
350 reconfigureBufferProviders();
Andy Hunge93b6b72014-07-17 21:30:53 -0700351 return NO_ERROR;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700352}
353
Andy Hung0f451e92014-08-04 21:28:47 -0700354void AudioMixer::track_t::unprepareForReformat() {
355 ALOGV("AudioMixer::unprepareForReformat(%p)", this);
Andy Hung7f475492014-08-25 16:36:37 -0700356 bool requiresReconfigure = false;
Andy Hung0f451e92014-08-04 21:28:47 -0700357 if (mReformatBufferProvider != NULL) {
358 delete mReformatBufferProvider;
359 mReformatBufferProvider = NULL;
Andy Hung7f475492014-08-25 16:36:37 -0700360 requiresReconfigure = true;
361 }
362 if (mPostDownmixReformatBufferProvider != NULL) {
363 delete mPostDownmixReformatBufferProvider;
364 mPostDownmixReformatBufferProvider = NULL;
365 requiresReconfigure = true;
366 }
367 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700368 reconfigureBufferProviders();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700369 }
370}
371
Andy Hung0f451e92014-08-04 21:28:47 -0700372status_t AudioMixer::track_t::prepareForReformat()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700373{
Andy Hung0f451e92014-08-04 21:28:47 -0700374 ALOGV("AudioMixer::prepareForReformat(%p) with format %#x", this, mFormat);
Andy Hung7f475492014-08-25 16:36:37 -0700375 // discard previous reformatters
Andy Hung0f451e92014-08-04 21:28:47 -0700376 unprepareForReformat();
Andy Hung7f475492014-08-25 16:36:37 -0700377 // only configure reformatters as needed
378 const audio_format_t targetFormat = mDownmixRequiresFormat != AUDIO_FORMAT_INVALID
379 ? mDownmixRequiresFormat : mMixerInFormat;
380 bool requiresReconfigure = false;
381 if (mFormat != targetFormat) {
Andy Hung0f451e92014-08-04 21:28:47 -0700382 mReformatBufferProvider = new ReformatBufferProvider(
383 audio_channel_count_from_out_mask(channelMask),
Andy Hung7f475492014-08-25 16:36:37 -0700384 mFormat,
385 targetFormat,
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700386 kCopyBufferFrameCount);
Andy Hung7f475492014-08-25 16:36:37 -0700387 requiresReconfigure = true;
388 }
389 if (targetFormat != mMixerInFormat) {
390 mPostDownmixReformatBufferProvider = new ReformatBufferProvider(
391 audio_channel_count_from_out_mask(mMixerChannelMask),
392 targetFormat,
393 mMixerInFormat,
394 kCopyBufferFrameCount);
395 requiresReconfigure = true;
396 }
397 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700398 reconfigureBufferProviders();
Andy Hung296b7412014-06-17 15:25:47 -0700399 }
400 return NO_ERROR;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700401}
402
Andy Hung0f451e92014-08-04 21:28:47 -0700403void AudioMixer::track_t::reconfigureBufferProviders()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700404{
Andy Hung0f451e92014-08-04 21:28:47 -0700405 bufferProvider = mInputBufferProvider;
406 if (mReformatBufferProvider) {
407 mReformatBufferProvider->setBufferProvider(bufferProvider);
408 bufferProvider = mReformatBufferProvider;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700409 }
Andy Hung0f451e92014-08-04 21:28:47 -0700410 if (downmixerBufferProvider) {
411 downmixerBufferProvider->setBufferProvider(bufferProvider);
412 bufferProvider = downmixerBufferProvider;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700413 }
Andy Hung7f475492014-08-25 16:36:37 -0700414 if (mPostDownmixReformatBufferProvider) {
415 mPostDownmixReformatBufferProvider->setBufferProvider(bufferProvider);
416 bufferProvider = mPostDownmixReformatBufferProvider;
417 }
Andy Hungc5656cc2015-03-26 19:04:33 -0700418 if (mTimestretchBufferProvider) {
419 mTimestretchBufferProvider->setBufferProvider(bufferProvider);
420 bufferProvider = mTimestretchBufferProvider;
421 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700422}
423
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800424void AudioMixer::deleteTrackName(int name)
425{
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700426 ALOGV("AudioMixer::deleteTrackName(%d)", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700427 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800428 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800429 ALOGV("deleteTrackName(%d)", name);
430 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800431 if (track.enabled) {
432 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800433 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700434 }
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700435 // delete the resampler
436 delete track.resampler;
437 track.resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700438 // delete the downmixer
Andy Hung0f451e92014-08-04 21:28:47 -0700439 mState.tracks[name].unprepareForDownmix();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700440 // delete the reformatter
Andy Hung0f451e92014-08-04 21:28:47 -0700441 mState.tracks[name].unprepareForReformat();
Andy Hungc5656cc2015-03-26 19:04:33 -0700442 // delete the timestretch provider
443 delete track.mTimestretchBufferProvider;
444 track.mTimestretchBufferProvider = NULL;
Glenn Kasten237a6242011-12-15 15:32:27 -0800445 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800446}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700447
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800448void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700449{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800450 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800451 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800452 track_t& track = mState.tracks[name];
453
Glenn Kasten4c340c62012-01-27 12:33:54 -0800454 if (!track.enabled) {
455 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800456 ALOGV("enable(%d)", name);
457 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700458 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700459}
460
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800461void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700462{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800463 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800464 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800465 track_t& track = mState.tracks[name];
466
Glenn Kasten4c340c62012-01-27 12:33:54 -0800467 if (track.enabled) {
468 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800469 ALOGV("disable(%d)", name);
470 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700471 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700472}
473
Andy Hung5866a3b2014-05-29 21:33:13 -0700474/* Sets the volume ramp variables for the AudioMixer.
475 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700476 * The volume ramp variables are used to transition from the previous
477 * volume to the set volume. ramp controls the duration of the transition.
478 * Its value is typically one state framecount period, but may also be 0,
479 * meaning "immediate."
Andy Hung5866a3b2014-05-29 21:33:13 -0700480 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700481 * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
482 * even if there is a nonzero floating point increment (in that case, the volume
483 * change is immediate). This restriction should be changed when the legacy mixer
484 * is removed (see #2).
485 * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
486 * when no longer needed.
487 *
488 * @param newVolume set volume target in floating point [0.0, 1.0].
489 * @param ramp number of frames to increment over. if ramp is 0, the volume
490 * should be set immediately. Currently ramp should not exceed 65535 (frames).
491 * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
492 * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
493 * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
494 * @param pSetVolume pointer to the float target volume, set on return.
495 * @param pPrevVolume pointer to the float previous volume, set on return.
496 * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
Andy Hung5866a3b2014-05-29 21:33:13 -0700497 * @return true if the volume has changed, false if volume is same.
498 */
Andy Hung5e58b0a2014-06-23 19:07:29 -0700499static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
500 int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
501 float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
502 if (newVolume == *pSetVolume) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700503 return false;
504 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700505 /* set the floating point volume variables */
Andy Hung5866a3b2014-05-29 21:33:13 -0700506 if (ramp != 0) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700507 *pVolumeInc = (newVolume - *pSetVolume) / ramp;
508 *pPrevVolume = *pSetVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700509 } else {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700510 *pVolumeInc = 0;
511 *pPrevVolume = newVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700512 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700513 *pSetVolume = newVolume;
514
515 /* set the legacy integer volume variables */
516 int32_t intVolume = newVolume * AudioMixer::UNITY_GAIN_INT;
517 if (intVolume > AudioMixer::UNITY_GAIN_INT) {
518 intVolume = AudioMixer::UNITY_GAIN_INT;
519 } else if (intVolume < 0) {
520 ALOGE("negative volume %.7g", newVolume);
521 intVolume = 0; // should never happen, but for safety check.
522 }
523 if (intVolume == *pIntSetVolume) {
524 *pIntVolumeInc = 0;
525 /* TODO: integer/float workaround: ignore floating volume ramp */
526 *pVolumeInc = 0;
527 *pPrevVolume = newVolume;
528 return true;
529 }
530 if (ramp != 0) {
531 *pIntVolumeInc = ((intVolume - *pIntSetVolume) << 16) / ramp;
532 *pIntPrevVolume = (*pIntVolumeInc == 0 ? intVolume : *pIntSetVolume) << 16;
533 } else {
534 *pIntVolumeInc = 0;
535 *pIntPrevVolume = intVolume << 16;
536 }
537 *pIntSetVolume = intVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700538 return true;
539}
540
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800541void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700542{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800543 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800544 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800545 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700546
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000547 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
548 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700549
550 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700551
Mathias Agopian65ab4712010-07-14 17:59:35 -0700552 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800553 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700554 case CHANNEL_MASK: {
Andy Hunge93b6b72014-07-17 21:30:53 -0700555 const audio_channel_mask_t trackChannelMask =
556 static_cast<audio_channel_mask_t>(valueInt);
557 if (setChannelMasks(name, trackChannelMask, track.mMixerChannelMask)) {
558 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800559 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700560 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700561 } break;
562 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800563 if (track.mainBuffer != valueBuf) {
564 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100565 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800566 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700567 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700568 break;
569 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800570 if (track.auxBuffer != valueBuf) {
571 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100572 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800573 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700574 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700575 break;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700576 case FORMAT: {
577 audio_format_t format = static_cast<audio_format_t>(valueInt);
578 if (track.mFormat != format) {
579 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
580 track.mFormat = format;
581 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
Andy Hung0f451e92014-08-04 21:28:47 -0700582 track.prepareForReformat();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700583 invalidateState(1 << name);
584 }
585 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700586 // FIXME do we want to support setting the downmix type from AudioFlinger?
587 // for a specific track? or per mixer?
588 /* case DOWNMIX_TYPE:
589 break */
Andy Hung78820702014-02-28 16:23:02 -0800590 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800591 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung78820702014-02-28 16:23:02 -0800592 if (track.mMixerFormat != format) {
593 track.mMixerFormat = format;
594 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800595 }
596 } break;
Andy Hunge93b6b72014-07-17 21:30:53 -0700597 case MIXER_CHANNEL_MASK: {
598 const audio_channel_mask_t mixerChannelMask =
599 static_cast<audio_channel_mask_t>(valueInt);
600 if (setChannelMasks(name, track.channelMask, mixerChannelMask)) {
601 ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
602 invalidateState(1 << name);
603 }
604 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700605 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800606 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700607 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700608 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700609
Mathias Agopian65ab4712010-07-14 17:59:35 -0700610 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800611 switch (param) {
612 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800613 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700614 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
615 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
616 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800617 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700618 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800619 break;
620 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800621 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800622 invalidateState(1 << name);
623 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700624 case REMOVE:
625 delete track.resampler;
626 track.resampler = NULL;
627 track.sampleRate = mSampleRate;
628 invalidateState(1 << name);
629 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700630 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800631 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800632 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700633 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700634
Mathias Agopian65ab4712010-07-14 17:59:35 -0700635 case RAMP_VOLUME:
636 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800637 switch (param) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800638 case AUXLEVEL:
Andy Hung6be49402014-05-30 10:42:03 -0700639 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung5866a3b2014-05-29 21:33:13 -0700640 target == RAMP_VOLUME ? mState.frameCount : 0,
Andy Hung5e58b0a2014-06-23 19:07:29 -0700641 &track.auxLevel, &track.prevAuxLevel, &track.auxInc,
642 &track.mAuxLevel, &track.mPrevAuxLevel, &track.mAuxInc)) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700643 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
Andy Hung6be49402014-05-30 10:42:03 -0700644 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track.auxLevel);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800645 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700646 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800647 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700648 default:
Andy Hunge93b6b72014-07-17 21:30:53 -0700649 if ((unsigned)param >= VOLUME0 && (unsigned)param < VOLUME0 + MAX_NUM_VOLUMES) {
650 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
651 target == RAMP_VOLUME ? mState.frameCount : 0,
652 &track.volume[param - VOLUME0], &track.prevVolume[param - VOLUME0],
653 &track.volumeInc[param - VOLUME0],
654 &track.mVolume[param - VOLUME0], &track.mPrevVolume[param - VOLUME0],
655 &track.mVolumeInc[param - VOLUME0])) {
656 ALOGV("setParameter(%s, VOLUME%d: %04x)",
657 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
658 track.volume[param - VOLUME0]);
659 invalidateState(1 << name);
660 }
661 } else {
662 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
663 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700664 }
665 break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700666 case TIMESTRETCH:
667 switch (param) {
668 case PLAYBACK_RATE: {
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700669 const AudioPlaybackRate *playbackRate =
670 reinterpret_cast<AudioPlaybackRate*>(value);
671 ALOG_ASSERT(AUDIO_TIMESTRETCH_SPEED_MIN <= playbackRate->mSpeed
672 && playbackRate->mSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX,
673 "bad speed %f", playbackRate->mSpeed);
674 ALOG_ASSERT(AUDIO_TIMESTRETCH_PITCH_MIN <= playbackRate->mPitch
675 && playbackRate->mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX,
676 "bad pitch %f", playbackRate->mPitch);
677 //TODO: use function from AudioResamplerPublic.h to test validity.
678 if (track.setPlaybackRate(*playbackRate)) {
679 ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE "
680 "%f %f %d %d",
681 playbackRate->mSpeed,
682 playbackRate->mPitch,
683 playbackRate->mStretchMode,
684 playbackRate->mFallbackMode);
Andy Hungc5656cc2015-03-26 19:04:33 -0700685 // invalidateState(1 << name);
686 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700687 } break;
Andy Hungc5656cc2015-03-26 19:04:33 -0700688 default:
689 LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);
690 }
691 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700692
693 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800694 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700695 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700696}
697
Andy Hunge93b6b72014-07-17 21:30:53 -0700698bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700699{
Andy Hunge93b6b72014-07-17 21:30:53 -0700700 if (trackSampleRate != devSampleRate || resampler != NULL) {
701 if (sampleRate != trackSampleRate) {
702 sampleRate = trackSampleRate;
Glenn Kastene0feee32011-12-13 11:53:26 -0800703 if (resampler == NULL) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700704 ALOGV("Creating resampler from track %d Hz to device %d Hz",
705 trackSampleRate, devSampleRate);
Glenn Kastenac602052012-10-01 14:04:31 -0700706 AudioResampler::src_quality quality;
707 // force lowest quality level resampler if use case isn't music or video
708 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
709 // quality level based on the initial ratio, but that could change later.
710 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
Andy Hungdb4c0312015-05-06 08:46:52 -0700711 if (isMusicRate(trackSampleRate)) {
Glenn Kastenac602052012-10-01 14:04:31 -0700712 quality = AudioResampler::DEFAULT_QUALITY;
Andy Hungdb4c0312015-05-06 08:46:52 -0700713 } else {
714 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700715 }
Andy Hung296b7412014-06-17 15:25:47 -0700716
Andy Hunge93b6b72014-07-17 21:30:53 -0700717 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
718 // but if none exists, it is the channel count (1 for mono).
719 const int resamplerChannelCount = downmixerBufferProvider != NULL
720 ? mMixerChannelCount : channelCount;
Andy Hung9a592762014-07-21 21:56:01 -0700721 ALOGVV("Creating resampler:"
722 " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
723 mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700724 resampler = AudioResampler::create(
Andy Hung3348e362014-07-07 10:21:44 -0700725 mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -0700726 resamplerChannelCount,
Glenn Kastenac602052012-10-01 14:04:31 -0700727 devSampleRate, quality);
Glenn Kasten52008f82012-03-18 09:34:41 -0700728 resampler->setLocalTimeFreq(sLocalTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700729 }
730 return true;
731 }
732 }
733 return false;
734}
735
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700736bool AudioMixer::track_t::setPlaybackRate(const AudioPlaybackRate &playbackRate)
Andy Hungc5656cc2015-03-26 19:04:33 -0700737{
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700738 if ((mTimestretchBufferProvider == NULL &&
739 fabs(playbackRate.mSpeed - mPlaybackRate.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
740 fabs(playbackRate.mPitch - mPlaybackRate.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA) ||
741 isAudioPlaybackRateEqual(playbackRate, mPlaybackRate)) {
Andy Hungc5656cc2015-03-26 19:04:33 -0700742 return false;
743 }
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700744 mPlaybackRate = playbackRate;
Andy Hungc5656cc2015-03-26 19:04:33 -0700745 if (mTimestretchBufferProvider == NULL) {
746 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
747 // but if none exists, it is the channel count (1 for mono).
748 const int timestretchChannelCount = downmixerBufferProvider != NULL
749 ? mMixerChannelCount : channelCount;
750 mTimestretchBufferProvider = new TimestretchBufferProvider(timestretchChannelCount,
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700751 mMixerInFormat, sampleRate, playbackRate);
Andy Hungc5656cc2015-03-26 19:04:33 -0700752 reconfigureBufferProviders();
753 } else {
754 reinterpret_cast<TimestretchBufferProvider*>(mTimestretchBufferProvider)
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700755 ->setPlaybackRate(playbackRate);
Andy Hungc5656cc2015-03-26 19:04:33 -0700756 }
757 return true;
758}
759
Andy Hung5e58b0a2014-06-23 19:07:29 -0700760/* Checks to see if the volume ramp has completed and clears the increment
761 * variables appropriately.
762 *
763 * FIXME: There is code to handle int/float ramp variable switchover should it not
764 * complete within a mixer buffer processing call, but it is preferred to avoid switchover
765 * due to precision issues. The switchover code is included for legacy code purposes
766 * and can be removed once the integer volume is removed.
767 *
768 * It is not sufficient to clear only the volumeInc integer variable because
769 * if one channel requires ramping, all channels are ramped.
770 *
771 * There is a bit of duplicated code here, but it keeps backward compatibility.
772 */
773inline void AudioMixer::track_t::adjustVolumeRamp(bool aux, bool useFloat)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700774{
Andy Hung5e58b0a2014-06-23 19:07:29 -0700775 if (useFloat) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700776 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700777 if (mVolumeInc[i] != 0 && fabs(mVolume[i] - mPrevVolume[i]) <= fabs(mVolumeInc[i])) {
778 volumeInc[i] = 0;
779 prevVolume[i] = volume[i] << 16;
780 mVolumeInc[i] = 0.;
781 mPrevVolume[i] = mVolume[i];
Andy Hung5e58b0a2014-06-23 19:07:29 -0700782 } else {
783 //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
784 prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
785 }
786 }
787 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -0700788 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700789 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
790 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
791 volumeInc[i] = 0;
792 prevVolume[i] = volume[i] << 16;
793 mVolumeInc[i] = 0.;
794 mPrevVolume[i] = mVolume[i];
795 } else {
796 //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
797 mPrevVolume[i] = float_from_u4_28(prevVolume[i]);
798 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700799 }
800 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700801 /* TODO: aux is always integer regardless of output buffer type */
Mathias Agopian65ab4712010-07-14 17:59:35 -0700802 if (aux) {
803 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
Andy Hung5e58b0a2014-06-23 19:07:29 -0700804 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700805 auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700806 prevAuxLevel = auxLevel << 16;
807 mAuxInc = 0.;
808 mPrevAuxLevel = mAuxLevel;
809 } else {
810 //ALOGV("aux ramp: %d %d %d", auxLevel << 16, prevAuxLevel, auxInc);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700811 }
812 }
813}
814
Glenn Kastenc59c0042012-02-02 14:06:11 -0800815size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800816{
817 name -= TRACK0;
818 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800819 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800820 }
821 return 0;
822}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700823
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800824void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700825{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800826 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800827 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700828
Andy Hung1d26ddf2014-05-29 15:53:09 -0700829 if (mState.tracks[name].mInputBufferProvider == bufferProvider) {
830 return; // don't reset any buffer providers if identical.
831 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700832 if (mState.tracks[name].mReformatBufferProvider != NULL) {
833 mState.tracks[name].mReformatBufferProvider->reset();
834 } else if (mState.tracks[name].downmixerBufferProvider != NULL) {
Andy Hung7f475492014-08-25 16:36:37 -0700835 mState.tracks[name].downmixerBufferProvider->reset();
836 } else if (mState.tracks[name].mPostDownmixReformatBufferProvider != NULL) {
837 mState.tracks[name].mPostDownmixReformatBufferProvider->reset();
Andy Hungc5656cc2015-03-26 19:04:33 -0700838 } else if (mState.tracks[name].mTimestretchBufferProvider != NULL) {
839 mState.tracks[name].mTimestretchBufferProvider->reset();
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700840 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700841
842 mState.tracks[name].mInputBufferProvider = bufferProvider;
Andy Hung0f451e92014-08-04 21:28:47 -0700843 mState.tracks[name].reconfigureBufferProviders();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700844}
845
846
John Grossman4ff14ba2012-02-08 16:37:41 -0800847void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700848{
John Grossman4ff14ba2012-02-08 16:37:41 -0800849 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700850}
851
852
John Grossman4ff14ba2012-02-08 16:37:41 -0800853void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700854{
Steve Block5ff1dd52012-01-05 23:22:43 +0000855 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700856 "in process__validate() but nothing's invalid");
857
858 uint32_t changed = state->needsChanged;
859 state->needsChanged = 0; // clear the validation flag
860
861 // recompute which tracks are enabled / disabled
862 uint32_t enabled = 0;
863 uint32_t disabled = 0;
864 while (changed) {
865 const int i = 31 - __builtin_clz(changed);
866 const uint32_t mask = 1<<i;
867 changed &= ~mask;
868 track_t& t = state->tracks[i];
869 (t.enabled ? enabled : disabled) |= mask;
870 }
871 state->enabledTracks &= ~disabled;
872 state->enabledTracks |= enabled;
873
874 // compute everything we need...
875 int countActiveTracks = 0;
Andy Hung395db4b2014-08-25 17:15:29 -0700876 // TODO: fix all16BitsStereNoResample logic to
877 // either properly handle muted tracks (it should ignore them)
878 // or remove altogether as an obsolete optimization.
Glenn Kasten4c340c62012-01-27 12:33:54 -0800879 bool all16BitsStereoNoResample = true;
880 bool resampling = false;
881 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700882 uint32_t en = state->enabledTracks;
883 while (en) {
884 const int i = 31 - __builtin_clz(en);
885 en &= ~(1<<i);
886
887 countActiveTracks++;
888 track_t& t = state->tracks[i];
889 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700890 // FIXME can overflow (mask is only 3 bits)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700891 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700892 if (t.doesResample()) {
893 n |= NEEDS_RESAMPLE;
894 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700895 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700896 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700897 }
898
899 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800900 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700901 } else if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700902 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700903 }
904 t.needs = n;
905
Glenn Kastend6fadf02013-10-30 14:37:29 -0700906 if (n & NEEDS_MUTE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700907 t.hook = track__nop;
908 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700909 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800910 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700911 }
Glenn Kastend6fadf02013-10-30 14:37:29 -0700912 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800913 all16BitsStereoNoResample = false;
914 resampling = true;
Andy Hunge93b6b72014-07-17 21:30:53 -0700915 t.hook = getTrackHook(TRACKTYPE_RESAMPLE, t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -0700916 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700917 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700918 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700919 } else {
920 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
Andy Hunge93b6b72014-07-17 21:30:53 -0700921 t.hook = getTrackHook(
Andy Hung73e62e22015-04-20 12:06:38 -0700922 (t.mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO // TODO: MONO_HACK
923 && t.channelMask == AUDIO_CHANNEL_OUT_MONO)
Andy Hunge93b6b72014-07-17 21:30:53 -0700924 ? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,
925 t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -0700926 t.mMixerInFormat, t.mMixerFormat);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800927 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700928 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700929 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Andy Hunge93b6b72014-07-17 21:30:53 -0700930 t.hook = getTrackHook(TRACKTYPE_NORESAMPLE, t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -0700931 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700932 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700933 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700934 }
935 }
936 }
937 }
938
939 // select the processing hooks
940 state->hook = process__nop;
Glenn Kasten34fca342013-08-13 09:48:14 -0700941 if (countActiveTracks > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700942 if (resampling) {
943 if (!state->outputTemp) {
944 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
945 }
946 if (!state->resampleTemp) {
947 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
948 }
949 state->hook = process__genericResampling;
950 } else {
951 if (state->outputTemp) {
952 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800953 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700954 }
955 if (state->resampleTemp) {
956 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800957 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700958 }
959 state->hook = process__genericNoResampling;
960 if (all16BitsStereoNoResample && !volumeRamp) {
961 if (countActiveTracks == 1) {
Andy Hung296b7412014-06-17 15:25:47 -0700962 const int i = 31 - __builtin_clz(state->enabledTracks);
963 track_t& t = state->tracks[i];
Andy Hung395db4b2014-08-25 17:15:29 -0700964 if ((t.needs & NEEDS_MUTE) == 0) {
965 // The check prevents a muted track from acquiring a process hook.
966 //
967 // This is dangerous if the track is MONO as that requires
968 // special case handling due to implicit channel duplication.
969 // Stereo or Multichannel should actually be fine here.
970 state->hook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
971 t.mMixerChannelCount, t.mMixerInFormat, t.mMixerFormat);
972 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700973 }
974 }
975 }
976 }
977
Steve Block3856b092011-10-20 11:56:00 +0100978 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700979 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
980 countActiveTracks, state->enabledTracks,
981 all16BitsStereoNoResample, resampling, volumeRamp);
982
John Grossman4ff14ba2012-02-08 16:37:41 -0800983 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700984
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800985 // Now that the volume ramp has been done, set optimal state and
986 // track hooks for subsequent mixer process
Glenn Kasten34fca342013-08-13 09:48:14 -0700987 if (countActiveTracks > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800988 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800989 uint32_t en = state->enabledTracks;
990 while (en) {
991 const int i = 31 - __builtin_clz(en);
992 en &= ~(1<<i);
993 track_t& t = state->tracks[i];
Glenn Kasten6e2ebe92013-08-13 09:14:51 -0700994 if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700995 t.needs |= NEEDS_MUTE;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800996 t.hook = track__nop;
997 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800998 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800999 }
1000 }
1001 if (allMuted) {
1002 state->hook = process__nop;
1003 } else if (all16BitsStereoNoResample) {
1004 if (countActiveTracks == 1) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001005 const int i = 31 - __builtin_clz(state->enabledTracks);
1006 track_t& t = state->tracks[i];
Andy Hung395db4b2014-08-25 17:15:29 -07001007 // Muted single tracks handled by allMuted above.
Andy Hunge93b6b72014-07-17 21:30:53 -07001008 state->hook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
1009 t.mMixerChannelCount, t.mMixerInFormat, t.mMixerFormat);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001010 }
1011 }
1012 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001013}
1014
Mathias Agopian65ab4712010-07-14 17:59:35 -07001015
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001016void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
1017 int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001018{
Andy Hung296b7412014-06-17 15:25:47 -07001019 ALOGVV("track__genericResample\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001020 t->resampler->setSampleRate(t->sampleRate);
1021
1022 // ramp gain - resample to temp buffer and scale/mix in 2nd step
1023 if (aux != NULL) {
1024 // always resample with unity gain when sending to auxiliary buffer to be able
1025 // to apply send level after resampling
Andy Hung5e58b0a2014-06-23 19:07:29 -07001026 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Andy Hunge93b6b72014-07-17 21:30:53 -07001027 memset(temp, 0, outFrameCount * t->mMixerChannelCount * sizeof(int32_t));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001028 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -08001029 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001030 volumeRampStereo(t, out, outFrameCount, temp, aux);
1031 } else {
1032 volumeStereo(t, out, outFrameCount, temp, aux);
1033 }
1034 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -08001035 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001036 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001037 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
1038 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
1039 volumeRampStereo(t, out, outFrameCount, temp, aux);
1040 }
1041
1042 // constant gain
1043 else {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001044 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001045 t->resampler->resample(out, outFrameCount, t->bufferProvider);
1046 }
1047 }
1048}
1049
Andy Hungee931ff2014-01-28 13:44:14 -08001050void AudioMixer::track__nop(track_t* t __unused, int32_t* out __unused,
1051 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001052{
1053}
1054
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001055void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1056 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001057{
1058 int32_t vl = t->prevVolume[0];
1059 int32_t vr = t->prevVolume[1];
1060 const int32_t vlInc = t->volumeInc[0];
1061 const int32_t vrInc = t->volumeInc[1];
1062
Steve Blockb8a80522011-12-20 16:23:08 +00001063 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001064 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1065 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1066
1067 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -08001068 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001069 int32_t va = t->prevAuxLevel;
1070 const int32_t vaInc = t->auxInc;
1071 int32_t l;
1072 int32_t r;
1073
1074 do {
1075 l = (*temp++ >> 12);
1076 r = (*temp++ >> 12);
1077 *out++ += (vl >> 16) * l;
1078 *out++ += (vr >> 16) * r;
1079 *aux++ += (va >> 17) * (l + r);
1080 vl += vlInc;
1081 vr += vrInc;
1082 va += vaInc;
1083 } while (--frameCount);
1084 t->prevAuxLevel = va;
1085 } else {
1086 do {
1087 *out++ += (vl >> 16) * (*temp++ >> 12);
1088 *out++ += (vr >> 16) * (*temp++ >> 12);
1089 vl += vlInc;
1090 vr += vrInc;
1091 } while (--frameCount);
1092 }
1093 t->prevVolume[0] = vl;
1094 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -08001095 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001096}
1097
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001098void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1099 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001100{
1101 const int16_t vl = t->volume[0];
1102 const int16_t vr = t->volume[1];
1103
Glenn Kastenf6b16782011-12-15 09:51:17 -08001104 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -08001105 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001106 do {
1107 int16_t l = (int16_t)(*temp++ >> 12);
1108 int16_t r = (int16_t)(*temp++ >> 12);
1109 out[0] = mulAdd(l, vl, out[0]);
1110 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1111 out[1] = mulAdd(r, vr, out[1]);
1112 out += 2;
1113 aux[0] = mulAdd(a, va, aux[0]);
1114 aux++;
1115 } while (--frameCount);
1116 } else {
1117 do {
1118 int16_t l = (int16_t)(*temp++ >> 12);
1119 int16_t r = (int16_t)(*temp++ >> 12);
1120 out[0] = mulAdd(l, vl, out[0]);
1121 out[1] = mulAdd(r, vr, out[1]);
1122 out += 2;
1123 } while (--frameCount);
1124 }
1125}
1126
Andy Hungee931ff2014-01-28 13:44:14 -08001127void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount,
1128 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001129{
Andy Hung296b7412014-06-17 15:25:47 -07001130 ALOGVV("track__16BitsStereo\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001131 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001132
Glenn Kastenf6b16782011-12-15 09:51:17 -08001133 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001134 int32_t l;
1135 int32_t r;
1136 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001137 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001138 int32_t vl = t->prevVolume[0];
1139 int32_t vr = t->prevVolume[1];
1140 int32_t va = t->prevAuxLevel;
1141 const int32_t vlInc = t->volumeInc[0];
1142 const int32_t vrInc = t->volumeInc[1];
1143 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001144 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001145 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1146 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1147
1148 do {
1149 l = (int32_t)*in++;
1150 r = (int32_t)*in++;
1151 *out++ += (vl >> 16) * l;
1152 *out++ += (vr >> 16) * r;
1153 *aux++ += (va >> 17) * (l + r);
1154 vl += vlInc;
1155 vr += vrInc;
1156 va += vaInc;
1157 } while (--frameCount);
1158
1159 t->prevVolume[0] = vl;
1160 t->prevVolume[1] = vr;
1161 t->prevAuxLevel = va;
1162 t->adjustVolumeRamp(true);
1163 }
1164
1165 // constant gain
1166 else {
1167 const uint32_t vrl = t->volumeRL;
1168 const int16_t va = (int16_t)t->auxLevel;
1169 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001170 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001171 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1172 in += 2;
1173 out[0] = mulAddRL(1, rl, vrl, out[0]);
1174 out[1] = mulAddRL(0, rl, vrl, out[1]);
1175 out += 2;
1176 aux[0] = mulAdd(a, va, aux[0]);
1177 aux++;
1178 } while (--frameCount);
1179 }
1180 } else {
1181 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001182 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001183 int32_t vl = t->prevVolume[0];
1184 int32_t vr = t->prevVolume[1];
1185 const int32_t vlInc = t->volumeInc[0];
1186 const int32_t vrInc = t->volumeInc[1];
1187
Steve Blockb8a80522011-12-20 16:23:08 +00001188 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001189 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1190 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1191
1192 do {
1193 *out++ += (vl >> 16) * (int32_t) *in++;
1194 *out++ += (vr >> 16) * (int32_t) *in++;
1195 vl += vlInc;
1196 vr += vrInc;
1197 } while (--frameCount);
1198
1199 t->prevVolume[0] = vl;
1200 t->prevVolume[1] = vr;
1201 t->adjustVolumeRamp(false);
1202 }
1203
1204 // constant gain
1205 else {
1206 const uint32_t vrl = t->volumeRL;
1207 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001208 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001209 in += 2;
1210 out[0] = mulAddRL(1, rl, vrl, out[0]);
1211 out[1] = mulAddRL(0, rl, vrl, out[1]);
1212 out += 2;
1213 } while (--frameCount);
1214 }
1215 }
1216 t->in = in;
1217}
1218
Andy Hungee931ff2014-01-28 13:44:14 -08001219void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount,
1220 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001221{
Andy Hung296b7412014-06-17 15:25:47 -07001222 ALOGVV("track__16BitsMono\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001223 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001224
Glenn Kastenf6b16782011-12-15 09:51:17 -08001225 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001226 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001227 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001228 int32_t vl = t->prevVolume[0];
1229 int32_t vr = t->prevVolume[1];
1230 int32_t va = t->prevAuxLevel;
1231 const int32_t vlInc = t->volumeInc[0];
1232 const int32_t vrInc = t->volumeInc[1];
1233 const int32_t vaInc = t->auxInc;
1234
Steve Blockb8a80522011-12-20 16:23:08 +00001235 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001236 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1237 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1238
1239 do {
1240 int32_t l = *in++;
1241 *out++ += (vl >> 16) * l;
1242 *out++ += (vr >> 16) * l;
1243 *aux++ += (va >> 16) * l;
1244 vl += vlInc;
1245 vr += vrInc;
1246 va += vaInc;
1247 } while (--frameCount);
1248
1249 t->prevVolume[0] = vl;
1250 t->prevVolume[1] = vr;
1251 t->prevAuxLevel = va;
1252 t->adjustVolumeRamp(true);
1253 }
1254 // constant gain
1255 else {
1256 const int16_t vl = t->volume[0];
1257 const int16_t vr = t->volume[1];
1258 const int16_t va = (int16_t)t->auxLevel;
1259 do {
1260 int16_t l = *in++;
1261 out[0] = mulAdd(l, vl, out[0]);
1262 out[1] = mulAdd(l, vr, out[1]);
1263 out += 2;
1264 aux[0] = mulAdd(l, va, aux[0]);
1265 aux++;
1266 } while (--frameCount);
1267 }
1268 } else {
1269 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001270 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001271 int32_t vl = t->prevVolume[0];
1272 int32_t vr = t->prevVolume[1];
1273 const int32_t vlInc = t->volumeInc[0];
1274 const int32_t vrInc = t->volumeInc[1];
1275
Steve Blockb8a80522011-12-20 16:23:08 +00001276 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001277 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1278 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1279
1280 do {
1281 int32_t l = *in++;
1282 *out++ += (vl >> 16) * l;
1283 *out++ += (vr >> 16) * l;
1284 vl += vlInc;
1285 vr += vrInc;
1286 } while (--frameCount);
1287
1288 t->prevVolume[0] = vl;
1289 t->prevVolume[1] = vr;
1290 t->adjustVolumeRamp(false);
1291 }
1292 // constant gain
1293 else {
1294 const int16_t vl = t->volume[0];
1295 const int16_t vr = t->volume[1];
1296 do {
1297 int16_t l = *in++;
1298 out[0] = mulAdd(l, vl, out[0]);
1299 out[1] = mulAdd(l, vr, out[1]);
1300 out += 2;
1301 } while (--frameCount);
1302 }
1303 }
1304 t->in = in;
1305}
1306
Mathias Agopian65ab4712010-07-14 17:59:35 -07001307// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -08001308void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001309{
Andy Hung296b7412014-06-17 15:25:47 -07001310 ALOGVV("process__nop\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001311 uint32_t e0 = state->enabledTracks;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001312 while (e0) {
1313 // process by group of tracks with same output buffer to
1314 // avoid multiple memset() on same buffer
1315 uint32_t e1 = e0, e2 = e0;
1316 int i = 31 - __builtin_clz(e1);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001317 {
1318 track_t& t1 = state->tracks[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001319 e2 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001320 while (e2) {
1321 i = 31 - __builtin_clz(e2);
1322 e2 &= ~(1<<i);
1323 track_t& t2 = state->tracks[i];
1324 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1325 e1 &= ~(1<<i);
1326 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001327 }
Glenn Kastenfc900c92013-02-18 12:47:49 -08001328 e0 &= ~(e1);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001329
Andy Hunge93b6b72014-07-17 21:30:53 -07001330 memset(t1.mainBuffer, 0, state->frameCount * t1.mMixerChannelCount
Andy Hung78820702014-02-28 16:23:02 -08001331 * audio_bytes_per_sample(t1.mMixerFormat));
Glenn Kastenfc900c92013-02-18 12:47:49 -08001332 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001333
1334 while (e1) {
1335 i = 31 - __builtin_clz(e1);
1336 e1 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001337 {
1338 track_t& t3 = state->tracks[i];
1339 size_t outFrames = state->frameCount;
1340 while (outFrames) {
1341 t3.buffer.frameCount = outFrames;
1342 int64_t outputPTS = calculateOutputPTS(
1343 t3, pts, state->frameCount - outFrames);
1344 t3.bufferProvider->getNextBuffer(&t3.buffer, outputPTS);
1345 if (t3.buffer.raw == NULL) break;
1346 outFrames -= t3.buffer.frameCount;
1347 t3.bufferProvider->releaseBuffer(&t3.buffer);
1348 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001349 }
1350 }
1351 }
1352}
1353
1354// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001355void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001356{
Andy Hung296b7412014-06-17 15:25:47 -07001357 ALOGVV("process__genericNoResampling\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001358 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1359
1360 // acquire each track's buffer
1361 uint32_t enabledTracks = state->enabledTracks;
1362 uint32_t e0 = enabledTracks;
1363 while (e0) {
1364 const int i = 31 - __builtin_clz(e0);
1365 e0 &= ~(1<<i);
1366 track_t& t = state->tracks[i];
1367 t.buffer.frameCount = state->frameCount;
John Grossman4ff14ba2012-02-08 16:37:41 -08001368 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001369 t.frameCount = t.buffer.frameCount;
1370 t.in = t.buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001371 }
1372
1373 e0 = enabledTracks;
1374 while (e0) {
1375 // process by group of tracks with same output buffer to
1376 // optimize cache use
1377 uint32_t e1 = e0, e2 = e0;
1378 int j = 31 - __builtin_clz(e1);
1379 track_t& t1 = state->tracks[j];
1380 e2 &= ~(1<<j);
1381 while (e2) {
1382 j = 31 - __builtin_clz(e2);
1383 e2 &= ~(1<<j);
1384 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001385 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001386 e1 &= ~(1<<j);
1387 }
1388 }
1389 e0 &= ~(e1);
1390 // this assumes output 16 bits stereo, no resampling
1391 int32_t *out = t1.mainBuffer;
1392 size_t numFrames = 0;
1393 do {
1394 memset(outTemp, 0, sizeof(outTemp));
1395 e2 = e1;
1396 while (e2) {
1397 const int i = 31 - __builtin_clz(e2);
1398 e2 &= ~(1<<i);
1399 track_t& t = state->tracks[i];
1400 size_t outFrames = BLOCKSIZE;
1401 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001402 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001403 aux = t.auxBuffer + numFrames;
1404 }
1405 while (outFrames) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301406 // t.in == NULL can happen if the track was flushed just after having
1407 // been enabled for mixing.
1408 if (t.in == NULL) {
1409 enabledTracks &= ~(1<<i);
1410 e1 &= ~(1<<i);
1411 break;
1412 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001413 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001414 if (inFrames > 0) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001415 t.hook(&t, outTemp + (BLOCKSIZE - outFrames) * t.mMixerChannelCount,
1416 inFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001417 t.frameCount -= inFrames;
1418 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001419 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001420 aux += inFrames;
1421 }
1422 }
1423 if (t.frameCount == 0 && outFrames) {
1424 t.bufferProvider->releaseBuffer(&t.buffer);
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001425 t.buffer.frameCount = (state->frameCount - numFrames) -
1426 (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -08001427 int64_t outputPTS = calculateOutputPTS(
1428 t, pts, numFrames + (BLOCKSIZE - outFrames));
1429 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001430 t.in = t.buffer.raw;
1431 if (t.in == NULL) {
1432 enabledTracks &= ~(1<<i);
1433 e1 &= ~(1<<i);
1434 break;
1435 }
1436 t.frameCount = t.buffer.frameCount;
1437 }
1438 }
1439 }
Andy Hung296b7412014-06-17 15:25:47 -07001440
1441 convertMixerFormat(out, t1.mMixerFormat, outTemp, t1.mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -07001442 BLOCKSIZE * t1.mMixerChannelCount);
Andy Hung296b7412014-06-17 15:25:47 -07001443 // TODO: fix ugly casting due to choice of out pointer type
1444 out = reinterpret_cast<int32_t*>((uint8_t*)out
Andy Hunge93b6b72014-07-17 21:30:53 -07001445 + BLOCKSIZE * t1.mMixerChannelCount
1446 * audio_bytes_per_sample(t1.mMixerFormat));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001447 numFrames += BLOCKSIZE;
1448 } while (numFrames < state->frameCount);
1449 }
1450
1451 // release each track's buffer
1452 e0 = enabledTracks;
1453 while (e0) {
1454 const int i = 31 - __builtin_clz(e0);
1455 e0 &= ~(1<<i);
1456 track_t& t = state->tracks[i];
1457 t.bufferProvider->releaseBuffer(&t.buffer);
1458 }
1459}
1460
1461
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001462// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001463void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001464{
Andy Hung296b7412014-06-17 15:25:47 -07001465 ALOGVV("process__genericResampling\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001466 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -07001467 int32_t* const outTemp = state->outputTemp;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001468 size_t numFrames = state->frameCount;
1469
1470 uint32_t e0 = state->enabledTracks;
1471 while (e0) {
1472 // process by group of tracks with same output buffer
1473 // to optimize cache use
1474 uint32_t e1 = e0, e2 = e0;
1475 int j = 31 - __builtin_clz(e1);
1476 track_t& t1 = state->tracks[j];
1477 e2 &= ~(1<<j);
1478 while (e2) {
1479 j = 31 - __builtin_clz(e2);
1480 e2 &= ~(1<<j);
1481 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001482 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001483 e1 &= ~(1<<j);
1484 }
1485 }
1486 e0 &= ~(e1);
1487 int32_t *out = t1.mainBuffer;
Andy Hunge93b6b72014-07-17 21:30:53 -07001488 memset(outTemp, 0, sizeof(*outTemp) * t1.mMixerChannelCount * state->frameCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001489 while (e1) {
1490 const int i = 31 - __builtin_clz(e1);
1491 e1 &= ~(1<<i);
1492 track_t& t = state->tracks[i];
1493 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001494 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001495 aux = t.auxBuffer;
1496 }
1497
1498 // this is a little goofy, on the resampling case we don't
1499 // acquire/release the buffers because it's done by
1500 // the resampler.
Glenn Kastend6fadf02013-10-30 14:37:29 -07001501 if (t.needs & NEEDS_RESAMPLE) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001502 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -08001503 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001504 } else {
1505
1506 size_t outFrames = 0;
1507
1508 while (outFrames < numFrames) {
1509 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001510 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
1511 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001512 t.in = t.buffer.raw;
1513 // t.in == NULL can happen if the track was flushed just after having
1514 // been enabled for mixing.
1515 if (t.in == NULL) break;
1516
Glenn Kastenf6b16782011-12-15 09:51:17 -08001517 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001518 aux += outFrames;
1519 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001520 t.hook(&t, outTemp + outFrames * t.mMixerChannelCount, t.buffer.frameCount,
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001521 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001522 outFrames += t.buffer.frameCount;
1523 t.bufferProvider->releaseBuffer(&t.buffer);
1524 }
1525 }
1526 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001527 convertMixerFormat(out, t1.mMixerFormat,
1528 outTemp, t1.mMixerInFormat, numFrames * t1.mMixerChannelCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001529 }
1530}
1531
1532// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -08001533void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
1534 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001535{
Andy Hung296b7412014-06-17 15:25:47 -07001536 ALOGVV("process__OneTrack16BitsStereoNoResampling\n");
Glenn Kasten99e53b82012-01-19 08:59:58 -08001537 // This method is only called when state->enabledTracks has exactly
1538 // one bit set. The asserts below would verify this, but are commented out
1539 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001540 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001541 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001542 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001543 const track_t& t = state->tracks[i];
1544
1545 AudioBufferProvider::Buffer& b(t.buffer);
1546
1547 int32_t* out = t.mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001548 float *fout = reinterpret_cast<float*>(out);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001549 size_t numFrames = state->frameCount;
1550
1551 const int16_t vl = t.volume[0];
1552 const int16_t vr = t.volume[1];
1553 const uint32_t vrl = t.volumeRL;
1554 while (numFrames) {
1555 b.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001556 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
1557 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001558 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001559
1560 // in == NULL can happen if the track was flushed just after having
1561 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001562 if (in == NULL || (((uintptr_t)in) & 3)) {
1563 memset(out, 0, numFrames
Andy Hunge93b6b72014-07-17 21:30:53 -07001564 * t.mMixerChannelCount * audio_bytes_per_sample(t.mMixerFormat));
Andy Hung395db4b2014-08-25 17:15:29 -07001565 ALOGE_IF((((uintptr_t)in) & 3),
1566 "process__OneTrack16BitsStereoNoResampling: misaligned buffer"
1567 " %p track %d, channels %d, needs %08x, volume %08x vfl %f vfr %f",
1568 in, i, t.channelCount, t.needs, vrl, t.mVolume[0], t.mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001569 return;
1570 }
1571 size_t outFrames = b.frameCount;
1572
Andy Hung78820702014-02-28 16:23:02 -08001573 switch (t.mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001574 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001575 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001576 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001577 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001578 int32_t l = mulRL(1, rl, vrl);
1579 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001580 *fout++ = float_from_q4_27(l);
1581 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001582 // Note: In case of later int16_t sink output,
1583 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001584 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001585 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001586 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung97ae8242014-05-30 10:35:47 -07001587 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001588 // volume is boosted, so we might need to clamp even though
1589 // we process only one track.
1590 do {
1591 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1592 in += 2;
1593 int32_t l = mulRL(1, rl, vrl) >> 12;
1594 int32_t r = mulRL(0, rl, vrl) >> 12;
1595 // clamping...
1596 l = clamp16(l);
1597 r = clamp16(r);
1598 *out++ = (r<<16) | (l & 0xFFFF);
1599 } while (--outFrames);
1600 } else {
1601 do {
1602 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1603 in += 2;
1604 int32_t l = mulRL(1, rl, vrl) >> 12;
1605 int32_t r = mulRL(0, rl, vrl) >> 12;
1606 *out++ = (r<<16) | (l & 0xFFFF);
1607 } while (--outFrames);
1608 }
1609 break;
1610 default:
Andy Hung78820702014-02-28 16:23:02 -08001611 LOG_ALWAYS_FATAL("bad mixer format: %d", t.mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001612 }
1613 numFrames -= b.frameCount;
1614 t.bufferProvider->releaseBuffer(&b);
1615 }
1616}
1617
John Grossman4ff14ba2012-02-08 16:37:41 -08001618int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1619 int outputFrameIndex)
1620{
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001621 if (AudioBufferProvider::kInvalidPTS == basePTS) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001622 return AudioBufferProvider::kInvalidPTS;
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001623 }
John Grossman4ff14ba2012-02-08 16:37:41 -08001624
Glenn Kasten52008f82012-03-18 09:34:41 -07001625 return basePTS + ((outputFrameIndex * sLocalTimeFreq) / t.sampleRate);
1626}
1627
1628/*static*/ uint64_t AudioMixer::sLocalTimeFreq;
1629/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1630
1631/*static*/ void AudioMixer::sInitRoutine()
1632{
1633 LocalClock lc;
Andy Hung34803d52014-07-16 21:41:35 -07001634 sLocalTimeFreq = lc.getLocalFreq(); // for the resampler
Glenn Kasten49c34ac2013-10-30 14:37:01 -07001635
Andy Hung34803d52014-07-16 21:41:35 -07001636 DownmixerBufferProvider::init(); // for the downmixer
John Grossman4ff14ba2012-02-08 16:37:41 -08001637}
1638
Andy Hunge93b6b72014-07-17 21:30:53 -07001639/* TODO: consider whether this level of optimization is necessary.
1640 * Perhaps just stick with a single for loop.
1641 */
1642
1643// Needs to derive a compile time constant (constexpr). Could be targeted to go
1644// to a MONOVOL mixtype based on MAX_NUM_VOLUMES, but that's an unnecessary complication.
1645#define MIXTYPE_MONOVOL(mixtype) (mixtype == MIXTYPE_MULTI ? MIXTYPE_MULTI_MONOVOL : \
1646 mixtype == MIXTYPE_MULTI_SAVEONLY ? MIXTYPE_MULTI_SAVEONLY_MONOVOL : mixtype)
1647
1648/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1649 * TO: int32_t (Q4.27) or float
1650 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1651 * TA: int32_t (Q4.27)
1652 */
1653template <int MIXTYPE,
1654 typename TO, typename TI, typename TV, typename TA, typename TAV>
1655static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
1656 const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc)
1657{
1658 switch (channels) {
1659 case 1:
1660 volumeRampMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1661 break;
1662 case 2:
1663 volumeRampMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1664 break;
1665 case 3:
1666 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out,
1667 frameCount, in, aux, vol, volinc, vola, volainc);
1668 break;
1669 case 4:
1670 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out,
1671 frameCount, in, aux, vol, volinc, vola, volainc);
1672 break;
1673 case 5:
1674 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out,
1675 frameCount, in, aux, vol, volinc, vola, volainc);
1676 break;
1677 case 6:
1678 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out,
1679 frameCount, in, aux, vol, volinc, vola, volainc);
1680 break;
1681 case 7:
1682 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out,
1683 frameCount, in, aux, vol, volinc, vola, volainc);
1684 break;
1685 case 8:
1686 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out,
1687 frameCount, in, aux, vol, volinc, vola, volainc);
1688 break;
1689 }
1690}
1691
1692/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1693 * TO: int32_t (Q4.27) or float
1694 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1695 * TA: int32_t (Q4.27)
1696 */
1697template <int MIXTYPE,
1698 typename TO, typename TI, typename TV, typename TA, typename TAV>
1699static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
1700 const TI* in, TA* aux, const TV *vol, TAV vola)
1701{
1702 switch (channels) {
1703 case 1:
1704 volumeMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, vola);
1705 break;
1706 case 2:
1707 volumeMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, vola);
1708 break;
1709 case 3:
1710 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out, frameCount, in, aux, vol, vola);
1711 break;
1712 case 4:
1713 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out, frameCount, in, aux, vol, vola);
1714 break;
1715 case 5:
1716 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out, frameCount, in, aux, vol, vola);
1717 break;
1718 case 6:
1719 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out, frameCount, in, aux, vol, vola);
1720 break;
1721 case 7:
1722 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out, frameCount, in, aux, vol, vola);
1723 break;
1724 case 8:
1725 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out, frameCount, in, aux, vol, vola);
1726 break;
1727 }
1728}
1729
1730/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1731 * USEFLOATVOL (set to true if float volume is used)
1732 * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards)
1733 * TO: int32_t (Q4.27) or float
1734 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1735 * TA: int32_t (Q4.27)
1736 */
1737template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001738 typename TO, typename TI, typename TA>
1739void AudioMixer::volumeMix(TO *out, size_t outFrames,
1740 const TI *in, TA *aux, bool ramp, AudioMixer::track_t *t)
1741{
1742 if (USEFLOATVOL) {
1743 if (ramp) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001744 volumeRampMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001745 t->mPrevVolume, t->mVolumeInc, &t->prevAuxLevel, t->auxInc);
1746 if (ADJUSTVOL) {
1747 t->adjustVolumeRamp(aux != NULL, true);
1748 }
1749 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -07001750 volumeMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001751 t->mVolume, t->auxLevel);
1752 }
1753 } else {
1754 if (ramp) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001755 volumeRampMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001756 t->prevVolume, t->volumeInc, &t->prevAuxLevel, t->auxInc);
1757 if (ADJUSTVOL) {
1758 t->adjustVolumeRamp(aux != NULL);
1759 }
1760 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -07001761 volumeMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001762 t->volume, t->auxLevel);
1763 }
1764 }
1765}
1766
Andy Hung296b7412014-06-17 15:25:47 -07001767/* This process hook is called when there is a single track without
1768 * aux buffer, volume ramp, or resampling.
1769 * TODO: Update the hook selection: this can properly handle aux and ramp.
Andy Hunge93b6b72014-07-17 21:30:53 -07001770 *
1771 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1772 * TO: int32_t (Q4.27) or float
1773 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1774 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07001775 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001776template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung296b7412014-06-17 15:25:47 -07001777void AudioMixer::process_NoResampleOneTrack(state_t* state, int64_t pts)
1778{
1779 ALOGVV("process_NoResampleOneTrack\n");
1780 // CLZ is faster than CTZ on ARM, though really not sure if true after 31 - clz.
1781 const int i = 31 - __builtin_clz(state->enabledTracks);
1782 ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
1783 track_t *t = &state->tracks[i];
Andy Hunge93b6b72014-07-17 21:30:53 -07001784 const uint32_t channels = t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07001785 TO* out = reinterpret_cast<TO*>(t->mainBuffer);
1786 TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
1787 const bool ramp = t->needsRamp();
1788
1789 for (size_t numFrames = state->frameCount; numFrames; ) {
1790 AudioBufferProvider::Buffer& b(t->buffer);
1791 // get input buffer
1792 b.frameCount = numFrames;
1793 const int64_t outputPTS = calculateOutputPTS(*t, pts, state->frameCount - numFrames);
1794 t->bufferProvider->getNextBuffer(&b, outputPTS);
1795 const TI *in = reinterpret_cast<TI*>(b.raw);
1796
1797 // in == NULL can happen if the track was flushed just after having
1798 // been enabled for mixing.
1799 if (in == NULL || (((uintptr_t)in) & 3)) {
1800 memset(out, 0, numFrames
Andy Hunge93b6b72014-07-17 21:30:53 -07001801 * channels * audio_bytes_per_sample(t->mMixerFormat));
Andy Hung296b7412014-06-17 15:25:47 -07001802 ALOGE_IF((((uintptr_t)in) & 3), "process_NoResampleOneTrack: bus error: "
1803 "buffer %p track %p, channels %d, needs %#x",
1804 in, t, t->channelCount, t->needs);
1805 return;
1806 }
1807
1808 const size_t outFrames = b.frameCount;
Andy Hunge93b6b72014-07-17 21:30:53 -07001809 volumeMix<MIXTYPE, is_same<TI, float>::value, false> (
1810 out, outFrames, in, aux, ramp, t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001811
Andy Hunge93b6b72014-07-17 21:30:53 -07001812 out += outFrames * channels;
Andy Hung296b7412014-06-17 15:25:47 -07001813 if (aux != NULL) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001814 aux += channels;
Andy Hung296b7412014-06-17 15:25:47 -07001815 }
1816 numFrames -= b.frameCount;
1817
1818 // release buffer
1819 t->bufferProvider->releaseBuffer(&b);
1820 }
1821 if (ramp) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001822 t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
Andy Hung296b7412014-06-17 15:25:47 -07001823 }
1824}
1825
1826/* This track hook is called to do resampling then mixing,
1827 * pulling from the track's upstream AudioBufferProvider.
Andy Hunge93b6b72014-07-17 21:30:53 -07001828 *
1829 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1830 * TO: int32_t (Q4.27) or float
1831 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1832 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07001833 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001834template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung296b7412014-06-17 15:25:47 -07001835void AudioMixer::track__Resample(track_t* t, TO* out, size_t outFrameCount, TO* temp, TA* aux)
1836{
1837 ALOGVV("track__Resample\n");
1838 t->resampler->setSampleRate(t->sampleRate);
Andy Hung296b7412014-06-17 15:25:47 -07001839 const bool ramp = t->needsRamp();
1840 if (ramp || aux != NULL) {
1841 // if ramp: resample with unity gain to temp buffer and scale/mix in 2nd step.
1842 // if aux != NULL: resample with unity gain to temp buffer then apply send level.
1843
Andy Hung5e58b0a2014-06-23 19:07:29 -07001844 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Andy Hunge93b6b72014-07-17 21:30:53 -07001845 memset(temp, 0, outFrameCount * t->mMixerChannelCount * sizeof(TO));
Andy Hung296b7412014-06-17 15:25:47 -07001846 t->resampler->resample((int32_t*)temp, outFrameCount, t->bufferProvider);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001847
Andy Hunge93b6b72014-07-17 21:30:53 -07001848 volumeMix<MIXTYPE, is_same<TI, float>::value, true>(
1849 out, outFrameCount, temp, aux, ramp, t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001850
Andy Hung296b7412014-06-17 15:25:47 -07001851 } else { // constant volume gain
Andy Hung5e58b0a2014-06-23 19:07:29 -07001852 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Andy Hung296b7412014-06-17 15:25:47 -07001853 t->resampler->resample((int32_t*)out, outFrameCount, t->bufferProvider);
1854 }
1855}
1856
1857/* This track hook is called to mix a track, when no resampling is required.
1858 * The input buffer should be present in t->in.
Andy Hunge93b6b72014-07-17 21:30:53 -07001859 *
1860 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1861 * TO: int32_t (Q4.27) or float
1862 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1863 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07001864 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001865template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung296b7412014-06-17 15:25:47 -07001866void AudioMixer::track__NoResample(track_t* t, TO* out, size_t frameCount,
1867 TO* temp __unused, TA* aux)
1868{
1869 ALOGVV("track__NoResample\n");
1870 const TI *in = static_cast<const TI *>(t->in);
1871
Andy Hunge93b6b72014-07-17 21:30:53 -07001872 volumeMix<MIXTYPE, is_same<TI, float>::value, true>(
1873 out, frameCount, in, aux, t->needsRamp(), t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001874
Andy Hung296b7412014-06-17 15:25:47 -07001875 // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
1876 // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
Andy Hunge93b6b72014-07-17 21:30:53 -07001877 in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07001878 t->in = in;
1879}
1880
1881/* The Mixer engine generates either int32_t (Q4_27) or float data.
1882 * We use this function to convert the engine buffers
1883 * to the desired mixer output format, either int16_t (Q.15) or float.
1884 */
1885void AudioMixer::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
1886 void *in, audio_format_t mixerInFormat, size_t sampleCount)
1887{
1888 switch (mixerInFormat) {
1889 case AUDIO_FORMAT_PCM_FLOAT:
1890 switch (mixerOutFormat) {
1891 case AUDIO_FORMAT_PCM_FLOAT:
1892 memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
1893 break;
1894 case AUDIO_FORMAT_PCM_16_BIT:
1895 memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
1896 break;
1897 default:
1898 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1899 break;
1900 }
1901 break;
1902 case AUDIO_FORMAT_PCM_16_BIT:
1903 switch (mixerOutFormat) {
1904 case AUDIO_FORMAT_PCM_FLOAT:
1905 memcpy_to_float_from_q4_27((float*)out, (int32_t*)in, sampleCount);
1906 break;
1907 case AUDIO_FORMAT_PCM_16_BIT:
1908 // two int16_t are produced per iteration
1909 ditherAndClamp((int32_t*)out, (int32_t*)in, sampleCount >> 1);
1910 break;
1911 default:
1912 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1913 break;
1914 }
1915 break;
1916 default:
1917 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1918 break;
1919 }
1920}
1921
1922/* Returns the proper track hook to use for mixing the track into the output buffer.
1923 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001924AudioMixer::hook_t AudioMixer::getTrackHook(int trackType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001925 audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
1926{
Andy Hunge93b6b72014-07-17 21:30:53 -07001927 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07001928 switch (trackType) {
1929 case TRACKTYPE_NOP:
1930 return track__nop;
1931 case TRACKTYPE_RESAMPLE:
1932 return track__genericResample;
1933 case TRACKTYPE_NORESAMPLEMONO:
1934 return track__16BitsMono;
1935 case TRACKTYPE_NORESAMPLE:
1936 return track__16BitsStereo;
1937 default:
1938 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1939 break;
1940 }
1941 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001942 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07001943 switch (trackType) {
1944 case TRACKTYPE_NOP:
1945 return track__nop;
1946 case TRACKTYPE_RESAMPLE:
1947 switch (mixerInFormat) {
1948 case AUDIO_FORMAT_PCM_FLOAT:
1949 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07001950 track__Resample<MIXTYPE_MULTI, float /*TO*/, float /*TI*/, int32_t /*TA*/>;
Andy Hung296b7412014-06-17 15:25:47 -07001951 case AUDIO_FORMAT_PCM_16_BIT:
1952 return (AudioMixer::hook_t)\
Andy Hunge93b6b72014-07-17 21:30:53 -07001953 track__Resample<MIXTYPE_MULTI, int32_t, int16_t, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07001954 default:
1955 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1956 break;
1957 }
1958 break;
1959 case TRACKTYPE_NORESAMPLEMONO:
1960 switch (mixerInFormat) {
1961 case AUDIO_FORMAT_PCM_FLOAT:
1962 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07001963 track__NoResample<MIXTYPE_MONOEXPAND, float, float, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07001964 case AUDIO_FORMAT_PCM_16_BIT:
1965 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07001966 track__NoResample<MIXTYPE_MONOEXPAND, int32_t, int16_t, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07001967 default:
1968 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1969 break;
1970 }
1971 break;
1972 case TRACKTYPE_NORESAMPLE:
1973 switch (mixerInFormat) {
1974 case AUDIO_FORMAT_PCM_FLOAT:
1975 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07001976 track__NoResample<MIXTYPE_MULTI, float, float, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07001977 case AUDIO_FORMAT_PCM_16_BIT:
1978 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07001979 track__NoResample<MIXTYPE_MULTI, int32_t, int16_t, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07001980 default:
1981 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1982 break;
1983 }
1984 break;
1985 default:
1986 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1987 break;
1988 }
1989 return NULL;
1990}
1991
1992/* Returns the proper process hook for mixing tracks. Currently works only for
1993 * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
Andy Hung395db4b2014-08-25 17:15:29 -07001994 *
1995 * TODO: Due to the special mixing considerations of duplicating to
1996 * a stereo output track, the input track cannot be MONO. This should be
1997 * prevented by the caller.
Andy Hung296b7412014-06-17 15:25:47 -07001998 */
Andy Hunge93b6b72014-07-17 21:30:53 -07001999AudioMixer::process_hook_t AudioMixer::getProcessHook(int processType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07002000 audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
2001{
2002 if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
2003 LOG_ALWAYS_FATAL("bad processType: %d", processType);
2004 return NULL;
2005 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002006 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07002007 return process__OneTrack16BitsStereoNoResampling;
2008 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002009 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07002010 switch (mixerInFormat) {
2011 case AUDIO_FORMAT_PCM_FLOAT:
2012 switch (mixerOutFormat) {
2013 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002014 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
2015 float /*TO*/, float /*TI*/, int32_t /*TA*/>;
Andy Hung296b7412014-06-17 15:25:47 -07002016 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002017 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
Andy Hung296b7412014-06-17 15:25:47 -07002018 int16_t, float, int32_t>;
2019 default:
2020 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2021 break;
2022 }
2023 break;
2024 case AUDIO_FORMAT_PCM_16_BIT:
2025 switch (mixerOutFormat) {
2026 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002027 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
Andy Hung296b7412014-06-17 15:25:47 -07002028 float, int16_t, int32_t>;
2029 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002030 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
Andy Hung296b7412014-06-17 15:25:47 -07002031 int16_t, int16_t, int32_t>;
2032 default:
2033 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2034 break;
2035 }
2036 break;
2037 default:
2038 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2039 break;
2040 }
2041 return NULL;
2042}
2043
Mathias Agopian65ab4712010-07-14 17:59:35 -07002044// ----------------------------------------------------------------------------
Glenn Kasten63238ef2015-03-02 15:50:29 -08002045} // namespace android