blob: 91f75156e063265474947bbac1c1df56f09df383 [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
Mathias Agopian65ab4712010-07-14 17:59:35 -070063 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -080064 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -070065 t->needs = 0;
66 t->volume[0] = UNITY_GAIN;
67 t->volume[1] = UNITY_GAIN;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080068 // no initialization needed
69 // t->prevVolume[0]
70 // t->prevVolume[1]
Mathias Agopian65ab4712010-07-14 17:59:35 -070071 t->volumeInc[0] = 0;
72 t->volumeInc[1] = 0;
73 t->auxLevel = 0;
74 t->auxInc = 0;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080075 // no initialization needed
76 // t->prevAuxLevel
77 // t->frameCount
Mathias Agopian65ab4712010-07-14 17:59:35 -070078 t->channelCount = 2;
Glenn Kasten4c340c62012-01-27 12:33:54 -080079 t->enabled = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -070080 t->format = 16;
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070081 t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
Glenn Kastene0feee32011-12-13 11:53:26 -080082 t->bufferProvider = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080083 t->buffer.raw = NULL;
84 // t->buffer.frameCount
Glenn Kastene0feee32011-12-13 11:53:26 -080085 t->hook = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080086 t->in = NULL;
Glenn Kastene0feee32011-12-13 11:53:26 -080087 t->resampler = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -070088 t->sampleRate = mSampleRate;
Mathias Agopian65ab4712010-07-14 17:59:35 -070089 t->mainBuffer = NULL;
90 t->auxBuffer = NULL;
John Grossman4ff14ba2012-02-08 16:37:41 -080091 t->localTimeFreq = lc.getLocalFreq();
Mathias Agopian65ab4712010-07-14 17:59:35 -070092 t++;
93 }
94}
95
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080096AudioMixer::~AudioMixer()
97{
98 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -080099 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800100 delete t->resampler;
101 t++;
102 }
103 delete [] mState.outputTemp;
104 delete [] mState.resampleTemp;
105}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700106
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800107int AudioMixer::getTrackName()
108{
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700109 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800110 if (names != 0) {
111 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100112 ALOGV("add track (%d)", n);
Glenn Kasten98dd5422011-12-15 14:38:29 -0800113 mTrackNames |= 1 << n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700114 return TRACK0 + n;
115 }
116 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800117}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700118
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800119void AudioMixer::invalidateState(uint32_t mask)
120{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700121 if (mask) {
122 mState.needsChanged |= mask;
123 mState.hook = process__validate;
124 }
125 }
126
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800127void AudioMixer::deleteTrackName(int name)
128{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700129 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800130 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800131 ALOGV("deleteTrackName(%d)", name);
132 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800133 if (track.enabled) {
134 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800135 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700136 }
Glenn Kastena0d68332012-01-27 16:47:15 -0800137 if (track.resampler != NULL) {
Glenn Kasten237a6242011-12-15 15:32:27 -0800138 // delete the resampler
139 delete track.resampler;
140 track.resampler = NULL;
141 track.sampleRate = mSampleRate;
142 invalidateState(1<<name);
143 }
144 track.volumeInc[0] = 0;
145 track.volumeInc[1] = 0;
146 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800147}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700148
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800149void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700150{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800151 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800152 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800153 track_t& track = mState.tracks[name];
154
Glenn Kasten4c340c62012-01-27 12:33:54 -0800155 if (!track.enabled) {
156 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800157 ALOGV("enable(%d)", name);
158 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700159 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700160}
161
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800162void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700163{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800164 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800165 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800166 track_t& track = mState.tracks[name];
167
Glenn Kasten4c340c62012-01-27 12:33:54 -0800168 if (track.enabled) {
169 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800170 ALOGV("disable(%d)", name);
171 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700172 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700173}
174
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800175void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700176{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800177 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800178 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800179 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700180
Mathias Agopian65ab4712010-07-14 17:59:35 -0700181 int valueInt = (int)value;
182 int32_t *valueBuf = (int32_t *)value;
183
184 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700185
Mathias Agopian65ab4712010-07-14 17:59:35 -0700186 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800187 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700188 case CHANNEL_MASK: {
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700189 uint32_t mask = (uint32_t)value;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800190 if (track.channelMask != mask) {
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800191 uint32_t channelCount = popcount(mask);
192 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS) && (channelCount),
193 "bad channel count %u", channelCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800194 track.channelMask = mask;
195 track.channelCount = channelCount;
Glenn Kasten788040c2011-05-05 08:19:00 -0700196 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800197 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700198 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700199 } break;
200 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800201 if (track.mainBuffer != valueBuf) {
202 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100203 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800204 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700205 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700206 break;
207 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800208 if (track.auxBuffer != valueBuf) {
209 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100210 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800211 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700212 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700213 break;
214 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800215 LOG_FATAL("bad param");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700216 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700217 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700218
Mathias Agopian65ab4712010-07-14 17:59:35 -0700219 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800220 switch (param) {
221 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800222 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700223 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
224 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
225 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800226 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700227 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800228 break;
229 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800230 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800231 invalidateState(1 << name);
232 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700233 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800234 LOG_FATAL("bad param");
Eric Laurent243f5f92011-02-28 16:52:51 -0800235 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700236 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700237
Mathias Agopian65ab4712010-07-14 17:59:35 -0700238 case RAMP_VOLUME:
239 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800240 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700241 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800242 case VOLUME1:
243 if (track.volume[param-VOLUME0] != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100244 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800245 track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16;
246 track.volume[param-VOLUME0] = valueInt;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700247 if (target == VOLUME) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800248 track.prevVolume[param-VOLUME0] = valueInt << 16;
249 track.volumeInc[param-VOLUME0] = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700250 } else {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800251 int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700252 int32_t volInc = d / int32_t(mState.frameCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800253 track.volumeInc[param-VOLUME0] = volInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700254 if (volInc == 0) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800255 track.prevVolume[param-VOLUME0] = valueInt << 16;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700256 }
257 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800258 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700259 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800260 break;
261 case AUXLEVEL:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800262 //ALOG_ASSERT(0 <= valueInt && valueInt <= MAX_GAIN_INT, "bad aux level %d", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700263 if (track.auxLevel != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100264 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700265 track.prevAuxLevel = track.auxLevel << 16;
266 track.auxLevel = valueInt;
267 if (target == VOLUME) {
268 track.prevAuxLevel = valueInt << 16;
269 track.auxInc = 0;
270 } else {
271 int32_t d = (valueInt<<16) - track.prevAuxLevel;
272 int32_t volInc = d / int32_t(mState.frameCount);
273 track.auxInc = volInc;
274 if (volInc == 0) {
275 track.prevAuxLevel = valueInt << 16;
276 }
277 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800278 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700279 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800280 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700281 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800282 LOG_FATAL("bad param");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700283 }
284 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700285
286 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800287 LOG_FATAL("bad target");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700288 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700289}
290
291bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
292{
293 if (value!=devSampleRate || resampler) {
294 if (sampleRate != value) {
295 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800296 if (resampler == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700297 resampler = AudioResampler::create(
298 format, channelCount, devSampleRate);
John Grossman4ff14ba2012-02-08 16:37:41 -0800299 resampler->setLocalTimeFreq(localTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700300 }
301 return true;
302 }
303 }
304 return false;
305}
306
Mathias Agopian65ab4712010-07-14 17:59:35 -0700307inline
308void AudioMixer::track_t::adjustVolumeRamp(bool aux)
309{
Glenn Kastenf9a27772012-01-06 07:47:26 -0800310 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700311 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
312 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
313 volumeInc[i] = 0;
314 prevVolume[i] = volume[i]<<16;
315 }
316 }
317 if (aux) {
318 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
319 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
320 auxInc = 0;
321 prevAuxLevel = auxLevel<<16;
322 }
323 }
324}
325
Glenn Kastenc59c0042012-02-02 14:06:11 -0800326size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800327{
328 name -= TRACK0;
329 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800330 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800331 }
332 return 0;
333}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700334
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800335void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700336{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800337 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800338 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800339 mState.tracks[name].bufferProvider = bufferProvider;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700340}
341
342
343
John Grossman4ff14ba2012-02-08 16:37:41 -0800344void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700345{
John Grossman4ff14ba2012-02-08 16:37:41 -0800346 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700347}
348
349
John Grossman4ff14ba2012-02-08 16:37:41 -0800350void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700351{
Steve Block5ff1dd52012-01-05 23:22:43 +0000352 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700353 "in process__validate() but nothing's invalid");
354
355 uint32_t changed = state->needsChanged;
356 state->needsChanged = 0; // clear the validation flag
357
358 // recompute which tracks are enabled / disabled
359 uint32_t enabled = 0;
360 uint32_t disabled = 0;
361 while (changed) {
362 const int i = 31 - __builtin_clz(changed);
363 const uint32_t mask = 1<<i;
364 changed &= ~mask;
365 track_t& t = state->tracks[i];
366 (t.enabled ? enabled : disabled) |= mask;
367 }
368 state->enabledTracks &= ~disabled;
369 state->enabledTracks |= enabled;
370
371 // compute everything we need...
372 int countActiveTracks = 0;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800373 bool all16BitsStereoNoResample = true;
374 bool resampling = false;
375 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700376 uint32_t en = state->enabledTracks;
377 while (en) {
378 const int i = 31 - __builtin_clz(en);
379 en &= ~(1<<i);
380
381 countActiveTracks++;
382 track_t& t = state->tracks[i];
383 uint32_t n = 0;
384 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
385 n |= NEEDS_FORMAT_16;
386 n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
387 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
388 n |= NEEDS_AUX_ENABLED;
389 }
390
391 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800392 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700393 } else if (!t.doesResample() && t.volumeRL == 0) {
394 n |= NEEDS_MUTE_ENABLED;
395 }
396 t.needs = n;
397
398 if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
399 t.hook = track__nop;
400 } else {
401 if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800402 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700403 }
404 if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800405 all16BitsStereoNoResample = false;
406 resampling = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700407 t.hook = track__genericResample;
408 } else {
409 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
410 t.hook = track__16BitsMono;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800411 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700412 }
413 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
414 t.hook = track__16BitsStereo;
415 }
416 }
417 }
418 }
419
420 // select the processing hooks
421 state->hook = process__nop;
422 if (countActiveTracks) {
423 if (resampling) {
424 if (!state->outputTemp) {
425 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
426 }
427 if (!state->resampleTemp) {
428 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
429 }
430 state->hook = process__genericResampling;
431 } else {
432 if (state->outputTemp) {
433 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800434 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700435 }
436 if (state->resampleTemp) {
437 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800438 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700439 }
440 state->hook = process__genericNoResampling;
441 if (all16BitsStereoNoResample && !volumeRamp) {
442 if (countActiveTracks == 1) {
443 state->hook = process__OneTrack16BitsStereoNoResampling;
444 }
445 }
446 }
447 }
448
Steve Block3856b092011-10-20 11:56:00 +0100449 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700450 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
451 countActiveTracks, state->enabledTracks,
452 all16BitsStereoNoResample, resampling, volumeRamp);
453
John Grossman4ff14ba2012-02-08 16:37:41 -0800454 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700455
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800456 // Now that the volume ramp has been done, set optimal state and
457 // track hooks for subsequent mixer process
458 if (countActiveTracks) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800459 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800460 uint32_t en = state->enabledTracks;
461 while (en) {
462 const int i = 31 - __builtin_clz(en);
463 en &= ~(1<<i);
464 track_t& t = state->tracks[i];
465 if (!t.doesResample() && t.volumeRL == 0)
466 {
467 t.needs |= NEEDS_MUTE_ENABLED;
468 t.hook = track__nop;
469 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800470 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800471 }
472 }
473 if (allMuted) {
474 state->hook = process__nop;
475 } else if (all16BitsStereoNoResample) {
476 if (countActiveTracks == 1) {
477 state->hook = process__OneTrack16BitsStereoNoResampling;
478 }
479 }
480 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700481}
482
Mathias Agopian65ab4712010-07-14 17:59:35 -0700483
484void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
485{
486 t->resampler->setSampleRate(t->sampleRate);
487
488 // ramp gain - resample to temp buffer and scale/mix in 2nd step
489 if (aux != NULL) {
490 // always resample with unity gain when sending to auxiliary buffer to be able
491 // to apply send level after resampling
492 // TODO: modify each resampler to support aux channel?
493 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
494 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
495 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -0800496 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700497 volumeRampStereo(t, out, outFrameCount, temp, aux);
498 } else {
499 volumeStereo(t, out, outFrameCount, temp, aux);
500 }
501 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -0800502 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700503 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
504 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
505 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
506 volumeRampStereo(t, out, outFrameCount, temp, aux);
507 }
508
509 // constant gain
510 else {
511 t->resampler->setVolume(t->volume[0], t->volume[1]);
512 t->resampler->resample(out, outFrameCount, t->bufferProvider);
513 }
514 }
515}
516
517void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
518{
519}
520
521void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
522{
523 int32_t vl = t->prevVolume[0];
524 int32_t vr = t->prevVolume[1];
525 const int32_t vlInc = t->volumeInc[0];
526 const int32_t vrInc = t->volumeInc[1];
527
Steve Blockb8a80522011-12-20 16:23:08 +0000528 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700529 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
530 // (vl + vlInc*frameCount)/65536.0f, frameCount);
531
532 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -0800533 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700534 int32_t va = t->prevAuxLevel;
535 const int32_t vaInc = t->auxInc;
536 int32_t l;
537 int32_t r;
538
539 do {
540 l = (*temp++ >> 12);
541 r = (*temp++ >> 12);
542 *out++ += (vl >> 16) * l;
543 *out++ += (vr >> 16) * r;
544 *aux++ += (va >> 17) * (l + r);
545 vl += vlInc;
546 vr += vrInc;
547 va += vaInc;
548 } while (--frameCount);
549 t->prevAuxLevel = va;
550 } else {
551 do {
552 *out++ += (vl >> 16) * (*temp++ >> 12);
553 *out++ += (vr >> 16) * (*temp++ >> 12);
554 vl += vlInc;
555 vr += vrInc;
556 } while (--frameCount);
557 }
558 t->prevVolume[0] = vl;
559 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -0800560 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700561}
562
563void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
564{
565 const int16_t vl = t->volume[0];
566 const int16_t vr = t->volume[1];
567
Glenn Kastenf6b16782011-12-15 09:51:17 -0800568 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800569 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700570 do {
571 int16_t l = (int16_t)(*temp++ >> 12);
572 int16_t r = (int16_t)(*temp++ >> 12);
573 out[0] = mulAdd(l, vl, out[0]);
574 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
575 out[1] = mulAdd(r, vr, out[1]);
576 out += 2;
577 aux[0] = mulAdd(a, va, aux[0]);
578 aux++;
579 } while (--frameCount);
580 } else {
581 do {
582 int16_t l = (int16_t)(*temp++ >> 12);
583 int16_t r = (int16_t)(*temp++ >> 12);
584 out[0] = mulAdd(l, vl, out[0]);
585 out[1] = mulAdd(r, vr, out[1]);
586 out += 2;
587 } while (--frameCount);
588 }
589}
590
591void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
592{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800593 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700594
Glenn Kastenf6b16782011-12-15 09:51:17 -0800595 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700596 int32_t l;
597 int32_t r;
598 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800599 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700600 int32_t vl = t->prevVolume[0];
601 int32_t vr = t->prevVolume[1];
602 int32_t va = t->prevAuxLevel;
603 const int32_t vlInc = t->volumeInc[0];
604 const int32_t vrInc = t->volumeInc[1];
605 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +0000606 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700607 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
608 // (vl + vlInc*frameCount)/65536.0f, frameCount);
609
610 do {
611 l = (int32_t)*in++;
612 r = (int32_t)*in++;
613 *out++ += (vl >> 16) * l;
614 *out++ += (vr >> 16) * r;
615 *aux++ += (va >> 17) * (l + r);
616 vl += vlInc;
617 vr += vrInc;
618 va += vaInc;
619 } while (--frameCount);
620
621 t->prevVolume[0] = vl;
622 t->prevVolume[1] = vr;
623 t->prevAuxLevel = va;
624 t->adjustVolumeRamp(true);
625 }
626
627 // constant gain
628 else {
629 const uint32_t vrl = t->volumeRL;
630 const int16_t va = (int16_t)t->auxLevel;
631 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800632 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700633 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
634 in += 2;
635 out[0] = mulAddRL(1, rl, vrl, out[0]);
636 out[1] = mulAddRL(0, rl, vrl, out[1]);
637 out += 2;
638 aux[0] = mulAdd(a, va, aux[0]);
639 aux++;
640 } while (--frameCount);
641 }
642 } else {
643 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800644 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700645 int32_t vl = t->prevVolume[0];
646 int32_t vr = t->prevVolume[1];
647 const int32_t vlInc = t->volumeInc[0];
648 const int32_t vrInc = t->volumeInc[1];
649
Steve Blockb8a80522011-12-20 16:23:08 +0000650 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700651 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
652 // (vl + vlInc*frameCount)/65536.0f, frameCount);
653
654 do {
655 *out++ += (vl >> 16) * (int32_t) *in++;
656 *out++ += (vr >> 16) * (int32_t) *in++;
657 vl += vlInc;
658 vr += vrInc;
659 } while (--frameCount);
660
661 t->prevVolume[0] = vl;
662 t->prevVolume[1] = vr;
663 t->adjustVolumeRamp(false);
664 }
665
666 // constant gain
667 else {
668 const uint32_t vrl = t->volumeRL;
669 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800670 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700671 in += 2;
672 out[0] = mulAddRL(1, rl, vrl, out[0]);
673 out[1] = mulAddRL(0, rl, vrl, out[1]);
674 out += 2;
675 } while (--frameCount);
676 }
677 }
678 t->in = in;
679}
680
681void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
682{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800683 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700684
Glenn Kastenf6b16782011-12-15 09:51:17 -0800685 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700686 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800687 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700688 int32_t vl = t->prevVolume[0];
689 int32_t vr = t->prevVolume[1];
690 int32_t va = t->prevAuxLevel;
691 const int32_t vlInc = t->volumeInc[0];
692 const int32_t vrInc = t->volumeInc[1];
693 const int32_t vaInc = t->auxInc;
694
Steve Blockb8a80522011-12-20 16:23:08 +0000695 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700696 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
697 // (vl + vlInc*frameCount)/65536.0f, frameCount);
698
699 do {
700 int32_t l = *in++;
701 *out++ += (vl >> 16) * l;
702 *out++ += (vr >> 16) * l;
703 *aux++ += (va >> 16) * l;
704 vl += vlInc;
705 vr += vrInc;
706 va += vaInc;
707 } while (--frameCount);
708
709 t->prevVolume[0] = vl;
710 t->prevVolume[1] = vr;
711 t->prevAuxLevel = va;
712 t->adjustVolumeRamp(true);
713 }
714 // constant gain
715 else {
716 const int16_t vl = t->volume[0];
717 const int16_t vr = t->volume[1];
718 const int16_t va = (int16_t)t->auxLevel;
719 do {
720 int16_t l = *in++;
721 out[0] = mulAdd(l, vl, out[0]);
722 out[1] = mulAdd(l, vr, out[1]);
723 out += 2;
724 aux[0] = mulAdd(l, va, aux[0]);
725 aux++;
726 } while (--frameCount);
727 }
728 } else {
729 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800730 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700731 int32_t vl = t->prevVolume[0];
732 int32_t vr = t->prevVolume[1];
733 const int32_t vlInc = t->volumeInc[0];
734 const int32_t vrInc = t->volumeInc[1];
735
Steve Blockb8a80522011-12-20 16:23:08 +0000736 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700737 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
738 // (vl + vlInc*frameCount)/65536.0f, frameCount);
739
740 do {
741 int32_t l = *in++;
742 *out++ += (vl >> 16) * l;
743 *out++ += (vr >> 16) * l;
744 vl += vlInc;
745 vr += vrInc;
746 } while (--frameCount);
747
748 t->prevVolume[0] = vl;
749 t->prevVolume[1] = vr;
750 t->adjustVolumeRamp(false);
751 }
752 // constant gain
753 else {
754 const int16_t vl = t->volume[0];
755 const int16_t vr = t->volume[1];
756 do {
757 int16_t l = *in++;
758 out[0] = mulAdd(l, vl, out[0]);
759 out[1] = mulAdd(l, vr, out[1]);
760 out += 2;
761 } while (--frameCount);
762 }
763 }
764 t->in = in;
765}
766
Mathias Agopian65ab4712010-07-14 17:59:35 -0700767// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -0800768void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700769{
770 uint32_t e0 = state->enabledTracks;
771 size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
772 while (e0) {
773 // process by group of tracks with same output buffer to
774 // avoid multiple memset() on same buffer
775 uint32_t e1 = e0, e2 = e0;
776 int i = 31 - __builtin_clz(e1);
777 track_t& t1 = state->tracks[i];
778 e2 &= ~(1<<i);
779 while (e2) {
780 i = 31 - __builtin_clz(e2);
781 e2 &= ~(1<<i);
782 track_t& t2 = state->tracks[i];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800783 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700784 e1 &= ~(1<<i);
785 }
786 }
787 e0 &= ~(e1);
788
789 memset(t1.mainBuffer, 0, bufSize);
790
791 while (e1) {
792 i = 31 - __builtin_clz(e1);
793 e1 &= ~(1<<i);
794 t1 = state->tracks[i];
795 size_t outFrames = state->frameCount;
796 while (outFrames) {
797 t1.buffer.frameCount = outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -0800798 int64_t outputPTS = calculateOutputPTS(
799 t1, pts, state->frameCount - outFrames);
800 t1.bufferProvider->getNextBuffer(&t1.buffer, outputPTS);
Glenn Kastena0d68332012-01-27 16:47:15 -0800801 if (t1.buffer.raw == NULL) break;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700802 outFrames -= t1.buffer.frameCount;
803 t1.bufferProvider->releaseBuffer(&t1.buffer);
804 }
805 }
806 }
807}
808
809// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -0800810void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700811{
812 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
813
814 // acquire each track's buffer
815 uint32_t enabledTracks = state->enabledTracks;
816 uint32_t e0 = enabledTracks;
817 while (e0) {
818 const int i = 31 - __builtin_clz(e0);
819 e0 &= ~(1<<i);
820 track_t& t = state->tracks[i];
821 t.buffer.frameCount = state->frameCount;
John Grossman4ff14ba2012-02-08 16:37:41 -0800822 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700823 t.frameCount = t.buffer.frameCount;
824 t.in = t.buffer.raw;
825 // t.in == NULL can happen if the track was flushed just after having
826 // been enabled for mixing.
827 if (t.in == NULL)
828 enabledTracks &= ~(1<<i);
829 }
830
831 e0 = enabledTracks;
832 while (e0) {
833 // process by group of tracks with same output buffer to
834 // optimize cache use
835 uint32_t e1 = e0, e2 = e0;
836 int j = 31 - __builtin_clz(e1);
837 track_t& t1 = state->tracks[j];
838 e2 &= ~(1<<j);
839 while (e2) {
840 j = 31 - __builtin_clz(e2);
841 e2 &= ~(1<<j);
842 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800843 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700844 e1 &= ~(1<<j);
845 }
846 }
847 e0 &= ~(e1);
848 // this assumes output 16 bits stereo, no resampling
849 int32_t *out = t1.mainBuffer;
850 size_t numFrames = 0;
851 do {
852 memset(outTemp, 0, sizeof(outTemp));
853 e2 = e1;
854 while (e2) {
855 const int i = 31 - __builtin_clz(e2);
856 e2 &= ~(1<<i);
857 track_t& t = state->tracks[i];
858 size_t outFrames = BLOCKSIZE;
859 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800860 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700861 aux = t.auxBuffer + numFrames;
862 }
863 while (outFrames) {
864 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
865 if (inFrames) {
Glenn Kastena1117922012-01-26 10:53:32 -0800866 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700867 t.frameCount -= inFrames;
868 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800869 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700870 aux += inFrames;
871 }
872 }
873 if (t.frameCount == 0 && outFrames) {
874 t.bufferProvider->releaseBuffer(&t.buffer);
875 t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -0800876 int64_t outputPTS = calculateOutputPTS(
877 t, pts, numFrames + (BLOCKSIZE - outFrames));
878 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700879 t.in = t.buffer.raw;
880 if (t.in == NULL) {
881 enabledTracks &= ~(1<<i);
882 e1 &= ~(1<<i);
883 break;
884 }
885 t.frameCount = t.buffer.frameCount;
886 }
887 }
888 }
889 ditherAndClamp(out, outTemp, BLOCKSIZE);
890 out += BLOCKSIZE;
891 numFrames += BLOCKSIZE;
892 } while (numFrames < state->frameCount);
893 }
894
895 // release each track's buffer
896 e0 = enabledTracks;
897 while (e0) {
898 const int i = 31 - __builtin_clz(e0);
899 e0 &= ~(1<<i);
900 track_t& t = state->tracks[i];
901 t.bufferProvider->releaseBuffer(&t.buffer);
902 }
903}
904
905
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800906// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -0800907void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700908{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800909 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -0700910 int32_t* const outTemp = state->outputTemp;
911 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700912
913 size_t numFrames = state->frameCount;
914
915 uint32_t e0 = state->enabledTracks;
916 while (e0) {
917 // process by group of tracks with same output buffer
918 // to optimize cache use
919 uint32_t e1 = e0, e2 = e0;
920 int j = 31 - __builtin_clz(e1);
921 track_t& t1 = state->tracks[j];
922 e2 &= ~(1<<j);
923 while (e2) {
924 j = 31 - __builtin_clz(e2);
925 e2 &= ~(1<<j);
926 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800927 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700928 e1 &= ~(1<<j);
929 }
930 }
931 e0 &= ~(e1);
932 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +0100933 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700934 while (e1) {
935 const int i = 31 - __builtin_clz(e1);
936 e1 &= ~(1<<i);
937 track_t& t = state->tracks[i];
938 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800939 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700940 aux = t.auxBuffer;
941 }
942
943 // this is a little goofy, on the resampling case we don't
944 // acquire/release the buffers because it's done by
945 // the resampler.
946 if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
John Grossman4ff14ba2012-02-08 16:37:41 -0800947 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -0800948 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700949 } else {
950
951 size_t outFrames = 0;
952
953 while (outFrames < numFrames) {
954 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -0800955 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
956 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700957 t.in = t.buffer.raw;
958 // t.in == NULL can happen if the track was flushed just after having
959 // been enabled for mixing.
960 if (t.in == NULL) break;
961
Glenn Kastenf6b16782011-12-15 09:51:17 -0800962 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700963 aux += outFrames;
964 }
Glenn Kastena1117922012-01-26 10:53:32 -0800965 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700966 outFrames += t.buffer.frameCount;
967 t.bufferProvider->releaseBuffer(&t.buffer);
968 }
969 }
970 }
971 ditherAndClamp(out, outTemp, numFrames);
972 }
973}
974
975// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -0800976void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
977 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700978{
Glenn Kasten99e53b82012-01-19 08:59:58 -0800979 // This method is only called when state->enabledTracks has exactly
980 // one bit set. The asserts below would verify this, but are commented out
981 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800982 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700983 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800984 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700985 const track_t& t = state->tracks[i];
986
987 AudioBufferProvider::Buffer& b(t.buffer);
988
989 int32_t* out = t.mainBuffer;
990 size_t numFrames = state->frameCount;
991
992 const int16_t vl = t.volume[0];
993 const int16_t vr = t.volume[1];
994 const uint32_t vrl = t.volumeRL;
995 while (numFrames) {
996 b.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -0800997 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
998 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -0800999 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001000
1001 // in == NULL can happen if the track was flushed just after having
1002 // been enabled for mixing.
1003 if (in == NULL || ((unsigned long)in & 3)) {
1004 memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
Steve Block29357bc2012-01-06 19:20:56 +00001005 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 -07001006 in, i, t.channelCount, t.needs);
1007 return;
1008 }
1009 size_t outFrames = b.frameCount;
1010
Glenn Kastenf6b16782011-12-15 09:51:17 -08001011 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001012 // volume is boosted, so we might need to clamp even though
1013 // we process only one track.
1014 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001015 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001016 in += 2;
1017 int32_t l = mulRL(1, rl, vrl) >> 12;
1018 int32_t r = mulRL(0, rl, vrl) >> 12;
1019 // clamping...
1020 l = clamp16(l);
1021 r = clamp16(r);
1022 *out++ = (r<<16) | (l & 0xFFFF);
1023 } while (--outFrames);
1024 } else {
1025 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001026 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001027 in += 2;
1028 int32_t l = mulRL(1, rl, vrl) >> 12;
1029 int32_t r = mulRL(0, rl, vrl) >> 12;
1030 *out++ = (r<<16) | (l & 0xFFFF);
1031 } while (--outFrames);
1032 }
1033 numFrames -= b.frameCount;
1034 t.bufferProvider->releaseBuffer(&b);
1035 }
1036}
1037
Glenn Kasten81a028f2011-12-15 09:53:12 -08001038#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001039// 2 tracks is also a common case
1040// NEVER used in current implementation of process__validate()
1041// only use if the 2 tracks have the same output buffer
John Grossman4ff14ba2012-02-08 16:37:41 -08001042void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
1043 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001044{
1045 int i;
1046 uint32_t en = state->enabledTracks;
1047
1048 i = 31 - __builtin_clz(en);
1049 const track_t& t0 = state->tracks[i];
1050 AudioBufferProvider::Buffer& b0(t0.buffer);
1051
1052 en &= ~(1<<i);
1053 i = 31 - __builtin_clz(en);
1054 const track_t& t1 = state->tracks[i];
1055 AudioBufferProvider::Buffer& b1(t1.buffer);
1056
Glenn Kasten54c3b662012-01-06 07:46:30 -08001057 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001058 const int16_t vl0 = t0.volume[0];
1059 const int16_t vr0 = t0.volume[1];
1060 size_t frameCount0 = 0;
1061
Glenn Kasten54c3b662012-01-06 07:46:30 -08001062 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001063 const int16_t vl1 = t1.volume[0];
1064 const int16_t vr1 = t1.volume[1];
1065 size_t frameCount1 = 0;
1066
1067 //FIXME: only works if two tracks use same buffer
1068 int32_t* out = t0.mainBuffer;
1069 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001070 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001071
1072
1073 while (numFrames) {
1074
1075 if (frameCount0 == 0) {
1076 b0.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001077 int64_t outputPTS = calculateOutputPTS(t0, pts,
1078 out - t0.mainBuffer);
1079 t0.bufferProvider->getNextBuffer(&b0, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001080 if (b0.i16 == NULL) {
1081 if (buff == NULL) {
1082 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1083 }
1084 in0 = buff;
1085 b0.frameCount = numFrames;
1086 } else {
1087 in0 = b0.i16;
1088 }
1089 frameCount0 = b0.frameCount;
1090 }
1091 if (frameCount1 == 0) {
1092 b1.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001093 int64_t outputPTS = calculateOutputPTS(t1, pts,
1094 out - t0.mainBuffer);
1095 t1.bufferProvider->getNextBuffer(&b1, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001096 if (b1.i16 == NULL) {
1097 if (buff == NULL) {
1098 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1099 }
1100 in1 = buff;
1101 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001102 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001103 in1 = b1.i16;
1104 }
1105 frameCount1 = b1.frameCount;
1106 }
1107
1108 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1109
1110 numFrames -= outFrames;
1111 frameCount0 -= outFrames;
1112 frameCount1 -= outFrames;
1113
1114 do {
1115 int32_t l0 = *in0++;
1116 int32_t r0 = *in0++;
1117 l0 = mul(l0, vl0);
1118 r0 = mul(r0, vr0);
1119 int32_t l = *in1++;
1120 int32_t r = *in1++;
1121 l = mulAdd(l, vl1, l0) >> 12;
1122 r = mulAdd(r, vr1, r0) >> 12;
1123 // clamping...
1124 l = clamp16(l);
1125 r = clamp16(r);
1126 *out++ = (r<<16) | (l & 0xFFFF);
1127 } while (--outFrames);
1128
1129 if (frameCount0 == 0) {
1130 t0.bufferProvider->releaseBuffer(&b0);
1131 }
1132 if (frameCount1 == 0) {
1133 t1.bufferProvider->releaseBuffer(&b1);
1134 }
1135 }
1136
Glenn Kastene9dd0172012-01-27 18:08:45 -08001137 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001138}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001139#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001140
John Grossman4ff14ba2012-02-08 16:37:41 -08001141int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1142 int outputFrameIndex)
1143{
1144 if (AudioBufferProvider::kInvalidPTS == basePTS)
1145 return AudioBufferProvider::kInvalidPTS;
1146
1147 return basePTS + ((outputFrameIndex * t.localTimeFreq) / t.sampleRate);
1148}
1149
Mathias Agopian65ab4712010-07-14 17:59:35 -07001150// ----------------------------------------------------------------------------
1151}; // namespace android