author | Jian Xu <jian.xu@amlogic.com> | 2015-04-15 06:07:21 (GMT) |
---|---|---|
committer | Jian Xu <jian.xu@amlogic.com> | 2015-04-20 07:26:54 (GMT) |
commit | 56d0dfe8f698cf01dae98cc67c8223922d8c22aa (patch) | |
tree | 1700d4f2695950a2d77cce11c74a268e25b0741b | |
parent | 39a7c235ab6f04927119285322a305e07faaa620 (diff) | |
download | audio-56d0dfe8f698cf01dae98cc67c8223922d8c22aa.zip audio-56d0dfe8f698cf01dae98cc67c8223922d8c22aa.tar.gz audio-56d0dfe8f698cf01dae98cc67c8223922d8c22aa.tar.bz2 |
PD#104078 : KK audio route clear up
Change-Id: I509239e36279590437241c7e7cb66313d7e0ead3
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | DLGAudioPolicyManager.cpp | 464 | ||||
-rw-r--r-- | DLGAudioPolicyManager.h | 25 | ||||
-rw-r--r--[-rwxr-xr-x] | audio_hw.c | 44 | ||||
-rw-r--r--[-rwxr-xr-x] | hdmi_audio_hw.c | 134 |
5 files changed, 38 insertions, 630 deletions
@@ -40,6 +40,7 @@ ifeq ($(strip $(BOARD_ALSA_AUDIO)),tiny) include $(BUILD_SHARED_LIBRARY) #build for USB audio +#BOARD_USE_USB_AUDIO := 1 ifeq ($(strip $(BOARD_USE_USB_AUDIO)),true) include $(CLEAR_VARS) diff --git a/DLGAudioPolicyManager.cpp b/DLGAudioPolicyManager.cpp index 7d0bc78..fa3893d 100644 --- a/DLGAudioPolicyManager.cpp +++ b/DLGAudioPolicyManager.cpp @@ -24,9 +24,6 @@ #include <utils/StrongPointer.h> #include "DLGAudioPolicyManager.h" -#include <stdlib.h> -#include <sys/stat.h> -#include <fcntl.h> namespace android { @@ -119,465 +116,4 @@ audio_devices_t DLGAudioPolicyManager::getDeviceForInputSource(audio_source_t in return device; } -audio_devices_t DLGAudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) { - // By checking the range of stream before calling getStrategy, we avoid - // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE - // and then return STRATEGY_MEDIA, but we want to return the empty set. - if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_CNT) { - return AUDIO_DEVICE_NONE; - } - audio_devices_t devices; - AudioPolicyManager::routing_strategy strategy = getStrategy(stream); - devices = getDeviceForStrategy(strategy, true /*fromCache*/); - - if (stream == AUDIO_STREAM_MUSIC && devices == AUDIO_DEVICE_OUT_HDMI) { - ALOGV("[%s %d]force change device from 0x/%x to 0x%x for AUDIO_STREAM_MUSIC\n",__FUNCTION__,__LINE__,AUDIO_DEVICE_OUT_HDMI,AUDIO_STREAM_MUSIC); - devices = AUDIO_DEVICE_OUT_SPEAKER; - } - - SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs); - for (size_t i = 0; i < outputs.size(); i++) { - sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); - if (outputDesc->isStrategyActive(strategy)) { - devices = outputDesc->device(); - break; - } - } - - /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it - and doesn't really need to.*/ - if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) { - devices |= AUDIO_DEVICE_OUT_SPEAKER; - devices &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE; - } - - return devices; -} - - -audio_io_handle_t DLGAudioPolicyManager::getOutput(audio_stream_type_t stream, - uint32_t samplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo) -{ - - routing_strategy strategy = getStrategy(stream); - audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); - ALOGV("[%s %d] device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",__FUNCTION__,__LINE__, - device, stream, samplingRate, format, channelMask, flags); - return getOutputForDevice(device, stream, samplingRate,format, channelMask, flags, - offloadInfo); -} - -audio_io_handle_t DLGAudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr, - uint32_t samplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo) -{ - if (attr == NULL) { - ALOGE("getOutputForAttr() called with NULL audio attributes"); - return 0; - } - ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x", - attr->usage, attr->content_type, attr->tags, attr->flags); - - // TODO this is where filtering for custom policies (rerouting, dynamic sources) will go - routing_strategy strategy = (routing_strategy) getStrategyForAttr(attr); - audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); - - if ((attr->flags & AUDIO_FLAG_HW_AV_SYNC) != 0) { - flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC); - } - - ALOGV("getOutputForAttr() device %d, samplingRate %d, format %x, channelMask %x, flags %x", - device, samplingRate, format, channelMask, flags); - - audio_stream_type_t stream = streamTypefromAttributesInt(attr); - return getOutputForDevice(device, stream, samplingRate, format, channelMask, flags, - offloadInfo); -} - -static int get_codec_type(const char * path) -{ - int val = 0; - int fd = open("/sys/class/audiodsp/digital_codec", O_RDONLY); - if (fd >= 0) { - char bcmd[16]; - read(fd, bcmd, sizeof(bcmd)); - val = strtol(bcmd, NULL, 10); - close(fd); - }else{ - ALOGI("[%s]open digital_codec node failed! return 0\n", __FUNCTION__); - } - return val; -} - -#define MAX_MIXER_SAMPLING_RATE 192000 - -audio_io_handle_t DLGAudioPolicyManager::getOutputForDevice( - audio_devices_t device, - audio_stream_type_t stream, - uint32_t samplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo) -{ - audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; - uint32_t latency = 0; - status_t status; - -#ifdef AUDIO_POLICY_TEST - if (mCurOutput != 0) { - ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d", - mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput); - - if (mTestOutputs[mCurOutput] == 0) { - ALOGV("getOutput() opening test output"); - sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL); - outputDesc->mDevice = mTestDevice; - outputDesc->mLatency = mTestLatencyMs; - outputDesc->mFlags = - (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0); - outputDesc->mRefCount[stream] = 0; - audio_config_t config = AUDIO_CONFIG_INITIALIZER; - config.sample_rate = mTestSamplingRate; - config.channel_mask = mTestChannels; - config.format = mTestFormat; - if (offloadInfo != NULL) { - config.offload_info = *offloadInfo; - } - status = mpClientInterface->openOutput(0, - &mTestOutputs[mCurOutput], - &config, - &outputDesc->mDevice, - String8(""), - &outputDesc->mLatency, - outputDesc->mFlags); - if (status == NO_ERROR) { - outputDesc->mSamplingRate = config.sample_rate; - outputDesc->mFormat = config.format; - outputDesc->mChannelMask = config.channel_mask; - AudioParameter outputCmd = AudioParameter(); - outputCmd.addInt(String8("set_id"),mCurOutput); - mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); - addOutput(mTestOutputs[mCurOutput], outputDesc); - } - } - return mTestOutputs[mCurOutput]; - } -#endif //AUDIO_POLICY_TEST - - // open a direct output if required by specified parameters - //force direct flag if offload flag is set: offloading implies a direct output stream - // and all common behaviors are driven by checking only the direct flag - // this should normally be set appropriately in the policy configuration file - if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { - flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT); - } - if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) { - flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT); - } - - sp<IOProfile> profile; - - // skip direct output selection if the request can obviously be attached to a mixed output - // and not explicitly requested - if (((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) && - audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE && - audio_channel_count_from_out_mask(channelMask) <= 2) { - goto non_direct_output; - } - - // Do not allow offloading if one non offloadable effect is enabled. This prevents from - // creating an offloaded track and tearing it down immediately after start when audioflinger - // detects there is an active non offloadable effect. - // FIXME: We should check the audio session here but we do not have it in this context. - // This may prevent offloading in rare situations where effects are left active by apps - // in the background. - - if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) || - !isNonOffloadableEffectEnabled()) { - profile = getProfileForDirectOutput(device, - samplingRate, - format, - channelMask, - (audio_output_flags_t)flags); - } - - if (profile != 0) { - sp<AudioOutputDescriptor> outputDesc = NULL; - - for (size_t i = 0; i < mOutputs.size(); i++) { - sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); - if (!desc->isDuplicated() && (profile == desc->mProfile)) { - outputDesc = desc; - // reuse direct output if currently open and configured with same parameters - if ((samplingRate == outputDesc->mSamplingRate) && - (format == outputDesc->mFormat) && - (channelMask == outputDesc->mChannelMask)) { - outputDesc->mDirectOpenCount++; - ALOGI("getOutput() reusing direct output %d", mOutputs.keyAt(i)); - return mOutputs.keyAt(i); - } - } - } - // close direct output if currently open and configured with different parameters - if (outputDesc != NULL) { - closeOutput(outputDesc->mIoHandle); - } - outputDesc = new AudioOutputDescriptor(profile); - outputDesc->mDevice = device; - outputDesc->mLatency = 0; - outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags); - audio_config_t config = AUDIO_CONFIG_INITIALIZER; - config.sample_rate = samplingRate; - config.channel_mask = channelMask; - config.format = format; - if (offloadInfo != NULL) { - config.offload_info = *offloadInfo; - } - status = mpClientInterface->openOutput(profile->mModule->mHandle, - &output, - &config, - &outputDesc->mDevice, - String8(""), - &outputDesc->mLatency, - outputDesc->mFlags); - - // only accept an output with the requested parameters - if (status != NO_ERROR || - (samplingRate != 0 && samplingRate != config.sample_rate) || - (format != AUDIO_FORMAT_DEFAULT && format != config.format) || - (channelMask != 0 && channelMask != config.channel_mask)) { - ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," - "format %d %d, channelMask %04x %04x", output, samplingRate, - outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, - outputDesc->mChannelMask); - if (output != AUDIO_IO_HANDLE_NONE) { - mpClientInterface->closeOutput(output); - } - return AUDIO_IO_HANDLE_NONE; - } - outputDesc->mSamplingRate = config.sample_rate; - outputDesc->mChannelMask = config.channel_mask; - outputDesc->mFormat = config.format; - outputDesc->mRefCount[stream] = 0; - outputDesc->mStopTime[stream] = 0; - outputDesc->mDirectOpenCount = 1; - - audio_io_handle_t srcOutput = getOutputForEffect(); - addOutput(output, outputDesc); - audio_io_handle_t dstOutput = getOutputForEffect(); - if (dstOutput == output) { - mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput); - } - mPreviousOutputs = mOutputs; - ALOGV("getOutput() returns new direct output %d", output); - mpClientInterface->onAudioPortListUpdate(); - return output; - } - -non_direct_output: - - // ignoring channel mask due to downmix capability in mixer - - // open a non direct output - - // for non direct outputs, only PCM is supported - int direct_in_use=0; - for (size_t i = 0; i < mOutputs.size(); i++) { - sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); - if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) - direct_in_use=1; - } - - audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types(); - if ( (device == AUDIO_DEVICE_OUT_AUX_DIGITAL && !get_codec_type("/sys/class/audiodsp/digital_codec")) || direct_in_use) - { - device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; - if (device == AUDIO_DEVICE_NONE) - device = AUDIO_DEVICE_OUT_AUX_DIGITAL; - if (device == AUDIO_DEVICE_OUT_SPEAKER) - { - ALOGV("[%s %d]direct_in_use/%d force change device from %x to %x\n",__FUNCTION__,__LINE__, - direct_in_use,AUDIO_DEVICE_OUT_AUX_DIGITAL,AUDIO_DEVICE_OUT_SPEAKER); - } - } - - if (audio_is_linear_pcm(format)) { - // get which output is suitable for the specified stream. The actual - // routing change will happen when startOutput() will be called - SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs); - - // at this stage we should ignore the DIRECT flag as no direct output could be found earlier - flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT); - output = selectOutput(outputs, flags, format); - } - ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d," - "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags); - - ALOGV("getOutput() returns output %d", output); - - return output; -} - -audio_stream_type_t DLGAudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr) -{ - // flags to stream type mapping - if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { - return AUDIO_STREAM_ENFORCED_AUDIBLE; - } - if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) { - return AUDIO_STREAM_BLUETOOTH_SCO; - } - - // usage to stream type mapping - switch (attr->usage) { - case AUDIO_USAGE_MEDIA: - case AUDIO_USAGE_GAME: - case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: - case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: - return AUDIO_STREAM_MUSIC; - case AUDIO_USAGE_ASSISTANCE_SONIFICATION: - return AUDIO_STREAM_SYSTEM; - case AUDIO_USAGE_VOICE_COMMUNICATION: - return AUDIO_STREAM_VOICE_CALL; - - case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: - return AUDIO_STREAM_DTMF; - - case AUDIO_USAGE_ALARM: - return AUDIO_STREAM_ALARM; - case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: - return AUDIO_STREAM_RING; - - case AUDIO_USAGE_NOTIFICATION: - case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: - case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: - case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: - case AUDIO_USAGE_NOTIFICATION_EVENT: - return AUDIO_STREAM_NOTIFICATION; - - case AUDIO_USAGE_UNKNOWN: - default: - return AUDIO_STREAM_MUSIC; - } -} -audio_devices_t DLGAudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, bool fromCache) -{ - audio_devices_t device = AUDIO_DEVICE_NONE; - - sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); - - ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); - if (index >= 0) { - sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index); - if (patchDesc->mUid != mUidCached) { - ALOGV("getNewOutputDevice() device %08x forced by patch %d", - outputDesc->device(), outputDesc->mPatchHandle); - return outputDesc->device(); - } - } - - // check the following by order of priority to request a routing change if necessary: - // 1: the strategy enforced audible is active and enforced on the output: - // use device for strategy enforced audible - // 2: we are in call or the strategy phone is active on the output: - // use device for strategy phone - // 3: the strategy for enforced audible is active but not enforced on the output: - // use the device for strategy enforced audible - // 4: the strategy sonification is active on the output: - // use device for strategy sonification - // 5: the strategy "respectful" sonification is active on the output: - // use device for strategy "respectful" sonification - // 6: the strategy media is active on the output: - // use device for strategy media - // 7: the strategy DTMF is active on the output: - // use device for strategy DTMF - if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE) && - mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { - device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); - } else if (isInCall() || - outputDesc->isStrategyActive(STRATEGY_PHONE)) { - device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); - } else if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { - device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); - } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) { - device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); - } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { - device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); - } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { - device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); - } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { - device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); - } - - int direct_in_use=0; - for (size_t i = 0; i < mOutputs.size(); i++) { - sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); - if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) - direct_in_use=1; - } - - audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types(); - ALOGV("[%s %d]outputDesc->mDevice/0x%x device/%x direct_in_use/%d availableOutputDeviceTypes/0x%x isStrategyActive(STRATEGY_MEDIA)/%d fromCache/%d\n", __FUNCTION__,__LINE__, - outputDesc->mDevice,device,direct_in_use,availableOutputDeviceTypes,outputDesc->isStrategyActive(STRATEGY_MEDIA),fromCache); - if (outputDesc->mDevice == AUDIO_DEVICE_OUT_SPEAKER && outputDesc->isStrategyActive(STRATEGY_MEDIA) && (device == AUDIO_DEVICE_OUT_AUX_DIGITAL && !get_codec_type("/sys/class/audiodsp/digital_codec")) || direct_in_use) - { - device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; - if (device == AUDIO_DEVICE_NONE) - device = AUDIO_DEVICE_OUT_AUX_DIGITAL; - if (device == AUDIO_DEVICE_OUT_SPEAKER) - { - ALOGV("[%s %d]direct_in_use/%d force change device from %x to %x\n",__FUNCTION__,__LINE__, - direct_in_use,AUDIO_DEVICE_OUT_AUX_DIGITAL,AUDIO_DEVICE_OUT_SPEAKER); - } - } - ALOGV("[%s %d]selected device %x", __FUNCTION__,__LINE__,device); - return device; -} - -uint32_t DLGAudioPolicyManager::AudioPort::pickSamplingRate() const -{ - // special case for uninitialized dynamic profile - if (mSamplingRates.size() == 1 && mSamplingRates[0] == 0) { - return 0; - } - - // For direct outputs, pick minimum sampling rate: this helps ensuring that the - // channel count / sampling rate combination chosen will be supported by the connected - // sink - if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && - (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) { - uint32_t samplingRate = UINT_MAX; - for (size_t i = 0; i < mSamplingRates.size(); i ++) { - if ((mSamplingRates[i] < samplingRate) && (mSamplingRates[i] > 0)) { - samplingRate = mSamplingRates[i]; - } - } - return (samplingRate == UINT_MAX) ? 0 : samplingRate; - } - - uint32_t samplingRate = 0; - uint32_t maxRate = MAX_MIXER_SAMPLING_RATE; - - // For mixed output and inputs, use max mixer sampling rates. Do not - // limit sampling rate otherwise - if (mType != AUDIO_PORT_TYPE_MIX) { - maxRate = UINT_MAX; - } - for (size_t i = 0; i < mSamplingRates.size(); i ++) { - if ((mSamplingRates[i] > samplingRate) && (mSamplingRates[i] <= maxRate)) { - samplingRate = mSamplingRates[i]; - } - } - return samplingRate; -} - - } // namespace android diff --git a/DLGAudioPolicyManager.h b/DLGAudioPolicyManager.h index 125b8d3..bd3a307 100644 --- a/DLGAudioPolicyManager.h +++ b/DLGAudioPolicyManager.h @@ -38,34 +38,13 @@ public: const char *device_address); virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource); - audio_io_handle_t getOutput(audio_stream_type_t stream, - uint32_t samplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo); - audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, - uint32_t samplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo); - audio_io_handle_t getOutputForDevice( - audio_devices_t device, - audio_stream_type_t stream, - uint32_t samplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo); - audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr); + protected: virtual float computeVolume(audio_stream_type_t stream, int index, audio_io_handle_t output, audio_devices_t device); - audio_devices_t getDevicesForStream(audio_stream_type_t stream); - audio_devices_t getNewOutputDevice(audio_io_handle_t output, bool fromCache); + private: // Flag which indicates whether to record from the submix device. bool mForceSubmixInputSelection; diff --git a/audio_hw.c b/audio_hw.c index 56fcc20..ea2d209 100755..100644 --- a/audio_hw.c +++ b/audio_hw.c @@ -188,6 +188,20 @@ static int getprop_bool(const char * path) } return 0; } +static int get_sysfs_int(const char * path) +{ + int val = 0; + int fd = open(path, O_RDONLY); + if (fd >= 0) { + char bcmd[16]; + read(fd, bcmd, sizeof(bcmd)); + val = strtol(bcmd, NULL, 10); + close(fd); + }else{ + LOGFUNC("[%s]open %s node failed! return 0\n",path, __FUNCTION__); + } + return val; +} static void select_devices(struct aml_audio_device *adev) { LOGFUNC("%s(mode=%d, out_device=%#x)", __FUNCTION__, adev->mode, adev->out_device); @@ -468,22 +482,6 @@ OUT: close(fd); return port; } - -#define NOTIFY_KERNEL_ANDROID50_NODE "/sys/class/amaudio/debug" -static void NotifyKernelAndroid50() -{ - int fd=open(NOTIFY_KERNEL_ANDROID50_NODE, O_RDWR | O_TRUNC, 0644); - int bytes,pos=0; - if (fd >= 0) { - char ubuf8[128]={0}; - bytes=sprintf(ubuf8,"kernel_android_50"); - write(fd, ubuf8, bytes); - close(fd); - }else{ - ALOGI("[%s %d]open %s failed!\n",__FUNCTION__,__LINE__,NOTIFY_KERNEL_ANDROID50_NODE); - } -} - /* must be called with hw device and output stream mutexes locked */ static int start_output_stream(struct aml_stream_out *out) { @@ -493,6 +491,7 @@ static int start_output_stream(struct aml_stream_out *out) int ret; LOGFUNC("%s(adev->out_device=%#x, adev->mode=%d)", __FUNCTION__, adev->out_device, adev->mode); + adev->active_output = out; if (adev->mode != AUDIO_MODE_IN_CALL) { @@ -961,6 +960,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, char *data, *data_dst; volatile char *data_src; uint i, total_len; + int codec_type = 0; + int samesource_flag = 0; //LOGFUNC("entring:%s(out->echo_reference=%p, in_frames=%d)", __FUNCTION__, out->echo_reference, in_frames); /* acquiring hw device mutex systematically is useful if a low priority thread is waiting @@ -969,7 +970,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, */ pthread_mutex_lock(&adev->lock); pthread_mutex_lock(&out->lock); - #if 1 + #if 0 #define DOLBY_SYSTEM_CHANNEL "ds1.audio.multichannel.support" char value[128]={0}; property_get(DOLBY_SYSTEM_CHANNEL,value,NULL); @@ -1086,6 +1087,12 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, ret = pcm_write(out->pcm, in_buffer, out_frames * frame_size); } #else + codec_type = get_sysfs_int("/sys/class/audiodsp/digital_codec"); + samesource_flag = get_sysfs_int("/sys/class/audiodsp/audio_samesource"); + if (samesource_flag == 0 && codec_type == 0) { + ALOGI("to enable same source,need reset alsa,type %d,same source flag %d \n",codec_type,samesource_flag); + pcm_stop(out->pcm); + } ret = pcm_write(out->pcm, in_buffer, out_frames * frame_size); out->frame_count += out_frames; #endif @@ -2157,7 +2164,6 @@ static int adev_close(hw_device_t *device) return 0; } - static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device) { @@ -2166,7 +2172,7 @@ static int adev_open(const hw_module_t* module, const char* name, int ret; if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL; - NotifyKernelAndroid50(); + adev = calloc(1, sizeof(struct aml_audio_device)); if (!adev) return -ENOMEM; diff --git a/hdmi_audio_hw.c b/hdmi_audio_hw.c index 0b7ff3a..8cd2a6d 100755..100644 --- a/hdmi_audio_hw.c +++ b/hdmi_audio_hw.c @@ -131,21 +131,6 @@ struct aml_stream_out { unsigned multich; }; -typedef struct hdmi_stream_state{ - void *pLastStreamOut; - int LastStreamDirectFlag; - int CurStreamDirectFlag; - int LastStreamInUse; - int CurStreamInUse; - int init_flag; - int N8ch_out_flag; - pthread_mutex_t hdmi_state_mutex; - -}hdmi_stream_state_t; -hdmi_stream_state_t HdmiStreamState={0}; -int pcm_opened=0; - - #define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */ struct aml_stream_in { struct audio_stream_in stream; @@ -557,60 +542,15 @@ static int start_output_stream(struct aml_stream_out *out) out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE*2; out->config.start_threshold = PLAYBACK_PERIOD_COUNT*PERIOD_SIZE*2; }else if(codec_type == 7||codec_type == 8){ - out->config.period_size=PERIOD_SIZE*4; - out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE*4; - out->config.start_threshold = PLAYBACK_PERIOD_COUNT*PERIOD_SIZE*4; + out->config.period_size=PERIOD_SIZE*4*2; + out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE*4*2; + out->config.start_threshold = PLAYBACK_PERIOD_COUNT*PERIOD_SIZE*4*2; }else{ out->config.period_size=PERIOD_SIZE; out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE; out->config.start_threshold = PERIOD_SIZE * PLAYBACK_PERIOD_COUNT; } - out->config.avail_min = 0;//SHORT_PERIOD_SIZE; - if(HdmiStreamState.LastStreamInUse) - { - if(HdmiStreamState.LastStreamDirectFlag|| HdmiStreamState.N8ch_out_flag){ - ALOGI("LatsStream/%p still inUse for Direct output/8ch output!\n",HdmiStreamState.pLastStreamOut); - return -1; - }else{ - struct aml_stream_out *pLastStreamOut=(struct aml_stream_out *)HdmiStreamState.pLastStreamOut; - if(pLastStreamOut!=NULL && pLastStreamOut!=out && - (codec_type || out->config.channels==8 || (out->config.channels==2 && out->config.rate>48000 && codec_type==0)) - )//corruent output mode:digital_raw - { - ALOGI("[%s %d]Force standy LastStream/%p\n",__FUNCTION__,__LINE__,pLastStreamOut); - //------------------------------------------------------------ - //do_output_standby(HdmiStreamState.pLastStreamOut); - struct aml_audio_device *adev_local =pLastStreamOut->dev; - if (!pLastStreamOut->standby) - { - pcm_close(pLastStreamOut->pcm); - pLastStreamOut->pcm = NULL; - adev_local->active_output = 0; - if (pLastStreamOut->echo_reference != NULL) { - pLastStreamOut->echo_reference->write(pLastStreamOut->echo_reference, NULL); - pLastStreamOut->echo_reference = NULL; - } - pLastStreamOut->standby = 1; - } - //-------------------------------------- - } - } - } - - HdmiStreamState.pLastStreamOut=out; - HdmiStreamState.LastStreamInUse=1; - HdmiStreamState.LastStreamDirectFlag=codec_type; - HdmiStreamState.N8ch_out_flag=0; - if(out->config.channels==8) - { - HdmiStreamState.N8ch_out_flag=1; - } - if(out->config.channels==2 && out->config.rate>48000 && codec_type==0) - { - ALOGI("[%s %d]HD-PCM(Fs/%d>48000) use DirectOuput\n",__FUNCTION__,__LINE__,out->config.rate); - HdmiStreamState.LastStreamDirectFlag=1; - } - + out->config.avail_min = 0;//SHORT_PERIOD_SIZE if(out->config.rate!=DEFAULT_OUT_SAMPLING_RATE){ @@ -637,7 +577,6 @@ static int start_output_stream(struct aml_stream_out *out) if (!pcm_is_ready(out->pcm)) { ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm)); pcm_close(out->pcm); - out->pcm=NULL; adev->active_output = NULL; return -ENOMEM; } @@ -809,8 +748,8 @@ static size_t out_get_buffer_size(const struct audio_stream *stream) int codec_type=get_codec_type("/sys/class/audiodsp/digital_codec"); if(codec_type == 4 || codec_type == 5)//dd+ size = (PERIOD_SIZE*2* PLAYBACK_PERIOD_COUNT * DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; - else if(codec_type == 7||codec_type == 8) - size = ((int64_t)PERIOD_SIZE*4* PLAYBACK_PERIOD_COUNT * DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; + else if(codec_type == 7) + size = (PERIOD_SIZE*2 * 4* PLAYBACK_PERIOD_COUNT * DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; else if(codec_type>0 && codec_type<4 ) //dd/dts size = (PERIOD_SIZE*4*DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; else//pcm @@ -852,15 +791,6 @@ static int out_set_format(struct audio_stream *stream, int format) static int do_output_standby(struct aml_stream_out *out) { struct aml_audio_device *adev = out->dev; - pthread_mutex_lock(&HdmiStreamState.hdmi_state_mutex); - if(HdmiStreamState.pLastStreamOut==out){ - ALOGI("[%s %d]Clear LastStream/%p \n",__FUNCTION__,__LINE__,HdmiStreamState.pLastStreamOut); - HdmiStreamState.pLastStreamOut=NULL; - HdmiStreamState.LastStreamInUse=0; - HdmiStreamState.LastStreamDirectFlag=0; - HdmiStreamState.N8ch_out_flag=0; - } - pthread_mutex_unlock(&HdmiStreamState.hdmi_state_mutex); if (!out->standby) { pcm_close(out->pcm); out->pcm = NULL; @@ -1067,44 +997,6 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, pthread_mutex_lock(&adev->lock); pthread_mutex_lock(&out->lock); - if(!HdmiStreamState.init_flag){ - HdmiStreamState.init_flag=1; - pthread_mutex_init(&HdmiStreamState.hdmi_state_mutex, NULL); - ALOGI("[%s %d]HdmiStreamState.hdmi_state_mutex init finised!\n",__FUNCTION__,__LINE__); - } - pthread_mutex_lock(&HdmiStreamState.hdmi_state_mutex); - - if(HdmiStreamState.LastStreamInUse && - HdmiStreamState.LastStreamDirectFlag && - out!= HdmiStreamState.pLastStreamOut) - { - ret=0; - pthread_mutex_unlock(&adev->lock); - goto exit; - } - //-----------8CH PCM judge----------- - #if 1 - #define DOLBY_SYSTEM_CHANNEL "ds1.audio.multichannel.support" - char value[128]={0}; - property_get(DOLBY_SYSTEM_CHANNEL,value,NULL); - if((!strcmp(value,"true") ||!strcmp(value,"1")) && out->config.channels!=8) - { - if (!out->standby) { - ALOGI("[%s %d]8ch PCM output,standby other outputs/%p...\n",__FUNCTION__,__LINE__,out); - pcm_close(out->pcm); - out->pcm = NULL; - adev->active_output = 0; - if (out->echo_reference != NULL) {/* stop writing to echo reference */ - out->echo_reference->write(out->echo_reference, NULL); - out->echo_reference = NULL; - } - out->standby = 1; - } - pthread_mutex_unlock(&adev->lock); - goto exit; - } - #endif - //-------------------------------- if (out->standby) { ret = start_output_stream(out); if (ret != 0) { @@ -1171,7 +1063,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, total_len = out_frames*frame_size + cached_len; - //LOGFUNC("total_len(%d) = resampler_out_len(%d) + cached_len111(%d)", total_len, out_frames*frame_size, cached_len); + LOGFUNC("total_len(%d) = resampler_out_len(%d) + cached_len111(%d)", total_len, out_frames*frame_size, cached_len); data_src = (char *)cache_buffer_bytes; data_dst = (char *)output_buffer_bytes; @@ -1235,7 +1127,6 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, exit: pthread_mutex_unlock(&out->lock); - pthread_mutex_unlock(&HdmiStreamState.hdmi_state_mutex); if (ret != 0) { usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) / out_get_sample_rate(&stream->common)); @@ -2103,8 +1994,8 @@ static int adev_open_output_stream(struct audio_hw_device *dev, dc = get_codec_type("/sys/class/audiodsp/digital_codec"); if(dc == 4 || dc == 5) out->config.period_size=pcm_config_out.period_size*2; - else if(dc == 7||dc == 8) - out->config.period_size=pcm_config_out.period_size*4; + else if(dc == 7) + out->config.period_size=pcm_config_out.period_size*4*2; if(channel_count > 2){ ALOGI("[adev_open_output_stream]: out/%p channel/%d\n",out,channel_count); out->multich = channel_count; @@ -2128,12 +2019,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev, LOGFUNC("%s(devices=0x%04x,format=0x%x, chmask=0x%04x, SR=%d)", __FUNCTION__, devices, config->format, config->channel_mask, config->sample_rate); - if(!HdmiStreamState.init_flag) - { - HdmiStreamState.init_flag=1; - pthread_mutex_init(&HdmiStreamState.hdmi_state_mutex, NULL); - ALOGI("[%s %d]HdmiStreamState.hdmi_state_mutex init finised!\n",__FUNCTION__,__LINE__); - } + *stream_out = &out->stream; return 0; |