100 lines
3.9 KiB
C++
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;
|
|
}
|