AudioOutputDescriptor.cpp revision a8ecc2c72ca26389bd6b0162181d60aaeaca8149
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "APM::AudioOutputDescriptor" 18//#define LOG_NDEBUG 0 19 20#include <AudioPolicyInterface.h> 21#include "AudioOutputDescriptor.h" 22#include "IOProfile.h" 23#include "AudioGain.h" 24#include "Volume.h" 25#include "HwModule.h" 26#include <media/AudioPolicy.h> 27 28// A device mask for all audio output devices that are considered "remote" when evaluating 29// active output devices in isStreamActiveRemotely() 30#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX 31 32namespace android { 33 34AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port, 35 AudioPolicyClientInterface *clientInterface) 36 : mPort(port), mDevice(AUDIO_DEVICE_NONE), 37 mPatchHandle(0), mClientInterface(clientInterface), mId(0) 38{ 39 // clear usage count for all stream types 40 for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 41 mRefCount[i] = 0; 42 mCurVolume[i] = -1.0; 43 mMuteCount[i] = 0; 44 mStopTime[i] = 0; 45 } 46 for (int i = 0; i < NUM_STRATEGIES; i++) { 47 mStrategyMutedByDevice[i] = false; 48 } 49 if (port != NULL) { 50 mSamplingRate = port->pickSamplingRate(); 51 mFormat = port->pickFormat(); 52 mChannelMask = port->pickChannelMask(); 53 if (port->mGains.size() > 0) { 54 port->mGains[0]->getDefaultConfig(&mGain); 55 } 56 } 57} 58 59audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const 60{ 61 return mPort->getModuleHandle(); 62} 63 64audio_port_handle_t AudioOutputDescriptor::getId() const 65{ 66 return mId; 67} 68 69audio_devices_t AudioOutputDescriptor::device() const 70{ 71 return mDevice; 72} 73 74audio_devices_t AudioOutputDescriptor::supportedDevices() 75{ 76 return mDevice; 77} 78 79bool AudioOutputDescriptor::sharesHwModuleWith( 80 const sp<AudioOutputDescriptor> outputDesc) 81{ 82 if (outputDesc->isDuplicated()) { 83 return sharesHwModuleWith(outputDesc->subOutput1()) || 84 sharesHwModuleWith(outputDesc->subOutput2()); 85 } else { 86 return (getModuleHandle() == outputDesc->getModuleHandle()); 87 } 88} 89 90void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 91 int delta) 92{ 93 if ((delta + (int)mRefCount[stream]) < 0) { 94 ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", 95 delta, stream, mRefCount[stream]); 96 mRefCount[stream] = 0; 97 return; 98 } 99 mRefCount[stream] += delta; 100 ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 101} 102 103bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const 104{ 105 nsecs_t sysTime = 0; 106 if (inPastMs != 0) { 107 sysTime = systemTime(); 108 } 109 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 110 if (i == AUDIO_STREAM_PATCH) { 111 continue; 112 } 113 if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) { 114 return true; 115 } 116 } 117 return false; 118} 119 120bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, 121 uint32_t inPastMs, 122 nsecs_t sysTime) const 123{ 124 if (mRefCount[stream] != 0) { 125 return true; 126 } 127 if (inPastMs == 0) { 128 return false; 129 } 130 if (sysTime == 0) { 131 sysTime = systemTime(); 132 } 133 if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 134 return true; 135 } 136 return false; 137} 138 139 140bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused) 141{ 142 return false; 143} 144 145bool AudioOutputDescriptor::setVolume(float volume, 146 audio_stream_type_t stream, 147 audio_devices_t device __unused, 148 uint32_t delayMs, 149 bool force) 150{ 151 // We actually change the volume if: 152 // - the float value returned by computeVolume() changed 153 // - the force flag is set 154 if (volume != mCurVolume[stream] || force) { 155 ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs); 156 mCurVolume[stream] = volume; 157 return true; 158 } 159 return false; 160} 161 162void AudioOutputDescriptor::toAudioPortConfig( 163 struct audio_port_config *dstConfig, 164 const struct audio_port_config *srcConfig) const 165{ 166 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 167 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 168 if (srcConfig != NULL) { 169 dstConfig->config_mask |= srcConfig->config_mask; 170 } 171 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 172 173 dstConfig->id = mId; 174 dstConfig->role = AUDIO_PORT_ROLE_SOURCE; 175 dstConfig->type = AUDIO_PORT_TYPE_MIX; 176 dstConfig->ext.mix.hw_module = getModuleHandle(); 177 dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 178} 179 180void AudioOutputDescriptor::toAudioPort( 181 struct audio_port *port) const 182{ 183 mPort->toAudioPort(port); 184 port->id = mId; 185 port->ext.mix.hw_module = getModuleHandle(); 186} 187 188status_t AudioOutputDescriptor::dump(int fd) 189{ 190 const size_t SIZE = 256; 191 char buffer[SIZE]; 192 String8 result; 193 194 snprintf(buffer, SIZE, " ID: %d\n", mId); 195 result.append(buffer); 196 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 197 result.append(buffer); 198 snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 199 result.append(buffer); 200 snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 201 result.append(buffer); 202 snprintf(buffer, SIZE, " Devices %08x\n", device()); 203 result.append(buffer); 204 snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 205 result.append(buffer); 206 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 207 snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", 208 i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 209 result.append(buffer); 210 } 211 write(fd, result.string(), result.size()); 212 213 return NO_ERROR; 214} 215 216void AudioOutputDescriptor::log(const char* indent) 217{ 218 ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]", 219 indent, mId, mId, mSamplingRate, mFormat, mChannelMask); 220} 221 222// SwAudioOutputDescriptor implementation 223SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile, 224 AudioPolicyClientInterface *clientInterface) 225 : AudioOutputDescriptor(profile, clientInterface), 226 mProfile(profile), mIoHandle(0), mLatency(0), 227 mFlags((audio_output_flags_t)0), mPolicyMix(NULL), 228 mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0) 229{ 230 if (profile != NULL) { 231 mFlags = (audio_output_flags_t)profile->getFlags(); 232 } 233} 234 235void SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle) 236{ 237 mId = AudioPort::getNextUniqueId(); 238 mIoHandle = ioHandle; 239} 240 241 242status_t SwAudioOutputDescriptor::dump(int fd) 243{ 244 const size_t SIZE = 256; 245 char buffer[SIZE]; 246 String8 result; 247 248 snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 249 result.append(buffer); 250 snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 251 result.append(buffer); 252 write(fd, result.string(), result.size()); 253 254 AudioOutputDescriptor::dump(fd); 255 256 return NO_ERROR; 257} 258 259audio_devices_t SwAudioOutputDescriptor::device() const 260{ 261 if (isDuplicated()) { 262 return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 263 } else { 264 return mDevice; 265 } 266} 267 268bool SwAudioOutputDescriptor::sharesHwModuleWith( 269 const sp<AudioOutputDescriptor> outputDesc) 270{ 271 if (isDuplicated()) { 272 return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 273 } else if (outputDesc->isDuplicated()){ 274 return sharesHwModuleWith(outputDesc->subOutput1()) || 275 sharesHwModuleWith(outputDesc->subOutput2()); 276 } else { 277 return AudioOutputDescriptor::sharesHwModuleWith(outputDesc); 278 } 279} 280 281audio_devices_t SwAudioOutputDescriptor::supportedDevices() 282{ 283 if (isDuplicated()) { 284 return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 285 } else { 286 return mProfile->getSupportedDevicesType(); 287 } 288} 289 290uint32_t SwAudioOutputDescriptor::latency() 291{ 292 if (isDuplicated()) { 293 return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 294 } else { 295 return mLatency; 296 } 297} 298 299void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 300 int delta) 301{ 302 // forward usage count change to attached outputs 303 if (isDuplicated()) { 304 mOutput1->changeRefCount(stream, delta); 305 mOutput2->changeRefCount(stream, delta); 306 } 307 AudioOutputDescriptor::changeRefCount(stream, delta); 308 309 // handle stream-independent ref count 310 uint32_t oldGlobalRefCount = mGlobalRefCount; 311 if ((delta + (int)mGlobalRefCount) < 0) { 312 ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount); 313 mGlobalRefCount = 0; 314 } else { 315 mGlobalRefCount += delta; 316 } 317 if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) { 318 if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) 319 { 320 mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId, 321 MIX_STATE_MIXING); 322 } 323 324 } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) { 325 if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) 326 { 327 mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId, 328 MIX_STATE_IDLE); 329 } 330 } 331} 332 333 334bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device) 335{ 336 // unit gain if rerouting to external policy 337 if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) { 338 if (mPolicyMix != NULL) { 339 ALOGV("max gain when rerouting for output=%d", mIoHandle); 340 return true; 341 } 342 } 343 return false; 344} 345 346void SwAudioOutputDescriptor::toAudioPortConfig( 347 struct audio_port_config *dstConfig, 348 const struct audio_port_config *srcConfig) const 349{ 350 351 ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle); 352 AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig); 353 354 dstConfig->ext.mix.handle = mIoHandle; 355} 356 357void SwAudioOutputDescriptor::toAudioPort( 358 struct audio_port *port) const 359{ 360 ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle); 361 362 AudioOutputDescriptor::toAudioPort(port); 363 364 toAudioPortConfig(&port->active_config); 365 port->ext.mix.handle = mIoHandle; 366 port->ext.mix.latency_class = 367 mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL; 368} 369 370bool SwAudioOutputDescriptor::setVolume(float volume, 371 audio_stream_type_t stream, 372 audio_devices_t device, 373 uint32_t delayMs, 374 bool force) 375{ 376 bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force); 377 378 if (changed) { 379 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 380 // enabled 381 float volume = Volume::DbToAmpl(mCurVolume[stream]); 382 if (stream == AUDIO_STREAM_BLUETOOTH_SCO) { 383 mClientInterface->setStreamVolume( 384 AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs); 385 } 386 mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs); 387 } 388 return changed; 389} 390 391// HwAudioOutputDescriptor implementation 392HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source, 393 AudioPolicyClientInterface *clientInterface) 394 : AudioOutputDescriptor(source->mDevice, clientInterface), 395 mSource(source) 396{ 397} 398 399status_t HwAudioOutputDescriptor::dump(int fd) 400{ 401 const size_t SIZE = 256; 402 char buffer[SIZE]; 403 String8 result; 404 405 AudioOutputDescriptor::dump(fd); 406 407 snprintf(buffer, SIZE, "Source:\n"); 408 result.append(buffer); 409 write(fd, result.string(), result.size()); 410 mSource->dump(fd); 411 412 return NO_ERROR; 413} 414 415audio_devices_t HwAudioOutputDescriptor::supportedDevices() 416{ 417 return mDevice; 418} 419 420void HwAudioOutputDescriptor::toAudioPortConfig( 421 struct audio_port_config *dstConfig, 422 const struct audio_port_config *srcConfig) const 423{ 424 mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig); 425} 426 427void HwAudioOutputDescriptor::toAudioPort( 428 struct audio_port *port) const 429{ 430 mSource->mDevice->toAudioPort(port); 431} 432 433 434bool HwAudioOutputDescriptor::setVolume(float volume, 435 audio_stream_type_t stream, 436 audio_devices_t device, 437 uint32_t delayMs, 438 bool force) 439{ 440 bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force); 441 442 if (changed) { 443 // TODO: use gain controller on source device if any to adjust volume 444 } 445 return changed; 446} 447 448// SwAudioOutputCollection implementation 449bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 450{ 451 nsecs_t sysTime = systemTime(); 452 for (size_t i = 0; i < this->size(); i++) { 453 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i); 454 if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 455 return true; 456 } 457 } 458 return false; 459} 460 461bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream, 462 uint32_t inPastMs) const 463{ 464 nsecs_t sysTime = systemTime(); 465 for (size_t i = 0; i < size(); i++) { 466 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 467 if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 468 outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 469 // do not consider re routing (when the output is going to a dynamic policy) 470 // as "remote playback" 471 if (outputDesc->mPolicyMix == NULL) { 472 return true; 473 } 474 } 475 } 476 return false; 477} 478 479audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const 480{ 481 for (size_t i = 0; i < size(); i++) { 482 sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 483 if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 484 return this->keyAt(i); 485 } 486 } 487 return 0; 488} 489 490sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const 491{ 492 for (size_t i = 0; i < size(); i++) { 493 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 494 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 495 return outputDesc; 496 } 497 } 498 return NULL; 499} 500 501sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const 502{ 503 sp<SwAudioOutputDescriptor> outputDesc = NULL; 504 for (size_t i = 0; i < size(); i++) { 505 outputDesc = valueAt(i); 506 if (outputDesc->getId() == id) { 507 break; 508 } 509 } 510 return outputDesc; 511} 512 513bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const 514{ 515 for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { 516 if (s == (size_t) streamToIgnore) { 517 continue; 518 } 519 for (size_t i = 0; i < size(); i++) { 520 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 521 if (outputDesc->mRefCount[s] != 0) { 522 return true; 523 } 524 } 525 } 526 return false; 527} 528 529audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const 530{ 531 sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle); 532 audio_devices_t devices = outputDesc->mProfile->getSupportedDevicesType(); 533 return devices; 534} 535 536 537status_t SwAudioOutputCollection::dump(int fd) const 538{ 539 const size_t SIZE = 256; 540 char buffer[SIZE]; 541 542 snprintf(buffer, SIZE, "\nOutputs dump:\n"); 543 write(fd, buffer, strlen(buffer)); 544 for (size_t i = 0; i < size(); i++) { 545 snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i)); 546 write(fd, buffer, strlen(buffer)); 547 valueAt(i)->dump(fd); 548 } 549 550 return NO_ERROR; 551} 552 553// HwAudioOutputCollection implementation 554bool HwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 555{ 556 nsecs_t sysTime = systemTime(); 557 for (size_t i = 0; i < this->size(); i++) { 558 const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i); 559 if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 560 return true; 561 } 562 } 563 return false; 564} 565 566bool HwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const 567{ 568 for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { 569 if (s == (size_t) streamToIgnore) { 570 continue; 571 } 572 for (size_t i = 0; i < size(); i++) { 573 const sp<HwAudioOutputDescriptor> outputDesc = valueAt(i); 574 if (outputDesc->mRefCount[s] != 0) { 575 return true; 576 } 577 } 578 } 579 return false; 580} 581 582status_t HwAudioOutputCollection::dump(int fd) const 583{ 584 const size_t SIZE = 256; 585 char buffer[SIZE]; 586 587 snprintf(buffer, SIZE, "\nOutputs dump:\n"); 588 write(fd, buffer, strlen(buffer)); 589 for (size_t i = 0; i < size(); i++) { 590 snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i)); 591 write(fd, buffer, strlen(buffer)); 592 valueAt(i)->dump(fd); 593 } 594 595 return NO_ERROR; 596} 597 598}; //namespace android 599