#include "SSamplePatternInstance.h" #include "Pattern/SamplePatternInstance.h" #include "UI/Widget/Thumbnail.h" #include "UI/Widget/WaveformViewer.h" FSamplePatternInstanceWaveformHandle::FSamplePatternInstanceWaveformHandle(TSharedRef InPatternInstance): PatternInstanceWidget(InPatternInstance) { } TArrayView FSamplePatternInstanceWaveformHandle::GetWaveform(int32 SizeX) { if (!PatternInstanceWidget.IsValid()) return TArrayView(); 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& RenderRange = GetRenderRange(); const bool Lower = FMath::IsNearlyEqual(LastRenderRange.GetLowerBoundValue(), RenderRange.GetLowerBoundValue()); const bool Upper = FMath::IsNearlyEqual(LastRenderRange.GetUpperBoundValue(), RenderRange.GetUpperBoundValue()); return !(Lower && Upper); } TRange FSamplePatternInstanceWaveformHandle::GetRenderRange() const { if (!PatternInstanceWidget.IsValid()) return TRange(0, 0); const TSharedPtr SamplePatternInstance = PatternInstanceWidget.Pin(); FSamplePatternInstance* Instance = static_cast(SamplePatternInstance->GetPatternInstance()); const TRange& TimeRange = Instance->TimeRange; TRange FrameViewRange = SamplePatternInstance->GetFrameViewRange(); const AudioFrame InstancePos = Instance->GetMidiPos(); FrameViewRange = TRange(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(BeginFrame, EndFrame); } SSamplePatternInstance::SSamplePatternInstance() { } void SSamplePatternInstance::Construct(const FArguments& InArgs) { WaveformHandle = MakeShared(SharedThis(this)); WaveformHandle->OnRequestUpdate.AddLambda([this]() { Invalidate(EInvalidateWidgetReason::Paint); }); SPatternInstance::Construct(InArgs); } TSharedRef 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(); }