84 lines
3.1 KiB
C++
84 lines
3.1 KiB
C++
#include "SSamplePatternInstance.h"
|
|
|
|
#include "Pattern/SamplePatternInstance.h"
|
|
#include "UI/Widget/Thumbnail.h"
|
|
#include "UI/Widget/WaveformViewer.h"
|
|
|
|
FSamplePatternInstanceWaveformHandle::FSamplePatternInstanceWaveformHandle(TSharedRef<SSamplePatternInstance> InPatternInstance):
|
|
PatternInstanceWidget(InPatternInstance)
|
|
{
|
|
}
|
|
|
|
TArrayView<const FSamplePeak> FSamplePatternInstanceWaveformHandle::GetWaveform(int32 SizeX)
|
|
{
|
|
if (!PatternInstanceWidget.IsValid())
|
|
return TArrayView<const FSamplePeak>();
|
|
const FSamplePatternInstance* Instance = (FSamplePatternInstance*)PatternInstanceWidget.Pin()->GetPatternInstance();
|
|
const FSampler* Sampler = Instance->GetInstanceOwner()->GetSampler();
|
|
|
|
if (!RenderData)
|
|
{
|
|
RenderData = new FWaveform(7, 256 * 128);
|
|
RenderData->OnPostUpdatePeak.AddLambda([this]() { OnRequestUpdate.Broadcast(); });
|
|
RenderData->UpdatePeak(Sampler->GetSampleBuffer());
|
|
}
|
|
LastRenderRange = GetRenderRange();
|
|
return RenderData->GetPeakFromRange(0, SizeX, LastRenderRange.GetLowerBoundValue(), LastRenderRange.GetUpperBoundValue());
|
|
}
|
|
|
|
bool FSamplePatternInstanceWaveformHandle::NeedUpdate() const
|
|
{
|
|
const TRange<AudioFrame>& RenderRange = GetRenderRange();
|
|
const bool Lower = FMath::IsNearlyEqual(LastRenderRange.GetLowerBoundValue(), RenderRange.GetLowerBoundValue());
|
|
const bool Upper = FMath::IsNearlyEqual(LastRenderRange.GetUpperBoundValue(), RenderRange.GetUpperBoundValue());
|
|
return !(Lower && Upper);
|
|
}
|
|
|
|
TRange<AudioFrame> FSamplePatternInstanceWaveformHandle::GetRenderRange() const
|
|
{
|
|
if (!PatternInstanceWidget.IsValid())
|
|
return TRange<AudioFrame>(0, 0);
|
|
const TSharedPtr<SSamplePatternInstance> SamplePatternInstance = PatternInstanceWidget.Pin();
|
|
FSamplePatternInstance* Instance = static_cast<FSamplePatternInstance*>(SamplePatternInstance->GetPatternInstance());
|
|
const TRange<AudioFrame>& TimeRange = Instance->TimeRange;
|
|
TRange<AudioFrame> FrameViewRange = SamplePatternInstance->GetFrameViewRange();
|
|
|
|
const AudioFrame InstancePos = Instance->GetMidiPos();
|
|
FrameViewRange = TRange<AudioFrame>(FrameViewRange.GetLowerBoundValue() - InstancePos, FrameViewRange.GetUpperBoundValue() - InstancePos);
|
|
const AudioFrame BeginFrame = FMath::Max(TimeRange.GetLowerBoundValue(), FrameViewRange.GetLowerBoundValue());
|
|
const AudioFrame EndFrame = FMath::Min(TimeRange.GetUpperBoundValue(), FrameViewRange.GetUpperBoundValue());
|
|
|
|
return TRange<AudioFrame>(BeginFrame, EndFrame);
|
|
}
|
|
|
|
SSamplePatternInstance::SSamplePatternInstance()
|
|
{
|
|
}
|
|
|
|
void SSamplePatternInstance::Construct(const FArguments& InArgs)
|
|
{
|
|
WaveformHandle = MakeShared<FSamplePatternInstanceWaveformHandle>(SharedThis(this));
|
|
WaveformHandle->OnRequestUpdate.AddLambda([this]()
|
|
{
|
|
Invalidate(EInvalidateWidgetReason::Paint);
|
|
});
|
|
SPatternInstance::Construct(InArgs);
|
|
}
|
|
|
|
TSharedRef<SWidget> SSamplePatternInstance::GetViewWidget()
|
|
{
|
|
return SAssignNew(WaveformViewer, SWaveformViewer)
|
|
.WaveformHandle(WaveformHandle);
|
|
}
|
|
|
|
void SSamplePatternInstance::RequestUpdate()
|
|
{
|
|
if (WaveformHandle.IsValid() && WaveformHandle->NeedUpdate())
|
|
Invalidate(EInvalidateWidgetReason::Paint);
|
|
}
|
|
|
|
FReply SSamplePatternInstance::OpenPatternMenu()
|
|
{
|
|
return FReply::Handled();
|
|
}
|