AudioMixer.cpp revision a5e821439996de6005b2fa36b3bdd31f003ce23f
1/* 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 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 29#include <cutils/bitops.h> 30#include <cutils/compiler.h> 31#include <utils/Debug.h> 32 33#include <system/audio.h> 34 35#include <audio_utils/primitives.h> 36#include <common_time/local_clock.h> 37#include <common_time/cc_helper.h> 38 39#include <media/EffectsFactoryApi.h> 40 41#include "AudioMixer.h" 42 43namespace android { 44 45// ---------------------------------------------------------------------------- 46AudioMixer::DownmixerBufferProvider::DownmixerBufferProvider() : AudioBufferProvider(), 47 mTrackBufferProvider(NULL), mDownmixHandle(NULL) 48{ 49} 50 51AudioMixer::DownmixerBufferProvider::~DownmixerBufferProvider() 52{ 53 ALOGV("AudioMixer deleting DownmixerBufferProvider (%p)", this); 54 EffectRelease(mDownmixHandle); 55} 56 57status_t AudioMixer::DownmixerBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer, 58 int64_t pts) { 59 //ALOGV("DownmixerBufferProvider::getNextBuffer()"); 60 if (this->mTrackBufferProvider != NULL) { 61 status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts); 62 if (res == OK) { 63 mDownmixConfig.inputCfg.buffer.frameCount = pBuffer->frameCount; 64 mDownmixConfig.inputCfg.buffer.raw = pBuffer->raw; 65 mDownmixConfig.outputCfg.buffer.frameCount = pBuffer->frameCount; 66 mDownmixConfig.outputCfg.buffer.raw = mDownmixConfig.inputCfg.buffer.raw; 67 // in-place so overwrite the buffer contents, has been set in prepareTrackForDownmix() 68 //mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE; 69 70 res = (*mDownmixHandle)->process(mDownmixHandle, 71 &mDownmixConfig.inputCfg.buffer, &mDownmixConfig.outputCfg.buffer); 72 ALOGV("getNextBuffer is downmixing"); 73 } 74 return res; 75 } else { 76 ALOGE("DownmixerBufferProvider::getNextBuffer() error: NULL track buffer provider"); 77 return NO_INIT; 78 } 79} 80 81void AudioMixer::DownmixerBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) { 82 ALOGV("DownmixerBufferProvider::releaseBuffer()"); 83 if (this->mTrackBufferProvider != NULL) { 84 mTrackBufferProvider->releaseBuffer(pBuffer); 85 } else { 86 ALOGE("DownmixerBufferProvider::releaseBuffer() error: NULL track buffer provider"); 87 } 88} 89 90 91// ---------------------------------------------------------------------------- 92bool AudioMixer::isMultichannelCapable = false; 93 94effect_descriptor_t AudioMixer::dwnmFxDesc; 95 96AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks) 97 : mTrackNames(0), mConfiguredNames((1 << maxNumTracks) - 1), mSampleRate(sampleRate) 98{ 99 // AudioMixer is not yet capable of multi-channel beyond stereo 100 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(2 == MAX_NUM_CHANNELS); 101 102 ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u", 103 maxNumTracks, MAX_NUM_TRACKS); 104 105 LocalClock lc; 106 107 mState.enabledTracks= 0; 108 mState.needsChanged = 0; 109 mState.frameCount = frameCount; 110 mState.hook = process__nop; 111 mState.outputTemp = NULL; 112 mState.resampleTemp = NULL; 113 // mState.reserved 114 115 // FIXME Most of the following initialization is probably redundant since 116 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0 117 // and mTrackNames is initially 0. However, leave it here until that's verified. 118 track_t* t = mState.tracks; 119 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) { 120 // FIXME redundant per track 121 t->localTimeFreq = lc.getLocalFreq(); 122 t->resampler = NULL; 123 t++; 124 } 125 126 // find multichannel downmix effect if we have to play multichannel content 127 uint32_t numEffects = 0; 128 int ret = EffectQueryNumberEffects(&numEffects); 129 if (ret != 0) { 130 ALOGE("AudioMixer() error %d querying number of effects", ret); 131 return; 132 } 133 ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects); 134 135 for (uint32_t i = 0 ; i < numEffects ; i++) { 136 if (EffectQueryEffect(i, &dwnmFxDesc) == 0) { 137 ALOGV("effect %d is called %s", i, dwnmFxDesc.name); 138 if (memcmp(&dwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) { 139 ALOGI("found effect \"%s\" from %s", 140 dwnmFxDesc.name, dwnmFxDesc.implementor); 141 isMultichannelCapable = true; 142 break; 143 } 144 } 145 } 146 ALOGE_IF(!isMultichannelCapable, "unable to find downmix effect"); 147} 148 149AudioMixer::~AudioMixer() 150{ 151 track_t* t = mState.tracks; 152 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) { 153 delete t->resampler; 154 t++; 155 } 156 delete [] mState.outputTemp; 157 delete [] mState.resampleTemp; 158} 159 160int AudioMixer::getTrackName() 161{ 162 uint32_t names = (~mTrackNames) & mConfiguredNames; 163 if (names != 0) { 164 int n = __builtin_ctz(names); 165 ALOGV("add track (%d)", n); 166 mTrackNames |= 1 << n; 167 // assume default parameters for the track, except where noted below 168 track_t* t = &mState.tracks[n]; 169 t->needs = 0; 170 t->volume[0] = UNITY_GAIN; 171 t->volume[1] = UNITY_GAIN; 172 // no initialization needed 173 // t->prevVolume[0] 174 // t->prevVolume[1] 175 t->volumeInc[0] = 0; 176 t->volumeInc[1] = 0; 177 t->auxLevel = 0; 178 t->auxInc = 0; 179 // no initialization needed 180 // t->prevAuxLevel 181 // t->frameCount 182 t->channelCount = 2; 183 t->enabled = false; 184 t->format = 16; 185 t->channelMask = AUDIO_CHANNEL_OUT_STEREO; 186 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name) 187 t->bufferProvider = NULL; 188 t->downmixerBufferProvider = NULL; 189 t->buffer.raw = NULL; 190 // no initialization needed 191 // t->buffer.frameCount 192 t->hook = NULL; 193 t->in = NULL; 194 t->resampler = NULL; 195 t->sampleRate = mSampleRate; 196 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name) 197 t->mainBuffer = NULL; 198 t->auxBuffer = NULL; 199 // see t->localTimeFreq in constructor above 200 return TRACK0 + n; 201 } 202 return -1; 203} 204 205void AudioMixer::invalidateState(uint32_t mask) 206{ 207 if (mask) { 208 mState.needsChanged |= mask; 209 mState.hook = process__validate; 210 } 211 } 212 213status_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName) 214{ 215 ALOGV("AudioMixer::prepareTrackForDownmix(%d) with mask 0x%x", trackName, pTrack->channelMask); 216 217 if (pTrack->downmixerBufferProvider != NULL) { 218 // this track had previously been configured with a downmixer, reset it 219 ALOGV("AudioMixer::prepareTrackForDownmix(%d) deleting old downmixer", trackName); 220 pTrack->bufferProvider = pTrack->downmixerBufferProvider->mTrackBufferProvider; 221 delete pTrack->downmixerBufferProvider; 222 } 223 224 DownmixerBufferProvider* pDbp = new DownmixerBufferProvider(); 225 int32_t status; 226 227 if (!isMultichannelCapable) { 228 ALOGE("prepareTrackForDownmix(%d) fails: mixer doesn't support multichannel content", 229 trackName); 230 goto noDownmixForActiveTrack; 231 } 232 233 if (EffectCreate(&dwnmFxDesc.uuid, 234 -2 /*sessionId*/, -2 /*ioId*/,// both not relevant here, using random value 235 &pDbp->mDownmixHandle/*pHandle*/) != 0) { 236 ALOGE("prepareTrackForDownmix(%d) fails: error creating downmixer effect", trackName); 237 goto noDownmixForActiveTrack; 238 } 239 240 // channel input configuration will be overridden per-track 241 pDbp->mDownmixConfig.inputCfg.channels = pTrack->channelMask; 242 pDbp->mDownmixConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 243 pDbp->mDownmixConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 244 pDbp->mDownmixConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 245 pDbp->mDownmixConfig.inputCfg.samplingRate = pTrack->sampleRate; 246 pDbp->mDownmixConfig.outputCfg.samplingRate = pTrack->sampleRate; 247 pDbp->mDownmixConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; 248 pDbp->mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE; 249 // input and output buffer provider, and frame count will not be used as the downmix effect 250 // process() function is called directly (see DownmixerBufferProvider::getNextBuffer()) 251 pDbp->mDownmixConfig.inputCfg.mask = EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | 252 EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE; 253 pDbp->mDownmixConfig.outputCfg.mask = pDbp->mDownmixConfig.inputCfg.mask; 254 255 {// scope for local variables that are not used in goto label "noDownmixForActiveTrack" 256 int cmdStatus; 257 uint32_t replySize = sizeof(int); 258 259 // Configure and enable downmixer 260 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle, 261 EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/, 262 &pDbp->mDownmixConfig /*pCmdData*/, 263 &replySize /*replySize*/, &cmdStatus /*pReplyData*/); 264 if ((status != 0) || (cmdStatus != 0)) { 265 ALOGE("error %d while configuring downmixer for track %d", status, trackName); 266 goto noDownmixForActiveTrack; 267 } 268 replySize = sizeof(int); 269 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle, 270 EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/, 271 &replySize /*replySize*/, &cmdStatus /*pReplyData*/); 272 if ((status != 0) || (cmdStatus != 0)) { 273 ALOGE("error %d while enabling downmixer for track %d", status, trackName); 274 goto noDownmixForActiveTrack; 275 } 276 277 // Set downmix type 278 // parameter size rounded for padding on 32bit boundary 279 const int psizePadded = ((sizeof(downmix_params_t) - 1)/sizeof(int) + 1) * sizeof(int); 280 const int downmixParamSize = 281 sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t); 282 effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize); 283 param->psize = sizeof(downmix_params_t); 284 const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE; 285 memcpy(param->data, &downmixParam, param->psize); 286 const downmix_type_t downmixType = DOWNMIX_TYPE_FOLD; 287 param->vsize = sizeof(downmix_type_t); 288 memcpy(param->data + psizePadded, &downmixType, param->vsize); 289 290 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle, 291 EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize/* cmdSize */, 292 param /*pCmndData*/, &replySize /*replySize*/, &cmdStatus /*pReplyData*/); 293 294 free(param); 295 296 if ((status != 0) || (cmdStatus != 0)) { 297 ALOGE("error %d while setting downmix type for track %d", status, trackName); 298 goto noDownmixForActiveTrack; 299 } else { 300 ALOGV("downmix type set to %d for track %d", (int) downmixType, trackName); 301 } 302 }// end of scope for local variables that are not used in goto label "noDownmixForActiveTrack" 303 304 // initialization successful: 305 // - keep track of the real buffer provider in case it was set before 306 pDbp->mTrackBufferProvider = pTrack->bufferProvider; 307 // - we'll use the downmix effect integrated inside this 308 // track's buffer provider, and we'll use it as the track's buffer provider 309 pTrack->downmixerBufferProvider = pDbp; 310 pTrack->bufferProvider = pDbp; 311 312 return NO_ERROR; 313 314noDownmixForActiveTrack: 315 delete pDbp; 316 pTrack->downmixerBufferProvider = NULL; 317 return NO_INIT; 318} 319 320void AudioMixer::deleteTrackName(int name) 321{ 322 name -= TRACK0; 323 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); 324 ALOGV("deleteTrackName(%d)", name); 325 track_t& track(mState.tracks[ name ]); 326 if (track.enabled) { 327 track.enabled = false; 328 invalidateState(1<<name); 329 } 330 if (track.resampler != NULL) { 331 // delete the resampler 332 delete track.resampler; 333 track.resampler = NULL; 334 track.sampleRate = mSampleRate; 335 invalidateState(1<<name); 336 } 337 track.volumeInc[0] = 0; 338 track.volumeInc[1] = 0; 339 mTrackNames &= ~(1<<name); 340} 341 342void AudioMixer::enable(int name) 343{ 344 name -= TRACK0; 345 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); 346 track_t& track = mState.tracks[name]; 347 348 if (!track.enabled) { 349 track.enabled = true; 350 ALOGV("enable(%d)", name); 351 invalidateState(1 << name); 352 } 353} 354 355void AudioMixer::disable(int name) 356{ 357 name -= TRACK0; 358 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); 359 track_t& track = mState.tracks[name]; 360 361 if (track.enabled) { 362 if (track.downmixerBufferProvider != NULL) { 363 ALOGV("AudioMixer::disable(%d) deleting downmixerBufferProvider", name); 364 delete track.downmixerBufferProvider; 365 track.downmixerBufferProvider = NULL; 366 } 367 track.enabled = false; 368 ALOGV("disable(%d)", name); 369 invalidateState(1 << name); 370 } 371} 372 373void AudioMixer::setParameter(int name, int target, int param, void *value) 374{ 375 name -= TRACK0; 376 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); 377 track_t& track = mState.tracks[name]; 378 379 int valueInt = (int)value; 380 int32_t *valueBuf = (int32_t *)value; 381 382 switch (target) { 383 384 case TRACK: 385 switch (param) { 386 case CHANNEL_MASK: { 387 uint32_t mask = (uint32_t)value; 388 if (track.channelMask != mask) { 389 uint32_t channelCount = popcount(mask); 390 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount); 391 track.channelMask = mask; 392 track.channelCount = channelCount; 393 if (channelCount > MAX_NUM_CHANNELS) { 394 ALOGV("AudioMixer::setParameter(TRACK, CHANNEL_MASK, mask=0x%x count=%d)", 395 mask, channelCount); 396 status_t status = prepareTrackForDownmix(&mState.tracks[name], name); 397 } 398 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask); 399 invalidateState(1 << name); 400 } 401 } break; 402 case MAIN_BUFFER: 403 if (track.mainBuffer != valueBuf) { 404 track.mainBuffer = valueBuf; 405 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf); 406 invalidateState(1 << name); 407 } 408 break; 409 case AUX_BUFFER: 410 if (track.auxBuffer != valueBuf) { 411 track.auxBuffer = valueBuf; 412 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf); 413 invalidateState(1 << name); 414 } 415 break; 416 case FORMAT: 417 ALOG_ASSERT(valueInt == AUDIO_FORMAT_PCM_16_BIT); 418 break; 419 // FIXME do we want to support setting the downmix type from AudioFlinger? 420 // for a specific track? or per mixer? 421 /* case DOWNMIX_TYPE: 422 break */ 423 default: 424 LOG_FATAL("bad param"); 425 } 426 break; 427 428 case RESAMPLE: 429 switch (param) { 430 case SAMPLE_RATE: 431 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt); 432 if (track.setResampler(uint32_t(valueInt), mSampleRate)) { 433 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)", 434 uint32_t(valueInt)); 435 invalidateState(1 << name); 436 } 437 break; 438 case RESET: 439 track.resetResampler(); 440 invalidateState(1 << name); 441 break; 442 default: 443 LOG_FATAL("bad param"); 444 } 445 break; 446 447 case RAMP_VOLUME: 448 case VOLUME: 449 switch (param) { 450 case VOLUME0: 451 case VOLUME1: 452 if (track.volume[param-VOLUME0] != valueInt) { 453 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt); 454 track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16; 455 track.volume[param-VOLUME0] = valueInt; 456 if (target == VOLUME) { 457 track.prevVolume[param-VOLUME0] = valueInt << 16; 458 track.volumeInc[param-VOLUME0] = 0; 459 } else { 460 int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0]; 461 int32_t volInc = d / int32_t(mState.frameCount); 462 track.volumeInc[param-VOLUME0] = volInc; 463 if (volInc == 0) { 464 track.prevVolume[param-VOLUME0] = valueInt << 16; 465 } 466 } 467 invalidateState(1 << name); 468 } 469 break; 470 case AUXLEVEL: 471 //ALOG_ASSERT(0 <= valueInt && valueInt <= MAX_GAIN_INT, "bad aux level %d", valueInt); 472 if (track.auxLevel != valueInt) { 473 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt); 474 track.prevAuxLevel = track.auxLevel << 16; 475 track.auxLevel = valueInt; 476 if (target == VOLUME) { 477 track.prevAuxLevel = valueInt << 16; 478 track.auxInc = 0; 479 } else { 480 int32_t d = (valueInt<<16) - track.prevAuxLevel; 481 int32_t volInc = d / int32_t(mState.frameCount); 482 track.auxInc = volInc; 483 if (volInc == 0) { 484 track.prevAuxLevel = valueInt << 16; 485 } 486 } 487 invalidateState(1 << name); 488 } 489 break; 490 default: 491 LOG_FATAL("bad param"); 492 } 493 break; 494 495 default: 496 LOG_FATAL("bad target"); 497 } 498} 499 500bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate) 501{ 502 if (value!=devSampleRate || resampler) { 503 if (sampleRate != value) { 504 sampleRate = value; 505 if (resampler == NULL) { 506 resampler = AudioResampler::create( 507 format, channelCount, devSampleRate); 508 resampler->setLocalTimeFreq(localTimeFreq); 509 } 510 return true; 511 } 512 } 513 return false; 514} 515 516inline 517void AudioMixer::track_t::adjustVolumeRamp(bool aux) 518{ 519 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) { 520 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) || 521 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) { 522 volumeInc[i] = 0; 523 prevVolume[i] = volume[i]<<16; 524 } 525 } 526 if (aux) { 527 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) || 528 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) { 529 auxInc = 0; 530 prevAuxLevel = auxLevel<<16; 531 } 532 } 533} 534 535size_t AudioMixer::getUnreleasedFrames(int name) const 536{ 537 name -= TRACK0; 538 if (uint32_t(name) < MAX_NUM_TRACKS) { 539 return mState.tracks[name].getUnreleasedFrames(); 540 } 541 return 0; 542} 543 544void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider) 545{ 546 name -= TRACK0; 547 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); 548 549 if (mState.tracks[name].downmixerBufferProvider != NULL) { 550 // update required? 551 if (mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider != bufferProvider) { 552 ALOGV("AudioMixer::setBufferProvider(%p) for downmix", bufferProvider); 553 // setting the buffer provider for a track that gets downmixed consists in: 554 // 1/ setting the buffer provider to the "downmix / buffer provider" wrapper 555 // so it's the one that gets called when the buffer provider is needed, 556 mState.tracks[name].bufferProvider = mState.tracks[name].downmixerBufferProvider; 557 // 2/ saving the buffer provider for the track so the wrapper can use it 558 // when it downmixes. 559 mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider = bufferProvider; 560 } 561 } else { 562 mState.tracks[name].bufferProvider = bufferProvider; 563 } 564} 565 566 567 568void AudioMixer::process(int64_t pts) 569{ 570 mState.hook(&mState, pts); 571} 572 573 574void AudioMixer::process__validate(state_t* state, int64_t pts) 575{ 576 ALOGW_IF(!state->needsChanged, 577 "in process__validate() but nothing's invalid"); 578 579 uint32_t changed = state->needsChanged; 580 state->needsChanged = 0; // clear the validation flag 581 582 // recompute which tracks are enabled / disabled 583 uint32_t enabled = 0; 584 uint32_t disabled = 0; 585 while (changed) { 586 const int i = 31 - __builtin_clz(changed); 587 const uint32_t mask = 1<<i; 588 changed &= ~mask; 589 track_t& t = state->tracks[i]; 590 (t.enabled ? enabled : disabled) |= mask; 591 } 592 state->enabledTracks &= ~disabled; 593 state->enabledTracks |= enabled; 594 595 // compute everything we need... 596 int countActiveTracks = 0; 597 bool all16BitsStereoNoResample = true; 598 bool resampling = false; 599 bool volumeRamp = false; 600 uint32_t en = state->enabledTracks; 601 while (en) { 602 const int i = 31 - __builtin_clz(en); 603 en &= ~(1<<i); 604 605 countActiveTracks++; 606 track_t& t = state->tracks[i]; 607 uint32_t n = 0; 608 n |= NEEDS_CHANNEL_1 + t.channelCount - 1; 609 n |= NEEDS_FORMAT_16; 610 n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED; 611 if (t.auxLevel != 0 && t.auxBuffer != NULL) { 612 n |= NEEDS_AUX_ENABLED; 613 } 614 615 if (t.volumeInc[0]|t.volumeInc[1]) { 616 volumeRamp = true; 617 } else if (!t.doesResample() && t.volumeRL == 0) { 618 n |= NEEDS_MUTE_ENABLED; 619 } 620 t.needs = n; 621 622 if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) { 623 t.hook = track__nop; 624 } else { 625 if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) { 626 all16BitsStereoNoResample = false; 627 } 628 if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) { 629 all16BitsStereoNoResample = false; 630 resampling = true; 631 t.hook = track__genericResample; 632 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2, 633 "Track needs downmix + resample"); 634 } else { 635 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){ 636 t.hook = track__16BitsMono; 637 all16BitsStereoNoResample = false; 638 } 639 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){ 640 t.hook = track__16BitsStereo; 641 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2, 642 "Track needs downmix"); 643 } 644 } 645 } 646 } 647 648 // select the processing hooks 649 state->hook = process__nop; 650 if (countActiveTracks) { 651 if (resampling) { 652 if (!state->outputTemp) { 653 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount]; 654 } 655 if (!state->resampleTemp) { 656 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount]; 657 } 658 state->hook = process__genericResampling; 659 } else { 660 if (state->outputTemp) { 661 delete [] state->outputTemp; 662 state->outputTemp = NULL; 663 } 664 if (state->resampleTemp) { 665 delete [] state->resampleTemp; 666 state->resampleTemp = NULL; 667 } 668 state->hook = process__genericNoResampling; 669 if (all16BitsStereoNoResample && !volumeRamp) { 670 if (countActiveTracks == 1) { 671 state->hook = process__OneTrack16BitsStereoNoResampling; 672 } 673 } 674 } 675 } 676 677 ALOGV("mixer configuration change: %d activeTracks (%08x) " 678 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d", 679 countActiveTracks, state->enabledTracks, 680 all16BitsStereoNoResample, resampling, volumeRamp); 681 682 state->hook(state, pts); 683 684 // Now that the volume ramp has been done, set optimal state and 685 // track hooks for subsequent mixer process 686 if (countActiveTracks) { 687 bool allMuted = true; 688 uint32_t en = state->enabledTracks; 689 while (en) { 690 const int i = 31 - __builtin_clz(en); 691 en &= ~(1<<i); 692 track_t& t = state->tracks[i]; 693 if (!t.doesResample() && t.volumeRL == 0) 694 { 695 t.needs |= NEEDS_MUTE_ENABLED; 696 t.hook = track__nop; 697 } else { 698 allMuted = false; 699 } 700 } 701 if (allMuted) { 702 state->hook = process__nop; 703 } else if (all16BitsStereoNoResample) { 704 if (countActiveTracks == 1) { 705 state->hook = process__OneTrack16BitsStereoNoResampling; 706 } 707 } 708 } 709} 710 711 712void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux) 713{ 714 t->resampler->setSampleRate(t->sampleRate); 715 716 // ramp gain - resample to temp buffer and scale/mix in 2nd step 717 if (aux != NULL) { 718 // always resample with unity gain when sending to auxiliary buffer to be able 719 // to apply send level after resampling 720 // TODO: modify each resampler to support aux channel? 721 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN); 722 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t)); 723 t->resampler->resample(temp, outFrameCount, t->bufferProvider); 724 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) { 725 volumeRampStereo(t, out, outFrameCount, temp, aux); 726 } else { 727 volumeStereo(t, out, outFrameCount, temp, aux); 728 } 729 } else { 730 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) { 731 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN); 732 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t)); 733 t->resampler->resample(temp, outFrameCount, t->bufferProvider); 734 volumeRampStereo(t, out, outFrameCount, temp, aux); 735 } 736 737 // constant gain 738 else { 739 t->resampler->setVolume(t->volume[0], t->volume[1]); 740 t->resampler->resample(out, outFrameCount, t->bufferProvider); 741 } 742 } 743} 744 745void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux) 746{ 747} 748 749void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux) 750{ 751 int32_t vl = t->prevVolume[0]; 752 int32_t vr = t->prevVolume[1]; 753 const int32_t vlInc = t->volumeInc[0]; 754 const int32_t vrInc = t->volumeInc[1]; 755 756 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d", 757 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0], 758 // (vl + vlInc*frameCount)/65536.0f, frameCount); 759 760 // ramp volume 761 if (CC_UNLIKELY(aux != NULL)) { 762 int32_t va = t->prevAuxLevel; 763 const int32_t vaInc = t->auxInc; 764 int32_t l; 765 int32_t r; 766 767 do { 768 l = (*temp++ >> 12); 769 r = (*temp++ >> 12); 770 *out++ += (vl >> 16) * l; 771 *out++ += (vr >> 16) * r; 772 *aux++ += (va >> 17) * (l + r); 773 vl += vlInc; 774 vr += vrInc; 775 va += vaInc; 776 } while (--frameCount); 777 t->prevAuxLevel = va; 778 } else { 779 do { 780 *out++ += (vl >> 16) * (*temp++ >> 12); 781 *out++ += (vr >> 16) * (*temp++ >> 12); 782 vl += vlInc; 783 vr += vrInc; 784 } while (--frameCount); 785 } 786 t->prevVolume[0] = vl; 787 t->prevVolume[1] = vr; 788 t->adjustVolumeRamp(aux != NULL); 789} 790 791void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux) 792{ 793 const int16_t vl = t->volume[0]; 794 const int16_t vr = t->volume[1]; 795 796 if (CC_UNLIKELY(aux != NULL)) { 797 const int16_t va = t->auxLevel; 798 do { 799 int16_t l = (int16_t)(*temp++ >> 12); 800 int16_t r = (int16_t)(*temp++ >> 12); 801 out[0] = mulAdd(l, vl, out[0]); 802 int16_t a = (int16_t)(((int32_t)l + r) >> 1); 803 out[1] = mulAdd(r, vr, out[1]); 804 out += 2; 805 aux[0] = mulAdd(a, va, aux[0]); 806 aux++; 807 } while (--frameCount); 808 } else { 809 do { 810 int16_t l = (int16_t)(*temp++ >> 12); 811 int16_t r = (int16_t)(*temp++ >> 12); 812 out[0] = mulAdd(l, vl, out[0]); 813 out[1] = mulAdd(r, vr, out[1]); 814 out += 2; 815 } while (--frameCount); 816 } 817} 818 819void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux) 820{ 821 const int16_t *in = static_cast<const int16_t *>(t->in); 822 823 if (CC_UNLIKELY(aux != NULL)) { 824 int32_t l; 825 int32_t r; 826 // ramp gain 827 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) { 828 int32_t vl = t->prevVolume[0]; 829 int32_t vr = t->prevVolume[1]; 830 int32_t va = t->prevAuxLevel; 831 const int32_t vlInc = t->volumeInc[0]; 832 const int32_t vrInc = t->volumeInc[1]; 833 const int32_t vaInc = t->auxInc; 834 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d", 835 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0], 836 // (vl + vlInc*frameCount)/65536.0f, frameCount); 837 838 do { 839 l = (int32_t)*in++; 840 r = (int32_t)*in++; 841 *out++ += (vl >> 16) * l; 842 *out++ += (vr >> 16) * r; 843 *aux++ += (va >> 17) * (l + r); 844 vl += vlInc; 845 vr += vrInc; 846 va += vaInc; 847 } while (--frameCount); 848 849 t->prevVolume[0] = vl; 850 t->prevVolume[1] = vr; 851 t->prevAuxLevel = va; 852 t->adjustVolumeRamp(true); 853 } 854 855 // constant gain 856 else { 857 const uint32_t vrl = t->volumeRL; 858 const int16_t va = (int16_t)t->auxLevel; 859 do { 860 uint32_t rl = *reinterpret_cast<const uint32_t *>(in); 861 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1); 862 in += 2; 863 out[0] = mulAddRL(1, rl, vrl, out[0]); 864 out[1] = mulAddRL(0, rl, vrl, out[1]); 865 out += 2; 866 aux[0] = mulAdd(a, va, aux[0]); 867 aux++; 868 } while (--frameCount); 869 } 870 } else { 871 // ramp gain 872 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) { 873 int32_t vl = t->prevVolume[0]; 874 int32_t vr = t->prevVolume[1]; 875 const int32_t vlInc = t->volumeInc[0]; 876 const int32_t vrInc = t->volumeInc[1]; 877 878 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d", 879 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0], 880 // (vl + vlInc*frameCount)/65536.0f, frameCount); 881 882 do { 883 *out++ += (vl >> 16) * (int32_t) *in++; 884 *out++ += (vr >> 16) * (int32_t) *in++; 885 vl += vlInc; 886 vr += vrInc; 887 } while (--frameCount); 888 889 t->prevVolume[0] = vl; 890 t->prevVolume[1] = vr; 891 t->adjustVolumeRamp(false); 892 } 893 894 // constant gain 895 else { 896 const uint32_t vrl = t->volumeRL; 897 do { 898 uint32_t rl = *reinterpret_cast<const uint32_t *>(in); 899 in += 2; 900 out[0] = mulAddRL(1, rl, vrl, out[0]); 901 out[1] = mulAddRL(0, rl, vrl, out[1]); 902 out += 2; 903 } while (--frameCount); 904 } 905 } 906 t->in = in; 907} 908 909void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux) 910{ 911 const int16_t *in = static_cast<int16_t const *>(t->in); 912 913 if (CC_UNLIKELY(aux != NULL)) { 914 // ramp gain 915 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) { 916 int32_t vl = t->prevVolume[0]; 917 int32_t vr = t->prevVolume[1]; 918 int32_t va = t->prevAuxLevel; 919 const int32_t vlInc = t->volumeInc[0]; 920 const int32_t vrInc = t->volumeInc[1]; 921 const int32_t vaInc = t->auxInc; 922 923 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d", 924 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0], 925 // (vl + vlInc*frameCount)/65536.0f, frameCount); 926 927 do { 928 int32_t l = *in++; 929 *out++ += (vl >> 16) * l; 930 *out++ += (vr >> 16) * l; 931 *aux++ += (va >> 16) * l; 932 vl += vlInc; 933 vr += vrInc; 934 va += vaInc; 935 } while (--frameCount); 936 937 t->prevVolume[0] = vl; 938 t->prevVolume[1] = vr; 939 t->prevAuxLevel = va; 940 t->adjustVolumeRamp(true); 941 } 942 // constant gain 943 else { 944 const int16_t vl = t->volume[0]; 945 const int16_t vr = t->volume[1]; 946 const int16_t va = (int16_t)t->auxLevel; 947 do { 948 int16_t l = *in++; 949 out[0] = mulAdd(l, vl, out[0]); 950 out[1] = mulAdd(l, vr, out[1]); 951 out += 2; 952 aux[0] = mulAdd(l, va, aux[0]); 953 aux++; 954 } while (--frameCount); 955 } 956 } else { 957 // ramp gain 958 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) { 959 int32_t vl = t->prevVolume[0]; 960 int32_t vr = t->prevVolume[1]; 961 const int32_t vlInc = t->volumeInc[0]; 962 const int32_t vrInc = t->volumeInc[1]; 963 964 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d", 965 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0], 966 // (vl + vlInc*frameCount)/65536.0f, frameCount); 967 968 do { 969 int32_t l = *in++; 970 *out++ += (vl >> 16) * l; 971 *out++ += (vr >> 16) * l; 972 vl += vlInc; 973 vr += vrInc; 974 } while (--frameCount); 975 976 t->prevVolume[0] = vl; 977 t->prevVolume[1] = vr; 978 t->adjustVolumeRamp(false); 979 } 980 // constant gain 981 else { 982 const int16_t vl = t->volume[0]; 983 const int16_t vr = t->volume[1]; 984 do { 985 int16_t l = *in++; 986 out[0] = mulAdd(l, vl, out[0]); 987 out[1] = mulAdd(l, vr, out[1]); 988 out += 2; 989 } while (--frameCount); 990 } 991 } 992 t->in = in; 993} 994 995// no-op case 996void AudioMixer::process__nop(state_t* state, int64_t pts) 997{ 998 uint32_t e0 = state->enabledTracks; 999 size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS; 1000 while (e0) { 1001 // process by group of tracks with same output buffer to 1002 // avoid multiple memset() on same buffer 1003 uint32_t e1 = e0, e2 = e0; 1004 int i = 31 - __builtin_clz(e1); 1005 track_t& t1 = state->tracks[i]; 1006 e2 &= ~(1<<i); 1007 while (e2) { 1008 i = 31 - __builtin_clz(e2); 1009 e2 &= ~(1<<i); 1010 track_t& t2 = state->tracks[i]; 1011 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) { 1012 e1 &= ~(1<<i); 1013 } 1014 } 1015 e0 &= ~(e1); 1016 1017 memset(t1.mainBuffer, 0, bufSize); 1018 1019 while (e1) { 1020 i = 31 - __builtin_clz(e1); 1021 e1 &= ~(1<<i); 1022 t1 = state->tracks[i]; 1023 size_t outFrames = state->frameCount; 1024 while (outFrames) { 1025 t1.buffer.frameCount = outFrames; 1026 int64_t outputPTS = calculateOutputPTS( 1027 t1, pts, state->frameCount - outFrames); 1028 t1.bufferProvider->getNextBuffer(&t1.buffer, outputPTS); 1029 if (t1.buffer.raw == NULL) break; 1030 outFrames -= t1.buffer.frameCount; 1031 t1.bufferProvider->releaseBuffer(&t1.buffer); 1032 } 1033 } 1034 } 1035} 1036 1037// generic code without resampling 1038void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts) 1039{ 1040 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32))); 1041 1042 // acquire each track's buffer 1043 uint32_t enabledTracks = state->enabledTracks; 1044 uint32_t e0 = enabledTracks; 1045 while (e0) { 1046 const int i = 31 - __builtin_clz(e0); 1047 e0 &= ~(1<<i); 1048 track_t& t = state->tracks[i]; 1049 t.buffer.frameCount = state->frameCount; 1050 t.bufferProvider->getNextBuffer(&t.buffer, pts); 1051 t.frameCount = t.buffer.frameCount; 1052 t.in = t.buffer.raw; 1053 // t.in == NULL can happen if the track was flushed just after having 1054 // been enabled for mixing. 1055 if (t.in == NULL) 1056 enabledTracks &= ~(1<<i); 1057 } 1058 1059 e0 = enabledTracks; 1060 while (e0) { 1061 // process by group of tracks with same output buffer to 1062 // optimize cache use 1063 uint32_t e1 = e0, e2 = e0; 1064 int j = 31 - __builtin_clz(e1); 1065 track_t& t1 = state->tracks[j]; 1066 e2 &= ~(1<<j); 1067 while (e2) { 1068 j = 31 - __builtin_clz(e2); 1069 e2 &= ~(1<<j); 1070 track_t& t2 = state->tracks[j]; 1071 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) { 1072 e1 &= ~(1<<j); 1073 } 1074 } 1075 e0 &= ~(e1); 1076 // this assumes output 16 bits stereo, no resampling 1077 int32_t *out = t1.mainBuffer; 1078 size_t numFrames = 0; 1079 do { 1080 memset(outTemp, 0, sizeof(outTemp)); 1081 e2 = e1; 1082 while (e2) { 1083 const int i = 31 - __builtin_clz(e2); 1084 e2 &= ~(1<<i); 1085 track_t& t = state->tracks[i]; 1086 size_t outFrames = BLOCKSIZE; 1087 int32_t *aux = NULL; 1088 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) { 1089 aux = t.auxBuffer + numFrames; 1090 } 1091 while (outFrames) { 1092 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount; 1093 if (inFrames) { 1094 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux); 1095 t.frameCount -= inFrames; 1096 outFrames -= inFrames; 1097 if (CC_UNLIKELY(aux != NULL)) { 1098 aux += inFrames; 1099 } 1100 } 1101 if (t.frameCount == 0 && outFrames) { 1102 t.bufferProvider->releaseBuffer(&t.buffer); 1103 t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames); 1104 int64_t outputPTS = calculateOutputPTS( 1105 t, pts, numFrames + (BLOCKSIZE - outFrames)); 1106 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS); 1107 t.in = t.buffer.raw; 1108 if (t.in == NULL) { 1109 enabledTracks &= ~(1<<i); 1110 e1 &= ~(1<<i); 1111 break; 1112 } 1113 t.frameCount = t.buffer.frameCount; 1114 } 1115 } 1116 } 1117 ditherAndClamp(out, outTemp, BLOCKSIZE); 1118 out += BLOCKSIZE; 1119 numFrames += BLOCKSIZE; 1120 } while (numFrames < state->frameCount); 1121 } 1122 1123 // release each track's buffer 1124 e0 = enabledTracks; 1125 while (e0) { 1126 const int i = 31 - __builtin_clz(e0); 1127 e0 &= ~(1<<i); 1128 track_t& t = state->tracks[i]; 1129 t.bufferProvider->releaseBuffer(&t.buffer); 1130 } 1131} 1132 1133 1134// generic code with resampling 1135void AudioMixer::process__genericResampling(state_t* state, int64_t pts) 1136{ 1137 // this const just means that local variable outTemp doesn't change 1138 int32_t* const outTemp = state->outputTemp; 1139 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount; 1140 1141 size_t numFrames = state->frameCount; 1142 1143 uint32_t e0 = state->enabledTracks; 1144 while (e0) { 1145 // process by group of tracks with same output buffer 1146 // to optimize cache use 1147 uint32_t e1 = e0, e2 = e0; 1148 int j = 31 - __builtin_clz(e1); 1149 track_t& t1 = state->tracks[j]; 1150 e2 &= ~(1<<j); 1151 while (e2) { 1152 j = 31 - __builtin_clz(e2); 1153 e2 &= ~(1<<j); 1154 track_t& t2 = state->tracks[j]; 1155 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) { 1156 e1 &= ~(1<<j); 1157 } 1158 } 1159 e0 &= ~(e1); 1160 int32_t *out = t1.mainBuffer; 1161 memset(outTemp, 0, size); 1162 while (e1) { 1163 const int i = 31 - __builtin_clz(e1); 1164 e1 &= ~(1<<i); 1165 track_t& t = state->tracks[i]; 1166 int32_t *aux = NULL; 1167 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) { 1168 aux = t.auxBuffer; 1169 } 1170 1171 // this is a little goofy, on the resampling case we don't 1172 // acquire/release the buffers because it's done by 1173 // the resampler. 1174 if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) { 1175 t.resampler->setPTS(pts); 1176 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux); 1177 } else { 1178 1179 size_t outFrames = 0; 1180 1181 while (outFrames < numFrames) { 1182 t.buffer.frameCount = numFrames - outFrames; 1183 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames); 1184 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS); 1185 t.in = t.buffer.raw; 1186 // t.in == NULL can happen if the track was flushed just after having 1187 // been enabled for mixing. 1188 if (t.in == NULL) break; 1189 1190 if (CC_UNLIKELY(aux != NULL)) { 1191 aux += outFrames; 1192 } 1193 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux); 1194 outFrames += t.buffer.frameCount; 1195 t.bufferProvider->releaseBuffer(&t.buffer); 1196 } 1197 } 1198 } 1199 ditherAndClamp(out, outTemp, numFrames); 1200 } 1201} 1202 1203// one track, 16 bits stereo without resampling is the most common case 1204void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state, 1205 int64_t pts) 1206{ 1207 // This method is only called when state->enabledTracks has exactly 1208 // one bit set. The asserts below would verify this, but are commented out 1209 // since the whole point of this method is to optimize performance. 1210 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled"); 1211 const int i = 31 - __builtin_clz(state->enabledTracks); 1212 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled"); 1213 const track_t& t = state->tracks[i]; 1214 1215 AudioBufferProvider::Buffer& b(t.buffer); 1216 1217 int32_t* out = t.mainBuffer; 1218 size_t numFrames = state->frameCount; 1219 1220 const int16_t vl = t.volume[0]; 1221 const int16_t vr = t.volume[1]; 1222 const uint32_t vrl = t.volumeRL; 1223 while (numFrames) { 1224 b.frameCount = numFrames; 1225 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer); 1226 t.bufferProvider->getNextBuffer(&b, outputPTS); 1227 const int16_t *in = b.i16; 1228 1229 // in == NULL can happen if the track was flushed just after having 1230 // been enabled for mixing. 1231 if (in == NULL || ((unsigned long)in & 3)) { 1232 memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t)); 1233 ALOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: buffer %p track %d, channels %d, needs %08x", 1234 in, i, t.channelCount, t.needs); 1235 return; 1236 } 1237 size_t outFrames = b.frameCount; 1238 1239 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) { 1240 // volume is boosted, so we might need to clamp even though 1241 // we process only one track. 1242 do { 1243 uint32_t rl = *reinterpret_cast<const uint32_t *>(in); 1244 in += 2; 1245 int32_t l = mulRL(1, rl, vrl) >> 12; 1246 int32_t r = mulRL(0, rl, vrl) >> 12; 1247 // clamping... 1248 l = clamp16(l); 1249 r = clamp16(r); 1250 *out++ = (r<<16) | (l & 0xFFFF); 1251 } while (--outFrames); 1252 } else { 1253 do { 1254 uint32_t rl = *reinterpret_cast<const uint32_t *>(in); 1255 in += 2; 1256 int32_t l = mulRL(1, rl, vrl) >> 12; 1257 int32_t r = mulRL(0, rl, vrl) >> 12; 1258 *out++ = (r<<16) | (l & 0xFFFF); 1259 } while (--outFrames); 1260 } 1261 numFrames -= b.frameCount; 1262 t.bufferProvider->releaseBuffer(&b); 1263 } 1264} 1265 1266#if 0 1267// 2 tracks is also a common case 1268// NEVER used in current implementation of process__validate() 1269// only use if the 2 tracks have the same output buffer 1270void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state, 1271 int64_t pts) 1272{ 1273 int i; 1274 uint32_t en = state->enabledTracks; 1275 1276 i = 31 - __builtin_clz(en); 1277 const track_t& t0 = state->tracks[i]; 1278 AudioBufferProvider::Buffer& b0(t0.buffer); 1279 1280 en &= ~(1<<i); 1281 i = 31 - __builtin_clz(en); 1282 const track_t& t1 = state->tracks[i]; 1283 AudioBufferProvider::Buffer& b1(t1.buffer); 1284 1285 const int16_t *in0; 1286 const int16_t vl0 = t0.volume[0]; 1287 const int16_t vr0 = t0.volume[1]; 1288 size_t frameCount0 = 0; 1289 1290 const int16_t *in1; 1291 const int16_t vl1 = t1.volume[0]; 1292 const int16_t vr1 = t1.volume[1]; 1293 size_t frameCount1 = 0; 1294 1295 //FIXME: only works if two tracks use same buffer 1296 int32_t* out = t0.mainBuffer; 1297 size_t numFrames = state->frameCount; 1298 const int16_t *buff = NULL; 1299 1300 1301 while (numFrames) { 1302 1303 if (frameCount0 == 0) { 1304 b0.frameCount = numFrames; 1305 int64_t outputPTS = calculateOutputPTS(t0, pts, 1306 out - t0.mainBuffer); 1307 t0.bufferProvider->getNextBuffer(&b0, outputPTS); 1308 if (b0.i16 == NULL) { 1309 if (buff == NULL) { 1310 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount]; 1311 } 1312 in0 = buff; 1313 b0.frameCount = numFrames; 1314 } else { 1315 in0 = b0.i16; 1316 } 1317 frameCount0 = b0.frameCount; 1318 } 1319 if (frameCount1 == 0) { 1320 b1.frameCount = numFrames; 1321 int64_t outputPTS = calculateOutputPTS(t1, pts, 1322 out - t0.mainBuffer); 1323 t1.bufferProvider->getNextBuffer(&b1, outputPTS); 1324 if (b1.i16 == NULL) { 1325 if (buff == NULL) { 1326 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount]; 1327 } 1328 in1 = buff; 1329 b1.frameCount = numFrames; 1330 } else { 1331 in1 = b1.i16; 1332 } 1333 frameCount1 = b1.frameCount; 1334 } 1335 1336 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1; 1337 1338 numFrames -= outFrames; 1339 frameCount0 -= outFrames; 1340 frameCount1 -= outFrames; 1341 1342 do { 1343 int32_t l0 = *in0++; 1344 int32_t r0 = *in0++; 1345 l0 = mul(l0, vl0); 1346 r0 = mul(r0, vr0); 1347 int32_t l = *in1++; 1348 int32_t r = *in1++; 1349 l = mulAdd(l, vl1, l0) >> 12; 1350 r = mulAdd(r, vr1, r0) >> 12; 1351 // clamping... 1352 l = clamp16(l); 1353 r = clamp16(r); 1354 *out++ = (r<<16) | (l & 0xFFFF); 1355 } while (--outFrames); 1356 1357 if (frameCount0 == 0) { 1358 t0.bufferProvider->releaseBuffer(&b0); 1359 } 1360 if (frameCount1 == 0) { 1361 t1.bufferProvider->releaseBuffer(&b1); 1362 } 1363 } 1364 1365 delete [] buff; 1366} 1367#endif 1368 1369int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS, 1370 int outputFrameIndex) 1371{ 1372 if (AudioBufferProvider::kInvalidPTS == basePTS) 1373 return AudioBufferProvider::kInvalidPTS; 1374 1375 return basePTS + ((outputFrameIndex * t.localTimeFreq) / t.sampleRate); 1376} 1377 1378// ---------------------------------------------------------------------------- 1379}; // namespace android 1380