96 lines
2.7 KiB
C++
96 lines
2.7 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "DSP/Encoders/IAudioEncoder.h"
|
|
|
|
Audio::IAudioEncoder::IAudioEncoder(uint32 AudioBufferSlack, uint32 DataBufferSlack /*= 4096*/)
|
|
: UncompressedAudioBuffer(AudioBufferSlack)
|
|
, CompressedDataBuffer(DataBufferSlack)
|
|
{
|
|
}
|
|
|
|
Audio::IAudioEncoder::~IAudioEncoder()
|
|
{
|
|
}
|
|
|
|
bool Audio::IAudioEncoder::PushAudio(const float* InBuffer, int32 NumSamples, bool bEncodeIfPossible /*= true*/)
|
|
{
|
|
if (UncompressedAudioBuffer.Remainder() < (uint32) NumSamples)
|
|
{
|
|
ensureAlwaysMsgf(false, TEXT("Not enough space. Please construct IAudioEncoder with a larager value for AudioBufferSlack"));
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
UncompressedAudioBuffer.Push(InBuffer, NumSamples);
|
|
}
|
|
|
|
if (bEncodeIfPossible)
|
|
{
|
|
return EncodeIfPossible();
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
int32 Audio::IAudioEncoder::PopData(uint8* OutData, int32 DataSize)
|
|
{
|
|
int32 Result = CompressedDataBuffer.Pop(OutData, DataSize);
|
|
|
|
// If result is negative, it indicates how many samples short we are
|
|
// of the requested amount.
|
|
return Result;
|
|
}
|
|
|
|
bool Audio::IAudioEncoder::EncodeIfPossible()
|
|
{
|
|
while (UncompressedAudioBuffer.Num() > SamplesRequiredPerEncode())
|
|
{
|
|
CurrentAudioBuffer.Reset();
|
|
CurrentAudioBuffer.AddUninitialized(SamplesRequiredPerEncode());
|
|
UncompressedAudioBuffer.Pop(CurrentAudioBuffer.GetData(), CurrentAudioBuffer.Num());
|
|
|
|
CurrentCompressedBuffer.Reset();
|
|
if (!EncodeChunk(CurrentAudioBuffer, CurrentCompressedBuffer))
|
|
{
|
|
ensureAlwaysMsgf(false, TEXT("Encode failed!"));
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
int32 Result = CompressedDataBuffer.Push(CurrentCompressedBuffer.GetData(), CurrentCompressedBuffer.Num());
|
|
ensureAlwaysMsgf(Result == CurrentCompressedBuffer.Num(), TEXT("Compressed Data Buffer full. Please construct IAudioEncoder with a larger value for DataBufferSlack or call PopData more often."));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int64 Audio::IAudioEncoder::Finalize()
|
|
{
|
|
// Encode all remaining uncompressed audio:
|
|
EncodeIfPossible();
|
|
|
|
CurrentCompressedBuffer.Reset();
|
|
EndFile(CurrentCompressedBuffer);
|
|
|
|
int32 Remainder = CompressedDataBuffer.Push(CurrentCompressedBuffer.GetData(), CurrentCompressedBuffer.Num());
|
|
if (Remainder < 0)
|
|
{
|
|
ensureAlwaysMsgf(false, TEXT("Insufficient slack for header! Please use a larger value for DataBufferSlack."));
|
|
return Remainder;
|
|
}
|
|
|
|
return CompressedDataBuffer.Num();
|
|
}
|
|
|
|
void Audio::IAudioEncoder::Init(const FSoundQualityInfo& InQualityInfo)
|
|
{
|
|
StartFile(InQualityInfo, CurrentCompressedBuffer);
|
|
int32 Remainder = CompressedDataBuffer.Push(CurrentCompressedBuffer.GetData(), CurrentCompressedBuffer.Num());
|
|
checkf(Remainder > 0, TEXT("Insufficient slack for header! Please use a larger value for DataBufferSlack."));
|
|
}
|
|
|