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

Commit b9135401 authored by Andy Hung's avatar Andy Hung Committed by Gerrit Code Review
Browse files

Merge "Spatial Audio: Fix display orientation, add fold state"

parents 3130b032 cd6c1069
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -96,17 +96,33 @@ interface ISpatializer {

    /**
     * Sets the display orientation.
     *
     * This is the rotation of the displayed content relative to its natural orientation.
     *
     * Orientation is expressed in the angle of rotation from the physical "up" side of the screen
     * to the logical "up" side of the content displayed the screen. Counterclockwise angles, as
     * viewed while facing the screen are positive.
     *
     * Note: DisplayManager currently only returns this in increments of 90 degrees,
     * so the values will be 0, PI/2, PI, 3PI/2.
     */
    void setDisplayOrientation(float physicalToLogicalAngle);

    /**
     * Sets the hinge angle for foldable devices.
     *
     * Per the hinge angle sensor, this returns a value from 0 to 2PI.
     * The value of 0 is considered closed, and PI is considered flat open.
     */
    void setHingeAngle(float hingeAngle);

    /**
     * Sets whether a foldable is considered "folded" or not.
     *
     * The fold state may affect which physical screen is active for display.
     */
    void setFoldState(boolean folded);

    /** Reports the list of supported spatialization modess (see SpatializationMode.aidl).
     * The list should never be empty if an ISpatializer interface was successfully
     * retrieved with IAudioPolicyService.getSpatializer().
+49 −10
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
//#define LOG_NDEBUG 0
#include <utils/Log.h>

#include <algorithm>
#include <inttypes.h>
#include <limits.h>
#include <stdint.h>
@@ -94,6 +95,16 @@ static std::vector<float> recordFromTranslationRotationVector(
    return record;
}

template<typename T>
static constexpr const T& safe_clamp(const T& value, const T& low, const T& high) {
    if constexpr (std::is_floating_point_v<T>) {
        return value != value /* constexpr isnan */
                ? low : std::clamp(value, low, high);
    } else /* constexpr */ {
        return std::clamp(value, low, high);
    }
}

// ---------------------------------------------------------------------------

class Spatializer::EngineCallbackHandler : public AHandler {
@@ -638,28 +649,48 @@ Status Spatializer::setScreenSensor(int sensorHandle) {

Status Spatializer::setDisplayOrientation(float physicalToLogicalAngle) {
    ALOGV("%s physicalToLogicalAngle %f", __func__, physicalToLogicalAngle);
    if (!mSupportsHeadTracking) {
        return binderStatusFromStatusT(INVALID_OPERATION);
    }
    std::lock_guard lock(mLock);
    mDisplayOrientation = physicalToLogicalAngle;
    mLocalLog.log("%s with %f", __func__, physicalToLogicalAngle);
    const float angle = safe_clamp(physicalToLogicalAngle, 0.f, (float)(2. * M_PI));
    // It is possible due to numerical inaccuracies to exceed the boundaries of 0 to 2 * M_PI.
    ALOGI_IF(angle != physicalToLogicalAngle,
            "%s: clamping %f to %f", __func__, physicalToLogicalAngle, angle);
    std::lock_guard lock(mLock);
    mDisplayOrientation = angle;
    if (mPoseController != nullptr) {
        mPoseController->setDisplayOrientation(mDisplayOrientation);
        // This turns on the rate-limiter.
        mPoseController->setDisplayOrientation(angle);
    }
    if (mEngine != nullptr) {
        setEffectParameter_l(
            SPATIALIZER_PARAM_DISPLAY_ORIENTATION, std::vector<float>{physicalToLogicalAngle});
            SPATIALIZER_PARAM_DISPLAY_ORIENTATION, std::vector<float>{angle});
    }
    return Status::ok();
}

Status Spatializer::setHingeAngle(float hingeAngle) {
    std::lock_guard lock(mLock);
    ALOGV("%s hingeAngle %f", __func__, hingeAngle);
    if (mEngine != nullptr) {
    mLocalLog.log("%s with %f", __func__, hingeAngle);
        setEffectParameter_l(SPATIALIZER_PARAM_HINGE_ANGLE, std::vector<float>{hingeAngle});
    const float angle = safe_clamp(hingeAngle, 0.f, (float)(2. * M_PI));
    // It is possible due to numerical inaccuracies to exceed the boundaries of 0 to 2 * M_PI.
    ALOGI_IF(angle != hingeAngle,
            "%s: clamping %f to %f", __func__, hingeAngle, angle);
    std::lock_guard lock(mLock);
    mHingeAngle = angle;
    if (mEngine != nullptr) {
        setEffectParameter_l(SPATIALIZER_PARAM_HINGE_ANGLE, std::vector<float>{angle});
    }
    return Status::ok();
}

Status Spatializer::setFoldState(bool folded) {
    ALOGV("%s foldState %d", __func__, (int)folded);
    mLocalLog.log("%s with %d", __func__, (int)folded);
    std::lock_guard lock(mLock);
    mFoldedState = folded;
    if (mEngine != nullptr) {
        // we don't suppress multiple calls with the same folded state - that's
        // done at the caller.
        setEffectParameter_l(SPATIALIZER_PARAM_FOLD_STATE, std::vector<uint8_t>{mFoldedState});
    }
    return Status::ok();
}
@@ -862,6 +893,14 @@ status_t Spatializer::attachOutput(audio_io_handle_t output, size_t numActiveTra
            checkSensorsState_l();
        }
        callback = mSpatializerCallback;

        // Restore common effect state.
        setEffectParameter_l(SPATIALIZER_PARAM_DISPLAY_ORIENTATION,
                std::vector<float>{mDisplayOrientation});
        setEffectParameter_l(SPATIALIZER_PARAM_FOLD_STATE,
                std::vector<uint8_t>{mFoldedState});
        setEffectParameter_l(SPATIALIZER_PARAM_HINGE_ANGLE,
                std::vector<float>{mHingeAngle});
    }

    if (outputChanged && callback != nullptr) {
+8 −2
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ class Spatializer : public media::BnSpatializer,
    binder::Status setScreenSensor(int sensorHandle) override;
    binder::Status setDisplayOrientation(float physicalToLogicalAngle) override;
    binder::Status setHingeAngle(float hingeAngle) override;
    binder::Status setFoldState(bool folded) override;
    binder::Status getSupportedModes(std::vector<media::SpatializationMode>* modes) override;
    binder::Status registerHeadTrackingCallback(
        const sp<media::ISpatializerHeadTrackingCallback>& callback) override;
@@ -376,8 +377,13 @@ private:
    int32_t mScreenSensor GUARDED_BY(mLock) = SpatializerPoseController::INVALID_SENSOR;

    /** Last display orientation received */
    static constexpr float kDisplayOrientationInvalid = 1000;
    float mDisplayOrientation GUARDED_BY(mLock) = kDisplayOrientationInvalid;
    float mDisplayOrientation GUARDED_BY(mLock) = 0.f;  // aligned to natural up orientation.

    /** Last folded state */
    bool mFoldedState GUARDED_BY(mLock) = false;  // foldable: true means folded.

    /** Last hinge angle */
    float mHingeAngle GUARDED_BY(mLock) = 0.f;  // foldable: 0.f is closed, M_PI flat open.

    std::vector<media::SpatializationLevel> mLevels;
    std::vector<media::SpatializerHeadTrackingMode> mHeadTrackingModes;