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

Commit 2dcd60c6 authored by Shunkai Yao's avatar Shunkai Yao
Browse files

Enable global effect on Spatializer thread

- APM select spatializer output for music effects when it is active
- mirror mEffectBuffer input/output for AUDIO_SESSION_OUTPUT_MIX session
- return mixerChannelMask for AUDIO_SESSION_OUTPUT_MIX session
- add a helper for stereo spatializer feature enablement check

Flag: EXEMPT bugfix
Bug: 361519000
Test: Enable Visualizer/DynamicsProcessing effect with Clarity
Test: atest CtsMediaAudioTestCases
Change-Id: I366da7bde778040fb8907505760b8e5fc061161d
parent 84677267
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -3266,7 +3266,9 @@ NO_THREAD_SAFETY_ANALYSIS
    }

    if (mThreadType == IAfThreadBase::SPATIALIZER) {
        if (c->sessionId() == AUDIO_SESSION_OUTPUT_STAGE) {
        if (c->sessionId() == AUDIO_SESSION_OUTPUT_MIX) {
            return t->mixerChannelMask();
        } else if (c->sessionId() == AUDIO_SESSION_OUTPUT_STAGE) {
            if (c->isFirstEffect_l(id)) {
                return t->mixerChannelMask();
            } else {
@@ -3313,7 +3315,8 @@ NO_THREAD_SAFETY_ANALYSIS
                return t->channelMask();
            }
        } else {
            return t->channelMask();
            return (c->sessionId() == AUDIO_SESSION_OUTPUT_MIX) ? t->mixerChannelMask()
                                                                : t->channelMask();
        }
    } else {
        return t->channelMask();
+28 −17
Original line number Diff line number Diff line
@@ -1578,14 +1578,13 @@ status_t PlaybackThread::checkEffectCompatibility_l(
        }
        break;
    case SPATIALIZER:
        // Global effects (AUDIO_SESSION_OUTPUT_MIX) are not supported on spatializer mixer
        // as there is no common accumulation buffer for sptialized and non sptialized tracks.
        // Global effects (AUDIO_SESSION_OUTPUT_MIX) are supported on spatializer mixer, but only
        // the spatialized track have global effects applied for now.
        // Post processing effects (AUDIO_SESSION_OUTPUT_STAGE or AUDIO_SESSION_DEVICE)
        // are supported and added after the spatializer.
        if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
            ALOGW("%s: global effect %s not supported on spatializer thread %s",
                    __func__, desc->name, mThreadName);
            return BAD_VALUE;
            ALOGD("%s: global effect %s on spatializer thread %s", __func__, desc->name,
                  mThreadName);
        } else if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
            // only post processing , downmixer or spatializer effects on output stage session
            if (IAfEffectModule::isSpatializer(&desc->type)
@@ -3803,13 +3802,24 @@ status_t PlaybackThread::addEffectChain_l(const sp<IAfEffectChain>& chain)
            ALOGV("addEffectChain_l() creating new input buffer %p session %d",
                    buffer, session);
        } else {
            // A global session on a SPATIALIZER thread is either OUTPUT_STAGE or DEVICE
            // - OUTPUT_STAGE session uses the mEffectBuffer as input buffer and
            status_t result = INVALID_OPERATION;
            // Buffer configuration for global sessions on a SPATIALIZER thread:
            // - AUDIO_SESSION_OUTPUT_MIX session uses the mEffectBuffer as input and output buffer
            // - AUDIO_SESSION_OUTPUT_STAGE session uses the mEffectBuffer as input buffer and
            //   mPostSpatializerBuffer as output buffer
            // - DEVICE session uses the mPostSpatializerBuffer as input and output buffer.
            status_t result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
            // - AUDIO_SESSION_DEVICE session uses the mPostSpatializerBuffer as input and output
            //   buffer
            if (session == AUDIO_SESSION_OUTPUT_MIX || session == AUDIO_SESSION_OUTPUT_STAGE) {
                result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
                        mEffectBuffer, mEffectBufferSize, &halInBuffer);
                if (result != OK) return result;

                if (session == AUDIO_SESSION_OUTPUT_MIX) {
                    halOutBuffer = halInBuffer;
                }
            }

            if (session == AUDIO_SESSION_OUTPUT_STAGE || session == AUDIO_SESSION_DEVICE) {
                result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
                        mPostSpatializerBuffer, mPostSpatializerBufferSize, &halOutBuffer);
                if (result != OK) return result;
@@ -3818,6 +3828,7 @@ status_t PlaybackThread::addEffectChain_l(const sp<IAfEffectChain>& chain)
                    halInBuffer = halOutBuffer;
                }
            }
        }
    } else {
        status_t result = mAfThreadCallback->getEffectsFactoryHal()->mirrorBuffer(
                mEffectBufferEnabled ? mEffectBuffer : mSinkBuffer,
+42 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <com_android_media_audio.h>
#include <cutils/properties.h>

namespace android {

class SpatializerHelper {
  public:
    /**
     * @brief Check if the stereo spatialization feature turned on by:
     *        - sysprop "ro.audio.stereo_spatialization_enabled" is true
     *        - com_android_media_audio_stereo_spatialization flag is on
     *
     * @return true if the stereo spatialization feature is enabled
     * @return false if the stereo spatialization feature is not enabled
     */
    static bool isStereoSpatializationFeatureEnabled() {
        static const bool stereoSpatializationEnabled =
                property_get_bool("ro.audio.stereo_spatialization_enabled", false) &&
                com_android_media_audio_stereo_spatialization();
        return stereoSpatializationEnabled;
    }
};

} // namespace android
+22 −16
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@
#include <android_media_audiopolicy.h>
#include <com_android_media_audioserver.h>
#include <cutils/bitops.h>
#include <cutils/properties.h>
#include <media/AudioParameter.h>
#include <policy.h>
#include <private/android_filesystem_config.h>
@@ -55,6 +54,7 @@
#include <utils/Log.h>

#include "AudioPolicyManager.h"
#include "SpatializerHelper.h"
#include "TypeConverter.h"

namespace android {
@@ -3797,9 +3797,10 @@ audio_io_handle_t AudioPolicyManager::selectOutputForMusicEffects()
    // 1: An offloaded output. If the effect ends up not being offloadable,
    //    AudioFlinger will invalidate the track and the offloaded output
    //    will be closed causing the effect to be moved to a PCM output.
    // 2: A deep buffer output
    // 3: The primary output
    // 4: the first output in the list
    // 2: Spatializer output if the stereo spatializer feature enabled
    // 3: A deep buffer output
    // 4: The primary output
    // 5: the first output in the list

    DeviceVector devices = mEngine->getOutputDevicesForAttributes(
                attributes_initializer(AUDIO_USAGE_MEDIA), nullptr, false /*fromCache*/);
@@ -3814,28 +3815,36 @@ audio_io_handle_t AudioPolicyManager::selectOutputForMusicEffects()

    while (output == AUDIO_IO_HANDLE_NONE) {
        audio_io_handle_t outputOffloaded = AUDIO_IO_HANDLE_NONE;
        audio_io_handle_t outputSpatializer = AUDIO_IO_HANDLE_NONE;
        audio_io_handle_t outputDeepBuffer = AUDIO_IO_HANDLE_NONE;
        audio_io_handle_t outputPrimary = AUDIO_IO_HANDLE_NONE;

        for (audio_io_handle_t output : outputs) {
            sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
        for (audio_io_handle_t outputLoop : outputs) {
            sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputLoop);
            if (activeOnly && !desc->isActive(toVolumeSource(AUDIO_STREAM_MUSIC))) {
                continue;
            }
            ALOGV("selectOutputForMusicEffects activeOnly %d output %d flags 0x%08x",
                  activeOnly, output, desc->mFlags);
                  activeOnly, outputLoop, desc->mFlags);
            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
                outputOffloaded = output;
                outputOffloaded = outputLoop;
            }
            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) {
                if (SpatializerHelper::isStereoSpatializationFeatureEnabled()) {
                    outputSpatializer = outputLoop;
                }
            }
            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
                outputDeepBuffer = output;
                outputDeepBuffer = outputLoop;
            }
            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) != 0) {
                outputPrimary = output;
                outputPrimary = outputLoop;
            }
        }
        if (outputOffloaded != AUDIO_IO_HANDLE_NONE) {
            output = outputOffloaded;
        } else if (outputSpatializer != AUDIO_IO_HANDLE_NONE) {
            output = outputSpatializer;
        } else if (outputDeepBuffer != AUDIO_IO_HANDLE_NONE) {
            output = outputDeepBuffer;
        } else if (outputPrimary != AUDIO_IO_HANDLE_NONE) {
@@ -6363,11 +6372,8 @@ bool AudioPolicyManager::canBeSpatializedInt(const audio_attributes_t *attr,
    // mode is not requested.

    if (config != nullptr && *config != AUDIO_CONFIG_INITIALIZER) {
        static const bool stereo_spatialization_prop_enabled =
                property_get_bool("ro.audio.stereo_spatialization_enabled", false);
        const bool channel_mask_spatialized =
                (stereo_spatialization_prop_enabled
                        && com_android_media_audio_stereo_spatialization())
                SpatializerHelper::isStereoSpatializationFeatureEnabled()
                        ? audio_channel_mask_contains_stereo(config->channel_mask)
                        : audio_is_channel_mask_spatialized(config->channel_mask);
        if (!channel_mask_spatialized) {
+7 −13
Original line number Diff line number Diff line
@@ -29,9 +29,7 @@
#include <android/content/AttributionSourceState.h>
#include <android/sysprop/BluetoothProperties.sysprop.h>
#include <audio_utils/fixedfft.h>
#include <com_android_media_audio.h>
#include <cutils/bitops.h>
#include <cutils/properties.h>
#include <hardware/sensors.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -43,6 +41,7 @@
#include <utils/Thread.h>

#include "Spatializer.h"
#include "SpatializerHelper.h"

namespace android {

@@ -398,10 +397,8 @@ status_t Spatializer::loadEngineConfiguration(sp<EffectHalInterface> effect) {
        return status;
    }
    for (const auto channelMask : channelMasks) {
        static const bool stereo_spatialization_enabled =
                property_get_bool("ro.audio.stereo_spatialization_enabled", false);
        const bool channel_mask_spatialized =
                (stereo_spatialization_enabled && com_android_media_audio_stereo_spatialization())
                SpatializerHelper::isStereoSpatializationFeatureEnabled()
                        ? audio_channel_mask_contains_stereo(channelMask)
                        : audio_is_channel_mask_spatialized(channelMask);
        if (!channel_mask_spatialized) {
@@ -1272,12 +1269,9 @@ std::string Spatializer::toString(unsigned level) const {
                        mDisplayOrientation);

    // 4. Show flag or property state.
    static const bool stereo_spatialization_prop_enabled =
            property_get_bool("ro.audio.stereo_spatialization_enabled", false);
    const bool stereo_spatialization = com_android_media_audio_stereo_spatialization()
            && stereo_spatialization_prop_enabled;
    base::StringAppendF(&ss, "%sStereo Spatialization: %s\n", prefixSpace.c_str(),
            stereo_spatialization ? "true" : "false");
    base::StringAppendF(
            &ss, "%sStereo Spatialization: %s\n", prefixSpace.c_str(),
            SpatializerHelper::isStereoSpatializationFeatureEnabled() ? "true" : "false");

    ss.append(prefixSpace + "CommandLog:\n");
    ss += mLocalLog.dumpToString((prefixSpace + " ").c_str(), mMaxLocalLogLine);