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

Commit fd505b3c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "ScaleHapticDataForHG"

* changes:
  Support scaling haptic data in HapticGenerator
  Force selecting haptic supported thread when creating HapticGenerator.
parents bdf951fb e70bc7fc
Loading
Loading
Loading
Loading
+3 −10
Original line number Diff line number Diff line
@@ -423,7 +423,7 @@ void AudioMixer::setParameter(int name, int target, int param, void *value)
            }
            } break;
        case HAPTIC_INTENSITY: {
            const haptic_intensity_t hapticIntensity = static_cast<haptic_intensity_t>(valueInt);
            const os::HapticScale hapticIntensity = static_cast<os::HapticScale>(valueInt);
            if (track->mHapticIntensity != hapticIntensity) {
                track->mHapticIntensity = hapticIntensity;
            }
@@ -545,7 +545,7 @@ status_t AudioMixer::postCreateTrack(TrackBase *track)
    t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
    // haptic
    t->mHapticPlaybackEnabled = false;
    t->mHapticIntensity = HAPTIC_SCALE_NONE;
    t->mHapticIntensity = os::HapticScale::NONE;
    t->mMixerHapticChannelMask = AUDIO_CHANNEL_NONE;
    t->mMixerHapticChannelCount = 0;
    t->mAdjustInChannelCount = t->channelCount + t->mHapticChannelCount;
@@ -590,19 +590,12 @@ void AudioMixer::postProcess()
            const std::shared_ptr<Track> &t = getTrack(name);
            if (t->mHapticPlaybackEnabled) {
                size_t sampleCount = mFrameCount * t->mMixerHapticChannelCount;
                float gamma = t->getHapticScaleGamma();
                float maxAmplitudeRatio = t->getHapticMaxAmplitudeRatio();
                uint8_t* buffer = (uint8_t*)pair.first + mFrameCount * audio_bytes_per_frame(
                        t->mMixerChannelCount, t->mMixerFormat);
                switch (t->mMixerFormat) {
                // Mixer format should be AUDIO_FORMAT_PCM_FLOAT.
                case AUDIO_FORMAT_PCM_FLOAT: {
                    float* fout = (float*) buffer;
                    for (size_t i = 0; i < sampleCount; i++) {
                        float mul = fout[i] >= 0 ? 1.0 : -1.0;
                        fout[i] = powf(fabsf(fout[i] / HAPTIC_MAX_AMPLITUDE_FLOAT), gamma)
                                * maxAmplitudeRatio * HAPTIC_MAX_AMPLITUDE_FLOAT * mul;
                    }
                    os::scaleHapticData((float*) buffer, sampleCount, t->mHapticIntensity);
                } break;
                default:
                    LOG_ALWAYS_FATAL("bad mMixerFormat: %#x", t->mMixerFormat);
+2 −60
Original line number Diff line number Diff line
@@ -22,10 +22,10 @@
#include <stdint.h>
#include <sys/types.h>

#include <android/os/IExternalVibratorService.h>
#include <media/AudioMixerBase.h>
#include <media/BufferProviders.h>
#include <utils/threads.h>
#include <vibrator/ExternalVibrationUtils.h>

// FIXME This is actually unity gain, which might not be max in future, expressed in U.12
#define MAX_GAIN_INT AudioMixerBase::UNITY_GAIN_INT
@@ -55,32 +55,6 @@ public:
                                  // parameter 'value' is a pointer to the new playback rate.
    };

    typedef enum { // Haptic intensity, should keep consistent with VibratorService
        HAPTIC_SCALE_MUTE = os::IExternalVibratorService::SCALE_MUTE,
        HAPTIC_SCALE_VERY_LOW = os::IExternalVibratorService::SCALE_VERY_LOW,
        HAPTIC_SCALE_LOW = os::IExternalVibratorService::SCALE_LOW,
        HAPTIC_SCALE_NONE = os::IExternalVibratorService::SCALE_NONE,
        HAPTIC_SCALE_HIGH = os::IExternalVibratorService::SCALE_HIGH,
        HAPTIC_SCALE_VERY_HIGH = os::IExternalVibratorService::SCALE_VERY_HIGH,
    } haptic_intensity_t;
    static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2.0f / 3.0f;
    static constexpr float HAPTIC_SCALE_LOW_RATIO = 3.0f / 4.0f;
    static const constexpr float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f;

    static inline bool isValidHapticIntensity(haptic_intensity_t hapticIntensity) {
        switch (hapticIntensity) {
        case HAPTIC_SCALE_MUTE:
        case HAPTIC_SCALE_VERY_LOW:
        case HAPTIC_SCALE_LOW:
        case HAPTIC_SCALE_NONE:
        case HAPTIC_SCALE_HIGH:
        case HAPTIC_SCALE_VERY_HIGH:
            return true;
        default:
            return false;
        }
    }

    AudioMixer(size_t frameCount, uint32_t sampleRate)
            : AudioMixerBase(frameCount, sampleRate) {
        pthread_once(&sOnceControl, &sInitRoutine);
@@ -170,7 +144,7 @@ private:

        // Haptic
        bool                 mHapticPlaybackEnabled;
        haptic_intensity_t   mHapticIntensity;
        os::HapticScale      mHapticIntensity;
        audio_channel_mask_t mHapticChannelMask;
        uint32_t             mHapticChannelCount;
        audio_channel_mask_t mMixerHapticChannelMask;
@@ -180,38 +154,6 @@ private:
        uint32_t             mAdjustNonDestructiveInChannelCount;
        uint32_t             mAdjustNonDestructiveOutChannelCount;
        bool                 mKeepContractedChannels;

        float getHapticScaleGamma() const {
        // Need to keep consistent with the value in VibratorService.
        switch (mHapticIntensity) {
        case HAPTIC_SCALE_VERY_LOW:
            return 2.0f;
        case HAPTIC_SCALE_LOW:
            return 1.5f;
        case HAPTIC_SCALE_HIGH:
            return 0.5f;
        case HAPTIC_SCALE_VERY_HIGH:
            return 0.25f;
        default:
            return 1.0f;
        }
        }

        float getHapticMaxAmplitudeRatio() const {
        // Need to keep consistent with the value in VibratorService.
        switch (mHapticIntensity) {
        case HAPTIC_SCALE_VERY_LOW:
            return HAPTIC_SCALE_VERY_LOW_RATIO;
        case HAPTIC_SCALE_LOW:
            return HAPTIC_SCALE_LOW_RATIO;
        case HAPTIC_SCALE_NONE:
        case HAPTIC_SCALE_HIGH:
        case HAPTIC_SCALE_VERY_HIGH:
            return 1.0f;
        default:
            return 0.0f;
        }
        }
    };

    inline std::shared_ptr<Track> getTrack(int name) {
+2 −0
Original line number Diff line number Diff line
@@ -36,8 +36,10 @@ cc_library_shared {

    shared_libs: [
        "libaudioutils",
        "libbinder",
        "liblog",
        "libutils",
        "libvibrator",
    ],

    relative_install_path: "soundfx",
+40 −7
Original line number Diff line number Diff line
@@ -96,7 +96,10 @@ int HapticGenerator_Init(struct HapticGeneratorContext *context) {
    context->config.outputCfg.bufferProvider.cookie = nullptr;
    context->config.outputCfg.mask = EFFECT_CONFIG_ALL;

    memset(&context->param, 0, sizeof(struct HapticGeneratorParam));
    memset(context->param.hapticChannelSource, 0, sizeof(context->param.hapticChannelSource));
    context->param.hapticChannelCount = 0;
    context->param.audioChannelCount = 0;
    context->param.maxHapticIntensity = os::HapticScale::MUTE;

    context->state = HAPTICGENERATOR_STATE_INITIALIZED;
    return 0;
@@ -236,12 +239,36 @@ int HapticGenerator_Reset(struct HapticGeneratorContext *context) {
    return 0;
}

int HapticGenerator_SetParameter(struct HapticGeneratorContext *context __unused,
                                 int32_t param __unused,
                                 uint32_t size __unused,
                                 void *value __unused) {
    ALOGW("Setparameter is not implemented in HapticGenerator");
    return -ENOSYS;
int HapticGenerator_SetParameter(struct HapticGeneratorContext *context,
                                 int32_t param,
                                 uint32_t size,
                                 void *value) {
    switch (param) {
    case HG_PARAM_HAPTIC_INTENSITY: {
        if (value == nullptr || size != (uint32_t) (2 * sizeof(int))) {
            return -EINVAL;
        }
        int id = *(int *) value;
        os::HapticScale hapticIntensity = static_cast<os::HapticScale>(*((int *) value + 1));
        if (hapticIntensity == os::HapticScale::MUTE) {
            context->param.id2Intensity.erase(id);
        } else {
            context->param.id2Intensity.emplace(id, hapticIntensity);
        }
        context->param.maxHapticIntensity = hapticIntensity;
        for (const auto&[id, intensity] : context->param.id2Intensity) {
            context->param.maxHapticIntensity = std::max(
                    context->param.maxHapticIntensity, intensity);
        }
        break;
    }

    default:
        ALOGW("Unknown param: %d", param);
        return -EINVAL;
    }

    return 0;
}

/**
@@ -346,6 +373,11 @@ int32_t HapticGenerator_Process(effect_handle_t self,
        return -ENODATA;
    }

    if (context->param.maxHapticIntensity == os::HapticScale::MUTE) {
        // Haptic channels are muted, not need to generate haptic data.
        return 0;
    }

    // Resize buffer if the haptic sample count is greater than buffer size.
    size_t hapticSampleCount = inBuffer->frameCount * context->param.hapticChannelCount;
    if (hapticSampleCount > context->inputBuffer.size()) {
@@ -367,6 +399,7 @@ int32_t HapticGenerator_Process(effect_handle_t self,
    float* hapticOutBuffer = HapticGenerator_runProcessingChain(
            context->processingChain, context->inputBuffer.data(),
            context->outputBuffer.data(), inBuffer->frameCount);
    os::scaleHapticData(hapticOutBuffer, hapticSampleCount, context->param.maxHapticIntensity);

    // For haptic data, the haptic playback thread will copy the data from effect input buffer,
    // which contains haptic data at the end of the buffer, directly to sink buffer.
+6 −0
Original line number Diff line number Diff line
@@ -19,9 +19,11 @@

#include <functional>
#include <vector>
#include <map>

#include <hardware/audio_effect.h>
#include <system/audio_effect.h>
#include <vibrator/ExternalVibrationUtils.h>

#include "Processors.h"

@@ -45,6 +47,10 @@ struct HapticGeneratorParam {
                                     // The value will be offset of audio channel
    uint32_t audioChannelCount;
    uint32_t hapticChannelCount;

    // A map from track id to haptic intensity.
    std::map<int, os::HapticScale> id2Intensity;
    os::HapticScale maxHapticIntensity; // max intensity will be used to scale haptic data.
};

// A structure to keep all shared pointers for all processors in HapticGenerator.
Loading