102 lines
2.5 KiB
C++
102 lines
2.5 KiB
C++
#pragma once
|
|
#include "CoreMinimal.h"
|
|
|
|
class FSampler;
|
|
|
|
struct FSamplePeak
|
|
{
|
|
float Min = 0;
|
|
float Max = 0;
|
|
|
|
void operator+=(const FSamplePeak& Other)
|
|
{
|
|
if (Min > Other.Min) Min = Other.Min;
|
|
if (Max < Other.Max) Max = Other.Max;
|
|
}
|
|
};
|
|
|
|
class FPeakBlock
|
|
{
|
|
public:
|
|
uint16 BlockNum;
|
|
uint16 Size;
|
|
uint16 Res;
|
|
uint16 Resolution;
|
|
TArray<void*> Buffer;
|
|
uint16 MaxLevel;
|
|
};
|
|
|
|
struct FWaveformBuffer
|
|
{
|
|
TArray<int16> Buffer;
|
|
void* HiResBuffer;
|
|
TArray<int8> RMSBuffer;
|
|
};
|
|
|
|
class FWaveformRenderData
|
|
{
|
|
public:
|
|
explicit FWaveformRenderData(int32 BlockSize)
|
|
: BlockSize(BlockSize)
|
|
{
|
|
}
|
|
|
|
virtual ~FWaveformRenderData() = default;
|
|
virtual void Generate(const TArray<TArray64<float>>& Data);
|
|
int32 GetMemSize() const
|
|
{
|
|
int32 Size = 0;
|
|
for (const auto& Array : Buffer)
|
|
{
|
|
Size += Array.GetAllocatedSize();
|
|
}
|
|
return Buffer.GetAllocatedSize() + Size;
|
|
}
|
|
const FSamplePeak& GetPeak(const uint16 Channel, const uint64 Frame) const
|
|
{
|
|
const int32 BlockIndex = Frame / BlockSize;
|
|
return Buffer[Channel][BlockIndex];
|
|
}
|
|
|
|
TArrayView<const FSamplePeak> GetPeakFromRange(const uint16 Channel, uint64 StartFrame, uint64 EndFrame) const
|
|
{
|
|
const int32 StartBlockIndex = StartFrame / BlockSize;
|
|
int32 EndBlockIndex = EndFrame / BlockSize;
|
|
EndBlockIndex = FMath::Min(EndBlockIndex, Buffer[Channel].Num() - 1);
|
|
|
|
// TArray<FSamplePeak> Out;
|
|
// Out.SetNum(EndBlockIndex - StartBlockIndex + 1);
|
|
// FMemory::Memcpy(Out.GetData(), Buffer[Channel].GetData() + StartBlockIndex, Out.Num() * sizeof(FSamplePeak));
|
|
return MakeArrayView(&Buffer[Channel][StartBlockIndex], EndBlockIndex - StartBlockIndex + 1);
|
|
}
|
|
TArray<TArray<FSamplePeak>> Buffer;
|
|
const int32 BlockSize; // 每一个块包含多少个Frame
|
|
};
|
|
|
|
class FWaveform
|
|
{
|
|
public:
|
|
FWaveform(int32 LevelNum, int32 MaxBlockSize = 128 * 128);
|
|
~FWaveform();
|
|
|
|
void UpdatePeak(const TArray<TArray64<float>>& SampleBuffer);
|
|
int32 GetMemSize() const
|
|
{
|
|
int32 Size = 0;
|
|
for (int i = 0; i < RenderData.Num(); ++i)
|
|
Size += RenderData[i]->GetMemSize();
|
|
return Size;
|
|
}
|
|
|
|
TArrayView<const FSamplePeak> GetPeakFromRange(const uint16 Channel, const int32 Width, const uint64 StartFrame, const uint64 EndFrame) const
|
|
{
|
|
const uint64 FrameCount = EndFrame - StartFrame;
|
|
const int32 BlockSize = FrameCount / Width;
|
|
for (int i = 0; i < RenderData.Num(); ++i)
|
|
if (RenderData[i]->BlockSize <= BlockSize)
|
|
return RenderData[i]->GetPeakFromRange(Channel, StartFrame, EndFrame);
|
|
return RenderData.Last()->GetPeakFromRange(Channel, StartFrame, EndFrame);
|
|
}
|
|
TArray<FWaveformRenderData*> RenderData;
|
|
};
|