blob: bd4c939f0fcda9cfe6cdf8a50997481bcd154a06 [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
45AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
Glenn Kasten9c56d4a2011-12-19 15:06:39 -080046 : mTrackNames(0), 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
51 LocalClock lc;
52
Mathias Agopian65ab4712010-07-14 17:59:35 -070053 mState.enabledTracks= 0;
54 mState.needsChanged = 0;
55 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080056 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -080057 mState.outputTemp = NULL;
58 mState.resampleTemp = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080059 // mState.reserved
Glenn Kasten17a736c2012-02-14 08:52:15 -080060
61 // FIXME Most of the following initialization is probably redundant since
62 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
63 // and mTrackNames is initially 0. However, leave it here until that's verified.
Mathias Agopian65ab4712010-07-14 17:59:35 -070064 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -080065 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -070066 t->needs = 0;
67 t->volume[0] = UNITY_GAIN;
68 t->volume[1] = UNITY_GAIN;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080069 // no initialization needed
70 // t->prevVolume[0]
71 // t->prevVolume[1]
Mathias Agopian65ab4712010-07-14 17:59:35 -070072 t->volumeInc[0] = 0;
73 t->volumeInc[1] = 0;
74 t->auxLevel = 0;
75 t->auxInc = 0;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080076 // no initialization needed
77 // t->prevAuxLevel
78 // t->frameCount
Mathias Agopian65ab4712010-07-14 17:59:35 -070079 t->channelCount = 2;
Glenn Kasten4c340c62012-01-27 12:33:54 -080080 t->enabled = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -070081 t->format = 16;
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070082 t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
Glenn Kastene0feee32011-12-13 11:53:26 -080083 t->bufferProvider = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080084 t->buffer.raw = NULL;
85 // t->buffer.frameCount
Glenn Kastene0feee32011-12-13 11:53:26 -080086 t->hook = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080087 t->in = NULL;
Glenn Kastene0feee32011-12-13 11:53:26 -080088 t->resampler = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -070089 t->sampleRate = mSampleRate;
Mathias Agopian65ab4712010-07-14 17:59:35 -070090 t->mainBuffer = NULL;
91 t->auxBuffer = NULL;
John Grossman4ff14ba2012-02-08 16:37:41 -080092 t->localTimeFreq = lc.getLocalFreq();
Mathias Agopian65ab4712010-07-14 17:59:35 -070093 t++;
94 }
95}
96
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080097AudioMixer::~AudioMixer()
98{
99 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800100 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800101 delete t->resampler;
102 t++;
103 }
104 delete [] mState.outputTemp;
105 delete [] mState.resampleTemp;
106}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700107
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800108int AudioMixer::getTrackName()
109{
Glenn Kasten98dd5422011-12-15 14:38:29 -0800110 uint32_t names = ~mTrackNames;
111 if (names != 0) {
112 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100113 ALOGV("add track (%d)", n);
Glenn Kasten98dd5422011-12-15 14:38:29 -0800114 mTrackNames |= 1 << n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700115 return TRACK0 + n;
116 }
117 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800118}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700119
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800120void AudioMixer::invalidateState(uint32_t mask)
121{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700122 if (mask) {
123 mState.needsChanged |= mask;
124 mState.hook = process__validate;
125 }
126 }
127
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800128void AudioMixer::deleteTrackName(int name)
129{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700130 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800131 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800132 ALOGV("deleteTrackName(%d)", name);
133 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800134 if (track.enabled) {
135 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800136 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700137 }
Glenn Kastena0d68332012-01-27 16:47:15 -0800138 if (track.resampler != NULL) {
Glenn Kasten237a6242011-12-15 15:32:27 -0800139 // delete the resampler
140 delete track.resampler;
141 track.resampler = NULL;
142 track.sampleRate = mSampleRate;
143 invalidateState(1<<name);
144 }
145 track.volumeInc[0] = 0;
146 track.volumeInc[1] = 0;
147 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800148}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700149
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800150void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700151{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800152 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800153 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800154 track_t& track = mState.tracks[name];
155
Glenn Kasten4c340c62012-01-27 12:33:54 -0800156 if (!track.enabled) {
157 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800158 ALOGV("enable(%d)", name);
159 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700160 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700161}
162
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800163void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700164{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800165 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800166 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800167 track_t& track = mState.tracks[name];
168
Glenn Kasten4c340c62012-01-27 12:33:54 -0800169 if (track.enabled) {
170 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800171 ALOGV("disable(%d)", name);
172 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700173 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700174}
175
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800176void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700177{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800178 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800179 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800180 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700181
Mathias Agopian65ab4712010-07-14 17:59:35 -0700182 int valueInt = (int)value;
183 int32_t *valueBuf = (int32_t *)value;
184
185 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700186
Mathias Agopian65ab4712010-07-14 17:59:35 -0700187 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800188 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700189 case CHANNEL_MASK: {
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700190 uint32_t mask = (uint32_t)value;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800191 if (track.channelMask != mask) {
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800192 uint32_t channelCount = popcount(mask);
193 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS) && (channelCount),
194 "bad channel count %u", channelCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800195 track.channelMask = mask;
196 track.channelCount = channelCount;
Glenn Kasten788040c2011-05-05 08:19:00 -0700197 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800198 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700199 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700200 } break;
201 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800202 if (track.mainBuffer != valueBuf) {
203 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100204 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800205 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700206 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700207 break;
208 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800209 if (track.auxBuffer != valueBuf) {
210 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100211 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800212 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700213 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700214 break;
215 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800216 LOG_FATAL("bad param");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700217 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700218 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700219
Mathias Agopian65ab4712010-07-14 17:59:35 -0700220 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800221 switch (param) {
222 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800223 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700224 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
225 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
226 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800227 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700228 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800229 break;
230 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800231 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800232 invalidateState(1 << name);
233 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700234 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800235 LOG_FATAL("bad param");
Eric Laurent243f5f92011-02-28 16:52:51 -0800236 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700237 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700238
Mathias Agopian65ab4712010-07-14 17:59:35 -0700239 case RAMP_VOLUME:
240 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800241 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700242 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800243 case VOLUME1:
244 if (track.volume[param-VOLUME0] != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100245 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800246 track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16;
247 track.volume[param-VOLUME0] = valueInt;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700248 if (target == VOLUME) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800249 track.prevVolume[param-VOLUME0] = valueInt << 16;
250 track.volumeInc[param-VOLUME0] = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700251 } else {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800252 int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700253 int32_t volInc = d / int32_t(mState.frameCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800254 track.volumeInc[param-VOLUME0] = volInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700255 if (volInc == 0) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800256 track.prevVolume[param-VOLUME0] = valueInt << 16;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700257 }
258 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800259 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700260 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800261 break;
262 case AUXLEVEL:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800263 //ALOG_ASSERT(0 <= valueInt && valueInt <= MAX_GAIN_INT, "bad aux level %d", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700264 if (track.auxLevel != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100265 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700266 track.prevAuxLevel = track.auxLevel << 16;
267 track.auxLevel = valueInt;
268 if (target == VOLUME) {
269 track.prevAuxLevel = valueInt << 16;
270 track.auxInc = 0;
271 } else {
272 int32_t d = (valueInt<<16) - track.prevAuxLevel;
273 int32_t volInc = d / int32_t(mState.frameCount);
274 track.auxInc = volInc;
275 if (volInc == 0) {
276 track.prevAuxLevel = valueInt << 16;
277 }
278 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800279 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700280 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800281 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700282 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800283 LOG_FATAL("bad param");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700284 }
285 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700286
287 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800288 LOG_FATAL("bad target");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700289 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700290}
291
292bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
293{
294 if (value!=devSampleRate || resampler) {
295 if (sampleRate != value) {
296 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800297 if (resampler == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700298 resampler = AudioResampler::create(
299 format, channelCount, devSampleRate);
John Grossman4ff14ba2012-02-08 16:37:41 -0800300 resampler->setLocalTimeFreq(localTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700301 }
302 return true;
303 }
304 }
305 return false;
306}
307
Mathias Agopian65ab4712010-07-14 17:59:35 -0700308inline
309void AudioMixer::track_t::adjustVolumeRamp(bool aux)
310{
Glenn Kastenf9a27772012-01-06 07:47:26 -0800311 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700312 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
313 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
314 volumeInc[i] = 0;
315 prevVolume[i] = volume[i]<<16;
316 }
317 }
318 if (aux) {
319 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
320 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
321 auxInc = 0;
322 prevAuxLevel = auxLevel<<16;
323 }
324 }
325}
326
Glenn Kastenc59c0042012-02-02 14:06:11 -0800327size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800328{
329 name -= TRACK0;
330 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800331 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800332 }
333 return 0;
334}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700335
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800336void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700337{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800338 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800339 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800340 mState.tracks[name].bufferProvider = bufferProvider;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700341}
342
343
344
John Grossman4ff14ba2012-02-08 16:37:41 -0800345void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700346{
John Grossman4ff14ba2012-02-08 16:37:41 -0800347 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700348}
349
350
John Grossman4ff14ba2012-02-08 16:37:41 -0800351void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700352{
Steve Block5ff1dd52012-01-05 23:22:43 +0000353 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700354 "in process__validate() but nothing's invalid");
355
356 uint32_t changed = state->needsChanged;
357 state->needsChanged = 0; // clear the validation flag
358
359 // recompute which tracks are enabled / disabled
360 uint32_t enabled = 0;
361 uint32_t disabled = 0;
362 while (changed) {
363 const int i = 31 - __builtin_clz(changed);
364 const uint32_t mask = 1<<i;
365 changed &= ~mask;
366 track_t& t = state->tracks[i];
367 (t.enabled ? enabled : disabled) |= mask;
368 }
369 state->enabledTracks &= ~disabled;
370 state->enabledTracks |= enabled;
371
372 // compute everything we need...
373 int countActiveTracks = 0;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800374 bool all16BitsStereoNoResample = true;
375 bool resampling = false;
376 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700377 uint32_t en = state->enabledTracks;
378 while (en) {
379 const int i = 31 - __builtin_clz(en);
380 en &= ~(1<<i);
381
382 countActiveTracks++;
383 track_t& t = state->tracks[i];
384 uint32_t n = 0;
385 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
386 n |= NEEDS_FORMAT_16;
387 n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
388 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
389 n |= NEEDS_AUX_ENABLED;
390 }
391
392 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800393 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700394 } else if (!t.doesResample() && t.volumeRL == 0) {
395 n |= NEEDS_MUTE_ENABLED;
396 }
397 t.needs = n;
398
399 if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
400 t.hook = track__nop;
401 } else {
402 if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800403 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700404 }
405 if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800406 all16BitsStereoNoResample = false;
407 resampling = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700408 t.hook = track__genericResample;
409 } else {
410 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
411 t.hook = track__16BitsMono;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800412 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700413 }
414 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
415 t.hook = track__16BitsStereo;
416 }
417 }
418 }
419 }
420
421 // select the processing hooks
422 state->hook = process__nop;
423 if (countActiveTracks) {
424 if (resampling) {
425 if (!state->outputTemp) {
426 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
427 }
428 if (!state->resampleTemp) {
429 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
430 }
431 state->hook = process__genericResampling;
432 } else {
433 if (state->outputTemp) {
434 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800435 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700436 }
437 if (state->resampleTemp) {
438 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800439 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700440 }
441 state->hook = process__genericNoResampling;
442 if (all16BitsStereoNoResample && !volumeRamp) {
443 if (countActiveTracks == 1) {
444 state->hook = process__OneTrack16BitsStereoNoResampling;
445 }
446 }
447 }
448 }
449
Steve Block3856b092011-10-20 11:56:00 +0100450 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700451 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
452 countActiveTracks, state->enabledTracks,
453 all16BitsStereoNoResample, resampling, volumeRamp);
454
John Grossman4ff14ba2012-02-08 16:37:41 -0800455 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700456
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800457 // Now that the volume ramp has been done, set optimal state and
458 // track hooks for subsequent mixer process
459 if (countActiveTracks) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800460 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800461 uint32_t en = state->enabledTracks;
462 while (en) {
463 const int i = 31 - __builtin_clz(en);
464 en &= ~(1<<i);
465 track_t& t = state->tracks[i];
466 if (!t.doesResample() && t.volumeRL == 0)
467 {
468 t.needs |= NEEDS_MUTE_ENABLED;
469 t.hook = track__nop;
470 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800471 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800472 }
473 }
474 if (allMuted) {
475 state->hook = process__nop;
476 } else if (all16BitsStereoNoResample) {
477 if (countActiveTracks == 1) {
478 state->hook = process__OneTrack16BitsStereoNoResampling;
479 }
480 }
481 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700482}
483
Mathias Agopian65ab4712010-07-14 17:59:35 -0700484
485void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
486{
487 t->resampler->setSampleRate(t->sampleRate);
488
489 // ramp gain - resample to temp buffer and scale/mix in 2nd step
490 if (aux != NULL) {
491 // always resample with unity gain when sending to auxiliary buffer to be able
492 // to apply send level after resampling
493 // TODO: modify each resampler to support aux channel?
494 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
495 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
496 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -0800497 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700498 volumeRampStereo(t, out, outFrameCount, temp, aux);
499 } else {
500 volumeStereo(t, out, outFrameCount, temp, aux);
501 }
502 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -0800503 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700504 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
505 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
506 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
507 volumeRampStereo(t, out, outFrameCount, temp, aux);
508 }
509
510 // constant gain
511 else {
512 t->resampler->setVolume(t->volume[0], t->volume[1]);
513 t->resampler->resample(out, outFrameCount, t->bufferProvider);
514 }
515 }
516}
517
518void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
519{
520}
521
522void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
523{
524 int32_t vl = t->prevVolume[0];
525 int32_t vr = t->prevVolume[1];
526 const int32_t vlInc = t->volumeInc[0];
527 const int32_t vrInc = t->volumeInc[1];
528
Steve Blockb8a80522011-12-20 16:23:08 +0000529 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700530 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
531 // (vl + vlInc*frameCount)/65536.0f, frameCount);
532
533 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -0800534 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700535 int32_t va = t->prevAuxLevel;
536 const int32_t vaInc = t->auxInc;
537 int32_t l;
538 int32_t r;
539
540 do {
541 l = (*temp++ >> 12);
542 r = (*temp++ >> 12);
543 *out++ += (vl >> 16) * l;
544 *out++ += (vr >> 16) * r;
545 *aux++ += (va >> 17) * (l + r);
546 vl += vlInc;
547 vr += vrInc;
548 va += vaInc;
549 } while (--frameCount);
550 t->prevAuxLevel = va;
551 } else {
552 do {
553 *out++ += (vl >> 16) * (*temp++ >> 12);
554 *out++ += (vr >> 16) * (*temp++ >> 12);
555 vl += vlInc;
556 vr += vrInc;
557 } while (--frameCount);
558 }
559 t->prevVolume[0] = vl;
560 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -0800561 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700562}
563
564void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
565{
566 const int16_t vl = t->volume[0];
567 const int16_t vr = t->volume[1];
568
Glenn Kastenf6b16782011-12-15 09:51:17 -0800569 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800570 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700571 do {
572 int16_t l = (int16_t)(*temp++ >> 12);
573 int16_t r = (int16_t)(*temp++ >> 12);
574 out[0] = mulAdd(l, vl, out[0]);
575 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
576 out[1] = mulAdd(r, vr, out[1]);
577 out += 2;
578 aux[0] = mulAdd(a, va, aux[0]);
579 aux++;
580 } while (--frameCount);
581 } else {
582 do {
583 int16_t l = (int16_t)(*temp++ >> 12);
584 int16_t r = (int16_t)(*temp++ >> 12);
585 out[0] = mulAdd(l, vl, out[0]);
586 out[1] = mulAdd(r, vr, out[1]);
587 out += 2;
588 } while (--frameCount);
589 }
590}
591
592void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
593{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800594 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700595
Glenn Kastenf6b16782011-12-15 09:51:17 -0800596 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700597 int32_t l;
598 int32_t r;
599 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800600 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700601 int32_t vl = t->prevVolume[0];
602 int32_t vr = t->prevVolume[1];
603 int32_t va = t->prevAuxLevel;
604 const int32_t vlInc = t->volumeInc[0];
605 const int32_t vrInc = t->volumeInc[1];
606 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +0000607 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700608 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
609 // (vl + vlInc*frameCount)/65536.0f, frameCount);
610
611 do {
612 l = (int32_t)*in++;
613 r = (int32_t)*in++;
614 *out++ += (vl >> 16) * l;
615 *out++ += (vr >> 16) * r;
616 *aux++ += (va >> 17) * (l + r);
617 vl += vlInc;
618 vr += vrInc;
619 va += vaInc;
620 } while (--frameCount);
621
622 t->prevVolume[0] = vl;
623 t->prevVolume[1] = vr;
624 t->prevAuxLevel = va;
625 t->adjustVolumeRamp(true);
626 }
627
628 // constant gain
629 else {
630 const uint32_t vrl = t->volumeRL;
631 const int16_t va = (int16_t)t->auxLevel;
632 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800633 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700634 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
635 in += 2;
636 out[0] = mulAddRL(1, rl, vrl, out[0]);
637 out[1] = mulAddRL(0, rl, vrl, out[1]);
638 out += 2;
639 aux[0] = mulAdd(a, va, aux[0]);
640 aux++;
641 } while (--frameCount);
642 }
643 } else {
644 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800645 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700646 int32_t vl = t->prevVolume[0];
647 int32_t vr = t->prevVolume[1];
648 const int32_t vlInc = t->volumeInc[0];
649 const int32_t vrInc = t->volumeInc[1];
650
Steve Blockb8a80522011-12-20 16:23:08 +0000651 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700652 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
653 // (vl + vlInc*frameCount)/65536.0f, frameCount);
654
655 do {
656 *out++ += (vl >> 16) * (int32_t) *in++;
657 *out++ += (vr >> 16) * (int32_t) *in++;
658 vl += vlInc;
659 vr += vrInc;
660 } while (--frameCount);
661
662 t->prevVolume[0] = vl;
663 t->prevVolume[1] = vr;
664 t->adjustVolumeRamp(false);
665 }
666
667 // constant gain
668 else {
669 const uint32_t vrl = t->volumeRL;
670 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800671 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700672 in += 2;
673 out[0] = mulAddRL(1, rl, vrl, out[0]);
674 out[1] = mulAddRL(0, rl, vrl, out[1]);
675 out += 2;
676 } while (--frameCount);
677 }
678 }
679 t->in = in;
680}
681
682void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
683{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800684 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700685
Glenn Kastenf6b16782011-12-15 09:51:17 -0800686 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700687 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800688 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700689 int32_t vl = t->prevVolume[0];
690 int32_t vr = t->prevVolume[1];
691 int32_t va = t->prevAuxLevel;
692 const int32_t vlInc = t->volumeInc[0];
693 const int32_t vrInc = t->volumeInc[1];
694 const int32_t vaInc = t->auxInc;
695
Steve Blockb8a80522011-12-20 16:23:08 +0000696 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700697 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
698 // (vl + vlInc*frameCount)/65536.0f, frameCount);
699
700 do {
701 int32_t l = *in++;
702 *out++ += (vl >> 16) * l;
703 *out++ += (vr >> 16) * l;
704 *aux++ += (va >> 16) * l;
705 vl += vlInc;
706 vr += vrInc;
707 va += vaInc;
708 } while (--frameCount);
709
710 t->prevVolume[0] = vl;
711 t->prevVolume[1] = vr;
712 t->prevAuxLevel = va;
713 t->adjustVolumeRamp(true);
714 }
715 // constant gain
716 else {
717 const int16_t vl = t->volume[0];
718 const int16_t vr = t->volume[1];
719 const int16_t va = (int16_t)t->auxLevel;
720 do {
721 int16_t l = *in++;
722 out[0] = mulAdd(l, vl, out[0]);
723 out[1] = mulAdd(l, vr, out[1]);
724 out += 2;
725 aux[0] = mulAdd(l, va, aux[0]);
726 aux++;
727 } while (--frameCount);
728 }
729 } else {
730 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800731 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700732 int32_t vl = t->prevVolume[0];
733 int32_t vr = t->prevVolume[1];
734 const int32_t vlInc = t->volumeInc[0];
735 const int32_t vrInc = t->volumeInc[1];
736
Steve Blockb8a80522011-12-20 16:23:08 +0000737 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700738 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
739 // (vl + vlInc*frameCount)/65536.0f, frameCount);
740
741 do {
742 int32_t l = *in++;
743 *out++ += (vl >> 16) * l;
744 *out++ += (vr >> 16) * l;
745 vl += vlInc;
746 vr += vrInc;
747 } while (--frameCount);
748
749 t->prevVolume[0] = vl;
750 t->prevVolume[1] = vr;
751 t->adjustVolumeRamp(false);
752 }
753 // constant gain
754 else {
755 const int16_t vl = t->volume[0];
756 const int16_t vr = t->volume[1];
757 do {
758 int16_t l = *in++;
759 out[0] = mulAdd(l, vl, out[0]);
760 out[1] = mulAdd(l, vr, out[1]);
761 out += 2;
762 } while (--frameCount);
763 }
764 }
765 t->in = in;
766}
767
Mathias Agopian65ab4712010-07-14 17:59:35 -0700768// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -0800769void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700770{
771 uint32_t e0 = state->enabledTracks;
772 size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
773 while (e0) {
774 // process by group of tracks with same output buffer to
775 // avoid multiple memset() on same buffer
776 uint32_t e1 = e0, e2 = e0;
777 int i = 31 - __builtin_clz(e1);
778 track_t& t1 = state->tracks[i];
779 e2 &= ~(1<<i);
780 while (e2) {
781 i = 31 - __builtin_clz(e2);
782 e2 &= ~(1<<i);
783 track_t& t2 = state->tracks[i];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800784 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700785 e1 &= ~(1<<i);
786 }
787 }
788 e0 &= ~(e1);
789
790 memset(t1.mainBuffer, 0, bufSize);
791
792 while (e1) {
793 i = 31 - __builtin_clz(e1);
794 e1 &= ~(1<<i);
795 t1 = state->tracks[i];
796 size_t outFrames = state->frameCount;
797 while (outFrames) {
798 t1.buffer.frameCount = outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -0800799 int64_t outputPTS = calculateOutputPTS(
800 t1, pts, state->frameCount - outFrames);
801 t1.bufferProvider->getNextBuffer(&t1.buffer, outputPTS);
Glenn Kastena0d68332012-01-27 16:47:15 -0800802 if (t1.buffer.raw == NULL) break;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700803 outFrames -= t1.buffer.frameCount;
804 t1.bufferProvider->releaseBuffer(&t1.buffer);
805 }
806 }
807 }
808}
809
810// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -0800811void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700812{
813 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
814
815 // acquire each track's buffer
816 uint32_t enabledTracks = state->enabledTracks;
817 uint32_t e0 = enabledTracks;
818 while (e0) {
819 const int i = 31 - __builtin_clz(e0);
820 e0 &= ~(1<<i);
821 track_t& t = state->tracks[i];
822 t.buffer.frameCount = state->frameCount;
John Grossman4ff14ba2012-02-08 16:37:41 -0800823 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700824 t.frameCount = t.buffer.frameCount;
825 t.in = t.buffer.raw;
826 // t.in == NULL can happen if the track was flushed just after having
827 // been enabled for mixing.
828 if (t.in == NULL)
829 enabledTracks &= ~(1<<i);
830 }
831
832 e0 = enabledTracks;
833 while (e0) {
834 // process by group of tracks with same output buffer to
835 // optimize cache use
836 uint32_t e1 = e0, e2 = e0;
837 int j = 31 - __builtin_clz(e1);
838 track_t& t1 = state->tracks[j];
839 e2 &= ~(1<<j);
840 while (e2) {
841 j = 31 - __builtin_clz(e2);
842 e2 &= ~(1<<j);
843 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800844 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700845 e1 &= ~(1<<j);
846 }
847 }
848 e0 &= ~(e1);
849 // this assumes output 16 bits stereo, no resampling
850 int32_t *out = t1.mainBuffer;
851 size_t numFrames = 0;
852 do {
853 memset(outTemp, 0, sizeof(outTemp));
854 e2 = e1;
855 while (e2) {
856 const int i = 31 - __builtin_clz(e2);
857 e2 &= ~(1<<i);
858 track_t& t = state->tracks[i];
859 size_t outFrames = BLOCKSIZE;
860 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800861 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700862 aux = t.auxBuffer + numFrames;
863 }
864 while (outFrames) {
865 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
866 if (inFrames) {
Glenn Kastena1117922012-01-26 10:53:32 -0800867 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700868 t.frameCount -= inFrames;
869 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800870 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700871 aux += inFrames;
872 }
873 }
874 if (t.frameCount == 0 && outFrames) {
875 t.bufferProvider->releaseBuffer(&t.buffer);
876 t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -0800877 int64_t outputPTS = calculateOutputPTS(
878 t, pts, numFrames + (BLOCKSIZE - outFrames));
879 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700880 t.in = t.buffer.raw;
881 if (t.in == NULL) {
882 enabledTracks &= ~(1<<i);
883 e1 &= ~(1<<i);
884 break;
885 }
886 t.frameCount = t.buffer.frameCount;
887 }
888 }
889 }
890 ditherAndClamp(out, outTemp, BLOCKSIZE);
891 out += BLOCKSIZE;
892 numFrames += BLOCKSIZE;
893 } while (numFrames < state->frameCount);
894 }
895
896 // release each track's buffer
897 e0 = enabledTracks;
898 while (e0) {
899 const int i = 31 - __builtin_clz(e0);
900 e0 &= ~(1<<i);
901 track_t& t = state->tracks[i];
902 t.bufferProvider->releaseBuffer(&t.buffer);
903 }
904}
905
906
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800907// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -0800908void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700909{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800910 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -0700911 int32_t* const outTemp = state->outputTemp;
912 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700913
914 size_t numFrames = state->frameCount;
915
916 uint32_t e0 = state->enabledTracks;
917 while (e0) {
918 // process by group of tracks with same output buffer
919 // to optimize cache use
920 uint32_t e1 = e0, e2 = e0;
921 int j = 31 - __builtin_clz(e1);
922 track_t& t1 = state->tracks[j];
923 e2 &= ~(1<<j);
924 while (e2) {
925 j = 31 - __builtin_clz(e2);
926 e2 &= ~(1<<j);
927 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800928 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700929 e1 &= ~(1<<j);
930 }
931 }
932 e0 &= ~(e1);
933 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +0100934 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700935 while (e1) {
936 const int i = 31 - __builtin_clz(e1);
937 e1 &= ~(1<<i);
938 track_t& t = state->tracks[i];
939 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800940 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700941 aux = t.auxBuffer;
942 }
943
944 // this is a little goofy, on the resampling case we don't
945 // acquire/release the buffers because it's done by
946 // the resampler.
947 if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
John Grossman4ff14ba2012-02-08 16:37:41 -0800948 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -0800949 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700950 } else {
951
952 size_t outFrames = 0;
953
954 while (outFrames < numFrames) {
955 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -0800956 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
957 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700958 t.in = t.buffer.raw;
959 // t.in == NULL can happen if the track was flushed just after having
960 // been enabled for mixing.
961 if (t.in == NULL) break;
962
Glenn Kastenf6b16782011-12-15 09:51:17 -0800963 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700964 aux += outFrames;
965 }
Glenn Kastena1117922012-01-26 10:53:32 -0800966 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700967 outFrames += t.buffer.frameCount;
968 t.bufferProvider->releaseBuffer(&t.buffer);
969 }
970 }
971 }
972 ditherAndClamp(out, outTemp, numFrames);
973 }
974}
975
976// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -0800977void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
978 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700979{
Glenn Kasten99e53b82012-01-19 08:59:58 -0800980 // This method is only called when state->enabledTracks has exactly
981 // one bit set. The asserts below would verify this, but are commented out
982 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800983 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700984 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800985 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700986 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;
John Grossman4ff14ba2012-02-08 16:37:41 -0800998 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
999 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001000 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001001
1002 // in == NULL can happen if the track was flushed just after having
1003 // been enabled for mixing.
1004 if (in == NULL || ((unsigned long)in & 3)) {
1005 memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
Steve Block29357bc2012-01-06 19:20:56 +00001006 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 -07001007 in, i, t.channelCount, t.needs);
1008 return;
1009 }
1010 size_t outFrames = b.frameCount;
1011
Glenn Kastenf6b16782011-12-15 09:51:17 -08001012 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001013 // volume is boosted, so we might need to clamp even though
1014 // we process only one track.
1015 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001016 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001017 in += 2;
1018 int32_t l = mulRL(1, rl, vrl) >> 12;
1019 int32_t r = mulRL(0, rl, vrl) >> 12;
1020 // clamping...
1021 l = clamp16(l);
1022 r = clamp16(r);
1023 *out++ = (r<<16) | (l & 0xFFFF);
1024 } while (--outFrames);
1025 } else {
1026 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001027 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001028 in += 2;
1029 int32_t l = mulRL(1, rl, vrl) >> 12;
1030 int32_t r = mulRL(0, rl, vrl) >> 12;
1031 *out++ = (r<<16) | (l & 0xFFFF);
1032 } while (--outFrames);
1033 }
1034 numFrames -= b.frameCount;
1035 t.bufferProvider->releaseBuffer(&b);
1036 }
1037}
1038
Glenn Kasten81a028f2011-12-15 09:53:12 -08001039#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001040// 2 tracks is also a common case
1041// NEVER used in current implementation of process__validate()
1042// only use if the 2 tracks have the same output buffer
John Grossman4ff14ba2012-02-08 16:37:41 -08001043void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
1044 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001045{
1046 int i;
1047 uint32_t en = state->enabledTracks;
1048
1049 i = 31 - __builtin_clz(en);
1050 const track_t& t0 = state->tracks[i];
1051 AudioBufferProvider::Buffer& b0(t0.buffer);
1052
1053 en &= ~(1<<i);
1054 i = 31 - __builtin_clz(en);
1055 const track_t& t1 = state->tracks[i];
1056 AudioBufferProvider::Buffer& b1(t1.buffer);
1057
Glenn Kasten54c3b662012-01-06 07:46:30 -08001058 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001059 const int16_t vl0 = t0.volume[0];
1060 const int16_t vr0 = t0.volume[1];
1061 size_t frameCount0 = 0;
1062
Glenn Kasten54c3b662012-01-06 07:46:30 -08001063 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001064 const int16_t vl1 = t1.volume[0];
1065 const int16_t vr1 = t1.volume[1];
1066 size_t frameCount1 = 0;
1067
1068 //FIXME: only works if two tracks use same buffer
1069 int32_t* out = t0.mainBuffer;
1070 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001071 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001072
1073
1074 while (numFrames) {
1075
1076 if (frameCount0 == 0) {
1077 b0.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001078 int64_t outputPTS = calculateOutputPTS(t0, pts,
1079 out - t0.mainBuffer);
1080 t0.bufferProvider->getNextBuffer(&b0, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001081 if (b0.i16 == NULL) {
1082 if (buff == NULL) {
1083 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1084 }
1085 in0 = buff;
1086 b0.frameCount = numFrames;
1087 } else {
1088 in0 = b0.i16;
1089 }
1090 frameCount0 = b0.frameCount;
1091 }
1092 if (frameCount1 == 0) {
1093 b1.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001094 int64_t outputPTS = calculateOutputPTS(t1, pts,
1095 out - t0.mainBuffer);
1096 t1.bufferProvider->getNextBuffer(&b1, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001097 if (b1.i16 == NULL) {
1098 if (buff == NULL) {
1099 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1100 }
1101 in1 = buff;
1102 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001103 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001104 in1 = b1.i16;
1105 }
1106 frameCount1 = b1.frameCount;
1107 }
1108
1109 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1110
1111 numFrames -= outFrames;
1112 frameCount0 -= outFrames;
1113 frameCount1 -= outFrames;
1114
1115 do {
1116 int32_t l0 = *in0++;
1117 int32_t r0 = *in0++;
1118 l0 = mul(l0, vl0);
1119 r0 = mul(r0, vr0);
1120 int32_t l = *in1++;
1121 int32_t r = *in1++;
1122 l = mulAdd(l, vl1, l0) >> 12;
1123 r = mulAdd(r, vr1, r0) >> 12;
1124 // clamping...
1125 l = clamp16(l);
1126 r = clamp16(r);
1127 *out++ = (r<<16) | (l & 0xFFFF);
1128 } while (--outFrames);
1129
1130 if (frameCount0 == 0) {
1131 t0.bufferProvider->releaseBuffer(&b0);
1132 }
1133 if (frameCount1 == 0) {
1134 t1.bufferProvider->releaseBuffer(&b1);
1135 }
1136 }
1137
Glenn Kastene9dd0172012-01-27 18:08:45 -08001138 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001139}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001140#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001141
John Grossman4ff14ba2012-02-08 16:37:41 -08001142int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1143 int outputFrameIndex)
1144{
1145 if (AudioBufferProvider::kInvalidPTS == basePTS)
1146 return AudioBufferProvider::kInvalidPTS;
1147
1148 return basePTS + ((outputFrameIndex * t.localTimeFreq) / t.sampleRate);
1149}
1150
Mathias Agopian65ab4712010-07-14 17:59:35 -07001151// ----------------------------------------------------------------------------
1152}; // namespace android