84 lines
1.9 KiB
C++

#include "PeakFile.h"
#include "Async.h"
#include "PluginHost/Sampler.h"
#define MID_TO_LOW (16 * 16)
DEFINE_LOG_CATEGORY(LogPeakFile);
TArray<TArray<FSamplePeak>> GenPeakData(const TArray<TArray64<float>>& Data, int32 BlockSize)
{
TArray<TArray<FSamplePeak>> Out;
Out.SetNum(Data.Num());
for (int64 Channel = 0; Channel < Data.Num(); ++Channel)
{
const uint64 SourceNum = Data[Channel].Num();
uint64 BlockNum = SourceNum / BlockSize;
BlockNum += SourceNum % BlockSize ? 1 : 0;
Out[Channel].SetNum(BlockNum);
uint64 Index = 0;
for (uint64 j = 0; j < BlockNum; j++)
{
float Max = FLT_MIN_EXP;
float Min = FLT_MAX;
for (uint64 S = 0; S < BlockSize; ++S)
{
if (Index >= SourceNum) break;
const float& Sample = Data[Channel][Index];
if (Max < Sample) Max = Sample;
if (Min > Sample) Min = Sample;
++Index;
}
Out[Channel][j].Max = Max;
Out[Channel][j].Min = Min;
}
}
return Out;
}
void FWaveformRenderData::Generate(const TArray<TArray64<float>>& Data)
{
Buffer = GenPeakData(Data, BlockSize);
}
FWaveform::FWaveform(int32 LevelNum, int32 MaxBlockSize)
{
RenderData.SetNum(LevelNum);
int32 BeginBlock = MaxBlockSize;
for (int i = 0; i < LevelNum; ++i)
{
RenderData[i] = new FWaveformRenderData(BeginBlock);
BeginBlock /= 4;
}
}
FWaveform::~FWaveform()
{
for (int i = 0; i < RenderData.Num(); ++i)
delete RenderData[i];
}
void FWaveform::UpdatePeak(const TArray<TArray64<float>>& SampleBuffer)
{
Processing = true;
Async(EAsyncExecution::TaskGraph, [this, &SampleBuffer]()
{
for (int i = 0; i < RenderData.Num(); ++i)
RenderData[i]->Generate(SampleBuffer);
const float MemSize = GetMemSize();
UE_LOG(LogPeakFile, Log, TEXT("Waveform MemSize: %f MB"), MemSize / 1024 / 1024);
// 创建一个主线程TaskGraph任务, 用于通知UI线程更新
Async(EAsyncExecution::TaskGraphMainThread, [this]()
{
OnPostUpdatePeak.Broadcast();
});
Processing = false;
});
}