Loading media/libmedia/AudioTrack.cpp +10 −2 Original line number Diff line number Diff line Loading @@ -278,7 +278,9 @@ status_t AudioTrack::set( } // handle default values first. if (streamType == AUDIO_STREAM_DEFAULT) { // TODO once AudioPolicyManager fully supports audio_attributes_t, // remove stream "text-to-speech" redirect if ((streamType == AUDIO_STREAM_DEFAULT) || (streamType == AUDIO_STREAM_TTS)) { streamType = AUDIO_STREAM_MUSIC; } Loading Loading @@ -2124,6 +2126,12 @@ void AudioTrack::setStreamTypeFromAttributes(audio_attributes_t& aa) { mStreamType = AUDIO_STREAM_BLUETOOTH_SCO; return; } // TODO once AudioPolicyManager fully supports audio_attributes_t, // remove stream remap, the flag will be enough if ((aa.flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) { mStreamType = AUDIO_STREAM_TTS; return; } // usage to stream type mapping switch (aa.usage) { Loading Loading @@ -2174,7 +2182,7 @@ void AudioTrack::setStreamTypeFromAttributes(audio_attributes_t& aa) { bool AudioTrack::isValidAttributes(const audio_attributes_t *paa) { // has flags that map to a strategy? if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO)) != 0) { if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) { return true; } Loading services/audiopolicy/AudioPolicyManager.cpp +126 −9 Original line number Diff line number Diff line Loading @@ -1127,6 +1127,20 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, return BAD_VALUE; } // cannot start playback of STREAM_TTS if any other output is being used uint32_t beaconMuteLatency = 0; if (stream == AUDIO_STREAM_TTS) { ALOGV("\t found BEACON stream"); if (isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) { return INVALID_OPERATION; } else { beaconMuteLatency = handleEventForBeacon(STARTING_BEACON); } } else { // some playback other than beacon starts beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT); } sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); // increment usage count for this stream on the requested output: Loading @@ -1138,8 +1152,9 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); routing_strategy strategy = getStrategy(stream); bool shouldWait = (strategy == STRATEGY_SONIFICATION) || (strategy == STRATEGY_SONIFICATION_RESPECTFUL); uint32_t waitMs = 0; (strategy == STRATEGY_SONIFICATION_RESPECTFUL) || (beaconMuteLatency > 0); uint32_t waitMs = beaconMuteLatency; bool force = false; for (size_t i = 0; i < mOutputs.size(); i++) { sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); Loading @@ -1153,7 +1168,8 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, force = true; } // wait for audio on other active outputs to be presented when starting // a notification so that audio focus effect can propagate. // a notification so that audio focus effect can propagate, or that a mute/unmute // event occurred for beacon uint32_t latency = desc->latency(); if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { waitMs = latency; Loading Loading @@ -1197,6 +1213,9 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); // always handle stream stop, check which stream type is stopping handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT); // handle special case for sonification while in call if (isInCall()) { handleIncallSonification(stream, false, false); Loading Loading @@ -2669,7 +2688,10 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), mA2dpSuspended(false), mSpeakerDrcEnabled(false), mNextUniqueId(1), mAudioPortGeneration(1) mAudioPortGeneration(1), mBeaconMuteRefCount(0), mBeaconPlayingRefCount(0), mBeaconMuted(false) { mUidCached = getuid(); mpClientInterface = clientInterface; Loading Loading @@ -3840,6 +3862,8 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, // use device for strategy media // 7: the strategy DTMF is active on the output: // use device for strategy DTMF // 8: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output: // use device for strategy t-t-s if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE) && mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); Loading @@ -3856,6 +3880,8 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) { device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache); } ALOGV("getNewOutputDevice() selected device %x", device); Loading Loading @@ -3934,16 +3960,20 @@ AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy( case AUDIO_STREAM_SYSTEM: // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs // while key clicks are played produces a poor result case AUDIO_STREAM_TTS: case AUDIO_STREAM_MUSIC: return STRATEGY_MEDIA; case AUDIO_STREAM_ENFORCED_AUDIBLE: return STRATEGY_ENFORCED_AUDIBLE; case AUDIO_STREAM_TTS: return STRATEGY_TRANSMITTED_THROUGH_SPEAKER; } } uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) { // flags to strategy mapping if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) { return (uint32_t) STRATEGY_TRANSMITTED_THROUGH_SPEAKER; } if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { return (uint32_t) STRATEGY_ENFORCED_AUDIBLE; } Loading Loading @@ -3991,6 +4021,74 @@ void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t } } bool AudioPolicyManager::isAnyOutputActive(audio_stream_type_t streamToIgnore) { for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { if (s == (size_t) streamToIgnore) { continue; } for (size_t i = 0; i < mOutputs.size(); i++) { const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); if (outputDesc->mRefCount[s] != 0) { return true; } } } return false; } uint32_t AudioPolicyManager::handleEventForBeacon(int event) { switch(event) { case STARTING_OUTPUT: mBeaconMuteRefCount++; break; case STOPPING_OUTPUT: if (mBeaconMuteRefCount > 0) { mBeaconMuteRefCount--; } break; case STARTING_BEACON: mBeaconPlayingRefCount++; break; case STOPPING_BEACON: if (mBeaconPlayingRefCount > 0) { mBeaconPlayingRefCount--; } break; } if (mBeaconMuteRefCount > 0) { // any playback causes beacon to be muted return setBeaconMute(true); } else { // no other playback: unmute when beacon starts playing, mute when it stops return setBeaconMute(mBeaconPlayingRefCount == 0); } } uint32_t AudioPolicyManager::setBeaconMute(bool mute) { ALOGV("setBeaconMute(%d) mBeaconMuteRefCount=%d mBeaconPlayingRefCount=%d", mute, mBeaconMuteRefCount, mBeaconPlayingRefCount); // keep track of muted state to avoid repeating mute/unmute operations if (mBeaconMuted != mute) { // mute/unmute AUDIO_STREAM_TTS on all outputs ALOGV("\t muting %d", mute); uint32_t maxLatency = 0; for (size_t i = 0; i < mOutputs.size(); i++) { sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); setStreamMute(AUDIO_STREAM_TTS, mute/*on*/, desc->mIoHandle, 0 /*delay*/, AUDIO_DEVICE_NONE); const uint32_t latency = desc->latency() * 2; if (latency > maxLatency) { maxLatency = latency; } } mBeaconMuted = mute; return maxLatency; } return 0; } audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, bool fromCache) { Loading @@ -4004,6 +4102,14 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types(); switch (strategy) { case STRATEGY_TRANSMITTED_THROUGH_SPEAKER: device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; if (!device) { ALOGE("getDeviceForStrategy() no device found for "\ "STRATEGY_TRANSMITTED_THROUGH_SPEAKER"); } break; case STRATEGY_SONIFICATION_RESPECTFUL: if (isInCall()) { device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); Loading Loading @@ -4928,6 +5034,16 @@ const AudioPolicyManager::VolumeCurvePoint {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f} }; const AudioPolicyManager::VolumeCurvePoint AudioPolicyManager::sLinearVolumeCurve[AudioPolicyManager::VOLCNT] = { {0, -96.0f}, {33, -68.0f}, {66, -34.0f}, {100, 0.0f} }; const AudioPolicyManager::VolumeCurvePoint AudioPolicyManager::sSilentVolumeCurve[AudioPolicyManager::VOLCNT] = { {0, -96.0f}, {1, -96.0f}, {2, -96.0f}, {100, -96.0f} }; const AudioPolicyManager::VolumeCurvePoint *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT] [AudioPolicyManager::DEVICE_CATEGORY_CNT] = { Loading Loading @@ -4986,10 +5102,11 @@ const AudioPolicyManager::VolumeCurvePoint sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA }, { // AUDIO_STREAM_TTS sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA // "Transmitted Through Speaker": always silent except on DEVICE_CATEGORY_SPEAKER sSilentVolumeCurve, // DEVICE_CATEGORY_HEADSET sLinearVolumeCurve, // DEVICE_CATEGORY_SPEAKER sSilentVolumeCurve, // DEVICE_CATEGORY_EARPIECE sSilentVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA }, }; Loading services/audiopolicy/AudioPolicyManager.h +22 −0 Original line number Diff line number Diff line Loading @@ -187,6 +187,7 @@ protected: STRATEGY_SONIFICATION_RESPECTFUL, STRATEGY_DTMF, STRATEGY_ENFORCED_AUDIBLE, STRATEGY_TRANSMITTED_THROUGH_SPEAKER, NUM_STRATEGIES }; Loading Loading @@ -434,6 +435,8 @@ protected: static const VolumeCurvePoint sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT]; static const VolumeCurvePoint sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT]; static const VolumeCurvePoint sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT]; static const VolumeCurvePoint sLinearVolumeCurve[AudioPolicyManager::VOLCNT]; static const VolumeCurvePoint sSilentVolumeCurve[AudioPolicyManager::VOLCNT]; // default volume curves per stream and device category. See initializeVolumeCurves() static const VolumeCurvePoint *sVolumeProfiles[AUDIO_STREAM_CNT][DEVICE_CATEGORY_CNT]; Loading Loading @@ -808,6 +811,18 @@ protected: sp<AudioPatch> mCallTxPatch; sp<AudioPatch> mCallRxPatch; // for supporting "beacon" streams, i.e. streams that only play on speaker, and never // when something other than STREAM_TTS (a.k.a. "Transmitted Through Speaker") is playing enum { STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON }; uint32_t mBeaconMuteRefCount; // ref count for stream that would mute beacon uint32_t mBeaconPlayingRefCount;// ref count for the playing beacon streams bool mBeaconMuted; // has STREAM_TTS been muted #ifdef AUDIO_POLICY_TEST Mutex mLock; Condition mWaitWorkCV; Loading Loading @@ -852,6 +867,13 @@ private: const audio_offload_info_t *offloadInfo); // internal function to derive a stream type value from audio attributes audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr); // return true if any output is playing anything besides the stream to ignore bool isAnyOutputActive(audio_stream_type_t streamToIgnore); // event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON // returns 0 if no mute/unmute event happened, the largest latency of the device where // the mute/unmute happened uint32_t handleEventForBeacon(int event); uint32_t setBeaconMute(bool mute); }; }; Loading
media/libmedia/AudioTrack.cpp +10 −2 Original line number Diff line number Diff line Loading @@ -278,7 +278,9 @@ status_t AudioTrack::set( } // handle default values first. if (streamType == AUDIO_STREAM_DEFAULT) { // TODO once AudioPolicyManager fully supports audio_attributes_t, // remove stream "text-to-speech" redirect if ((streamType == AUDIO_STREAM_DEFAULT) || (streamType == AUDIO_STREAM_TTS)) { streamType = AUDIO_STREAM_MUSIC; } Loading Loading @@ -2124,6 +2126,12 @@ void AudioTrack::setStreamTypeFromAttributes(audio_attributes_t& aa) { mStreamType = AUDIO_STREAM_BLUETOOTH_SCO; return; } // TODO once AudioPolicyManager fully supports audio_attributes_t, // remove stream remap, the flag will be enough if ((aa.flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) { mStreamType = AUDIO_STREAM_TTS; return; } // usage to stream type mapping switch (aa.usage) { Loading Loading @@ -2174,7 +2182,7 @@ void AudioTrack::setStreamTypeFromAttributes(audio_attributes_t& aa) { bool AudioTrack::isValidAttributes(const audio_attributes_t *paa) { // has flags that map to a strategy? if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO)) != 0) { if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) { return true; } Loading
services/audiopolicy/AudioPolicyManager.cpp +126 −9 Original line number Diff line number Diff line Loading @@ -1127,6 +1127,20 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, return BAD_VALUE; } // cannot start playback of STREAM_TTS if any other output is being used uint32_t beaconMuteLatency = 0; if (stream == AUDIO_STREAM_TTS) { ALOGV("\t found BEACON stream"); if (isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) { return INVALID_OPERATION; } else { beaconMuteLatency = handleEventForBeacon(STARTING_BEACON); } } else { // some playback other than beacon starts beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT); } sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); // increment usage count for this stream on the requested output: Loading @@ -1138,8 +1152,9 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); routing_strategy strategy = getStrategy(stream); bool shouldWait = (strategy == STRATEGY_SONIFICATION) || (strategy == STRATEGY_SONIFICATION_RESPECTFUL); uint32_t waitMs = 0; (strategy == STRATEGY_SONIFICATION_RESPECTFUL) || (beaconMuteLatency > 0); uint32_t waitMs = beaconMuteLatency; bool force = false; for (size_t i = 0; i < mOutputs.size(); i++) { sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); Loading @@ -1153,7 +1168,8 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, force = true; } // wait for audio on other active outputs to be presented when starting // a notification so that audio focus effect can propagate. // a notification so that audio focus effect can propagate, or that a mute/unmute // event occurred for beacon uint32_t latency = desc->latency(); if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { waitMs = latency; Loading Loading @@ -1197,6 +1213,9 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); // always handle stream stop, check which stream type is stopping handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT); // handle special case for sonification while in call if (isInCall()) { handleIncallSonification(stream, false, false); Loading Loading @@ -2669,7 +2688,10 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), mA2dpSuspended(false), mSpeakerDrcEnabled(false), mNextUniqueId(1), mAudioPortGeneration(1) mAudioPortGeneration(1), mBeaconMuteRefCount(0), mBeaconPlayingRefCount(0), mBeaconMuted(false) { mUidCached = getuid(); mpClientInterface = clientInterface; Loading Loading @@ -3840,6 +3862,8 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, // use device for strategy media // 7: the strategy DTMF is active on the output: // use device for strategy DTMF // 8: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output: // use device for strategy t-t-s if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE) && mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); Loading @@ -3856,6 +3880,8 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) { device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache); } ALOGV("getNewOutputDevice() selected device %x", device); Loading Loading @@ -3934,16 +3960,20 @@ AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy( case AUDIO_STREAM_SYSTEM: // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs // while key clicks are played produces a poor result case AUDIO_STREAM_TTS: case AUDIO_STREAM_MUSIC: return STRATEGY_MEDIA; case AUDIO_STREAM_ENFORCED_AUDIBLE: return STRATEGY_ENFORCED_AUDIBLE; case AUDIO_STREAM_TTS: return STRATEGY_TRANSMITTED_THROUGH_SPEAKER; } } uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) { // flags to strategy mapping if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) { return (uint32_t) STRATEGY_TRANSMITTED_THROUGH_SPEAKER; } if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { return (uint32_t) STRATEGY_ENFORCED_AUDIBLE; } Loading Loading @@ -3991,6 +4021,74 @@ void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t } } bool AudioPolicyManager::isAnyOutputActive(audio_stream_type_t streamToIgnore) { for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { if (s == (size_t) streamToIgnore) { continue; } for (size_t i = 0; i < mOutputs.size(); i++) { const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); if (outputDesc->mRefCount[s] != 0) { return true; } } } return false; } uint32_t AudioPolicyManager::handleEventForBeacon(int event) { switch(event) { case STARTING_OUTPUT: mBeaconMuteRefCount++; break; case STOPPING_OUTPUT: if (mBeaconMuteRefCount > 0) { mBeaconMuteRefCount--; } break; case STARTING_BEACON: mBeaconPlayingRefCount++; break; case STOPPING_BEACON: if (mBeaconPlayingRefCount > 0) { mBeaconPlayingRefCount--; } break; } if (mBeaconMuteRefCount > 0) { // any playback causes beacon to be muted return setBeaconMute(true); } else { // no other playback: unmute when beacon starts playing, mute when it stops return setBeaconMute(mBeaconPlayingRefCount == 0); } } uint32_t AudioPolicyManager::setBeaconMute(bool mute) { ALOGV("setBeaconMute(%d) mBeaconMuteRefCount=%d mBeaconPlayingRefCount=%d", mute, mBeaconMuteRefCount, mBeaconPlayingRefCount); // keep track of muted state to avoid repeating mute/unmute operations if (mBeaconMuted != mute) { // mute/unmute AUDIO_STREAM_TTS on all outputs ALOGV("\t muting %d", mute); uint32_t maxLatency = 0; for (size_t i = 0; i < mOutputs.size(); i++) { sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); setStreamMute(AUDIO_STREAM_TTS, mute/*on*/, desc->mIoHandle, 0 /*delay*/, AUDIO_DEVICE_NONE); const uint32_t latency = desc->latency() * 2; if (latency > maxLatency) { maxLatency = latency; } } mBeaconMuted = mute; return maxLatency; } return 0; } audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, bool fromCache) { Loading @@ -4004,6 +4102,14 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types(); switch (strategy) { case STRATEGY_TRANSMITTED_THROUGH_SPEAKER: device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; if (!device) { ALOGE("getDeviceForStrategy() no device found for "\ "STRATEGY_TRANSMITTED_THROUGH_SPEAKER"); } break; case STRATEGY_SONIFICATION_RESPECTFUL: if (isInCall()) { device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); Loading Loading @@ -4928,6 +5034,16 @@ const AudioPolicyManager::VolumeCurvePoint {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f} }; const AudioPolicyManager::VolumeCurvePoint AudioPolicyManager::sLinearVolumeCurve[AudioPolicyManager::VOLCNT] = { {0, -96.0f}, {33, -68.0f}, {66, -34.0f}, {100, 0.0f} }; const AudioPolicyManager::VolumeCurvePoint AudioPolicyManager::sSilentVolumeCurve[AudioPolicyManager::VOLCNT] = { {0, -96.0f}, {1, -96.0f}, {2, -96.0f}, {100, -96.0f} }; const AudioPolicyManager::VolumeCurvePoint *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT] [AudioPolicyManager::DEVICE_CATEGORY_CNT] = { Loading Loading @@ -4986,10 +5102,11 @@ const AudioPolicyManager::VolumeCurvePoint sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA }, { // AUDIO_STREAM_TTS sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA // "Transmitted Through Speaker": always silent except on DEVICE_CATEGORY_SPEAKER sSilentVolumeCurve, // DEVICE_CATEGORY_HEADSET sLinearVolumeCurve, // DEVICE_CATEGORY_SPEAKER sSilentVolumeCurve, // DEVICE_CATEGORY_EARPIECE sSilentVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA }, }; Loading
services/audiopolicy/AudioPolicyManager.h +22 −0 Original line number Diff line number Diff line Loading @@ -187,6 +187,7 @@ protected: STRATEGY_SONIFICATION_RESPECTFUL, STRATEGY_DTMF, STRATEGY_ENFORCED_AUDIBLE, STRATEGY_TRANSMITTED_THROUGH_SPEAKER, NUM_STRATEGIES }; Loading Loading @@ -434,6 +435,8 @@ protected: static const VolumeCurvePoint sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT]; static const VolumeCurvePoint sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT]; static const VolumeCurvePoint sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT]; static const VolumeCurvePoint sLinearVolumeCurve[AudioPolicyManager::VOLCNT]; static const VolumeCurvePoint sSilentVolumeCurve[AudioPolicyManager::VOLCNT]; // default volume curves per stream and device category. See initializeVolumeCurves() static const VolumeCurvePoint *sVolumeProfiles[AUDIO_STREAM_CNT][DEVICE_CATEGORY_CNT]; Loading Loading @@ -808,6 +811,18 @@ protected: sp<AudioPatch> mCallTxPatch; sp<AudioPatch> mCallRxPatch; // for supporting "beacon" streams, i.e. streams that only play on speaker, and never // when something other than STREAM_TTS (a.k.a. "Transmitted Through Speaker") is playing enum { STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON }; uint32_t mBeaconMuteRefCount; // ref count for stream that would mute beacon uint32_t mBeaconPlayingRefCount;// ref count for the playing beacon streams bool mBeaconMuted; // has STREAM_TTS been muted #ifdef AUDIO_POLICY_TEST Mutex mLock; Condition mWaitWorkCV; Loading Loading @@ -852,6 +867,13 @@ private: const audio_offload_info_t *offloadInfo); // internal function to derive a stream type value from audio attributes audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr); // return true if any output is playing anything besides the stream to ignore bool isAnyOutputActive(audio_stream_type_t streamToIgnore); // event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON // returns 0 if no mute/unmute event happened, the largest latency of the device where // the mute/unmute happened uint32_t handleEventForBeacon(int event); uint32_t setBeaconMute(bool mute); }; };