Pause a sequence and lose sound when played

Unreal Version - 4.27.2
FMOD Plugin Version - 2.02.06

Hello.

If you pause the sequence and resume it, there is a problem that the sound cannot be heard.

Reproduction methods are as follows:

  1. Play the sequence containing FMOD-Event.
  2. Pause the Level Sequence Player.
  3. Play the Level Sequence Player.

Is there any solution?

We tried to bind the play function of FMODAudioComponent to the sequence, but in this case, the sound is not played at the sequence-editor time.

Hi,

Currently, when you pause the sequence it will end the event instance which means it cannot be resumed from within the sequence again. I will pass this on to our development team to look into further.

Could you elaborate on what you are trying to do with the sequence that requires it to play and pause?

Thanks

Sorry for the late confirmation.

When expressing game effect in Sequence, you should stop in the following situations:

  1. Press the pause button.
  2. When the app is in the background

Do you need any more information?
Thanks.

Is there a way around?

I wonder what direction the discussion with the development team is going.

Thanks for sharing that.

Unfortunately, this currently isn’t possible from a sequence. This can be done on an event through a blueprint if you can get the current state of the game and pass that to the event. E.g. playing, paused, and/or in the background.

Currently, the ticket is still in our backlog.

1 Like

Hello.
Does this problem is fixed?

Hi,

Unfortunately, there hasn’t been a fix implemented yet. The task is still in our backlog.

1 Like

Hi, I think I solved this problem.
Since I was using Wwise before, I referred to the Wwise code.
It’s here.


Hi,

Thank you for looking into this. Could I get the files and lines that you implemented these changes?

Off course.
In the file “FMODEventControlSectionTemplate.cpp”.
Sorry I don’t know how to upload a file, so I paste it below.

// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2022.

#include "FMODEventControlSectionTemplate.h"
#include "FMODAmbientSound.h"
#include "FMODAudioComponent.h"
#include "Evaluation/MovieSceneEvaluation.h"
#include "IMovieScenePlayer.h"

struct FPlayingToken : IMovieScenePreAnimatedToken
{
    FPlayingToken(UObject &InObject)
    {
        bPlaying = false;

        if (UFMODAudioComponent *AudioComponent = Cast<UFMODAudioComponent>(&InObject))
        {
            if (IsValid(AudioComponent))
            {
                bPlaying = AudioComponent->IsPlaying();
            }
        }
    }

    virtual void RestoreState(UObject &Object, const UE::MovieScene::FRestoreStateParams& Params) override
    {
        UFMODAudioComponent *AudioComponent = CastChecked<UFMODAudioComponent>(&Object);

        if (AudioComponent)
        {
            if (bPlaying)
            {
                AudioComponent->Play();
            }
            else
            {
                AudioComponent->Stop();
            }
        }
    }

private:
    bool bPlaying;
};

struct FPlayingTokenProducer : IMovieScenePreAnimatedTokenProducer
{
    static FMovieSceneAnimTypeID GetAnimTypeID() { return TMovieSceneAnimTypeID<FPlayingTokenProducer>(); }

private:
    virtual IMovieScenePreAnimatedTokenPtr CacheExistingState(UObject &Object) const override { return FPlayingToken(Object); }
};

struct FFMODEventKeyState : IPersistentEvaluationData
{
    FKeyHandle LastKeyHandle;
    FKeyHandle InvalidKeyHandle;
};

struct FFMODEventControlExecutionToken : IMovieSceneExecutionToken
{
    FFMODEventControlExecutionToken()
        : EventControlKey(EFMODEventControlKey::Stop)
        , KeyTime(FFrameTime(0))
    {
    }

    FFMODEventControlExecutionToken(EFMODEventControlKey InEventControlKey, FFrameTime InKeyTime)
        : EventControlKey(InEventControlKey)
        , KeyTime(InKeyTime)
    {
    }

    float inline GetTimeInSeconds(const FMovieSceneContext& Context)
    {
        return (float)Context.GetFrameRate().AsSeconds(Context.GetTime());
    }

    /** Execute this token, operating on all objects referenced by 'Operand' */
    /*virtual void Execute(const FMovieSceneContext &Context, const FMovieSceneEvaluationOperand &Operand, FPersistentEvaluationData &PersistentData,
        IMovieScenePlayer &Player)
    {
        for (TWeakObjectPtr<> &WeakObject : Player.FindBoundObjects(Operand))
        {
            UFMODAudioComponent *AudioComponent = Cast<UFMODAudioComponent>(WeakObject.Get());

            if (!AudioComponent)
            {
                AFMODAmbientSound *AmbientSound = Cast<AFMODAmbientSound>(WeakObject.Get());
                AudioComponent = AmbientSound ? AmbientSound->AudioComponent : nullptr;
            }

            if (IsValid(AudioComponent))
            {
                Player.SavePreAnimatedState(*AudioComponent, FPlayingTokenProducer::GetAnimTypeID(), FPlayingTokenProducer());

                if (EventControlKey == EFMODEventControlKey::Play)
                {
                    if (AudioComponent->IsPlaying())
                    {
                        AudioComponent->Stop();
                    }

                    EFMODSystemContext::Type SystemContext =
                        (GWorld && GWorld->WorldType == EWorldType::Editor) ? EFMODSystemContext::Editor : EFMODSystemContext::Runtime;
                    AudioComponent->PlayInternal(SystemContext);
                }
                else if (EventControlKey == EFMODEventControlKey::Stop)
                {
                    AudioComponent->Stop();
                }
            }
        }
    }*/

    virtual void Execute(const FMovieSceneContext& Context, const FMovieSceneEvaluationOperand& Operand, FPersistentEvaluationData& PersistentData,
        IMovieScenePlayer& Player)
    {
        for (TWeakObjectPtr<>& WeakObject : Player.FindBoundObjects(Operand))
        {
            UFMODAudioComponent* AudioComponent = Cast<UFMODAudioComponent>(WeakObject.Get());

            if (!AudioComponent)
            {
                AFMODAmbientSound* AmbientSound = Cast<AFMODAmbientSound>(WeakObject.Get());
                AudioComponent = AmbientSound ? AmbientSound->AudioComponent : nullptr;
            }

            if (IsValid(AudioComponent))
            {
                bool isPaused = false;
                if (AudioComponent->StudioInstance)
                {
                    AudioComponent->StudioInstance->getPaused(&isPaused);
                }
                switch (Player.GetPlaybackStatus())
                {
                case EMovieScenePlayerStatus::Paused:
                {
                    if (!isPaused && AudioComponent->StudioInstance)
                    {
                        AudioComponent->StudioInstance->setPaused(true);
                    }
                    break;
                }
                case EMovieScenePlayerStatus::Stopped:
                {
                    AudioComponent->Stop();
                    break;
                }
                case EMovieScenePlayerStatus::Playing:
                {
                    const float CurrentTime = GetTimeInSeconds(Context);
                    if (!isPaused && AudioComponent->StudioInstance)
                    {
                        return;
                    }
                    else if (!AudioComponent->IsPlaying())
                    {
                        EFMODSystemContext::Type SystemContext =
                            (GWorld && GWorld->WorldType == EWorldType::Editor) ? EFMODSystemContext::Editor : EFMODSystemContext::Runtime;
                        AudioComponent->PlayInternal(SystemContext);
                    }
                    else
                    {
                        AudioComponent->StudioInstance->setPaused(false);
                    }
                    break;
                }
                }
            }
        }
    }

    EFMODEventControlKey EventControlKey;
    FFrameTime KeyTime;
};

FFMODEventControlSectionTemplate::FFMODEventControlSectionTemplate(const UFMODEventControlSection &Section)
    : ControlKeys(Section.ControlKeys)
{
}

void FFMODEventControlSectionTemplate::Evaluate(const FMovieSceneEvaluationOperand &Operand, const FMovieSceneContext &Context,
    const FPersistentEvaluationData &PersistentData, FMovieSceneExecutionTokens &ExecutionTokens) const
{
    //const bool bPlaying = Context.IsSilent() == false && Context.GetDirection() == EPlayDirection::Forwards &&
    //                      Context.GetRange().Size<FFrameTime>() >= FFrameTime(0) && Context.GetStatus() == EMovieScenePlayerStatus::Playing;

    //if (!bPlaying)
    //{
    //    ExecutionTokens.Add(FFMODEventControlExecutionToken(EFMODEventControlKey::Stop, FFrameTime(0)));
    //}
    //else
    //{
    //    TRange<FFrameNumber> PlaybackRange = Context.GetFrameNumberRange();
    //    TMovieSceneChannelData<const uint8> ChannelData = ControlKeys.GetData();

    //    // Find the index of the key handle that exists before this time
    //    TArrayView<const FFrameNumber> Times = ChannelData.GetTimes();
    //    TArrayView<const uint8> Values = ChannelData.GetValues();

    //    const int32 LastKeyIndex = Algo::UpperBound(Times, PlaybackRange.GetUpperBoundValue()) - 1;
    //    if (LastKeyIndex >= 0 && PlaybackRange.Contains(Times[LastKeyIndex]))
    //    {
    //        FFMODEventControlExecutionToken NewToken((EFMODEventControlKey)Values[LastKeyIndex], Times[LastKeyIndex]);
    //        ExecutionTokens.Add(MoveTemp(NewToken));
    //    }
    //}
    ExecutionTokens.Add(FFMODEventControlExecutionToken());
}
2 Likes

Thank you for sharing those! I will pass this fix on to our development team to look into it further.

Thank you again for looking into this, we greatly appreciate it!

2 Likes

Was there a solution to this issue? We are having the same problem and the proposed fix by pigeon55 is not working for us. While active events are being resumed, others are not played at all.

Hi,

Unfortunately, the task is still in our backlog.

What version of FMOD and Unreal are you using?

Ok, thats unfortunate. We are on Unreal 4.27 and FMOD Plugin version 2.02.09.

1 Like

Hello.
Was this problem fixed? I have a troubles with pause in the UE 5.1. My ambient sound stops playing if sequence is paused

1 Like

Hi,

Unfortunately, there hasn’t been any progress on this task. I will note your interest.

If there are any updates I will post them here.