159 lines
3.3 KiB
C++
159 lines
3.3 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
#include "MetasoundTrigger.h"
|
|
|
|
#include "MetasoundDataReference.h"
|
|
#include "MetasoundDataTypeRegistrationMacro.h"
|
|
#include "MetasoundOperatorSettings.h"
|
|
|
|
|
|
namespace Metasound
|
|
{
|
|
FTrigger::FTrigger(const FOperatorSettings& InSettings, bool bShouldTrigger)
|
|
: NumFramesPerBlock(InSettings.GetNumFramesPerBlock())
|
|
, SampleRate(InSettings.GetSampleRate())
|
|
{
|
|
if (bShouldTrigger)
|
|
{
|
|
TriggerFrame(0);
|
|
}
|
|
}
|
|
|
|
FTrigger::FTrigger(const FOperatorSettings& InSettings, int32 InFrameToTrigger)
|
|
: NumFramesPerBlock(InSettings.GetNumFramesPerBlock())
|
|
, SampleRate(InSettings.GetSampleRate())
|
|
{
|
|
TriggerFrame(InFrameToTrigger);
|
|
}
|
|
|
|
FTrigger::FTrigger(const FOperatorSettings& InSettings)
|
|
: FTrigger(InSettings, false)
|
|
{}
|
|
|
|
void FTrigger::AssignRawParameter(const void* ParamPackPayload)
|
|
{
|
|
// We don't even need to check the payload. If the parameter pack contained
|
|
// a Trigger bool, it must be true. There is no concept of "un-trigger" :-)
|
|
TriggerFrame(0);
|
|
}
|
|
|
|
void FTrigger::TriggerFrame(int32 InFrameToTrigger)
|
|
{
|
|
// Insert trigger frame index into sorted triggered frames
|
|
TriggeredFrames.Insert(InFrameToTrigger, Algo::LowerBound(TriggeredFrames, InFrameToTrigger));
|
|
|
|
if (InFrameToTrigger < NumFramesPerBlock)
|
|
{
|
|
UpdateLastTriggerIndexInBlock();
|
|
}
|
|
|
|
bHasTrigger = true;
|
|
}
|
|
|
|
void FTrigger::AdvanceBlock()
|
|
{
|
|
Advance(NumFramesPerBlock);
|
|
}
|
|
|
|
void FTrigger::Advance(int32 InNumFrames)
|
|
{
|
|
if (bHasTrigger)
|
|
{
|
|
const int32 NumToRemove = Algo::LowerBound(TriggeredFrames, InNumFrames);
|
|
|
|
if (NumToRemove)
|
|
{
|
|
TriggeredFrames.RemoveAt(0, NumToRemove, EAllowShrinking::No);
|
|
}
|
|
|
|
const int32 Num = TriggeredFrames.Num();
|
|
|
|
if (Num > 0)
|
|
{
|
|
for (int32 i = 0; i < Num; i++)
|
|
{
|
|
TriggeredFrames[i] -= InNumFrames;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bHasTrigger = false;
|
|
}
|
|
|
|
UpdateLastTriggerIndexInBlock();
|
|
}
|
|
}
|
|
|
|
int32 FTrigger::Num() const
|
|
{
|
|
return TriggeredFrames.Num();
|
|
}
|
|
|
|
int32 FTrigger::NumTriggeredInBlock() const
|
|
{
|
|
return LastTriggerIndexInBlock;
|
|
}
|
|
|
|
int32 FTrigger::operator[](int32 InTriggerIndex) const
|
|
{
|
|
return TriggeredFrames[InTriggerIndex];
|
|
}
|
|
|
|
int32 FTrigger::First() const
|
|
{
|
|
return TriggeredFrames.IsEmpty() ? INDEX_NONE : TriggeredFrames[0];
|
|
}
|
|
|
|
int32 FTrigger::Last() const
|
|
{
|
|
return TriggeredFrames.IsEmpty() ? INDEX_NONE : TriggeredFrames.Last();
|
|
}
|
|
|
|
bool FTrigger::IsTriggered() const
|
|
{
|
|
return bHasTrigger;
|
|
}
|
|
|
|
bool FTrigger::IsTriggeredInBlock() const
|
|
{
|
|
return LastTriggerIndexInBlock > 0;
|
|
}
|
|
|
|
FTrigger::operator bool() const
|
|
{
|
|
return IsTriggeredInBlock();
|
|
}
|
|
|
|
void FTrigger::Reset()
|
|
{
|
|
TriggeredFrames.Reset();
|
|
LastTriggerIndexInBlock = 0;
|
|
bHasTrigger = false;
|
|
}
|
|
|
|
void FTrigger::RemoveAfter(int32 InStartingFrame)
|
|
{
|
|
if (InStartingFrame <= 0)
|
|
{
|
|
Reset();
|
|
}
|
|
else if (TriggeredFrames.Num() > 0)
|
|
{
|
|
// Algo::UpperBound Returns index of first element > InStartingFrame
|
|
int32 BeginningIndex = Algo::UpperBound(TriggeredFrames, InStartingFrame);
|
|
int32 NumToRemove = TriggeredFrames.Num() - BeginningIndex;
|
|
|
|
if (NumToRemove > 0)
|
|
{
|
|
TriggeredFrames.RemoveAt(BeginningIndex, NumToRemove);
|
|
UpdateLastTriggerIndexInBlock();
|
|
bHasTrigger = TriggeredFrames.Num() > 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FTrigger::UpdateLastTriggerIndexInBlock()
|
|
{
|
|
LastTriggerIndexInBlock = Algo::LowerBound(TriggeredFrames, NumFramesPerBlock);
|
|
}
|
|
}
|