Files
UnrealEngineUWP/Engine/Source/Runtime/AudioCodecEngine/Private/DecoderBackCompat.cpp
jake burga 9bd573fa1a Fix audio sync issues.
Properly report the number of samples that have been "streamed".

Update it in all of our decoders that implement this method.

Still using the "BackCompat" decoder, take advantage of this number to mantain sync with the audio.

[REVIEW] [at]jimmy.smith [at]phil.popp [at]buzz.burrowes [at]charlie.huguenard

[CL 27599211 by jake burga in ue5-main branch]
2023-09-05 12:09:38 -04:00

139 lines
3.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "DecoderBackCompat.h"
#include "DecoderInputBackCompat.h"
#include "AudioDecompress.h"
namespace Audio
{
PRAGMA_DISABLE_DEPRECATION_WARNINGS
static const FCodecDetails Details =
{
TEXT("BackCompat"),
TEXT("BackCompat"),
1,
{ FCodecFeatures::HasDecoder }
};
bool FBackCompatCodec::SupportsPlatform(FName InPlatformName) const
{
// Everything right now.
return true;
}
const FCodecDetails& FBackCompatCodec::GetDetails() const
{
return Details;
}
const FCodecDetails& FBackCompatCodec::GetDetailsStatic()
{
return Details;
}
ICodec::FDecoderPtr FBackCompatCodec::CreateDecoder(
IDecoder::FDecoderInputPtr InSrc,
IDecoder::FDecoderOutputPtr InDst)
{
return MakeUnique<FBackCompat>(
InSrc,
InDst
);
}
FBackCompat::FBackCompat(IDecoder::FDecoderInputPtr InSrc, IDecoder::FDecoderOutputPtr InDst)
: Src(InSrc)
, Dst(InDst)
{
audio_ensure(InSrc->FindSection(Desc));
FDecodedFormatInfo Info{ Desc.NumChannels, Desc.NumFramesPerSec, EBitRepresentation::Int16_Interleaved };
Reqs = Dst->GetRequirements(Info);
ResidualBuffer.SetNum(Reqs.NumSampleFramesWanted * Desc.NumChannels);
}
Audio::IDecoder::FDecodeReturn FBackCompat::Decode(bool bLoop)
{
int32 NumFramesRemaining = Reqs.NumSampleFramesWanted;
FBackCompatInput& BackCompatSrc = static_cast<FBackCompatInput&>(*Src);
ICompressedAudioInfo* Info = BackCompatSrc.GetInfo();
// cache the streaming flag off the wave
// if it has changed since the last Decode() call, bail
// something has probably changed in editor
if (bIsFirstDecode)
{
bIsFirstDecode = false;
}
else
{
if (bPreviousIsStreaming != BackCompatSrc.Wave->IsStreaming())
{
return EDecodeResult::Finished;
}
}
bPreviousIsStreaming = BackCompatSrc.Wave->IsStreaming();
// prepare for decode operation
bool bFinished = false;
IDecoderOutput::FPushedAudioDetails PushedDetails(
Desc.NumFramesPerSec,
Desc.NumChannels,
FrameOffset
);
uint32 BuffSizeInBytes = ResidualBuffer.Num() * sizeof(int16);
uint32 BuffSizeInFrames = Reqs.NumSampleFramesWanted;
uint8* Buff = (uint8*)ResidualBuffer.GetData();
int32 NumBytesStreamed = 0;
while (!bFinished && NumFramesRemaining > 0)
{
if (BackCompatSrc.Wave->IsStreaming())
{
NumBytesStreamed = 0;
bFinished = Info->StreamCompressedData(Buff, bLoop, BuffSizeInBytes, NumBytesStreamed);
}
else
{
NumBytesStreamed = BuffSizeInBytes;
bFinished = Info->ReadCompressedData(Buff, bLoop, BuffSizeInBytes);
}
if (NumBytesStreamed == 0)
{
// early out so we don't hold up down stream rendering
break;
}
int32 NumSamplesStreamed = NumBytesStreamed / sizeof(int16);
int32 NumFramesStreamed = NumSamplesStreamed / Desc.NumChannels;
PushedDetails.SampleFramesStartOffset = FrameOffset;
//ResidualBuffer.SetNum(NumBytesStreamed / sizeof(int16));
Dst->PushAudio(
PushedDetails,
MakeArrayView(ResidualBuffer.GetData(), NumSamplesStreamed)
);
FrameOffset += NumFramesStreamed;
NumFramesRemaining -= FMath::Min(NumFramesStreamed, NumFramesRemaining);
BuffSizeInBytes -= NumBytesStreamed;
}
if (!bFinished)
{
return EDecodeResult::MoreDataRemaining;
}
else if (bLoop) // (bFinished is true)
{
return EDecodeResult::Looped;
}
else // (bFinished is true and we aren't looping)
{
return EDecodeResult::Finished;
}
}
PRAGMA_ENABLE_DEPRECATION_WARNINGS
}