From 7bbb31f670965d0e29ef0ff398a367522cdb4507 Mon Sep 17 00:00:00 2001 From: Mingming Yin Date: Mon, 3 Dec 2012 13:32:11 -0800 Subject: audio: Add support for QCOM audio devices, formats, and channels - Add QCOM supported devices, fomats, and input/output channels in AudioPolicyManagerBase - Add QCOM supported devices in AudioSystemLegacy.h Change-Id: I5e2977a630c2bf9211af62d97ae024c5c57075f9 libhardware_legacy: Add support for DirectTrack - Add support for DirectOutput in libhardware_legacy - Add new APIs to AudioStreamOut base class - Add audio output flags to openOutputStream Change-Id: I301b3b9b2c2ad08dba75f616008d692e825af96f audio: add missing QCOM audio devices, formats, and channels - Add support for FM I/O devices and communication device for VOIP - Add support for mp2 audio format - Add support for 6.1 audio channels Change-Id: I7b3042902c658dc8e5dfa34719fb80d18f3ff4e7 libhardware_legacy: Support LPA Playback Add support to enable Playback in LPA mode When Alarm is playing on headset+spkr, if LPA playback is selected STARTEGY_MEDIA gets selected and switches device from Combo device to Headset. - Fix the issue by selecting Combo device only even incase of LPA when stream ALARM/NOTIFICATION is active. Change-Id: Ifde78a744a17ce613eac92b4c3bcf875167aaeb6 Add ifdefs for QCOM enhanced features Change-Id: I87ce3503ed85458c775d0c8c7fa649d8194e28e3 --- audio/AudioPolicyManagerBase.cpp | 118 ++++++++++++++++++++--- include/hardware_legacy/AudioHardwareInterface.h | 12 +++ include/hardware_legacy/AudioPolicyManagerBase.h | 16 +++ include/hardware_legacy/AudioSystemLegacy.h | 22 ++++- 4 files changed, 151 insertions(+), 17 deletions(-) diff --git a/audio/AudioPolicyManagerBase.cpp b/audio/AudioPolicyManagerBase.cpp index cb9afa6..a73a5b9 100644 --- a/audio/AudioPolicyManagerBase.cpp +++ b/audio/AudioPolicyManagerBase.cpp @@ -495,7 +495,12 @@ AudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getProfileForDirectOu IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; if (profile->isCompatibleProfile(device, samplingRate, format, channelMask, - AUDIO_OUTPUT_FLAG_DIRECT)) { +#ifdef QCOM_HARDWARE + (audio_output_flags_t)(flags|AUDIO_OUTPUT_FLAG_DIRECT))) +#else + AUDIO_OUTPUT_FLAG_DIRECT)) +#endif + { if (mAvailableOutputDevices & profile->mSupportedDevices) { return mHwModules[i]->mOutputProfiles[j]; } @@ -550,12 +555,12 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str } #endif //AUDIO_POLICY_TEST - // open a direct output if required by specified parameters IOProfile *profile = getProfileForDirectOutput(device, - samplingRate, - format, - channelMask, - (audio_output_flags_t)flags); + samplingRate, + format, + channelMask, + (audio_output_flags_t)flags); + if (profile != NULL) { ALOGV("getOutput() opening direct output device %x", device); @@ -1328,8 +1333,13 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j]; - - if (outProfile->mSupportedDevices & mAttachedOutputDevices) { +#ifdef QCOM_HARDWARE + if ( (outProfile->mSupportedDevices & mAttachedOutputDevices) && + !(outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) ) +#else + if (outProfile->mSupportedDevices & mAttachedOutputDevices) +#endif + { AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile); outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice & outProfile->mSupportedDevices); @@ -1631,13 +1641,21 @@ status_t AudioPolicyManagerBase::checkOutputsForDevice(audio_devices_t device, ALOGV("opening output for device %08x", device); desc = new AudioOutputDescriptor(profile); desc->mDevice = device; - audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle, - &desc->mDevice, - &desc->mSamplingRate, - &desc->mFormat, - &desc->mChannelMask, - &desc->mLatency, - desc->mFlags); + audio_io_handle_t output = 0; +#ifdef QCOM_HARDWARE + if (!(desc->mFlags & AUDIO_OUTPUT_FLAG_LPA || desc->mFlags & AUDIO_OUTPUT_FLAG_TUNNEL || + desc->mFlags & AUDIO_OUTPUT_FLAG_VOIP_RX)) { +#endif + output = mpClientInterface->openOutput(profile->mModule->mHandle, + &desc->mDevice, + &desc->mSamplingRate, + &desc->mFormat, + &desc->mChannelMask, + &desc->mLatency, + desc->mFlags); +#ifdef QCOM_HARDWARE + } +#endif if (output != 0) { if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { String8 reply; @@ -1981,6 +1999,9 @@ audio_devices_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, b audio_devices_t device = AUDIO_DEVICE_NONE; AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); +#ifdef QCOM_HARDWARE + AudioOutputDescriptor *primaryOutputDesc = mOutputs.valueFor(mPrimaryOutput); +#endif // check the following by order of priority to request a routing change if necessary: // 1: the strategy enforced audible is active on the output: // use device for strategy enforced audible @@ -1999,7 +2020,13 @@ audio_devices_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, b } else if (isInCall() || outputDesc->isUsedByStrategy(STRATEGY_PHONE)) { device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); - } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) { +#ifdef QCOM_HARDWARE + } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION) || + (primaryOutputDesc->isUsedByStrategy(STRATEGY_SONIFICATION))) +#else + } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) +#endif + { device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION_RESPECTFUL)) { device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); @@ -3350,6 +3377,10 @@ const struct StringToEnum sDeviceNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER), STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET), STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE), +#ifdef QCOM_HARDWARE + STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANC_HEADSET), + STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANC_HEADPHONE), +#endif STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO), STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP), STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL), @@ -3357,18 +3388,36 @@ const struct StringToEnum sDeviceNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET), STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE), STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY), +#ifdef QCOM_HARDWARE + STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM), + STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM_TX), +#endif STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB), +#ifdef QCOM_HARDWARE + STRING_TO_ENUM(AUDIO_DEVICE_OUT_PROXY), +#endif STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX), STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET), +#ifdef QCOM_HARDWARE + STRING_TO_ENUM(AUDIO_DEVICE_IN_ANC_HEADSET), +#endif STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL), +#ifdef QCOM_HARDWARE + STRING_TO_ENUM(AUDIO_DEVICE_IN_FM_RX), + STRING_TO_ENUM(AUDIO_DEVICE_IN_FM_RX_A2DP), +#endif STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL), STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC), STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX), STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET), STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET), STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY), +#ifdef QCOM_HARDWARE + STRING_TO_ENUM(AUDIO_DEVICE_IN_PROXY), + STRING_TO_ENUM(AUDIO_DEVICE_IN_COMMUNICATION), +#endif }; const struct StringToEnum sFlagNameToEnumTable[] = { @@ -3376,6 +3425,11 @@ const struct StringToEnum sFlagNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), +#ifdef QCOM_HARDWARE + STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_VOIP_RX), + STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_LPA), + STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_TUNNEL), +#endif }; const struct StringToEnum sFormatNameToEnumTable[] = { @@ -3384,18 +3438,50 @@ const struct StringToEnum sFormatNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_FORMAT_MP3), STRING_TO_ENUM(AUDIO_FORMAT_AAC), STRING_TO_ENUM(AUDIO_FORMAT_VORBIS), +#ifdef QCOM_HARDWARE + STRING_TO_ENUM(AUDIO_FORMAT_AC3), + STRING_TO_ENUM(AUDIO_FORMAT_EAC3), + STRING_TO_ENUM(AUDIO_FORMAT_DTS), + STRING_TO_ENUM(AUDIO_FORMAT_DTS_LBR), + STRING_TO_ENUM(AUDIO_FORMAT_WMA), + STRING_TO_ENUM(AUDIO_FORMAT_WMA_PRO), + STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADIF), + STRING_TO_ENUM(AUDIO_FORMAT_AMR_NB), + STRING_TO_ENUM(AUDIO_FORMAT_AMR_WB), + STRING_TO_ENUM(AUDIO_FORMAT_AMR_WB_PLUS), + STRING_TO_ENUM(AUDIO_FORMAT_EVRC), + STRING_TO_ENUM(AUDIO_FORMAT_EVRCB), + STRING_TO_ENUM(AUDIO_FORMAT_EVRCWB), + STRING_TO_ENUM(AUDIO_FORMAT_QCELP), + STRING_TO_ENUM(AUDIO_FORMAT_MP2), +#endif }; const struct StringToEnum sOutChannelsNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO), STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), +#ifdef QCOM_HARDWARE + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_2POINT1), + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_QUAD), + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_SURROUND), + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_PENTA), +#endif STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), +#ifdef QCOM_HARDWARE + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_6POINT1), +#endif STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), }; const struct StringToEnum sInChannelsNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), +#ifdef QCOM_HARDWARE + STRING_TO_ENUM(AUDIO_CHANNEL_IN_5POINT1), + STRING_TO_ENUM(AUDIO_CHANNEL_IN_VOICE_CALL_MONO), + STRING_TO_ENUM(AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO), + STRING_TO_ENUM(AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO), +#endif }; diff --git a/include/hardware_legacy/AudioHardwareInterface.h b/include/hardware_legacy/AudioHardwareInterface.h index 4bd56d4..82fc633 100644 --- a/include/hardware_legacy/AudioHardwareInterface.h +++ b/include/hardware_legacy/AudioHardwareInterface.h @@ -116,6 +116,18 @@ public: */ #ifndef ICS_AUDIO_BLOB virtual status_t getNextWriteTimestamp(int64_t *timestamp); +#ifdef QCOM_HARDWARE + virtual status_t start() {return INVALID_OPERATION;} + virtual status_t pause() {return INVALID_OPERATION;} + virtual status_t flush() {return INVALID_OPERATION;} + virtual status_t stop() {return INVALID_OPERATION;} + virtual int setObserver(void *observer) {return INVALID_OPERATION;} + virtual status_t getBufferInfo(buf_info **buf) {return INVALID_OPERATION;} + virtual status_t isBufferAvailable(int *isAvail) { + *isAvail = true; + return NO_ERROR; + } +#endif #endif }; diff --git a/include/hardware_legacy/AudioPolicyManagerBase.h b/include/hardware_legacy/AudioPolicyManagerBase.h index 451fe8a..47ee3c3 100644 --- a/include/hardware_legacy/AudioPolicyManagerBase.h +++ b/include/hardware_legacy/AudioPolicyManagerBase.h @@ -339,7 +339,11 @@ protected: // change the route of the specified output. Returns the number of ms we have slept to // allow new routing to take effect in certain cases. +#ifdef QCOM_HARDWARE + virtual uint32_t setOutputDevice(audio_io_handle_t output, +#else uint32_t setOutputDevice(audio_io_handle_t output, +#endif audio_devices_t device, bool force = false, int delayMs = 0); @@ -360,7 +364,11 @@ protected: virtual float computeVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device); // check that volume change is permitted, compute and send new volume to audio hardware +#ifdef QCOM_HARDWARE + virtual status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false); +#else status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false); +#endif // apply all stream volumes to the specified output and device void applyStreamVolumes(audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false); @@ -373,7 +381,11 @@ protected: audio_devices_t device = (audio_devices_t)0); // Mute or unmute the stream on the specified output +#ifdef QCOM_HARDWARE + virtual void setStreamMute(int stream, +#else void setStreamMute(int stream, +#endif bool on, audio_io_handle_t output, int delayMs = 0, @@ -476,7 +488,11 @@ protected: uint32_t samplingRate, uint32_t format, uint32_t channelMask); +#ifdef QCOM_HARDWARE + virtual IOProfile *getProfileForDirectOutput(audio_devices_t device, +#else IOProfile *getProfileForDirectOutput(audio_devices_t device, +#endif uint32_t samplingRate, uint32_t format, uint32_t channelMask, diff --git a/include/hardware_legacy/AudioSystemLegacy.h b/include/hardware_legacy/AudioSystemLegacy.h index 6296b8b..1b854c6 100644 --- a/include/hardware_legacy/AudioSystemLegacy.h +++ b/include/hardware_legacy/AudioSystemLegacy.h @@ -243,12 +243,23 @@ public: DEVICE_OUT_AUX_DIGITAL = 0x400, DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800, DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000, +#ifdef QCOM_HARDWARE + DEVICE_OUT_ANC_HEADSET = 0x2000, + DEVICE_OUT_ANC_HEADPHONE = 0x4000, + DEVICE_OUT_PROXY = 0x8000, + DEVICE_OUT_DEFAULT = DEVICE_OUT_SPEAKER, +#else DEVICE_OUT_DEFAULT = 0x8000, +#endif DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADSET | DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO | DEVICE_OUT_BLUETOOTH_SCO_HEADSET | DEVICE_OUT_BLUETOOTH_SCO_CARKIT | DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL | DEVICE_OUT_ANLG_DOCK_HEADSET | DEVICE_OUT_DGTL_DOCK_HEADSET | +#ifdef QCOM_HARDWARE + DEVICE_OUT_ANC_HEADSET | DEVICE_OUT_ANC_HEADPHONE | + DEVICE_OUT_PROXY | +#endif DEVICE_OUT_DEFAULT), DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER), @@ -262,11 +273,20 @@ public: DEVICE_IN_AUX_DIGITAL = 0x200000, DEVICE_IN_VOICE_CALL = 0x400000, DEVICE_IN_BACK_MIC = 0x800000, +#ifdef QCOM_HARDWARE + DEVICE_IN_ANC_HEADSET = 0x10000000, + DEVICE_IN_PROXY = 0x20000000, + DEVICE_IN_ANLG_DOCK_HEADSET = 0x40000000, +#endif DEVICE_IN_DEFAULT = 0x80000000, DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION | DEVICE_IN_AMBIENT | DEVICE_IN_BUILTIN_MIC | DEVICE_IN_BLUETOOTH_SCO_HEADSET | DEVICE_IN_WIRED_HEADSET | DEVICE_IN_AUX_DIGITAL | - DEVICE_IN_VOICE_CALL | DEVICE_IN_BACK_MIC | DEVICE_IN_DEFAULT) + DEVICE_IN_VOICE_CALL | DEVICE_IN_BACK_MIC | +#ifdef QCOM_HARDWARE + DEVICE_IN_ANC_HEADSET | DEVICE_IN_PROXY | DEVICE_IN_ANLG_DOCK_HEADSET | +#endif + DEVICE_IN_DEFAULT) }; // request to open a direct output with getOutput() (by opposition to sharing an output with other AudioTracks) -- cgit v1.1