Files
2025-05-18 13:04:45 +08:00

79 lines
2.2 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "FileDecoder.h"
#include "HAL/PlatformFileManager.h"
#include "DSP/FloatArrayMath.h"
FAudioFileReader::FAudioFileReader(const FString& InPath)
{
QualityInfo = { 0 };
IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
FileHandle.Reset(PlatformFile.OpenRead(*InPath));
if (FileHandle.IsValid())
{
int64 FileSize = FileHandle->Size();
CompressedFile.Reset();
CompressedFile.AddUninitialized(FileSize);
FileHandle->Read(CompressedFile.GetData(), FileSize);
Decompressor.Reset(GetNewDecompressorForFile(InPath));
if (Decompressor.IsValid())
{
Decompressor->ReadCompressedInfo(CompressedFile.GetData(), FileSize, &QualityInfo);
}
else
{
QualityInfo.NumChannels = 0;
UE_LOG(LogTemp, Error, TEXT("Invalid file extension!"));
}
}
else
{
QualityInfo.NumChannels = 0;
UE_LOG(LogTemp, Error, TEXT("Invalid file %s!"), *InPath);
}
}
void FAudioFileReader::GetFileInfo(FSoundQualityInfo& OutInfo)
{
OutInfo = QualityInfo;
}
bool FAudioFileReader::PopAudio(float* OutAudio, int32 NumSamples)
{
check(FileHandle.IsValid());
check(Decompressor.IsValid());
DecompressionBuffer.Reset();
DecompressionBuffer.AddUninitialized(NumSamples);
bool bIsFinished = Decompressor->ReadCompressedData((uint8*) DecompressionBuffer.GetData(), false, NumSamples * sizeof(Audio::DefaultUSoundWaveSampleType));
// Convert to float:
Audio::ArrayPcm16ToFloat(MakeArrayView((int16*)DecompressionBuffer.GetData(), NumSamples), MakeArrayView(OutAudio, NumSamples));
return bIsFinished;
}
ICompressedAudioInfo* FAudioFileReader::GetNewDecompressorForFile(const FString& InPath)
{
using namespace Audio;
using FMapping = TTuple<FString, FName>;
const FMapping Extensions[] =
{
{ TEXT(".opus"), NAME_OPUS },
{ TEXT(".vorbis"), NAME_OGG },
{ TEXT(".binka"), NAME_BINKA }
};
const FString LowerPath = InPath.ToLower();
if (const FMapping* Found = Algo::FindByPredicate(Extensions, [LowerPath](const auto &i) -> bool { return LowerPath.EndsWith(i.Key); }) )
{
return IAudioInfoFactoryRegistry::Get().Create(Found->Value);
}
UE_LOG(LogTemp, Error, TEXT("Unable to determin/create decompressor for '%s'"), *InPath);
return nullptr;
}