blob: 3f4c19affdd57df8351a7dd90b58377876ff860e [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"
19//#define LOG_NDEBUG 0
20
21#include <stdint.h>
22#include <string.h>
23#include <stdlib.h>
24#include <sys/types.h>
25
26#include <utils/Errors.h>
27#include <utils/Log.h>
28
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070029#include <cutils/bitops.h>
Glenn Kastenf6b16782011-12-15 09:51:17 -080030#include <cutils/compiler.h>
Glenn Kasten5798d4e2012-03-08 12:18:35 -080031#include <utils/Debug.h>
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070032
33#include <system/audio.h>
34
Glenn Kasten3b21c502011-12-15 09:52:39 -080035#include <audio_utils/primitives.h>
John Grossman4ff14ba2012-02-08 16:37:41 -080036#include <common_time/local_clock.h>
37#include <common_time/cc_helper.h>
Glenn Kasten3b21c502011-12-15 09:52:39 -080038
Mathias Agopian65ab4712010-07-14 17:59:35 -070039#include "AudioMixer.h"
40
41namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070042
43// ----------------------------------------------------------------------------
44
Glenn Kasten5c94b6c2012-03-20 17:01:29 -070045AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks)
46 : mTrackNames(0), mConfiguredNames((1 << maxNumTracks) - 1), mSampleRate(sampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -070047{
Glenn Kasten788040c2011-05-05 08:19:00 -070048 // AudioMixer is not yet capable of multi-channel beyond stereo
Glenn Kasten5798d4e2012-03-08 12:18:35 -080049 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(2 == MAX_NUM_CHANNELS);
John Grossman4ff14ba2012-02-08 16:37:41 -080050
Glenn Kasten5c94b6c2012-03-20 17:01:29 -070051 ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
52 maxNumTracks, MAX_NUM_TRACKS);
53
John Grossman4ff14ba2012-02-08 16:37:41 -080054 LocalClock lc;
55
Mathias Agopian65ab4712010-07-14 17:59:35 -070056 mState.enabledTracks= 0;
57 mState.needsChanged = 0;
58 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080059 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -080060 mState.outputTemp = NULL;
61 mState.resampleTemp = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080062 // mState.reserved
Glenn Kasten17a736c2012-02-14 08:52:15 -080063
64 // FIXME Most of the following initialization is probably redundant since
65 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
66 // and mTrackNames is initially 0. However, leave it here until that's verified.
Mathias Agopian65ab4712010-07-14 17:59:35 -070067 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -080068 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -070069 t->needs = 0;
70 t->volume[0] = UNITY_GAIN;
71 t->volume[1] = UNITY_GAIN;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080072 // no initialization needed
73 // t->prevVolume[0]
74 // t->prevVolume[1]
Mathias Agopian65ab4712010-07-14 17:59:35 -070075 t->volumeInc[0] = 0;
76 t->volumeInc[1] = 0;
77 t->auxLevel = 0;
78 t->auxInc = 0;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080079 // no initialization needed
80 // t->prevAuxLevel
81 // t->frameCount
Mathias Agopian65ab4712010-07-14 17:59:35 -070082 t->channelCount = 2;
Glenn Kasten4c340c62012-01-27 12:33:54 -080083 t->enabled = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -070084 t->format = 16;
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070085 t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
Glenn Kastene0feee32011-12-13 11:53:26 -080086 t->bufferProvider = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080087 t->buffer.raw = NULL;
88 // t->buffer.frameCount
Glenn Kastene0feee32011-12-13 11:53:26 -080089 t->hook = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080090 t->in = NULL;
Glenn Kastene0feee32011-12-13 11:53:26 -080091 t->resampler = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -070092 t->sampleRate = mSampleRate;
Mathias Agopian65ab4712010-07-14 17:59:35 -070093 t->mainBuffer = NULL;
94 t->auxBuffer = NULL;
John Grossman4ff14ba2012-02-08 16:37:41 -080095 t->localTimeFreq = lc.getLocalFreq();
Mathias Agopian65ab4712010-07-14 17:59:35 -070096 t++;
97 }
98}
99
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800100AudioMixer::~AudioMixer()
101{
102 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800103 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800104 delete t->resampler;
105 t++;
106 }
107 delete [] mState.outputTemp;
108 delete [] mState.resampleTemp;
109}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700110
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800111int AudioMixer::getTrackName()
112{
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700113 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800114 if (names != 0) {
115 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100116 ALOGV("add track (%d)", n);
Glenn Kasten98dd5422011-12-15 14:38:29 -0800117 mTrackNames |= 1 << n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700118 return TRACK0 + n;
119 }
120 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800121}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700122
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800123void AudioMixer::invalidateState(uint32_t mask)
124{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700125 if (mask) {
126 mState.needsChanged |= mask;
127 mState.hook = process__validate;
128 }
129 }
130
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800131void AudioMixer::deleteTrackName(int name)
132{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700133 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800134 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800135 ALOGV("deleteTrackName(%d)", name);
136 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800137 if (track.enabled) {
138 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800139 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700140 }
Glenn Kastena0d68332012-01-27 16:47:15 -0800141 if (track.resampler != NULL) {
Glenn Kastenea7939a2012-03-14 12:56:26 -0700142 // delete the resampler
Glenn Kasten237a6242011-12-15 15:32:27 -0800143 delete track.resampler;
144 track.resampler = NULL;
145 track.sampleRate = mSampleRate;
146 invalidateState(1<<name);
147 }
148 track.volumeInc[0] = 0;
149 track.volumeInc[1] = 0;
150 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800151}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700152
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800153void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700154{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800155 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800156 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800157 track_t& track = mState.tracks[name];
158
Glenn Kasten4c340c62012-01-27 12:33:54 -0800159 if (!track.enabled) {
160 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800161 ALOGV("enable(%d)", name);
162 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700163 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700164}
165
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800166void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700167{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800168 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800169 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800170 track_t& track = mState.tracks[name];
171
Glenn Kasten4c340c62012-01-27 12:33:54 -0800172 if (track.enabled) {
173 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800174 ALOGV("disable(%d)", name);
175 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700176 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700177}
178
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800179void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700180{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800181 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800182 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800183 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700184
Mathias Agopian65ab4712010-07-14 17:59:35 -0700185 int valueInt = (int)value;
186 int32_t *valueBuf = (int32_t *)value;
187
188 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700189
Mathias Agopian65ab4712010-07-14 17:59:35 -0700190 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800191 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700192 case CHANNEL_MASK: {
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700193 uint32_t mask = (uint32_t)value;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800194 if (track.channelMask != mask) {
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800195 uint32_t channelCount = popcount(mask);
196 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS) && (channelCount),
197 "bad channel count %u", channelCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800198 track.channelMask = mask;
199 track.channelCount = channelCount;
Glenn Kasten788040c2011-05-05 08:19:00 -0700200 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800201 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700202 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700203 } break;
204 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800205 if (track.mainBuffer != valueBuf) {
206 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100207 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800208 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700209 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700210 break;
211 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800212 if (track.auxBuffer != valueBuf) {
213 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100214 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800215 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700216 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700217 break;
218 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800219 LOG_FATAL("bad param");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700220 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700221 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700222
Mathias Agopian65ab4712010-07-14 17:59:35 -0700223 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800224 switch (param) {
225 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800226 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700227 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
228 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
229 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800230 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700231 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800232 break;
233 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800234 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800235 invalidateState(1 << name);
236 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700237 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800238 LOG_FATAL("bad param");
Eric Laurent243f5f92011-02-28 16:52:51 -0800239 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700240 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700241
Mathias Agopian65ab4712010-07-14 17:59:35 -0700242 case RAMP_VOLUME:
243 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800244 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700245 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800246 case VOLUME1:
247 if (track.volume[param-VOLUME0] != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100248 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800249 track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16;
250 track.volume[param-VOLUME0] = valueInt;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700251 if (target == VOLUME) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800252 track.prevVolume[param-VOLUME0] = valueInt << 16;
253 track.volumeInc[param-VOLUME0] = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700254 } else {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800255 int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700256 int32_t volInc = d / int32_t(mState.frameCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800257 track.volumeInc[param-VOLUME0] = volInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700258 if (volInc == 0) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800259 track.prevVolume[param-VOLUME0] = valueInt << 16;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700260 }
261 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800262 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700263 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800264 break;
265 case AUXLEVEL:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800266 //ALOG_ASSERT(0 <= valueInt && valueInt <= MAX_GAIN_INT, "bad aux level %d", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700267 if (track.auxLevel != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100268 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700269 track.prevAuxLevel = track.auxLevel << 16;
270 track.auxLevel = valueInt;
271 if (target == VOLUME) {
272 track.prevAuxLevel = valueInt << 16;
273 track.auxInc = 0;
274 } else {
275 int32_t d = (valueInt<<16) - track.prevAuxLevel;
276 int32_t volInc = d / int32_t(mState.frameCount);
277 track.auxInc = volInc;
278 if (volInc == 0) {
279 track.prevAuxLevel = valueInt << 16;
280 }
281 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800282 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700283 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800284 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700285 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800286 LOG_FATAL("bad param");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700287 }
288 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700289
290 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800291 LOG_FATAL("bad target");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700292 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700293}
294
295bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
296{
297 if (value!=devSampleRate || resampler) {
298 if (sampleRate != value) {
299 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800300 if (resampler == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700301 resampler = AudioResampler::create(
302 format, channelCount, devSampleRate);
John Grossman4ff14ba2012-02-08 16:37:41 -0800303 resampler->setLocalTimeFreq(localTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700304 }
305 return true;
306 }
307 }
308 return false;
309}
310
Mathias Agopian65ab4712010-07-14 17:59:35 -0700311inline
312void AudioMixer::track_t::adjustVolumeRamp(bool aux)
313{
Glenn Kastenf9a27772012-01-06 07:47:26 -0800314 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700315 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
316 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
317 volumeInc[i] = 0;
318 prevVolume[i] = volume[i]<<16;
319 }
320 }
321 if (aux) {
322 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
323 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
324 auxInc = 0;
325 prevAuxLevel = auxLevel<<16;
326 }
327 }
328}
329
Glenn Kastenc59c0042012-02-02 14:06:11 -0800330size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800331{
332 name -= TRACK0;
333 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800334 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800335 }
336 return 0;
337}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700338
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800339void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700340{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800341 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800342 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800343 mState.tracks[name].bufferProvider = bufferProvider;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700344}
345
346
347
John Grossman4ff14ba2012-02-08 16:37:41 -0800348void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700349{
John Grossman4ff14ba2012-02-08 16:37:41 -0800350 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700351}
352
353
John Grossman4ff14ba2012-02-08 16:37:41 -0800354void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700355{
Steve Block5ff1dd52012-01-05 23:22:43 +0000356 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700357 "in process__validate() but nothing's invalid");
358
359 uint32_t changed = state->needsChanged;
360 state->needsChanged = 0; // clear the validation flag
361
362 // recompute which tracks are enabled / disabled
363 uint32_t enabled = 0;
364 uint32_t disabled = 0;
365 while (changed) {
366 const int i = 31 - __builtin_clz(changed);
367 const uint32_t mask = 1<<i;
368 changed &= ~mask;
369 track_t& t = state->tracks[i];
370 (t.enabled ? enabled : disabled) |= mask;
371 }
372 state->enabledTracks &= ~disabled;
373 state->enabledTracks |= enabled;
374
375 // compute everything we need...
376 int countActiveTracks = 0;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800377 bool all16BitsStereoNoResample = true;
378 bool resampling = false;
379 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700380 uint32_t en = state->enabledTracks;
381 while (en) {
382 const int i = 31 - __builtin_clz(en);
383 en &= ~(1<<i);
384
385 countActiveTracks++;
386 track_t& t = state->tracks[i];
387 uint32_t n = 0;
388 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
389 n |= NEEDS_FORMAT_16;
390 n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
391 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
392 n |= NEEDS_AUX_ENABLED;
393 }
394
395 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800396 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700397 } else if (!t.doesResample() && t.volumeRL == 0) {
398 n |= NEEDS_MUTE_ENABLED;
399 }
400 t.needs = n;
401
402 if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
403 t.hook = track__nop;
404 } else {
405 if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800406 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700407 }
408 if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800409 all16BitsStereoNoResample = false;
410 resampling = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700411 t.hook = track__genericResample;
412 } else {
413 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
414 t.hook = track__16BitsMono;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800415 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700416 }
417 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
418 t.hook = track__16BitsStereo;
419 }
420 }
421 }
422 }
423
424 // select the processing hooks
425 state->hook = process__nop;
426 if (countActiveTracks) {
427 if (resampling) {
428 if (!state->outputTemp) {
429 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
430 }
431 if (!state->resampleTemp) {
432 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
433 }
434 state->hook = process__genericResampling;
435 } else {
436 if (state->outputTemp) {
437 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800438 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700439 }
440 if (state->resampleTemp) {
441 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800442 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700443 }
444 state->hook = process__genericNoResampling;
445 if (all16BitsStereoNoResample && !volumeRamp) {
446 if (countActiveTracks == 1) {
447 state->hook = process__OneTrack16BitsStereoNoResampling;
448 }
449 }
450 }
451 }
452
Steve Block3856b092011-10-20 11:56:00 +0100453 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700454 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
455 countActiveTracks, state->enabledTracks,
456 all16BitsStereoNoResample, resampling, volumeRamp);
457
John Grossman4ff14ba2012-02-08 16:37:41 -0800458 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700459
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800460 // Now that the volume ramp has been done, set optimal state and
461 // track hooks for subsequent mixer process
462 if (countActiveTracks) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800463 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800464 uint32_t en = state->enabledTracks;
465 while (en) {
466 const int i = 31 - __builtin_clz(en);
467 en &= ~(1<<i);
468 track_t& t = state->tracks[i];
469 if (!t.doesResample() && t.volumeRL == 0)
470 {
471 t.needs |= NEEDS_MUTE_ENABLED;
472 t.hook = track__nop;
473 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800474 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800475 }
476 }
477 if (allMuted) {
478 state->hook = process__nop;
479 } else if (all16BitsStereoNoResample) {
480 if (countActiveTracks == 1) {
481 state->hook = process__OneTrack16BitsStereoNoResampling;
482 }
483 }
484 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700485}
486
Mathias Agopian65ab4712010-07-14 17:59:35 -0700487
488void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
489{
490 t->resampler->setSampleRate(t->sampleRate);
491
492 // ramp gain - resample to temp buffer and scale/mix in 2nd step
493 if (aux != NULL) {
494 // always resample with unity gain when sending to auxiliary buffer to be able
495 // to apply send level after resampling
496 // TODO: modify each resampler to support aux channel?
497 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
498 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
499 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -0800500 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700501 volumeRampStereo(t, out, outFrameCount, temp, aux);
502 } else {
503 volumeStereo(t, out, outFrameCount, temp, aux);
504 }
505 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -0800506 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700507 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
508 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
509 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
510 volumeRampStereo(t, out, outFrameCount, temp, aux);
511 }
512
513 // constant gain
514 else {
515 t->resampler->setVolume(t->volume[0], t->volume[1]);
516 t->resampler->resample(out, outFrameCount, t->bufferProvider);
517 }
518 }
519}
520
521void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
522{
523}
524
525void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
526{
527 int32_t vl = t->prevVolume[0];
528 int32_t vr = t->prevVolume[1];
529 const int32_t vlInc = t->volumeInc[0];
530 const int32_t vrInc = t->volumeInc[1];
531
Steve Blockb8a80522011-12-20 16:23:08 +0000532 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700533 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
534 // (vl + vlInc*frameCount)/65536.0f, frameCount);
535
536 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -0800537 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700538 int32_t va = t->prevAuxLevel;
539 const int32_t vaInc = t->auxInc;
540 int32_t l;
541 int32_t r;
542
543 do {
544 l = (*temp++ >> 12);
545 r = (*temp++ >> 12);
546 *out++ += (vl >> 16) * l;
547 *out++ += (vr >> 16) * r;
548 *aux++ += (va >> 17) * (l + r);
549 vl += vlInc;
550 vr += vrInc;
551 va += vaInc;
552 } while (--frameCount);
553 t->prevAuxLevel = va;
554 } else {
555 do {
556 *out++ += (vl >> 16) * (*temp++ >> 12);
557 *out++ += (vr >> 16) * (*temp++ >> 12);
558 vl += vlInc;
559 vr += vrInc;
560 } while (--frameCount);
561 }
562 t->prevVolume[0] = vl;
563 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -0800564 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700565}
566
567void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
568{
569 const int16_t vl = t->volume[0];
570 const int16_t vr = t->volume[1];
571
Glenn Kastenf6b16782011-12-15 09:51:17 -0800572 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800573 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700574 do {
575 int16_t l = (int16_t)(*temp++ >> 12);
576 int16_t r = (int16_t)(*temp++ >> 12);
577 out[0] = mulAdd(l, vl, out[0]);
578 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
579 out[1] = mulAdd(r, vr, out[1]);
580 out += 2;
581 aux[0] = mulAdd(a, va, aux[0]);
582 aux++;
583 } while (--frameCount);
584 } else {
585 do {
586 int16_t l = (int16_t)(*temp++ >> 12);
587 int16_t r = (int16_t)(*temp++ >> 12);
588 out[0] = mulAdd(l, vl, out[0]);
589 out[1] = mulAdd(r, vr, out[1]);
590 out += 2;
591 } while (--frameCount);
592 }
593}
594
595void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
596{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800597 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700598
Glenn Kastenf6b16782011-12-15 09:51:17 -0800599 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700600 int32_t l;
601 int32_t r;
602 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800603 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700604 int32_t vl = t->prevVolume[0];
605 int32_t vr = t->prevVolume[1];
606 int32_t va = t->prevAuxLevel;
607 const int32_t vlInc = t->volumeInc[0];
608 const int32_t vrInc = t->volumeInc[1];
609 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +0000610 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700611 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
612 // (vl + vlInc*frameCount)/65536.0f, frameCount);
613
614 do {
615 l = (int32_t)*in++;
616 r = (int32_t)*in++;
617 *out++ += (vl >> 16) * l;
618 *out++ += (vr >> 16) * r;
619 *aux++ += (va >> 17) * (l + r);
620 vl += vlInc;
621 vr += vrInc;
622 va += vaInc;
623 } while (--frameCount);
624
625 t->prevVolume[0] = vl;
626 t->prevVolume[1] = vr;
627 t->prevAuxLevel = va;
628 t->adjustVolumeRamp(true);
629 }
630
631 // constant gain
632 else {
633 const uint32_t vrl = t->volumeRL;
634 const int16_t va = (int16_t)t->auxLevel;
635 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800636 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700637 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
638 in += 2;
639 out[0] = mulAddRL(1, rl, vrl, out[0]);
640 out[1] = mulAddRL(0, rl, vrl, out[1]);
641 out += 2;
642 aux[0] = mulAdd(a, va, aux[0]);
643 aux++;
644 } while (--frameCount);
645 }
646 } else {
647 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800648 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700649 int32_t vl = t->prevVolume[0];
650 int32_t vr = t->prevVolume[1];
651 const int32_t vlInc = t->volumeInc[0];
652 const int32_t vrInc = t->volumeInc[1];
653
Steve Blockb8a80522011-12-20 16:23:08 +0000654 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700655 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
656 // (vl + vlInc*frameCount)/65536.0f, frameCount);
657
658 do {
659 *out++ += (vl >> 16) * (int32_t) *in++;
660 *out++ += (vr >> 16) * (int32_t) *in++;
661 vl += vlInc;
662 vr += vrInc;
663 } while (--frameCount);
664
665 t->prevVolume[0] = vl;
666 t->prevVolume[1] = vr;
667 t->adjustVolumeRamp(false);
668 }
669
670 // constant gain
671 else {
672 const uint32_t vrl = t->volumeRL;
673 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800674 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700675 in += 2;
676 out[0] = mulAddRL(1, rl, vrl, out[0]);
677 out[1] = mulAddRL(0, rl, vrl, out[1]);
678 out += 2;
679 } while (--frameCount);
680 }
681 }
682 t->in = in;
683}
684
685void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
686{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800687 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700688
Glenn Kastenf6b16782011-12-15 09:51:17 -0800689 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700690 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800691 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700692 int32_t vl = t->prevVolume[0];
693 int32_t vr = t->prevVolume[1];
694 int32_t va = t->prevAuxLevel;
695 const int32_t vlInc = t->volumeInc[0];
696 const int32_t vrInc = t->volumeInc[1];
697 const int32_t vaInc = t->auxInc;
698
Steve Blockb8a80522011-12-20 16:23:08 +0000699 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700700 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
701 // (vl + vlInc*frameCount)/65536.0f, frameCount);
702
703 do {
704 int32_t l = *in++;
705 *out++ += (vl >> 16) * l;
706 *out++ += (vr >> 16) * l;
707 *aux++ += (va >> 16) * l;
708 vl += vlInc;
709 vr += vrInc;
710 va += vaInc;
711 } while (--frameCount);
712
713 t->prevVolume[0] = vl;
714 t->prevVolume[1] = vr;
715 t->prevAuxLevel = va;
716 t->adjustVolumeRamp(true);
717 }
718 // constant gain
719 else {
720 const int16_t vl = t->volume[0];
721 const int16_t vr = t->volume[1];
722 const int16_t va = (int16_t)t->auxLevel;
723 do {
724 int16_t l = *in++;
725 out[0] = mulAdd(l, vl, out[0]);
726 out[1] = mulAdd(l, vr, out[1]);
727 out += 2;
728 aux[0] = mulAdd(l, va, aux[0]);
729 aux++;
730 } while (--frameCount);
731 }
732 } else {
733 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800734 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700735 int32_t vl = t->prevVolume[0];
736 int32_t vr = t->prevVolume[1];
737 const int32_t vlInc = t->volumeInc[0];
738 const int32_t vrInc = t->volumeInc[1];
739
Steve Blockb8a80522011-12-20 16:23:08 +0000740 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700741 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
742 // (vl + vlInc*frameCount)/65536.0f, frameCount);
743
744 do {
745 int32_t l = *in++;
746 *out++ += (vl >> 16) * l;
747 *out++ += (vr >> 16) * l;
748 vl += vlInc;
749 vr += vrInc;
750 } while (--frameCount);
751
752 t->prevVolume[0] = vl;
753 t->prevVolume[1] = vr;
754 t->adjustVolumeRamp(false);
755 }
756 // constant gain
757 else {
758 const int16_t vl = t->volume[0];
759 const int16_t vr = t->volume[1];
760 do {
761 int16_t l = *in++;
762 out[0] = mulAdd(l, vl, out[0]);
763 out[1] = mulAdd(l, vr, out[1]);
764 out += 2;
765 } while (--frameCount);
766 }
767 }
768 t->in = in;
769}
770
Mathias Agopian65ab4712010-07-14 17:59:35 -0700771// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -0800772void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700773{
774 uint32_t e0 = state->enabledTracks;
775 size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
776 while (e0) {
777 // process by group of tracks with same output buffer to
778 // avoid multiple memset() on same buffer
779 uint32_t e1 = e0, e2 = e0;
780 int i = 31 - __builtin_clz(e1);
781 track_t& t1 = state->tracks[i];
782 e2 &= ~(1<<i);
783 while (e2) {
784 i = 31 - __builtin_clz(e2);
785 e2 &= ~(1<<i);
786 track_t& t2 = state->tracks[i];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800787 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700788 e1 &= ~(1<<i);
789 }
790 }
791 e0 &= ~(e1);
792
793 memset(t1.mainBuffer, 0, bufSize);
794
795 while (e1) {
796 i = 31 - __builtin_clz(e1);
797 e1 &= ~(1<<i);
798 t1 = state->tracks[i];
799 size_t outFrames = state->frameCount;
800 while (outFrames) {
801 t1.buffer.frameCount = outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -0800802 int64_t outputPTS = calculateOutputPTS(
803 t1, pts, state->frameCount - outFrames);
804 t1.bufferProvider->getNextBuffer(&t1.buffer, outputPTS);
Glenn Kastena0d68332012-01-27 16:47:15 -0800805 if (t1.buffer.raw == NULL) break;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700806 outFrames -= t1.buffer.frameCount;
807 t1.bufferProvider->releaseBuffer(&t1.buffer);
808 }
809 }
810 }
811}
812
813// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -0800814void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700815{
816 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
817
818 // acquire each track's buffer
819 uint32_t enabledTracks = state->enabledTracks;
820 uint32_t e0 = enabledTracks;
821 while (e0) {
822 const int i = 31 - __builtin_clz(e0);
823 e0 &= ~(1<<i);
824 track_t& t = state->tracks[i];
825 t.buffer.frameCount = state->frameCount;
John Grossman4ff14ba2012-02-08 16:37:41 -0800826 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700827 t.frameCount = t.buffer.frameCount;
828 t.in = t.buffer.raw;
829 // t.in == NULL can happen if the track was flushed just after having
830 // been enabled for mixing.
831 if (t.in == NULL)
832 enabledTracks &= ~(1<<i);
833 }
834
835 e0 = enabledTracks;
836 while (e0) {
837 // process by group of tracks with same output buffer to
838 // optimize cache use
839 uint32_t e1 = e0, e2 = e0;
840 int j = 31 - __builtin_clz(e1);
841 track_t& t1 = state->tracks[j];
842 e2 &= ~(1<<j);
843 while (e2) {
844 j = 31 - __builtin_clz(e2);
845 e2 &= ~(1<<j);
846 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800847 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700848 e1 &= ~(1<<j);
849 }
850 }
851 e0 &= ~(e1);
852 // this assumes output 16 bits stereo, no resampling
853 int32_t *out = t1.mainBuffer;
854 size_t numFrames = 0;
855 do {
856 memset(outTemp, 0, sizeof(outTemp));
857 e2 = e1;
858 while (e2) {
859 const int i = 31 - __builtin_clz(e2);
860 e2 &= ~(1<<i);
861 track_t& t = state->tracks[i];
862 size_t outFrames = BLOCKSIZE;
863 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800864 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700865 aux = t.auxBuffer + numFrames;
866 }
867 while (outFrames) {
868 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
869 if (inFrames) {
Glenn Kastena1117922012-01-26 10:53:32 -0800870 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700871 t.frameCount -= inFrames;
872 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800873 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700874 aux += inFrames;
875 }
876 }
877 if (t.frameCount == 0 && outFrames) {
878 t.bufferProvider->releaseBuffer(&t.buffer);
879 t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -0800880 int64_t outputPTS = calculateOutputPTS(
881 t, pts, numFrames + (BLOCKSIZE - outFrames));
882 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700883 t.in = t.buffer.raw;
884 if (t.in == NULL) {
885 enabledTracks &= ~(1<<i);
886 e1 &= ~(1<<i);
887 break;
888 }
889 t.frameCount = t.buffer.frameCount;
890 }
891 }
892 }
893 ditherAndClamp(out, outTemp, BLOCKSIZE);
894 out += BLOCKSIZE;
895 numFrames += BLOCKSIZE;
896 } while (numFrames < state->frameCount);
897 }
898
899 // release each track's buffer
900 e0 = enabledTracks;
901 while (e0) {
902 const int i = 31 - __builtin_clz(e0);
903 e0 &= ~(1<<i);
904 track_t& t = state->tracks[i];
905 t.bufferProvider->releaseBuffer(&t.buffer);
906 }
907}
908
909
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800910// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -0800911void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700912{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800913 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -0700914 int32_t* const outTemp = state->outputTemp;
915 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700916
917 size_t numFrames = state->frameCount;
918
919 uint32_t e0 = state->enabledTracks;
920 while (e0) {
921 // process by group of tracks with same output buffer
922 // to optimize cache use
923 uint32_t e1 = e0, e2 = e0;
924 int j = 31 - __builtin_clz(e1);
925 track_t& t1 = state->tracks[j];
926 e2 &= ~(1<<j);
927 while (e2) {
928 j = 31 - __builtin_clz(e2);
929 e2 &= ~(1<<j);
930 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800931 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700932 e1 &= ~(1<<j);
933 }
934 }
935 e0 &= ~(e1);
936 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +0100937 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700938 while (e1) {
939 const int i = 31 - __builtin_clz(e1);
940 e1 &= ~(1<<i);
941 track_t& t = state->tracks[i];
942 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800943 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700944 aux = t.auxBuffer;
945 }
946
947 // this is a little goofy, on the resampling case we don't
948 // acquire/release the buffers because it's done by
949 // the resampler.
950 if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
John Grossman4ff14ba2012-02-08 16:37:41 -0800951 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -0800952 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700953 } else {
954
955 size_t outFrames = 0;
956
957 while (outFrames < numFrames) {
958 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -0800959 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
960 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700961 t.in = t.buffer.raw;
962 // t.in == NULL can happen if the track was flushed just after having
963 // been enabled for mixing.
964 if (t.in == NULL) break;
965
Glenn Kastenf6b16782011-12-15 09:51:17 -0800966 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700967 aux += outFrames;
968 }
Glenn Kastena1117922012-01-26 10:53:32 -0800969 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700970 outFrames += t.buffer.frameCount;
971 t.bufferProvider->releaseBuffer(&t.buffer);
972 }
973 }
974 }
975 ditherAndClamp(out, outTemp, numFrames);
976 }
977}
978
979// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -0800980void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
981 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700982{
Glenn Kasten99e53b82012-01-19 08:59:58 -0800983 // This method is only called when state->enabledTracks has exactly
984 // one bit set. The asserts below would verify this, but are commented out
985 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800986 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700987 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800988 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700989 const track_t& t = state->tracks[i];
990
991 AudioBufferProvider::Buffer& b(t.buffer);
992
993 int32_t* out = t.mainBuffer;
994 size_t numFrames = state->frameCount;
995
996 const int16_t vl = t.volume[0];
997 const int16_t vr = t.volume[1];
998 const uint32_t vrl = t.volumeRL;
999 while (numFrames) {
1000 b.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001001 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
1002 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001003 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001004
1005 // in == NULL can happen if the track was flushed just after having
1006 // been enabled for mixing.
1007 if (in == NULL || ((unsigned long)in & 3)) {
1008 memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
Steve Block29357bc2012-01-06 19:20:56 +00001009 ALOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: buffer %p track %d, channels %d, needs %08x",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001010 in, i, t.channelCount, t.needs);
1011 return;
1012 }
1013 size_t outFrames = b.frameCount;
1014
Glenn Kastenf6b16782011-12-15 09:51:17 -08001015 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001016 // volume is boosted, so we might need to clamp even though
1017 // we process only one track.
1018 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001019 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001020 in += 2;
1021 int32_t l = mulRL(1, rl, vrl) >> 12;
1022 int32_t r = mulRL(0, rl, vrl) >> 12;
1023 // clamping...
1024 l = clamp16(l);
1025 r = clamp16(r);
1026 *out++ = (r<<16) | (l & 0xFFFF);
1027 } while (--outFrames);
1028 } else {
1029 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001030 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001031 in += 2;
1032 int32_t l = mulRL(1, rl, vrl) >> 12;
1033 int32_t r = mulRL(0, rl, vrl) >> 12;
1034 *out++ = (r<<16) | (l & 0xFFFF);
1035 } while (--outFrames);
1036 }
1037 numFrames -= b.frameCount;
1038 t.bufferProvider->releaseBuffer(&b);
1039 }
1040}
1041
Glenn Kasten81a028f2011-12-15 09:53:12 -08001042#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001043// 2 tracks is also a common case
1044// NEVER used in current implementation of process__validate()
1045// only use if the 2 tracks have the same output buffer
John Grossman4ff14ba2012-02-08 16:37:41 -08001046void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
1047 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001048{
1049 int i;
1050 uint32_t en = state->enabledTracks;
1051
1052 i = 31 - __builtin_clz(en);
1053 const track_t& t0 = state->tracks[i];
1054 AudioBufferProvider::Buffer& b0(t0.buffer);
1055
1056 en &= ~(1<<i);
1057 i = 31 - __builtin_clz(en);
1058 const track_t& t1 = state->tracks[i];
1059 AudioBufferProvider::Buffer& b1(t1.buffer);
1060
Glenn Kasten54c3b662012-01-06 07:46:30 -08001061 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001062 const int16_t vl0 = t0.volume[0];
1063 const int16_t vr0 = t0.volume[1];
1064 size_t frameCount0 = 0;
1065
Glenn Kasten54c3b662012-01-06 07:46:30 -08001066 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001067 const int16_t vl1 = t1.volume[0];
1068 const int16_t vr1 = t1.volume[1];
1069 size_t frameCount1 = 0;
1070
1071 //FIXME: only works if two tracks use same buffer
1072 int32_t* out = t0.mainBuffer;
1073 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001074 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001075
1076
1077 while (numFrames) {
1078
1079 if (frameCount0 == 0) {
1080 b0.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001081 int64_t outputPTS = calculateOutputPTS(t0, pts,
1082 out - t0.mainBuffer);
1083 t0.bufferProvider->getNextBuffer(&b0, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001084 if (b0.i16 == NULL) {
1085 if (buff == NULL) {
1086 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1087 }
1088 in0 = buff;
1089 b0.frameCount = numFrames;
1090 } else {
1091 in0 = b0.i16;
1092 }
1093 frameCount0 = b0.frameCount;
1094 }
1095 if (frameCount1 == 0) {
1096 b1.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001097 int64_t outputPTS = calculateOutputPTS(t1, pts,
1098 out - t0.mainBuffer);
1099 t1.bufferProvider->getNextBuffer(&b1, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001100 if (b1.i16 == NULL) {
1101 if (buff == NULL) {
1102 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1103 }
1104 in1 = buff;
1105 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001106 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001107 in1 = b1.i16;
1108 }
1109 frameCount1 = b1.frameCount;
1110 }
1111
1112 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1113
1114 numFrames -= outFrames;
1115 frameCount0 -= outFrames;
1116 frameCount1 -= outFrames;
1117
1118 do {
1119 int32_t l0 = *in0++;
1120 int32_t r0 = *in0++;
1121 l0 = mul(l0, vl0);
1122 r0 = mul(r0, vr0);
1123 int32_t l = *in1++;
1124 int32_t r = *in1++;
1125 l = mulAdd(l, vl1, l0) >> 12;
1126 r = mulAdd(r, vr1, r0) >> 12;
1127 // clamping...
1128 l = clamp16(l);
1129 r = clamp16(r);
1130 *out++ = (r<<16) | (l & 0xFFFF);
1131 } while (--outFrames);
1132
1133 if (frameCount0 == 0) {
1134 t0.bufferProvider->releaseBuffer(&b0);
1135 }
1136 if (frameCount1 == 0) {
1137 t1.bufferProvider->releaseBuffer(&b1);
1138 }
1139 }
1140
Glenn Kastene9dd0172012-01-27 18:08:45 -08001141 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001142}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001143#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001144
John Grossman4ff14ba2012-02-08 16:37:41 -08001145int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1146 int outputFrameIndex)
1147{
1148 if (AudioBufferProvider::kInvalidPTS == basePTS)
1149 return AudioBufferProvider::kInvalidPTS;
1150
1151 return basePTS + ((outputFrameIndex * t.localTimeFreq) / t.sampleRate);
1152}
1153
Mathias Agopian65ab4712010-07-14 17:59:35 -07001154// ----------------------------------------------------------------------------
1155}; // namespace android