blob: 1f7d883068c40ff300346b0f0a6d7eb51e6e640a [file] [log] [blame]
Mathias Agopian65ab4712010-07-14 17:59:35 -07001/* //device/include/server/AudioFlinger/AudioMixer.cpp
2**
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
Glenn Kastenfba380a2011-12-15 15:46:46 -080021#include <assert.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070022#include <stdint.h>
23#include <string.h>
24#include <stdlib.h>
25#include <sys/types.h>
26
27#include <utils/Errors.h>
28#include <utils/Log.h>
29
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070030#include <cutils/bitops.h>
Glenn Kastenf6b16782011-12-15 09:51:17 -080031#include <cutils/compiler.h>
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>
36
Mathias Agopian65ab4712010-07-14 17:59:35 -070037#include "AudioMixer.h"
38
39namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070040
41// ----------------------------------------------------------------------------
42
43AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
Glenn Kasten9c56d4a2011-12-19 15:06:39 -080044 : mTrackNames(0), mSampleRate(sampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -070045{
Glenn Kasten788040c2011-05-05 08:19:00 -070046 // AudioMixer is not yet capable of multi-channel beyond stereo
47 assert(2 == MAX_NUM_CHANNELS);
Mathias Agopian65ab4712010-07-14 17:59:35 -070048 mState.enabledTracks= 0;
49 mState.needsChanged = 0;
50 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080051 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -080052 mState.outputTemp = NULL;
53 mState.resampleTemp = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080054 // mState.reserved
Mathias Agopian65ab4712010-07-14 17:59:35 -070055 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -080056 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -070057 t->needs = 0;
58 t->volume[0] = UNITY_GAIN;
59 t->volume[1] = UNITY_GAIN;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080060 // no initialization needed
61 // t->prevVolume[0]
62 // t->prevVolume[1]
Mathias Agopian65ab4712010-07-14 17:59:35 -070063 t->volumeInc[0] = 0;
64 t->volumeInc[1] = 0;
65 t->auxLevel = 0;
66 t->auxInc = 0;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080067 // no initialization needed
68 // t->prevAuxLevel
69 // t->frameCount
Mathias Agopian65ab4712010-07-14 17:59:35 -070070 t->channelCount = 2;
71 t->enabled = 0;
72 t->format = 16;
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070073 t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
Glenn Kastene0feee32011-12-13 11:53:26 -080074 t->bufferProvider = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080075 t->buffer.raw = NULL;
76 // t->buffer.frameCount
Glenn Kastene0feee32011-12-13 11:53:26 -080077 t->hook = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080078 t->in = NULL;
Glenn Kastene0feee32011-12-13 11:53:26 -080079 t->resampler = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -070080 t->sampleRate = mSampleRate;
Mathias Agopian65ab4712010-07-14 17:59:35 -070081 t->mainBuffer = NULL;
82 t->auxBuffer = NULL;
83 t++;
84 }
85}
86
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080087AudioMixer::~AudioMixer()
88{
89 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -080090 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080091 delete t->resampler;
92 t++;
93 }
94 delete [] mState.outputTemp;
95 delete [] mState.resampleTemp;
96}
Mathias Agopian65ab4712010-07-14 17:59:35 -070097
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080098int AudioMixer::getTrackName()
99{
Glenn Kasten98dd5422011-12-15 14:38:29 -0800100 uint32_t names = ~mTrackNames;
101 if (names != 0) {
102 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100103 ALOGV("add track (%d)", n);
Glenn Kasten98dd5422011-12-15 14:38:29 -0800104 mTrackNames |= 1 << n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700105 return TRACK0 + n;
106 }
107 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800108}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700109
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800110void AudioMixer::invalidateState(uint32_t mask)
111{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700112 if (mask) {
113 mState.needsChanged |= mask;
114 mState.hook = process__validate;
115 }
116 }
117
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800118void AudioMixer::deleteTrackName(int name)
119{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700120 name -= TRACK0;
Glenn Kasten237a6242011-12-15 15:32:27 -0800121 assert(uint32_t(name) < MAX_NUM_TRACKS);
122 ALOGV("deleteTrackName(%d)", name);
123 track_t& track(mState.tracks[ name ]);
124 if (track.enabled != 0) {
125 track.enabled = 0;
126 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700127 }
Glenn Kasten237a6242011-12-15 15:32:27 -0800128 if (track.resampler) {
129 // delete the resampler
130 delete track.resampler;
131 track.resampler = NULL;
132 track.sampleRate = mSampleRate;
133 invalidateState(1<<name);
134 }
135 track.volumeInc[0] = 0;
136 track.volumeInc[1] = 0;
137 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800138}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700139
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800140void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700141{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800142 name -= TRACK0;
143 assert(uint32_t(name) < MAX_NUM_TRACKS);
144 track_t& track = mState.tracks[name];
145
146 if (track.enabled != 1) {
147 track.enabled = 1;
148 ALOGV("enable(%d)", name);
149 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700150 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700151}
152
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800153void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700154{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800155 name -= TRACK0;
156 assert(uint32_t(name) < MAX_NUM_TRACKS);
157 track_t& track = mState.tracks[name];
158
159 if (track.enabled != 0) {
160 track.enabled = 0;
161 ALOGV("disable(%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::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700167{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800168 name -= TRACK0;
169 assert(uint32_t(name) < MAX_NUM_TRACKS);
170 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700171
Mathias Agopian65ab4712010-07-14 17:59:35 -0700172 int valueInt = (int)value;
173 int32_t *valueBuf = (int32_t *)value;
174
175 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700176
Mathias Agopian65ab4712010-07-14 17:59:35 -0700177 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800178 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700179 case CHANNEL_MASK: {
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700180 uint32_t mask = (uint32_t)value;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800181 if (track.channelMask != mask) {
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700182 uint8_t channelCount = popcount(mask);
Glenn Kasten788040c2011-05-05 08:19:00 -0700183 assert((channelCount <= MAX_NUM_CHANNELS) && (channelCount));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800184 track.channelMask = mask;
185 track.channelCount = channelCount;
Glenn Kasten788040c2011-05-05 08:19:00 -0700186 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800187 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700188 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700189 } break;
190 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800191 if (track.mainBuffer != valueBuf) {
192 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100193 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800194 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700195 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700196 break;
197 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800198 if (track.auxBuffer != valueBuf) {
199 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100200 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
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 default:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800205 // bad param
Glenn Kasten788040c2011-05-05 08:19:00 -0700206 assert(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700207 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700208 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700209
Mathias Agopian65ab4712010-07-14 17:59:35 -0700210 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800211 switch (param) {
212 case SAMPLE_RATE:
Glenn Kasten788040c2011-05-05 08:19:00 -0700213 assert(valueInt > 0);
Glenn Kasten788040c2011-05-05 08:19:00 -0700214 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
215 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
216 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800217 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700218 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800219 break;
220 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800221 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800222 invalidateState(1 << name);
223 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700224 default:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800225 // bad param
Glenn Kasten788040c2011-05-05 08:19:00 -0700226 assert(false);
Eric Laurent243f5f92011-02-28 16:52:51 -0800227 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700228 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700229
Mathias Agopian65ab4712010-07-14 17:59:35 -0700230 case RAMP_VOLUME:
231 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800232 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700233 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800234 case VOLUME1:
235 if (track.volume[param-VOLUME0] != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100236 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800237 track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16;
238 track.volume[param-VOLUME0] = valueInt;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700239 if (target == VOLUME) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800240 track.prevVolume[param-VOLUME0] = valueInt << 16;
241 track.volumeInc[param-VOLUME0] = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700242 } else {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800243 int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700244 int32_t volInc = d / int32_t(mState.frameCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800245 track.volumeInc[param-VOLUME0] = volInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700246 if (volInc == 0) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800247 track.prevVolume[param-VOLUME0] = valueInt << 16;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700248 }
249 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800250 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700251 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800252 break;
253 case AUXLEVEL:
Mathias Agopian65ab4712010-07-14 17:59:35 -0700254 if (track.auxLevel != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100255 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700256 track.prevAuxLevel = track.auxLevel << 16;
257 track.auxLevel = valueInt;
258 if (target == VOLUME) {
259 track.prevAuxLevel = valueInt << 16;
260 track.auxInc = 0;
261 } else {
262 int32_t d = (valueInt<<16) - track.prevAuxLevel;
263 int32_t volInc = d / int32_t(mState.frameCount);
264 track.auxInc = volInc;
265 if (volInc == 0) {
266 track.prevAuxLevel = valueInt << 16;
267 }
268 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800269 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700270 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800271 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700272 default:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800273 // bad param
Glenn Kasten788040c2011-05-05 08:19:00 -0700274 assert(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700275 }
276 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700277
278 default:
279 // bad target
280 assert(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700281 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700282}
283
284bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
285{
286 if (value!=devSampleRate || resampler) {
287 if (sampleRate != value) {
288 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800289 if (resampler == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700290 resampler = AudioResampler::create(
291 format, channelCount, devSampleRate);
292 }
293 return true;
294 }
295 }
296 return false;
297}
298
299bool AudioMixer::track_t::doesResample() const
300{
Glenn Kastene0feee32011-12-13 11:53:26 -0800301 return resampler != NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700302}
303
Eric Laurent243f5f92011-02-28 16:52:51 -0800304void AudioMixer::track_t::resetResampler()
305{
Glenn Kastene0feee32011-12-13 11:53:26 -0800306 if (resampler != NULL) {
Eric Laurent243f5f92011-02-28 16:52:51 -0800307 resampler->reset();
308 }
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
Eric Laurent071ccd52011-12-22 16:08:41 -0800330size_t AudioMixer::track_t::getUnreleasedFrames()
331{
332 if (resampler != NULL) {
333 return resampler->getUnreleasedFrames();
334 }
335 return 0;
336}
337
338size_t AudioMixer::getUnreleasedFrames(int name)
339{
340 name -= TRACK0;
341 if (uint32_t(name) < MAX_NUM_TRACKS) {
342 track_t& track(mState.tracks[name]);
343 return track.getUnreleasedFrames();
344 }
345 return 0;
346}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700347
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800348void AudioMixer::setBufferProvider(int name, AudioBufferProvider* buffer)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700349{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800350 name -= TRACK0;
351 assert(uint32_t(name) < MAX_NUM_TRACKS);
352 mState.tracks[name].bufferProvider = buffer;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700353}
354
355
356
357void AudioMixer::process()
358{
359 mState.hook(&mState);
360}
361
362
363void AudioMixer::process__validate(state_t* state)
364{
Steve Block5ff1dd52012-01-05 23:22:43 +0000365 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700366 "in process__validate() but nothing's invalid");
367
368 uint32_t changed = state->needsChanged;
369 state->needsChanged = 0; // clear the validation flag
370
371 // recompute which tracks are enabled / disabled
372 uint32_t enabled = 0;
373 uint32_t disabled = 0;
374 while (changed) {
375 const int i = 31 - __builtin_clz(changed);
376 const uint32_t mask = 1<<i;
377 changed &= ~mask;
378 track_t& t = state->tracks[i];
379 (t.enabled ? enabled : disabled) |= mask;
380 }
381 state->enabledTracks &= ~disabled;
382 state->enabledTracks |= enabled;
383
384 // compute everything we need...
385 int countActiveTracks = 0;
386 int all16BitsStereoNoResample = 1;
387 int resampling = 0;
388 int volumeRamp = 0;
389 uint32_t en = state->enabledTracks;
390 while (en) {
391 const int i = 31 - __builtin_clz(en);
392 en &= ~(1<<i);
393
394 countActiveTracks++;
395 track_t& t = state->tracks[i];
396 uint32_t n = 0;
397 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
398 n |= NEEDS_FORMAT_16;
399 n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
400 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
401 n |= NEEDS_AUX_ENABLED;
402 }
403
404 if (t.volumeInc[0]|t.volumeInc[1]) {
405 volumeRamp = 1;
406 } else if (!t.doesResample() && t.volumeRL == 0) {
407 n |= NEEDS_MUTE_ENABLED;
408 }
409 t.needs = n;
410
411 if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
412 t.hook = track__nop;
413 } else {
414 if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
415 all16BitsStereoNoResample = 0;
416 }
417 if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
418 all16BitsStereoNoResample = 0;
419 resampling = 1;
420 t.hook = track__genericResample;
421 } else {
422 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
423 t.hook = track__16BitsMono;
424 all16BitsStereoNoResample = 0;
425 }
426 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
427 t.hook = track__16BitsStereo;
428 }
429 }
430 }
431 }
432
433 // select the processing hooks
434 state->hook = process__nop;
435 if (countActiveTracks) {
436 if (resampling) {
437 if (!state->outputTemp) {
438 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
439 }
440 if (!state->resampleTemp) {
441 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
442 }
443 state->hook = process__genericResampling;
444 } else {
445 if (state->outputTemp) {
446 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800447 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700448 }
449 if (state->resampleTemp) {
450 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800451 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700452 }
453 state->hook = process__genericNoResampling;
454 if (all16BitsStereoNoResample && !volumeRamp) {
455 if (countActiveTracks == 1) {
456 state->hook = process__OneTrack16BitsStereoNoResampling;
457 }
458 }
459 }
460 }
461
Steve Block3856b092011-10-20 11:56:00 +0100462 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700463 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
464 countActiveTracks, state->enabledTracks,
465 all16BitsStereoNoResample, resampling, volumeRamp);
466
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800467 state->hook(state);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700468
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800469 // Now that the volume ramp has been done, set optimal state and
470 // track hooks for subsequent mixer process
471 if (countActiveTracks) {
472 int allMuted = 1;
473 uint32_t en = state->enabledTracks;
474 while (en) {
475 const int i = 31 - __builtin_clz(en);
476 en &= ~(1<<i);
477 track_t& t = state->tracks[i];
478 if (!t.doesResample() && t.volumeRL == 0)
479 {
480 t.needs |= NEEDS_MUTE_ENABLED;
481 t.hook = track__nop;
482 } else {
483 allMuted = 0;
484 }
485 }
486 if (allMuted) {
487 state->hook = process__nop;
488 } else if (all16BitsStereoNoResample) {
489 if (countActiveTracks == 1) {
490 state->hook = process__OneTrack16BitsStereoNoResampling;
491 }
492 }
493 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700494}
495
Mathias Agopian65ab4712010-07-14 17:59:35 -0700496
497void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
498{
499 t->resampler->setSampleRate(t->sampleRate);
500
501 // ramp gain - resample to temp buffer and scale/mix in 2nd step
502 if (aux != NULL) {
503 // always resample with unity gain when sending to auxiliary buffer to be able
504 // to apply send level after resampling
505 // TODO: modify each resampler to support aux channel?
506 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
507 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
508 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -0800509 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700510 volumeRampStereo(t, out, outFrameCount, temp, aux);
511 } else {
512 volumeStereo(t, out, outFrameCount, temp, aux);
513 }
514 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -0800515 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700516 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
517 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
518 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
519 volumeRampStereo(t, out, outFrameCount, temp, aux);
520 }
521
522 // constant gain
523 else {
524 t->resampler->setVolume(t->volume[0], t->volume[1]);
525 t->resampler->resample(out, outFrameCount, t->bufferProvider);
526 }
527 }
528}
529
530void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
531{
532}
533
534void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
535{
536 int32_t vl = t->prevVolume[0];
537 int32_t vr = t->prevVolume[1];
538 const int32_t vlInc = t->volumeInc[0];
539 const int32_t vrInc = t->volumeInc[1];
540
Steve Blockb8a80522011-12-20 16:23:08 +0000541 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700542 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
543 // (vl + vlInc*frameCount)/65536.0f, frameCount);
544
545 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -0800546 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700547 int32_t va = t->prevAuxLevel;
548 const int32_t vaInc = t->auxInc;
549 int32_t l;
550 int32_t r;
551
552 do {
553 l = (*temp++ >> 12);
554 r = (*temp++ >> 12);
555 *out++ += (vl >> 16) * l;
556 *out++ += (vr >> 16) * r;
557 *aux++ += (va >> 17) * (l + r);
558 vl += vlInc;
559 vr += vrInc;
560 va += vaInc;
561 } while (--frameCount);
562 t->prevAuxLevel = va;
563 } else {
564 do {
565 *out++ += (vl >> 16) * (*temp++ >> 12);
566 *out++ += (vr >> 16) * (*temp++ >> 12);
567 vl += vlInc;
568 vr += vrInc;
569 } while (--frameCount);
570 }
571 t->prevVolume[0] = vl;
572 t->prevVolume[1] = vr;
573 t->adjustVolumeRamp((aux != NULL));
574}
575
576void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
577{
578 const int16_t vl = t->volume[0];
579 const int16_t vr = t->volume[1];
580
Glenn Kastenf6b16782011-12-15 09:51:17 -0800581 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700582 const int16_t va = (int16_t)t->auxLevel;
583 do {
584 int16_t l = (int16_t)(*temp++ >> 12);
585 int16_t r = (int16_t)(*temp++ >> 12);
586 out[0] = mulAdd(l, vl, out[0]);
587 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
588 out[1] = mulAdd(r, vr, out[1]);
589 out += 2;
590 aux[0] = mulAdd(a, va, aux[0]);
591 aux++;
592 } while (--frameCount);
593 } else {
594 do {
595 int16_t l = (int16_t)(*temp++ >> 12);
596 int16_t r = (int16_t)(*temp++ >> 12);
597 out[0] = mulAdd(l, vl, out[0]);
598 out[1] = mulAdd(r, vr, out[1]);
599 out += 2;
600 } while (--frameCount);
601 }
602}
603
604void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
605{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800606 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700607
Glenn Kastenf6b16782011-12-15 09:51:17 -0800608 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700609 int32_t l;
610 int32_t r;
611 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800612 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700613 int32_t vl = t->prevVolume[0];
614 int32_t vr = t->prevVolume[1];
615 int32_t va = t->prevAuxLevel;
616 const int32_t vlInc = t->volumeInc[0];
617 const int32_t vrInc = t->volumeInc[1];
618 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +0000619 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700620 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
621 // (vl + vlInc*frameCount)/65536.0f, frameCount);
622
623 do {
624 l = (int32_t)*in++;
625 r = (int32_t)*in++;
626 *out++ += (vl >> 16) * l;
627 *out++ += (vr >> 16) * r;
628 *aux++ += (va >> 17) * (l + r);
629 vl += vlInc;
630 vr += vrInc;
631 va += vaInc;
632 } while (--frameCount);
633
634 t->prevVolume[0] = vl;
635 t->prevVolume[1] = vr;
636 t->prevAuxLevel = va;
637 t->adjustVolumeRamp(true);
638 }
639
640 // constant gain
641 else {
642 const uint32_t vrl = t->volumeRL;
643 const int16_t va = (int16_t)t->auxLevel;
644 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800645 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700646 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
647 in += 2;
648 out[0] = mulAddRL(1, rl, vrl, out[0]);
649 out[1] = mulAddRL(0, rl, vrl, out[1]);
650 out += 2;
651 aux[0] = mulAdd(a, va, aux[0]);
652 aux++;
653 } while (--frameCount);
654 }
655 } else {
656 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800657 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700658 int32_t vl = t->prevVolume[0];
659 int32_t vr = t->prevVolume[1];
660 const int32_t vlInc = t->volumeInc[0];
661 const int32_t vrInc = t->volumeInc[1];
662
Steve Blockb8a80522011-12-20 16:23:08 +0000663 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700664 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
665 // (vl + vlInc*frameCount)/65536.0f, frameCount);
666
667 do {
668 *out++ += (vl >> 16) * (int32_t) *in++;
669 *out++ += (vr >> 16) * (int32_t) *in++;
670 vl += vlInc;
671 vr += vrInc;
672 } while (--frameCount);
673
674 t->prevVolume[0] = vl;
675 t->prevVolume[1] = vr;
676 t->adjustVolumeRamp(false);
677 }
678
679 // constant gain
680 else {
681 const uint32_t vrl = t->volumeRL;
682 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800683 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700684 in += 2;
685 out[0] = mulAddRL(1, rl, vrl, out[0]);
686 out[1] = mulAddRL(0, rl, vrl, out[1]);
687 out += 2;
688 } while (--frameCount);
689 }
690 }
691 t->in = in;
692}
693
694void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
695{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800696 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700697
Glenn Kastenf6b16782011-12-15 09:51:17 -0800698 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700699 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800700 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700701 int32_t vl = t->prevVolume[0];
702 int32_t vr = t->prevVolume[1];
703 int32_t va = t->prevAuxLevel;
704 const int32_t vlInc = t->volumeInc[0];
705 const int32_t vrInc = t->volumeInc[1];
706 const int32_t vaInc = t->auxInc;
707
Steve Blockb8a80522011-12-20 16:23:08 +0000708 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700709 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
710 // (vl + vlInc*frameCount)/65536.0f, frameCount);
711
712 do {
713 int32_t l = *in++;
714 *out++ += (vl >> 16) * l;
715 *out++ += (vr >> 16) * l;
716 *aux++ += (va >> 16) * l;
717 vl += vlInc;
718 vr += vrInc;
719 va += vaInc;
720 } while (--frameCount);
721
722 t->prevVolume[0] = vl;
723 t->prevVolume[1] = vr;
724 t->prevAuxLevel = va;
725 t->adjustVolumeRamp(true);
726 }
727 // constant gain
728 else {
729 const int16_t vl = t->volume[0];
730 const int16_t vr = t->volume[1];
731 const int16_t va = (int16_t)t->auxLevel;
732 do {
733 int16_t l = *in++;
734 out[0] = mulAdd(l, vl, out[0]);
735 out[1] = mulAdd(l, vr, out[1]);
736 out += 2;
737 aux[0] = mulAdd(l, va, aux[0]);
738 aux++;
739 } while (--frameCount);
740 }
741 } else {
742 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800743 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700744 int32_t vl = t->prevVolume[0];
745 int32_t vr = t->prevVolume[1];
746 const int32_t vlInc = t->volumeInc[0];
747 const int32_t vrInc = t->volumeInc[1];
748
Steve Blockb8a80522011-12-20 16:23:08 +0000749 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700750 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
751 // (vl + vlInc*frameCount)/65536.0f, frameCount);
752
753 do {
754 int32_t l = *in++;
755 *out++ += (vl >> 16) * l;
756 *out++ += (vr >> 16) * l;
757 vl += vlInc;
758 vr += vrInc;
759 } while (--frameCount);
760
761 t->prevVolume[0] = vl;
762 t->prevVolume[1] = vr;
763 t->adjustVolumeRamp(false);
764 }
765 // constant gain
766 else {
767 const int16_t vl = t->volume[0];
768 const int16_t vr = t->volume[1];
769 do {
770 int16_t l = *in++;
771 out[0] = mulAdd(l, vl, out[0]);
772 out[1] = mulAdd(l, vr, out[1]);
773 out += 2;
774 } while (--frameCount);
775 }
776 }
777 t->in = in;
778}
779
Mathias Agopian65ab4712010-07-14 17:59:35 -0700780// no-op case
781void AudioMixer::process__nop(state_t* state)
782{
783 uint32_t e0 = state->enabledTracks;
784 size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
785 while (e0) {
786 // process by group of tracks with same output buffer to
787 // avoid multiple memset() on same buffer
788 uint32_t e1 = e0, e2 = e0;
789 int i = 31 - __builtin_clz(e1);
790 track_t& t1 = state->tracks[i];
791 e2 &= ~(1<<i);
792 while (e2) {
793 i = 31 - __builtin_clz(e2);
794 e2 &= ~(1<<i);
795 track_t& t2 = state->tracks[i];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800796 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700797 e1 &= ~(1<<i);
798 }
799 }
800 e0 &= ~(e1);
801
802 memset(t1.mainBuffer, 0, bufSize);
803
804 while (e1) {
805 i = 31 - __builtin_clz(e1);
806 e1 &= ~(1<<i);
807 t1 = state->tracks[i];
808 size_t outFrames = state->frameCount;
809 while (outFrames) {
810 t1.buffer.frameCount = outFrames;
811 t1.bufferProvider->getNextBuffer(&t1.buffer);
812 if (!t1.buffer.raw) break;
813 outFrames -= t1.buffer.frameCount;
814 t1.bufferProvider->releaseBuffer(&t1.buffer);
815 }
816 }
817 }
818}
819
820// generic code without resampling
821void AudioMixer::process__genericNoResampling(state_t* state)
822{
823 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
824
825 // acquire each track's buffer
826 uint32_t enabledTracks = state->enabledTracks;
827 uint32_t e0 = enabledTracks;
828 while (e0) {
829 const int i = 31 - __builtin_clz(e0);
830 e0 &= ~(1<<i);
831 track_t& t = state->tracks[i];
832 t.buffer.frameCount = state->frameCount;
833 t.bufferProvider->getNextBuffer(&t.buffer);
834 t.frameCount = t.buffer.frameCount;
835 t.in = t.buffer.raw;
836 // t.in == NULL can happen if the track was flushed just after having
837 // been enabled for mixing.
838 if (t.in == NULL)
839 enabledTracks &= ~(1<<i);
840 }
841
842 e0 = enabledTracks;
843 while (e0) {
844 // process by group of tracks with same output buffer to
845 // optimize cache use
846 uint32_t e1 = e0, e2 = e0;
847 int j = 31 - __builtin_clz(e1);
848 track_t& t1 = state->tracks[j];
849 e2 &= ~(1<<j);
850 while (e2) {
851 j = 31 - __builtin_clz(e2);
852 e2 &= ~(1<<j);
853 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800854 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700855 e1 &= ~(1<<j);
856 }
857 }
858 e0 &= ~(e1);
859 // this assumes output 16 bits stereo, no resampling
860 int32_t *out = t1.mainBuffer;
861 size_t numFrames = 0;
862 do {
863 memset(outTemp, 0, sizeof(outTemp));
864 e2 = e1;
865 while (e2) {
866 const int i = 31 - __builtin_clz(e2);
867 e2 &= ~(1<<i);
868 track_t& t = state->tracks[i];
869 size_t outFrames = BLOCKSIZE;
870 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800871 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700872 aux = t.auxBuffer + numFrames;
873 }
874 while (outFrames) {
875 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
876 if (inFrames) {
877 (t.hook)(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
878 t.frameCount -= inFrames;
879 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800880 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700881 aux += inFrames;
882 }
883 }
884 if (t.frameCount == 0 && outFrames) {
885 t.bufferProvider->releaseBuffer(&t.buffer);
886 t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames);
887 t.bufferProvider->getNextBuffer(&t.buffer);
888 t.in = t.buffer.raw;
889 if (t.in == NULL) {
890 enabledTracks &= ~(1<<i);
891 e1 &= ~(1<<i);
892 break;
893 }
894 t.frameCount = t.buffer.frameCount;
895 }
896 }
897 }
898 ditherAndClamp(out, outTemp, BLOCKSIZE);
899 out += BLOCKSIZE;
900 numFrames += BLOCKSIZE;
901 } while (numFrames < state->frameCount);
902 }
903
904 // release each track's buffer
905 e0 = enabledTracks;
906 while (e0) {
907 const int i = 31 - __builtin_clz(e0);
908 e0 &= ~(1<<i);
909 track_t& t = state->tracks[i];
910 t.bufferProvider->releaseBuffer(&t.buffer);
911 }
912}
913
914
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800915// generic code with resampling
Mathias Agopian65ab4712010-07-14 17:59:35 -0700916void AudioMixer::process__genericResampling(state_t* state)
917{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800918 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -0700919 int32_t* const outTemp = state->outputTemp;
920 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700921
922 size_t numFrames = state->frameCount;
923
924 uint32_t e0 = state->enabledTracks;
925 while (e0) {
926 // process by group of tracks with same output buffer
927 // to optimize cache use
928 uint32_t e1 = e0, e2 = e0;
929 int j = 31 - __builtin_clz(e1);
930 track_t& t1 = state->tracks[j];
931 e2 &= ~(1<<j);
932 while (e2) {
933 j = 31 - __builtin_clz(e2);
934 e2 &= ~(1<<j);
935 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800936 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700937 e1 &= ~(1<<j);
938 }
939 }
940 e0 &= ~(e1);
941 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +0100942 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700943 while (e1) {
944 const int i = 31 - __builtin_clz(e1);
945 e1 &= ~(1<<i);
946 track_t& t = state->tracks[i];
947 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800948 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700949 aux = t.auxBuffer;
950 }
951
952 // this is a little goofy, on the resampling case we don't
953 // acquire/release the buffers because it's done by
954 // the resampler.
955 if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
956 (t.hook)(&t, outTemp, numFrames, state->resampleTemp, aux);
957 } else {
958
959 size_t outFrames = 0;
960
961 while (outFrames < numFrames) {
962 t.buffer.frameCount = numFrames - outFrames;
963 t.bufferProvider->getNextBuffer(&t.buffer);
964 t.in = t.buffer.raw;
965 // t.in == NULL can happen if the track was flushed just after having
966 // been enabled for mixing.
967 if (t.in == NULL) break;
968
Glenn Kastenf6b16782011-12-15 09:51:17 -0800969 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700970 aux += outFrames;
971 }
972 (t.hook)(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
973 outFrames += t.buffer.frameCount;
974 t.bufferProvider->releaseBuffer(&t.buffer);
975 }
976 }
977 }
978 ditherAndClamp(out, outTemp, numFrames);
979 }
980}
981
982// one track, 16 bits stereo without resampling is the most common case
983void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state)
984{
985 const int i = 31 - __builtin_clz(state->enabledTracks);
986 const track_t& t = state->tracks[i];
987
988 AudioBufferProvider::Buffer& b(t.buffer);
989
990 int32_t* out = t.mainBuffer;
991 size_t numFrames = state->frameCount;
992
993 const int16_t vl = t.volume[0];
994 const int16_t vr = t.volume[1];
995 const uint32_t vrl = t.volumeRL;
996 while (numFrames) {
997 b.frameCount = numFrames;
998 t.bufferProvider->getNextBuffer(&b);
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
1042void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state)
1043{
1044 int i;
1045 uint32_t en = state->enabledTracks;
1046
1047 i = 31 - __builtin_clz(en);
1048 const track_t& t0 = state->tracks[i];
1049 AudioBufferProvider::Buffer& b0(t0.buffer);
1050
1051 en &= ~(1<<i);
1052 i = 31 - __builtin_clz(en);
1053 const track_t& t1 = state->tracks[i];
1054 AudioBufferProvider::Buffer& b1(t1.buffer);
1055
Glenn Kasten54c3b662012-01-06 07:46:30 -08001056 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001057 const int16_t vl0 = t0.volume[0];
1058 const int16_t vr0 = t0.volume[1];
1059 size_t frameCount0 = 0;
1060
Glenn Kasten54c3b662012-01-06 07:46:30 -08001061 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001062 const int16_t vl1 = t1.volume[0];
1063 const int16_t vr1 = t1.volume[1];
1064 size_t frameCount1 = 0;
1065
1066 //FIXME: only works if two tracks use same buffer
1067 int32_t* out = t0.mainBuffer;
1068 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001069 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001070
1071
1072 while (numFrames) {
1073
1074 if (frameCount0 == 0) {
1075 b0.frameCount = numFrames;
1076 t0.bufferProvider->getNextBuffer(&b0);
1077 if (b0.i16 == NULL) {
1078 if (buff == NULL) {
1079 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1080 }
1081 in0 = buff;
1082 b0.frameCount = numFrames;
1083 } else {
1084 in0 = b0.i16;
1085 }
1086 frameCount0 = b0.frameCount;
1087 }
1088 if (frameCount1 == 0) {
1089 b1.frameCount = numFrames;
1090 t1.bufferProvider->getNextBuffer(&b1);
1091 if (b1.i16 == NULL) {
1092 if (buff == NULL) {
1093 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1094 }
1095 in1 = buff;
1096 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001097 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001098 in1 = b1.i16;
1099 }
1100 frameCount1 = b1.frameCount;
1101 }
1102
1103 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1104
1105 numFrames -= outFrames;
1106 frameCount0 -= outFrames;
1107 frameCount1 -= outFrames;
1108
1109 do {
1110 int32_t l0 = *in0++;
1111 int32_t r0 = *in0++;
1112 l0 = mul(l0, vl0);
1113 r0 = mul(r0, vr0);
1114 int32_t l = *in1++;
1115 int32_t r = *in1++;
1116 l = mulAdd(l, vl1, l0) >> 12;
1117 r = mulAdd(r, vr1, r0) >> 12;
1118 // clamping...
1119 l = clamp16(l);
1120 r = clamp16(r);
1121 *out++ = (r<<16) | (l & 0xFFFF);
1122 } while (--outFrames);
1123
1124 if (frameCount0 == 0) {
1125 t0.bufferProvider->releaseBuffer(&b0);
1126 }
1127 if (frameCount1 == 0) {
1128 t1.bufferProvider->releaseBuffer(&b1);
1129 }
1130 }
1131
Glenn Kastene9dd0172012-01-27 18:08:45 -08001132 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001133}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001134#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001135
1136// ----------------------------------------------------------------------------
1137}; // namespace android