AronaSlate/Source/Arona/UI/Widget/WaveformViewer.cpp
2024-01-25 11:21:15 +08:00

100 lines
3.9 KiB
C++

#include "WaveformViewer.h"
#include "Async.h"
#include "ExecutionTime.h"
#include "SlateComputeShader.h"
#include "SlatePixelShader.h"
#include "Thumbnail.h"
#include "Pattern/SamplePattern.h"
#include "Pattern/SamplePatternInstance.h"
void SWaveformViewer::Construct(const FArguments& InArgs)
{
Sampler.Load(TEXT("F:\\FL垃圾桶\\Kawaii Anokoga Kiniiranai.mp3"));
// Sampler.Load(TEXT("F:\\Sample\\cs1.6\\26_Kick_15_95_SP.wav"));
const TArray<TArray64<float>>& Buffer = Sampler.GetSampleBuffer();
Param.WaveColor = FLinearColor(0.0f, 1.0f, 1.0f, 1.0f).ToFColorSRGB();
Param.BgColor = FLinearColor(0.0f, 0.0f, 0.0f, 0.0f).ToFColorSRGB();
FSlateRenderer* Renderer = FSlateApplication::Get().GetRenderer();
RenderTarget = Renderer->CreateRenderTargetTexture(16, 16, EPixelFormat::PF_R8G8B8A8);
RenderTarget->OnResizeDelegate.AddSP(this, &SWaveformViewer::OnResize);
if (Renderer->GetRendererAPI() == ERendererAPI::D3D11)
{
Params = Renderer->CreateComputeShaderParam(ComputeShader);
Params->Init();
Params->AddComputeShaderTextureParameter("Result", RenderTarget, 2);
Params->AddComputeShaderParam("Samples", Buffer[0].GetData(), Buffer[0].Num(), 0);
Params->AddShaderParam("Params", (bool*)&Param, sizeof(FCSParam) / sizeof(bool));
ComputeShader = Renderer->CreateComputeShader(TEXT("Arona"), TEXT("WaveformCS"));
}
else if (Renderer->GetRendererAPI() == ERendererAPI::OpenGL)
{
ComputeShader = Renderer->CreateComputeShader(TEXT("Arona"), TEXT("WaveformCS"));
Params = Renderer->CreateComputeShaderParam(ComputeShader);
Params->Init();
Params->AddComputeShaderTextureParameter("Result", RenderTarget, 2);
Params->AddComputeShaderParam("Samples", Buffer[0].GetData(), Buffer[0].Num(), 0);
Params->AddComputeShaderParam("Params", (bool*)&Param, sizeof(FCSParam) / sizeof(bool), 1);
}
ComputeElement = Renderer->MakeComputeShaderElement(ComputeShader, Params);
}
void SWaveformViewer::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
{
SLeafWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
UpdateTimer += InDeltaTime;
if (UpdateTimer > UpdateInterval && bNeedCompute)
{
UpdateTimer = 0.0f;
Async(EAsyncExecution::TaskGraph, [this]()
{
const FIntPoint& Size = RenderTarget->GetSize();
UpdateTask Task;
Task.LineUV = 1.0f / Size.Y;
Task.Array = WaveformHandle->GetWaveform(Size.X);
Task.Size = Size;
UpdateQueue.Enqueue(Task);
});
bNeedCompute = false;
}
}
int32 SWaveformViewer::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry,
const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId,
const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
if (const UpdateTask* UpdateTask = UpdateQueue.Peek())
{
Param.LineUV = UpdateTask->LineUV;
Params->AddComputeShaderParam("Samples", UpdateTask->Array.GetData(), UpdateTask->Array.Num(), 0);
UpdateQueue.Pop();
if (FSlateApplication::Get().GetRenderer()->GetRendererAPI() == ERendererAPI::OpenGL)
Params->AddComputeShaderParam("Params", (bool*)&Param, sizeof(FCSParam) / sizeof(bool), 1);
else
Params->AddShaderParam("Params", (bool*)&Param, sizeof(FCSParam) / sizeof(bool));
Params->AddComputeShaderParam("Samples", UpdateTask->Array.GetData(), UpdateTask->Array.Num(), 0);
const FIntPoint& Size = UpdateTask->Size;
FSlateDrawElement::MakeComputeShaderDispatch(OutDrawElements, LayerId, Size.X , Size.Y, 1, ComputeElement);
}
LayerId++;
RenderTarget->OnDrawViewport(AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
FSlateDrawElement::MakeViewport(OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), RenderTarget, ESlateDrawEffect::None, FLinearColor::White);
return LayerId;
}
void SWaveformViewer::OnResize(const FIntPoint& InSize) const
{
bNeedCompute = true;
}