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

Commit 4eb45d0a authored by Eric Laurent's avatar Eric Laurent
Browse files

AudioFlinger: forward active tracks channel mask to spatializer effect

Partial implementation of track metadata forwarding to effects.
Currently limited to spatializer effect and track channel masks.

Bug: 303920722
Test: atest AudioEffectTest
Test: atest atest android.media.audio.cts.SpatializerTest
Change-Id: Iaaa947f12946d6f87dffb3993612d58f0400e6c5
parent 46741303
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ cc_defaults {
        "audioflinger-aidl-cpp",
        "audioclient-types-aidl-cpp",
        "av-types-aidl-cpp",
        "com.android.media.audio-aconfig-cc",
        "effect-aidl-cpp",
        "libaudioclient_aidl_conversion",
        "libactivitymanager_aidl",
+1 −1
Original line number Diff line number Diff line
@@ -4144,7 +4144,7 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request,
        }

        // Only audio policy service can create a spatializer effect
        if ((memcmp(&descOut.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0) &&
        if (IAfEffectModule::isSpatializer(&descOut.type) &&
            (callingUid != AID_AUDIOSERVER || currentPid != getpid())) {
            ALOGW("%s: attempt to create a spatializer effect from uid/pid %d/%d",
                    __func__, callingUid, currentPid);
+53 −1
Original line number Diff line number Diff line
@@ -1528,6 +1528,15 @@ bool EffectModule::isHapticGenerator() const {
    return IAfEffectModule::isHapticGenerator(&mDescriptor.type);
}

/*static*/
bool IAfEffectModule::isSpatializer(const effect_uuid_t *type) {
    return memcmp(type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0;
}

bool EffectModule::isSpatializer() const {
    return IAfEffectModule::isSpatializer(&mDescriptor.type);
}

status_t EffectModule::setHapticIntensity(int id, os::HapticScale intensity)
{
    if (mStatus != NO_ERROR) {
@@ -1600,6 +1609,35 @@ status_t EffectModule::getConfigs(
    return NO_ERROR;
}

status_t EffectModule::sendMetadata(const std::vector<playback_track_metadata_v7_t>& metadata) {
    if (mStatus != NO_ERROR) {
        return mStatus;
    }
    // TODO b/307368176: send all metadata to effects if requested by the implementation.
    // For now only send channel mask to Spatializer.
    if (!isSpatializer()) {
        return INVALID_OPERATION;
    }

    std::vector<uint8_t> request(
            sizeof(effect_param_t) + sizeof(int32_t) + metadata.size() * sizeof(uint32_t));
    effect_param_t *param = (effect_param_t*) request.data();
    param->psize = sizeof(int32_t);
    param->vsize = metadata.size() * sizeof(uint32_t);
    *(int32_t*)param->data = SPATIALIZER_PARAM_INPUT_CHANNEL_MASK;
    uint32_t* channelMasks = reinterpret_cast<uint32_t*>(param->data + sizeof(int32_t));
    for (auto m : metadata) {
        *channelMasks++ = m.channel_mask;
    }
    std::vector<uint8_t> response;
    status_t status = command(EFFECT_CMD_SET_PARAM, request, sizeof(int32_t), &response);
    if (status == NO_ERROR) {
        LOG_ALWAYS_FATAL_IF(response.size() != sizeof(status_t));
        status = *reinterpret_cast<const status_t*>(response.data());
    }
    return status;
}

static std::string dumpInOutBuffer(bool isInput, const sp<EffectBufferHalInterface> &buffer) {
    std::stringstream ss;

@@ -2387,7 +2425,7 @@ ssize_t EffectChain::getInsertIndex(const effect_descriptor_t& desc) {
    // already present
    // Spatializer or Downmixer effects are inserted in first position because
    // they adapt the channel count for all other effects in the chain
    if ((memcmp(&desc.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0)
    if (IAfEffectModule::isSpatializer(&desc.type)
            || (memcmp(&desc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0)) {
        return 0;
    }
@@ -2983,6 +3021,20 @@ bool EffectChain::isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) cons
    return true;
}

// sendMetadata_l() must be called with thread->mutex() held
void EffectChain::sendMetadata_l(const std::vector<playback_track_metadata_v7_t>& allMetadata,
        const std::optional<const std::vector<playback_track_metadata_v7_t>> spatializedMetadata) {
    audio_utils::lock_guard _l(mutex());
    for (const auto& effect : mEffects) {
        if (spatializedMetadata.has_value()
                && IAfEffectModule::isSpatializer(&effect->desc().type)) {
            effect->sendMetadata(spatializedMetadata.value());
        } else {
            effect->sendMetadata(allMetadata);
        }
    }
}

// EffectCallbackInterface implementation
status_t EffectChain::EffectCallback::createEffectHal(
        const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
+6 −0
Original line number Diff line number Diff line
@@ -224,9 +224,11 @@ public:
    sp<IAfEffectModule> asEffectModule() final { return this; }

    bool isHapticGenerator() const final;
    bool isSpatializer() const final;

    status_t setHapticIntensity(int id, os::HapticScale intensity) final;
    status_t setVibratorInfo(const media::AudioVibratorInfo& vibratorInfo) final;
    status_t sendMetadata(const std::vector<playback_track_metadata_v7_t>& metadata) final;

    status_t getConfigs(audio_config_base_t* inputCfg,
                                audio_config_base_t* outputCfg,
@@ -513,6 +515,10 @@ public:
        return mEffects[index];
    }

    void sendMetadata_l(const std::vector<playback_track_metadata_v7_t>& allMetadata,
        const std::optional<const std::vector<playback_track_metadata_v7_t>> spatializedMetadata)
            final REQUIRES(audio_utils::ThreadBase_Mutex);

    void setThread(const sp<IAfThreadBase>& thread) final;

private:
+8 −0
Original line number Diff line number Diff line
@@ -175,8 +175,12 @@ public:

    static bool isHapticGenerator(const effect_uuid_t* type);
    virtual bool isHapticGenerator() const = 0;
    static bool isSpatializer(const effect_uuid_t* type);
    virtual bool isSpatializer() const = 0;

    virtual status_t setHapticIntensity(int id, os::HapticScale intensity) = 0;
    virtual status_t setVibratorInfo(const media::AudioVibratorInfo& vibratorInfo) = 0;
    virtual status_t sendMetadata(const std::vector<playback_track_metadata_v7_t>& metadata) = 0;

private:
    virtual void process() = 0;
@@ -309,6 +313,10 @@ public:
    virtual size_t numberOfEffects() const = 0;
    virtual sp<IAfEffectModule> getEffectModule(size_t index) const = 0;

    // sendMetadata_l() must be called with thread->mLock held
    virtual void sendMetadata_l(const std::vector<playback_track_metadata_v7_t>& allMetadata,
        const std::optional<const std::vector<playback_track_metadata_v7_t>> spatializedMetadata);

    virtual void dump(int fd, const Vector<String16>& args) const = 0;
};

Loading