3 Commits

Author SHA1 Message Date
Brandon Thomas 2ecfcee44d Running older project; tired of editor complaints 2021-03-06 19:03:12 -05:00
Brandon Thomas a3bb87a497 Use in conjunction w/ RuntimeFilesDownloader causes symbol redefinition
I've renamed the conflicting symbols so I can import both libraries
publicly without crazy wrapper/module hijinks.
2021-03-06 04:01:29 -05:00
Georgy Treshchev 3ff7ed6fba Global update: full working with compressed formats, pre-importing audio files and much more. Check the updated documentation. 2021-03-05 20:41:25 +01:00
3 changed files with 118 additions and 33 deletions
@@ -14,7 +14,7 @@
"IsBetaVersion": false, "IsBetaVersion": false,
"IsExperimentalVersion": false, "IsExperimentalVersion": false,
"Installed": true, "Installed": true,
"EngineVersion": "4.26.0", "EngineVersion": "4.25.0",
"Modules": [ "Modules": [
{ {
"Name": "RuntimeAudioImporter", "Name": "RuntimeAudioImporter",
@@ -11,11 +11,23 @@
#include "OpusCompressor.h" #include "OpusCompressor.h"
#include "AdvancedPCMCompressor.h" #include "AdvancedPCMCompressor.h"
#include "PreimportedSoundAsset.h"
#include "Misc/FileHelper.h"
URuntimeAudioImporterLibrary* URuntimeAudioImporterLibrary::CreateRuntimeAudioImporter() URuntimeAudioImporterLibrary* URuntimeAudioImporterLibrary::CreateRuntimeAudioImporter()
{ {
URuntimeAudioImporterLibrary* Importer = NewObject<URuntimeAudioImporterLibrary>(); URuntimeAudioImporterLibrary* Importer = NewObject<URuntimeAudioImporterLibrary>();
Importer->AddToRoot(); Importer->bUseOfAdvancedBuffersInfo = false;
return Importer;
}
URuntimeAudioImporterLibrary* URuntimeAudioImporterLibrary::CreateAdvancedRuntimeAudioImporter(
const bool UseOfAdvancedBufferInfo)
{
URuntimeAudioImporterLibrary* Importer = NewObject<URuntimeAudioImporterLibrary>();
Importer->bUseOfAdvancedBuffersInfo = UseOfAdvancedBufferInfo;
return Importer; return Importer;
} }
@@ -24,9 +36,6 @@ void URuntimeAudioImporterLibrary::ImportAudioFromFile(
{ {
if (!FPaths::FileExists(FilePath)) if (!FPaths::FileExists(FilePath))
{ {
// Trying to get a file inside packaged build
IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
OnResult_Internal(nullptr, ETranscodingStatus::AudioDoesNotExist); OnResult_Internal(nullptr, ETranscodingStatus::AudioDoesNotExist);
return; return;
} }
@@ -47,6 +56,7 @@ void URuntimeAudioImporterLibrary::ImportAudioFromFile(
ImportAudioFromBuffer(AudioBuffer, Format, BuffersDetails); ImportAudioFromBuffer(AudioBuffer, Format, BuffersDetails);
} }
void URuntimeAudioImporterLibrary::ImportAudioFromPreimportedSound(UPreimportedSoundAsset* PreimportedSoundAssetRef, void URuntimeAudioImporterLibrary::ImportAudioFromPreimportedSound(UPreimportedSoundAsset* PreimportedSoundAssetRef,
const FBuffersDetailsStruct& BuffersDetails) const FBuffersDetailsStruct& BuffersDetails)
{ {
@@ -145,7 +155,8 @@ USoundWave* URuntimeAudioImporterLibrary::DefineSoundWave()
OnProgress_Internal(45); OnProgress_Internal(45);
// Whether to fill the compressed buffer or not. If not filled, it is necessary to fill Raw (Wave) data so that the engine will automatically generate compressed data. // Whether to fill the compressed buffer or not. If not filled, it is necessary to fill Raw (Wave) data so that the engine will automatically generate compressed data.
if (BuffersDetailsInfo.CompressionFormat == ECompressionFormat::RawData) if (BuffersDetailsInfo.CompressionFormat == ECompressionFormat::RawData || (bUseOfAdvancedBuffersInfo &&
AdvancedBuffersInfo.FillRawData))
{ {
// Callback Dispatcher OnProgress // Callback Dispatcher OnProgress
OnProgress_Internal(60); OnProgress_Internal(60);
@@ -157,8 +168,11 @@ USoundWave* URuntimeAudioImporterLibrary::DefineSoundWave()
return nullptr; return nullptr;
} }
if (!bUseOfAdvancedBuffersInfo || (bUseOfAdvancedBuffersInfo && !AdvancedBuffersInfo.FillPCMData))
{
// free unneeded PCM Data // free unneeded PCM Data
FMemory::Free(TranscodingFillInfo.PCMInfo.RawPCMData); FMemory::Free(TranscodingFillInfo.PCMInfo.RawPCMData);
}
// Callback Dispatcher OnProgress // Callback Dispatcher OnProgress
OnProgress_Internal(75); OnProgress_Internal(75);
@@ -166,16 +180,18 @@ USoundWave* URuntimeAudioImporterLibrary::DefineSoundWave()
// Fill Raw (Wave) Data // Fill Raw (Wave) Data
FillRawWaveData(SoundWaveRef); FillRawWaveData(SoundWaveRef);
// Fill PCM Data if needed
if (bUseOfAdvancedBuffersInfo && AdvancedBuffersInfo.FillPCMData)
{
FillPCMData(SoundWaveRef);
}
// Callback Dispatcher OnProgress // Callback Dispatcher OnProgress
OnProgress_Internal(95); OnProgress_Internal(95);
return SoundWaveRef; return SoundWaveRef;
} }
/* We don't need to fill RawPCMData buffer since it is not used at runtime during audio playback. But in case you want to fill this buffer - uncomment the code below (you should also remove some RawPCMData cleanups in code before it is executed)
sw->RawPCMData = static_cast<uint8*>(FMemory::Malloc(sw->RawPCMDataSize));
FMemory::Memmove(sw->RawPCMData, TranscodingFillInfo.PCMInfo.RawPCMData, sw->RawPCMDataSize);
*/
// Set a new sound compression quality // Set a new sound compression quality
SoundWaveRef->CompressionQuality = BuffersDetailsInfo.SoundCompressionQuality; SoundWaveRef->CompressionQuality = BuffersDetailsInfo.SoundCompressionQuality;
@@ -186,6 +202,9 @@ USoundWave* URuntimeAudioImporterLibrary::DefineSoundWave()
// Callback Dispatcher OnProgress // Callback Dispatcher OnProgress
OnProgress_Internal(60); OnProgress_Internal(60);
if (!bUseOfAdvancedBuffersInfo || (bUseOfAdvancedBuffersInfo && AdvancedBuffersInfo.FillCompressedData &&
AdvancedBuffersInfo.CompressionFormat != ECompressionFormat::RawData))
{
// Transcode Raw PCM data to Compressed data // Transcode Raw PCM data to Compressed data
if (!TranscodePCMToCompressedData(SoundWaveRef)) if (!TranscodePCMToCompressedData(SoundWaveRef))
{ {
@@ -200,6 +219,13 @@ USoundWave* URuntimeAudioImporterLibrary::DefineSoundWave()
// Fill the compressed data // Fill the compressed data
FillCompressedData(SoundWaveRef); FillCompressedData(SoundWaveRef);
// Fill PCM Data if needed
if (bUseOfAdvancedBuffersInfo && AdvancedBuffersInfo.FillPCMData)
{
FillPCMData(SoundWaveRef);
}
}
// Callback Dispatcher OnProgress // Callback Dispatcher OnProgress
OnProgress_Internal(95); OnProgress_Internal(95);
@@ -227,6 +253,9 @@ void URuntimeAudioImporterLibrary::FillRawWaveData(USoundWave* SoundWaveRef) con
FMemory::Memmove(SoundWaveRef->RawData.Realloc(TranscodingFillInfo.WAVInfo.WaveDataSize), FMemory::Memmove(SoundWaveRef->RawData.Realloc(TranscodingFillInfo.WAVInfo.WaveDataSize),
TranscodingFillInfo.WAVInfo.WaveData, TranscodingFillInfo.WAVInfo.WaveDataSize); TranscodingFillInfo.WAVInfo.WaveData, TranscodingFillInfo.WAVInfo.WaveDataSize);
SoundWaveRef->RawData.Unlock(); SoundWaveRef->RawData.Unlock();
UE_LOG(LogTemp, Warning, TEXT("RawData has been filled successfully, Raw data size: %d"),
TranscodingFillInfo.WAVInfo.WaveDataSize);
} }
void URuntimeAudioImporterLibrary::FillCompressedData(USoundWave* SoundWaveRef) void URuntimeAudioImporterLibrary::FillCompressedData(USoundWave* SoundWaveRef)
@@ -247,6 +276,18 @@ void URuntimeAudioImporterLibrary::FillCompressedData(USoundWave* SoundWaveRef)
CompressedBulkData->Unlock(); CompressedBulkData->Unlock();
SoundWaveRef->SetPrecacheState(ESoundWavePrecacheState::Done); SoundWaveRef->SetPrecacheState(ESoundWavePrecacheState::Done);
UE_LOG(LogTemp, Warning, TEXT("Compressed data has been filled successfully, Cmpressed data size: %d"),
TranscodingFillInfo.CompressedInfo.CompressedFormatData.Num());
}
void URuntimeAudioImporterLibrary::FillPCMData(USoundWave* SoundWaveRef)
{
SoundWaveRef->RawPCMData = static_cast<uint8*>(FMemory::Malloc(SoundWaveRef->RawPCMDataSize));
FMemory::Memmove(SoundWaveRef->RawPCMData, TranscodingFillInfo.PCMInfo.RawPCMData,
SoundWaveRef->RawPCMDataSize);
UE_LOG(LogTemp, Warning, TEXT("PCM Data has been filled successfully, PCMData size: %d"),
TranscodingFillInfo.PCMInfo.RawPCMDataSize);
} }
bool URuntimeAudioImporterLibrary::TranscodePCMToCompressedData(USoundWave* SoundWaveToGetData) bool URuntimeAudioImporterLibrary::TranscodePCMToCompressedData(USoundWave* SoundWaveToGetData)
@@ -258,6 +299,11 @@ bool URuntimeAudioImporterLibrary::TranscodePCMToCompressedData(USoundWave* Soun
// Sound quality information for compression purposes // Sound quality information for compression purposes
FSoundQualityInfo SoundQualityInfo = GenerateSoundQualityInfo(SoundWaveToGetData); FSoundQualityInfo SoundQualityInfo = GenerateSoundQualityInfo(SoundWaveToGetData);
if (bUseOfAdvancedBuffersInfo)
{
BuffersDetailsInfo.CompressionFormat = AdvancedBuffersInfo.CompressionFormat;
}
switch (BuffersDetailsInfo.CompressionFormat) switch (BuffersDetailsInfo.CompressionFormat)
{ {
case OggVorbis: case OggVorbis:
@@ -315,9 +361,12 @@ bool URuntimeAudioImporterLibrary::TranscodePCMToCompressedData(USoundWave* Soun
} }
} }
// When the compressed data is generated, RawPCMData is no longer needed. if (!bUseOfAdvancedBuffersInfo || (bUseOfAdvancedBuffersInfo && !AdvancedBuffersInfo.FillPCMData))
{
// When the compressed data is generated, RawPCMData is no longer needed
RawPCMArray.Empty(); RawPCMArray.Empty();
FMemory::Free(TranscodingFillInfo.PCMInfo.RawPCMData); FMemory::Free(TranscodingFillInfo.PCMInfo.RawPCMData);
}
// Callback Dispatcher OnProgress // Callback Dispatcher OnProgress
OnProgress_Internal(85); OnProgress_Internal(85);
@@ -5,8 +5,6 @@
#include "Sound/SoundWave.h" #include "Sound/SoundWave.h"
#include "Async/Async.h" #include "Async/Async.h"
#include "PreimportedSoundAsset.h"
#include "RuntimeAudioImporterLibrary.generated.h" #include "RuntimeAudioImporterLibrary.generated.h"
/** Possible audio importing results */ /** Possible audio importing results */
@@ -79,7 +77,7 @@ enum ECompressionFormat
}; };
/** Information about which buffers to fill */ /** Information about which buffers to fill */
USTRUCT(BlueprintType) USTRUCT(BlueprintType, Category = "RuntimeAudioImporter")
struct FBuffersDetailsStruct struct FBuffersDetailsStruct
{ {
GENERATED_BODY() GENERATED_BODY()
@@ -155,15 +153,34 @@ struct FTranscodingFillStruct
FCompressedStruct CompressedInfo; FCompressedStruct CompressedInfo;
}; };
/** Advanced CPP only structure which contains information about which buffers to fill */
struct FAdvancedBuffersStruct
{
/** Needed compression format. Do not select RawData here! If you want to fill Raw (Wav) Data, check the "FillRawData" parameter */
TEnumAsByte<ECompressionFormat> CompressionFormat;
/** Whether to fill the compressed data or not */
bool FillCompressedData = false;
/** Whether to fill PCM Data or not */
bool FillPCMData = false;
/** Whether to fill Raw (Wav) data */
bool FillRawData = false;
};
// Forward declaration of the FSoundQualityInfo structure // Forward declaration of the FSoundQualityInfo structure
struct FSoundQualityInfo; struct FSoundQualityInfo;
// Forward declaration of the UPreimportedSoundAsset class
class UPreimportedSoundAsset;
/** /**
* Declare delegate which will be called during the transcoding process * Declare delegate which will be called during the transcoding process
* *
* @param Percentage Percentage of importing completed (0-100%) * @param Percentage Percentage of importing completed (0-100%)
*/ */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnProgress, const int32, Percentage); DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAudioProgress, const int32, Percentage);
/** /**
* Declare a delegate that will be called on the transcoding result * Declare a delegate that will be called on the transcoding result
@@ -172,7 +189,7 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnProgress, const int32, Percentage
* @param ReadySoundWave Ready SoundWave object reference * @param ReadySoundWave Ready SoundWave object reference
* @param Status TranscodingStatus Enum in case an error occurs * @param Status TranscodingStatus Enum in case an error occurs
*/ */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnResult, class URuntimeAudioImporterLibrary*, DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnAudioResult, class URuntimeAudioImporterLibrary*,
RuntimeAudioImporterObjectRef, RuntimeAudioImporterObjectRef,
const USoundWave*, SoundWaveRef, const USoundWave*, SoundWaveRef,
const TEnumAsByte < ETranscodingStatus >&, Status); const TEnumAsByte < ETranscodingStatus >&, Status);
@@ -189,11 +206,11 @@ public:
/** Bind to know when the transcoding is on progress */ /** Bind to know when the transcoding is on progress */
UPROPERTY(BlueprintAssignable, Category = "RuntimeAudioImporter") UPROPERTY(BlueprintAssignable, Category = "RuntimeAudioImporter")
FOnProgress OnProgress; FOnAudioProgress OnProgress;
/** Bind to know when the transcoding is complete (even if it fails) */ /** Bind to know when the transcoding is complete (even if it fails) */
UPROPERTY(BlueprintAssignable, Category = "RuntimeAudioImporter") UPROPERTY(BlueprintAssignable, Category = "RuntimeAudioImporter")
FOnResult OnResult; FOnAudioResult OnResult;
/** Transcoding fill info. CPP use only */ /** Transcoding fill info. CPP use only */
FTranscodingFillStruct TranscodingFillInfo = FTranscodingFillStruct(); FTranscodingFillStruct TranscodingFillInfo = FTranscodingFillStruct();
@@ -201,6 +218,10 @@ public:
/** Buffers details info. CPP use only */ /** Buffers details info. CPP use only */
FBuffersDetailsStruct BuffersDetailsInfo = FBuffersDetailsStruct(); FBuffersDetailsStruct BuffersDetailsInfo = FBuffersDetailsStruct();
/** Advanced buffer details info. CPP use only (even as an input parameter) */
FAdvancedBuffersStruct AdvancedBuffersInfo = FAdvancedBuffersStruct();
bool bUseOfAdvancedBuffersInfo = false;
/** /**
* Instantiates a RuntimeAudioImporter object * Instantiates a RuntimeAudioImporter object
* *
@@ -211,6 +232,14 @@ public:
"RuntimeAudioImporter") "RuntimeAudioImporter")
static URuntimeAudioImporterLibrary* CreateRuntimeAudioImporter(); static URuntimeAudioImporterLibrary* CreateRuntimeAudioImporter();
/**
* If you want to select a separate formats to fill (using of "FAdvancedBuffersStruct"), then use this method in CPP
*
* @param UseOfAdvancedBufferInfo Whether to use the advanced buffer info or not
*/
UFUNCTION()
static URuntimeAudioImporterLibrary* CreateAdvancedRuntimeAudioImporter(const bool UseOfAdvancedBufferInfo);
/** /**
* Transcode audio file to SoundWave object * Transcode audio file to SoundWave object
* *
@@ -296,6 +325,13 @@ private:
*/ */
void FillCompressedData(USoundWave* SoundWaveRef); void FillCompressedData(USoundWave* SoundWaveRef);
/**
* Fill SoundWave PCM data buffer
*
* @param SoundWaveRef SoundWave object reference
*/
void FillPCMData(USoundWave* SoundWaveRef);
/** /**
* Transcode Audio from PCM to 16-bit WAV data * Transcode Audio from PCM to 16-bit WAV data
* *