Files
UnrealEngineUWP/Engine/Source/Runtime/SignalProcessing/Private/MultichannelBuffer.cpp
phil popp 57a164eb62 Deinterleaved DSP for metasound wave player
#rb Aaron.McLeran
#jira UE-134456
#preflight 61f01048fd5285142b185e3e

#ROBOMERGE-AUTHOR: phil.popp
#ROBOMERGE-SOURCE: CL 18722673 in //UE5/Release-5.0/... via CL 18722699 via CL 18722914
#ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v903-18687472)

[CL 18722926 by phil popp in ue5-main branch]
2022-01-25 10:40:58 -05:00

113 lines
3.2 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "DSP/MultichannelBuffer.h"
#include "Algo/AllOf.h"
#include "Containers/Array.h"
#include "DSP/BufferVectorOperations.h"
#include "DSP/Dsp.h"
namespace Audio
{
namespace MultichannelBufferPrivate
{
template<typename BufferType>
int32 GetMultichannelBufferNumFrames(const TArray<BufferType>& InBuffer)
{
if (InBuffer.Num() > 0)
{
const int32 NumFrames = InBuffer[0].Num();
// Check that all of the buffers contain the same frame count.
checkf(Algo::AllOf(InBuffer, [&NumFrames](const BufferType& Buffer) { return NumFrames == Buffer.Num(); }), TEXT("Buffers contain inconsistent frame sizes"));
return NumFrames;
}
return 0;
}
}
void SetMultichannelBufferSize(int32 InNumChannels, int32 InNumFrames, FMultichannelBuffer& OutBuffer)
{
OutBuffer.SetNum(InNumChannels, false /* bAllowShrinking */);
for (FAlignedFloatBuffer& Buffer : OutBuffer)
{
Buffer.SetNumUninitialized(InNumFrames, false /* bAllowShrinking */);
}
}
void SetMultichannelCircularBufferCapacity(int32 InNumChannels, int32 InNumFrames, FMultichannelCircularBuffer& OutBuffer)
{
OutBuffer.SetNum(InNumChannels, false /* bAllowShrinking */);
for (TCircularAudioBuffer<float>& Buffer : OutBuffer)
{
Buffer.SetCapacity(InNumFrames);
}
}
int32 GetMultichannelBufferNumFrames(const FMultichannelBuffer& InBuffer)
{
return MultichannelBufferPrivate::GetMultichannelBufferNumFrames(InBuffer);
}
int32 GetMultichannelBufferNumFrames(const FMultichannelCircularBuffer& InBuffer)
{
return MultichannelBufferPrivate::GetMultichannelBufferNumFrames(InBuffer);
}
int32 GetMultichannelBufferNumFrames(const FMultichannelBufferView& InBuffer)
{
return MultichannelBufferPrivate::GetMultichannelBufferNumFrames(InBuffer);
}
FMultichannelBufferView MakeMultichannelBufferView(FMultichannelBuffer& InBuffer)
{
FMultichannelBufferView View;
View.Reset(InBuffer.Num());
for (FAlignedFloatBuffer& ChannelBuffer: InBuffer)
{
View.Emplace(ChannelBuffer);
}
return View;
}
FMultichannelBufferView MakeMultichannelBufferView(FMultichannelBuffer& InBuffer, int32 InStartFrameIndex, int32 InNumFrames)
{
FMultichannelBufferView View;
View.Reset(InBuffer.Num());
for (FAlignedFloatBuffer& ChannelBuffer: InBuffer)
{
check(InBuffer.Num() <= (InStartFrameIndex + InNumFrames));
View.Emplace(&ChannelBuffer.GetData()[InStartFrameIndex], InNumFrames);
}
return View;
}
FMultichannelBufferView SliceMultichannelBufferView(const FMultichannelBufferView& View, int32 InStartFrameIndex, int32 InNumFrames)
{
FMultichannelBufferView OutView;
for (int32 ChannelIndex = 0; ChannelIndex < View.Num(); ChannelIndex++)
{
OutView.Emplace(View[ChannelIndex].Slice(InStartFrameIndex, InNumFrames));
}
return OutView;
}
void ShiftMultichannelBufferView(int32 InNumFrames, FMultichannelBufferView& View)
{
int32 NumRemainingFrames = GetMultichannelBufferNumFrames(View);
int32 NumFramesToShift = FMath::Clamp(InNumFrames, 0, NumRemainingFrames);
int32 NumFramesToKeep = NumRemainingFrames - NumFramesToShift;
for (int32 ChannelIndex = 0; ChannelIndex < View.Num(); ChannelIndex++)
{
View[ChannelIndex] = View[ChannelIndex].Slice(NumFramesToShift, NumFramesToKeep);
}
}
}