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

Commit 97f00044 authored by Tomoharu Kasahara's avatar Tomoharu Kasahara Committed by android-build-merger
Browse files

Merge "Set volume for output when effect is enabled/disabled." am: e7785479

am: e414f58c

Change-Id: Ib35db79fe1b1c58794bcd8184954f7c2334cd908
parents 6c89c060 e414f58c
Loading
Loading
Loading
Loading
+39 −4
Original line number Diff line number Diff line
@@ -263,7 +263,9 @@ bool AudioFlinger::EffectModule::updateState() {
        }
        break;
    case STOPPING:
        if (stop_l() == NO_ERROR) {
        // volume control for offload and direct threads must take effect immediately.
        if (stop_l() == NO_ERROR
            && !(isVolumeControl() && isOffloadedOrDirect())) {
            mDisableWaitCnt = mMaxDisableWaitCnt;
        } else {
            mDisableWaitCnt = 1; // will cause immediate transition to IDLE
@@ -778,6 +780,16 @@ status_t AudioFlinger::EffectModule::stop_l()
    }
    status_t cmdStatus = NO_ERROR;
    uint32_t size = sizeof(status_t);

    if (isVolumeControl() && isOffloadedOrDirect()) {
        sp<EffectChain>chain = mChain.promote();
        // We have the EffectChain and EffectModule lock, permit a reentrant call to setVolume:
        // resetVolume_l --> setVolume_l --> EffectModule::setVolume
        mSetVolumeReentrantTid = gettid();
        chain->resetVolume_l();
        mSetVolumeReentrantTid = INVALID_PID;
    }

    status_t status = mEffectInterface->command(EFFECT_CMD_DISABLE,
                                                0,
                                                NULL,
@@ -993,6 +1005,16 @@ bool AudioFlinger::EffectModule::isProcessEnabled() const
    }
}

bool AudioFlinger::EffectModule::isOffloadedOrDirect() const
{
    return (mThreadType == ThreadBase::OFFLOAD || mThreadType == ThreadBase::DIRECT);
}

bool AudioFlinger::EffectModule::isVolumeControlEnabled() const
{
    return (isVolumeControl() && (isOffloadedOrDirect() ? isEnabled() : isProcessEnabled()));
}

void AudioFlinger::EffectModule::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
    ALOGVV("setInBuffer %p",(&buffer));

@@ -1091,7 +1113,7 @@ void AudioFlinger::EffectModule::setOutBuffer(const sp<EffectBufferHalInterface>

status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
{
    Mutex::Autolock _l(mLock);
    AutoLockReentrant _l(mLock, mSetVolumeReentrantTid);
    if (mStatus != NO_ERROR) {
        return mStatus;
    }
@@ -1122,6 +1144,18 @@ status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right,
    return status;
}

void AudioFlinger::EffectChain::setVolumeForOutput_l(uint32_t left, uint32_t right)
{
    sp<ThreadBase> thread = mThread.promote();
    if (thread != 0 &&
        (thread->type() == ThreadBase::OFFLOAD || thread->type() == ThreadBase::DIRECT)) {
        PlaybackThread *t = (PlaybackThread *)thread.get();
        float vol_l = (float)left / (1 << 24);
        float vol_r = (float)right / (1 << 24);
        t->setVolumeForOutput_l(vol_l, vol_r);
    }
}

status_t AudioFlinger::EffectModule::setDevice(audio_devices_t device)
{
    if (device == AUDIO_DEVICE_NONE) {
@@ -2200,8 +2234,7 @@ bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right, boo

    // first update volume controller
    for (size_t i = size; i > 0; i--) {
        if (mEffects[i - 1]->isProcessEnabled() &&
            (mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL) {
        if (mEffects[i - 1]->isVolumeControlEnabled()) {
            ctrlIdx = i - 1;
            hasControl = true;
            break;
@@ -2247,6 +2280,8 @@ bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right, boo
    *left = newLeft;
    *right = newRight;

    setVolumeForOutput_l(*left, *right);

    return hasControl;
}

+28 −1
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ public:
    status_t    setEnabled_l(bool enabled);
    bool isEnabled() const;
    bool isProcessEnabled() const;
    bool isOffloadedOrDirect() const;
    bool isVolumeControlEnabled() const;

    void        setInBuffer(const sp<EffectBufferHalInterface>& buffer);
    int16_t     *inBuffer() const {
@@ -95,7 +97,8 @@ public:
        return mOutBuffer != 0 ? reinterpret_cast<int16_t*>(mOutBuffer->ptr()) : NULL;
    }
    void        setChain(const wp<EffectChain>& chain) { mChain = chain; }
    void        setThread(const wp<ThreadBase>& thread) { mThread = thread; }
    void        setThread(const wp<ThreadBase>& thread)
                    { mThread = thread; mThreadType = thread.promote()->type(); }
    const wp<ThreadBase>& thread() { return mThread; }

    status_t addHandle(EffectHandle *handle);
@@ -128,6 +131,9 @@ public:
                        { return (mDescriptor.flags & EFFECT_FLAG_HW_ACC_MASK) == 0; }
    bool             isProcessImplemented() const
                        { return (mDescriptor.flags & EFFECT_FLAG_NO_PROCESS) == 0; }
    bool             isVolumeControl() const
                        { return (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK)
                            == EFFECT_FLAG_VOLUME_CTRL; }
    status_t         setOffloaded(bool offloaded, audio_io_handle_t io);
    bool             isOffloaded() const;
    void             addEffectToHal_l();
@@ -150,6 +156,7 @@ private:

mutable Mutex               mLock;      // mutex for process, commands and handles list protection
    wp<ThreadBase>      mThread;    // parent thread
    ThreadBase::type_t  mThreadType; // parent thread type
    wp<EffectChain>     mChain;     // parent effect chain
    const int           mId;        // this instance unique ID
    const audio_session_t mSessionId; // audio session ID
@@ -176,6 +183,24 @@ mutable Mutex mLock; // mutex for process, commands and handl
    uint32_t mInChannelCountRequested;
    uint32_t mOutChannelCountRequested;
#endif

    class AutoLockReentrant {
    public:
        AutoLockReentrant(Mutex& mutex, pid_t allowedTid)
            : mMutex(gettid() == allowedTid ? nullptr : &mutex)
        {
            if (mMutex != nullptr) mMutex->lock();
        }
        ~AutoLockReentrant() {
            if (mMutex != nullptr) mMutex->unlock();
        }
    private:
        Mutex * const mMutex;
    };

    static constexpr pid_t INVALID_PID = (pid_t)-1;
    // this tid is allowed to call setVolume() without acquiring the mutex.
    pid_t mSetVolumeReentrantTid = INVALID_PID;
};

// The EffectHandle class implements the IEffect interface. It provides resources
@@ -403,6 +428,8 @@ private:

    void setThread(const sp<ThreadBase>& thread);

    void setVolumeForOutput_l(uint32_t left, uint32_t right);

             wp<ThreadBase> mThread;     // parent mixer thread
    mutable  Mutex mLock;        // mutex protecting effect list
             Vector< sp<EffectModule> > mEffects; // list of effect modules
+14 −9
Original line number Diff line number Diff line
@@ -2286,6 +2286,11 @@ float AudioFlinger::PlaybackThread::streamVolume(audio_stream_type_t stream) con
    return mStreamTypes[stream].volume;
}

void AudioFlinger::PlaybackThread::setVolumeForOutput_l(float left, float right) const
{
    mOutput->stream->setVolume(left, right);
}

// addTrack_l() must be called with ThreadBase::mLock held
status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
{
@@ -5142,20 +5147,20 @@ void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTr
            mLeftVolFloat = left;
            mRightVolFloat = right;

            // Convert volumes from float to 8.24
            uint32_t vl = (uint32_t)(left * (1 << 24));
            uint32_t vr = (uint32_t)(right * (1 << 24));

            // Delegate volume control to effect in track effect chain if needed
            // only one effect chain can be present on DirectOutputThread, so if
            // there is one, the track is connected to it
            if (!mEffectChains.isEmpty()) {
                mEffectChains[0]->setVolume_l(&vl, &vr);
                left = (float)vl / (1 << 24);
                right = (float)vr / (1 << 24);
                // if effect chain exists, volume is handled by it.
                // Convert volumes from float to 8.24
                uint32_t vl = (uint32_t)(left * (1 << 24));
                uint32_t vr = (uint32_t)(right * (1 << 24));
                // Direct/Offload effect chains set output volume in setVolume_l().
                (void)mEffectChains[0]->setVolume_l(&vl, &vr);
            } else {
                // otherwise we directly set the volume.
                setVolumeForOutput_l(left, right);
            }
            status_t result = mOutput->stream->setVolume(left, right);
            ALOGE_IF(result != OK, "Error when setting output stream volume: %d", result);
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -712,6 +712,8 @@ public:
    virtual     void        setStreamMute(audio_stream_type_t stream, bool muted);
    virtual     float       streamVolume(audio_stream_type_t stream) const;

                void        setVolumeForOutput_l(float left, float right) const;

                sp<Track>   createTrack_l(
                                const sp<AudioFlinger::Client>& client,
                                audio_stream_type_t streamType,