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