Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ae807c4 authored by SathishKumar Mani's avatar SathishKumar Mani Committed by Eric Laurent
Browse files

mm-audio: Fix delay at the start of MT voice call

- Reducing the delay for playing the RINGTONE
  before voice call is accepted saves,appr 340ms.
- on this platform reducing the delay wont affect
  the RINGTONE as the delay in setting up voice
  path after accepting the voice call will
  compensate RINGTONE buffers with kernel and
  firmware played on the device.

Bug-id: 7612431

Change-Id: Iff5b4545ca7e2316178b0db8cb6760b173c189be
parent 29555939
Loading
Loading
Loading
Loading
+1 −9
Original line number Diff line number Diff line
@@ -66,7 +66,6 @@ LOCAL_MODULE_TAGS := optional

include $(BUILD_SHARED_LIBRARY)

ifeq (1,0) # use default audio policy manager
# This is the ALSA audio policy manager

include $(CLEAR_VARS)
@@ -74,10 +73,6 @@ include $(CLEAR_VARS)
LOCAL_CFLAGS := -D_POSIX_SOURCE
LOCAL_CFLAGS += -DQCOM_ACDB_ENABLED

ifeq ($(BOARD_HAVE_BLUETOOTH),true)
  LOCAL_CFLAGS += -DWITH_A2DP
endif

LOCAL_SRC_FILES := \
    audio_policy_hal.cpp \
    AudioPolicyManagerALSA.cpp
@@ -88,18 +83,15 @@ LOCAL_MODULE_TAGS := optional

LOCAL_STATIC_LIBRARIES := \
    libmedia_helper \
    libaudiohw_legacy \
    libaudiopolicy_legacy

LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libmedia
    libutils

LOCAL_C_INCLUDES += hardware/libhardware_legacy/audio

include $(BUILD_SHARED_LIBRARY)
endif

# This is the ALSA module which behaves closely like the original

+123 −3
Original line number Diff line number Diff line
@@ -29,9 +29,9 @@ namespace android_audio_legacy {
// AudioPolicyManagerALSA
// ----------------------------------------------------------------------------

//Compiling error seen (only) on mako-pdk project if AudioParamer doesn't exist in this file
//No issue is seen on QCOM jb-mailine if remvong this line
//AudioParameter param;
//Compiling error seen if AudioParamer doesn't exist in this file

AudioParameter param;

// ---  class factory

@@ -46,4 +46,124 @@ extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
    delete interface;
}

void AudioPolicyManager::setPhoneState(int state) {
    ALOGV("setPhoneState() state %d", state);
    audio_devices_t newDevice = AUDIO_DEVICE_NONE;
    if (state < 0 || state >= AudioSystem::NUM_MODES) {
        ALOGW("setPhoneState() invalid state %d", state);
        return;
    }

    if (state == mPhoneState) {
        ALOGW("setPhoneState() setting same state %d", state);
        return;
    }

    // if leaving call state, handle special case of active streams
    // pertaining to sonification strategy see handleIncallSonification()
    if (isInCall()) {
        ALOGV("setPhoneState() in call state management: new state is %d", state);
        for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
            handleIncallSonification(stream, false, true);
        }
    }

    // store previous phone state for management of sonification strategy below
    int oldState = mPhoneState;
    mPhoneState = state;
    bool force = false;

    // are we entering or starting a call
    if (!isStateInCall(oldState) && isStateInCall(state)) {
        ALOGV("  Entering call in setPhoneState()");
        // force routing command to audio hardware when starting a call
        // even if no device change is needed
        force = true;
    } else if (isStateInCall(oldState) && !isStateInCall(state)) {
        ALOGV("  Exiting call in setPhoneState()");
        // force routing command to audio hardware when exiting a call
        // even if no device change is needed
        force = true;
    } else if (isStateInCall(state) && (state != oldState)) {
        ALOGV("  Switching between telephony and VoIP in setPhoneState()");
        // force routing command to audio hardware when switching between telephony and VoIP
        // even if no device change is needed
        force = true;
    }

    // check for device and output changes triggered by new phone state
    newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/);
    checkA2dpSuspend();
    checkOutputForAllStrategies();
    updateDevicesAndOutputs();

    AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);

    // force routing command to audio hardware when ending call
    // even if no device change is needed
    if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) {
        newDevice = hwOutputDesc->device();
    }

    // when changing from ring tone to in call mode, mute the ringing tone
    // immediately and delay the route change to avoid sending the ring tone
    // tail into the earpiece or headset.
    int delayMs = 0;
    if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) {
        // delay the device change command by twice the output latency to have some margin
        // and be sure that audio buffers not yet affected by the mute are out when
        // we actually apply the route change
        delayMs = hwOutputDesc->mLatency*2;
        setStreamMute(AudioSystem::RING, true, mPrimaryOutput);
    }

    if (isStateInCall(state)) {
        for (size_t i = 0; i < mOutputs.size(); i++) {
            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
            //take the biggest latency for all outputs
            if (delayMs < desc->mLatency*2) {
                delayMs = desc->mLatency*2;
            }
            //mute STRATEGY_MEDIA on all outputs
            if (desc->strategyRefCount(STRATEGY_MEDIA) != 0) {
                setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
                setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
                    getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
            }
        }
    }

    // Ignore the delay to enable voice call on this target as the enabling the
    // voice call has enough delay to make sure the ringtone audio completely
    // played out
    if (state == AudioSystem::MODE_IN_CALL && oldState == AudioSystem::MODE_RINGTONE) {
        delayMs = 0;
    }

    // change routing is necessary
    setOutputDevice(mPrimaryOutput, newDevice, force, delayMs);

    // if entering in call state, handle special case of active streams
    // pertaining to sonification strategy see handleIncallSonification()
    if (isStateInCall(state)) {
        ALOGV("setPhoneState() in call state management: new state is %d", state);
        // unmute the ringing tone after a sufficient delay if it was muted before
        // setting output device above
        if (oldState == AudioSystem::MODE_RINGTONE) {
            setStreamMute(AudioSystem::RING, false, mPrimaryOutput, MUTE_TIME_MS);
        }
        for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
            handleIncallSonification(stream, true, true);
        }
    }

    // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
    if (state == AudioSystem::MODE_RINGTONE &&
        isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
        mLimitRingtoneVolume = true;
    } else {
        mLimitRingtoneVolume = false;
    }
}

}; // namespace androidi_audio_legacy
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ public:
                AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
                : AudioPolicyManagerBase(clientInterface) {}

        virtual void setPhoneState(int state);

        virtual ~AudioPolicyManager() {}

};
+35 −65
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ static int ap_set_device_connection_state(struct audio_policy *pol,
{
    struct qcom_audio_policy *qap = to_qap(pol);
    return qap->apm->setDeviceConnectionState(
                    device,
                    (AudioSystem::audio_devices)device,
                    (AudioSystem::device_connection_state)state,
                    device_address);
}
@@ -80,14 +80,22 @@ static audio_policy_dev_state_t ap_get_device_connection_state(
{
    const struct qcom_audio_policy *qap = to_cqap(pol);
    return (audio_policy_dev_state_t)qap->apm->getDeviceConnectionState(
                    device,
                    (AudioSystem::audio_devices)device,
                    device_address);
}

static void ap_set_phone_state(struct audio_policy *pol, audio_mode_t state)
{
    struct qcom_audio_policy *qap = to_qap(pol);
    qap->apm->setPhoneState(state);
    // as this is the legacy API, don't change it to use audio_mode_t instead of int
    qap->apm->setPhoneState((int) state);
}

    /* indicate a change in ringer mode */
static void ap_set_ringer_mode(struct audio_policy *pol, uint32_t mode,
                               uint32_t mask)
{
    // deprecated, never called
}

    /* force using a specific device category for the specified usage */
@@ -125,58 +133,18 @@ static int ap_init_check(const struct audio_policy *pol)
    return qap->apm->initCheck();
}

#ifdef QCOM_TUNNEL_LPA_ENABLED
static audio_io_handle_t ap_get_session(struct audio_policy *pol,
                                       audio_stream_type_t stream,
                                       audio_format_t format,
                                       audio_policy_output_flags_t flags,
                                       int sessionId,
                                       uint32_t samplingRate,
                                       uint32_t channels)
{
    struct qcom_audio_policy *qap = to_qap(pol);

    ALOGV("%s: tid %d", __func__, gettid());
    return qap->apm->getSession((AudioSystem::stream_type)stream,
                               format, (AudioSystem::output_flags)flags,
                               sessionId,
                               samplingRate,
                               channels);
}

static void ap_pause_session(struct audio_policy *pol, audio_io_handle_t output,
                          audio_stream_type_t stream)
{
    struct qcom_audio_policy *qap = to_qap(pol);
    qap->apm->pauseSession(output, (AudioSystem::stream_type)stream);
}

static void ap_resume_session(struct audio_policy *pol, audio_io_handle_t output,
                          audio_stream_type_t stream)
{
    struct qcom_audio_policy *qap = to_qap(pol);
    qap->apm->resumeSession(output, (AudioSystem::stream_type)stream);
}

static void ap_release_session(struct audio_policy *pol, audio_io_handle_t output)
{
    struct qcom_audio_policy *qap = to_qap(pol);
    qap->apm->releaseSession(output);
}
#endif

static audio_io_handle_t ap_get_output(struct audio_policy *pol,
                                       audio_stream_type_t stream,
                                       uint32_t sampling_rate,
                                       audio_format_t format,
                                       uint32_t channels,
                                       audio_channel_mask_t channelMask,
                                       audio_output_flags_t flags)
{
    struct qcom_audio_policy *qap = to_qap(pol);

    ALOGV("%s: tid %d", __func__, gettid());
    return qap->apm->getOutput((AudioSystem::stream_type)stream,
                               sampling_rate, format, channels,
                               sampling_rate, (int) format, channelMask,
                               (AudioSystem::output_flags)flags);
}

@@ -206,11 +174,11 @@ static void ap_release_output(struct audio_policy *pol,
static audio_io_handle_t ap_get_input(struct audio_policy *pol, audio_source_t inputSource,
                                      uint32_t sampling_rate,
                                      audio_format_t format,
                                      uint32_t channels,
                                      audio_channel_mask_t channelMask,
                                      audio_in_acoustics_t acoustics)
{
    struct qcom_audio_policy *qap = to_qap(pol);
    return qap->apm->getInput(inputSource, sampling_rate, format, channels,
    return qap->apm->getInput((int) inputSource, sampling_rate, (int) format, channelMask,
                              (AudioSystem::audio_in_acoustics)acoustics);
}

@@ -261,13 +229,6 @@ static int ap_get_stream_volume_index(const struct audio_policy *pol,
                                          AUDIO_DEVICE_OUT_DEFAULT);
}

static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol,
                                           audio_stream_type_t stream)
{
    const struct qcom_audio_policy *qap = to_cqap(pol);
    return qap->apm->getStrategyForStream((AudioSystem::stream_type)stream);
}

static int ap_set_stream_volume_index_for_device(struct audio_policy *pol,
                                      audio_stream_type_t stream,
                                      int index,
@@ -287,7 +248,14 @@ static int ap_get_stream_volume_index_for_device(const struct audio_policy *pol,
   const struct qcom_audio_policy *qap = to_cqap(pol);
   return qap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream,
                                          index,
                                          AUDIO_DEVICE_OUT_DEFAULT);
                                          device);
}

static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol,
                                           audio_stream_type_t stream)
{
    const struct qcom_audio_policy *qap = to_cqap(pol);
    return qap->apm->getStrategyForStream((AudioSystem::stream_type)stream);
}

static audio_devices_t ap_get_devices_for_stream(const struct audio_policy *pol,
@@ -298,14 +266,14 @@ static audio_devices_t ap_get_devices_for_stream(const struct audio_policy *pol,
}

static audio_io_handle_t ap_get_output_for_effect(struct audio_policy *pol,
                                            struct effect_descriptor_s *desc)
                                            const struct effect_descriptor_s *desc)
{
    struct qcom_audio_policy *qap = to_qap(pol);
    return qap->apm->getOutputForEffect(desc);
}

static int ap_register_effect(struct audio_policy *pol,
                              struct effect_descriptor_s *desc,
                              const struct effect_descriptor_s *desc,
                              audio_io_handle_t io,
                              uint32_t strategy,
                              int session,
@@ -332,7 +300,13 @@ static bool ap_is_stream_active(const struct audio_policy *pol,
                                uint32_t in_past_ms)
{
    const struct qcom_audio_policy *qap = to_cqap(pol);
    return qap->apm->isStreamActive(stream, in_past_ms);
    return qap->apm->isStreamActive((int) stream, in_past_ms);
}

static bool ap_is_source_active(const struct audio_policy *pol, audio_source_t source)
{
    const struct qcom_audio_policy *qap = to_cqap(pol);
    return qap->apm->isSourceActive(source);
}

static int ap_dump(const struct audio_policy *pol, int fd)
@@ -359,18 +333,13 @@ static int create_qcom_ap(const struct audio_policy_device *device,
    qap->policy.set_device_connection_state = ap_set_device_connection_state;
    qap->policy.get_device_connection_state = ap_get_device_connection_state;
    qap->policy.set_phone_state = ap_set_phone_state;
    qap->policy.set_ringer_mode = ap_set_ringer_mode;
    qap->policy.set_force_use = ap_set_force_use;
    qap->policy.get_force_use = ap_get_force_use;
    qap->policy.set_can_mute_enforced_audible =
        ap_set_can_mute_enforced_audible;
    qap->policy.init_check = ap_init_check;
    qap->policy.get_output = ap_get_output;
#ifdef QCOM_TUNNEL_LPA_ENABLED
    qap->policy.get_session = ap_get_session;
    qap->policy.pause_session = ap_pause_session;
    qap->policy.resume_session = ap_resume_session;
    qap->policy.release_session = ap_release_session;
#endif
    qap->policy.start_output = ap_start_output;
    qap->policy.stop_output = ap_stop_output;
    qap->policy.release_output = ap_release_output;
@@ -390,6 +359,7 @@ static int create_qcom_ap(const struct audio_policy_device *device,
    qap->policy.unregister_effect = ap_unregister_effect;
    qap->policy.set_effect_enabled = ap_set_effect_enabled;
    qap->policy.is_stream_active = ap_is_stream_active;
    qap->policy.is_source_active = ap_is_source_active;
    qap->policy.dump = ap_dump;

    qap->service = service;