void USoundWave::PostLoad() { Super::PostLoad(); if (GetOutermost()->HasAnyPackageFlags(PKG_ReloadingForCooker)) { return; } // Compress to whatever formats the active target platforms want // static here as an optimization ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); if (TPM) { const TArray<ITargetPlatform*>& Platforms = TPM->GetActiveTargetPlatforms(); for (int32 Index = 0; Index < Platforms.Num(); Index++) { GetCompressedData(Platforms[Index]->GetWaveFormat(this)); } } // We don't precache default objects and we don't precache in the Editor as the latter will // most likely cause us to run out of memory. if (!GIsEditor && !IsTemplate( RF_ClassDefaultObject ) && GEngine) { FAudioDevice* AudioDevice = GEngine->GetMainAudioDevice(); if (AudioDevice && AudioDevice->AreStartupSoundsPreCached()) { // Upload the data to the hardware, but only if we've precached startup sounds already AudioDevice->Precache(this); } // remove bulk data if no AudioDevice is used and no sounds were initialized else if(IsRunningGame()) { RawData.RemoveBulkData(); } } // Only add this streaming sound if we're not a dedicated server or if there is an audio device manager if (IsStreaming() && !IsRunningDedicatedServer() && GEngine && GEngine->GetAudioDeviceManager()) { #if WITH_EDITORONLY_DATA FinishCachePlatformData(); #endif // #if WITH_EDITORONLY_DATA IStreamingManager::Get().GetAudioStreamingManager().AddStreamingSoundWave(this); } #if WITH_EDITORONLY_DATA if (!SourceFilePath_DEPRECATED.IsEmpty() && AssetImportData) { FAssetImportInfo Info; Info.Insert(FAssetImportInfo::FSourceFile(SourceFilePath_DEPRECATED)); AssetImportData->SourceData = MoveTemp(Info); } #endif // #if WITH_EDITORONLY_DATA INC_FLOAT_STAT_BY( STAT_AudioBufferTime, Duration ); INC_FLOAT_STAT_BY( STAT_AudioBufferTimeChannels, NumChannels * Duration ); }
const TArray<FName>& GetTargetShaderFormats() { static bool bInit = false; static TArray<FName> Results; #if WITH_ENGINE if (!bInit) { bInit = true; ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); if (!TPM || TPM->RestrictFormatsToRuntimeOnly()) { // for now a runtime format and a cook format are very different, we don't put any formats here } else { const TArray<ITargetPlatform*>& Platforms = TPM->GetActiveTargetPlatforms(); for (int32 Index = 0; Index < Platforms.Num(); Index++) { Platforms[Index]->GetAllTargetedShaderFormats(Results); } } } #endif // WITH_ENGINE return Results; }
/** * Computes the derived data key suffix for a SoundWave's Streamed Audio. * @param SoundWave - The SoundWave for which to compute the derived data key. * @param AudioFormatName - The audio format we're creating the key for * @param OutKeySuffix - The derived data key suffix. */ static void GetStreamedAudioDerivedDataKeySuffix( const USoundWave& SoundWave, FName AudioFormatName, FString& OutKeySuffix ) { uint16 Version = 0; // get the version for this soundwave's platform format ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); if (TPM) { const IAudioFormat* AudioFormat = TPM->FindAudioFormat(AudioFormatName); if (AudioFormat) { Version = AudioFormat->GetVersion(AudioFormatName); } } // build the key OutKeySuffix = FString::Printf(TEXT("%s_%d_%s"), *AudioFormatName.ToString(), Version, *SoundWave.CompressedDataGuid.ToString() ); }
/** * Gets Wave format for a SoundWave on the current running platform * @param SoundWave - The SoundWave to get format for. */ static FName GetWaveFormatForRunningPlatform(USoundWave& SoundWave) { // Compress to whatever format the active target platform wants ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); if (TPM) { ITargetPlatform* CurrentPlatform = NULL; const TArray<ITargetPlatform*>& Platforms = TPM->GetActiveTargetPlatforms(); check(Platforms.Num()); CurrentPlatform = Platforms[0]; for (int32 Index = 1; Index < Platforms.Num(); Index++) { if (Platforms[Index]->IsRunningPlatform()) { CurrentPlatform = Platforms[Index]; break; } } check(CurrentPlatform != NULL); return CurrentPlatform->GetWaveFormat(&SoundWave); } return NAME_None; }
FDerivedAudioDataCompressor::FDerivedAudioDataCompressor(USoundWave* InSoundNode, FName InFormat) : SoundNode(InSoundNode) , Format(InFormat) , Compressor(NULL) { ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); if (TPM) { Compressor = TPM->FindAudioFormat(InFormat); } }
SDeviceOutputLog::~SDeviceOutputLog() { ITargetPlatformManagerModule* Module = FModuleManager::GetModulePtr<ITargetPlatformManagerModule>("TargetPlatform"); if (Module) { TArray<ITargetPlatform*> Platforms = Module->GetTargetPlatforms(); for (ITargetPlatform* Platform : Platforms) { Platform->OnDeviceDiscovered().RemoveAll(this); Platform->OnDeviceLost().RemoveAll(this); } } }
void USoundWave::PostLoad() { Super::PostLoad(); if (GetOutermost()->PackageFlags & PKG_ReloadingForCooker) { return; } // Compress to whatever formats the active target platforms want // static here as an optimization ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); if (TPM) { const TArray<ITargetPlatform*>& Platforms = TPM->GetActiveTargetPlatforms(); for (int32 Index = 0; Index < Platforms.Num(); Index++) { GetCompressedData(Platforms[Index]->GetWaveFormat(this)); } } // We don't precache default objects and we don't precache in the Editor as the latter will // most likely cause us to run out of memory. if( !GIsEditor && !IsTemplate( RF_ClassDefaultObject ) && GEngine ) { FAudioDevice* AudioDevice = GEngine->GetAudioDevice(); if( AudioDevice && AudioDevice->bStartupSoundsPreCached) { // Upload the data to the hardware, but only if we've precached startup sounds already AudioDevice->Precache( this ); } // remove bulk data if no AudioDevice is used and no sounds were initialized else if( IsRunningGame() ) { RawData.RemoveBulkData(); } } if (IsStreaming()) { #if WITH_EDITORONLY_DATA FinishCachePlatformData(); #endif // #if WITH_EDITORONLY_DATA IStreamingManager::Get().GetAudioStreamingManager().AddStreamingSoundWave(this); } INC_FLOAT_STAT_BY( STAT_AudioBufferTime, Duration ); INC_FLOAT_STAT_BY( STAT_AudioBufferTimeChannels, NumChannels * Duration ); }
void USoundWave::BeginCachePlatformData() { CachePlatformData(true); #if WITH_EDITOR // enable caching in postload for derived data cache commandlet and cook by the book ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); if (TPM && (TPM->RestrictFormatsToRuntimeOnly() == false)) { TArray<ITargetPlatform*> Platforms = TPM->GetActiveTargetPlatforms(); // Cache for all the audio formats that the cooking target requires for (int32 FormatIndex = 0; FormatIndex < Platforms.Num(); FormatIndex++) { BeginCacheForCookedPlatformData(Platforms[FormatIndex]); } } #endif }
USoundWave* ImportSoundWave(const FString& InSoundWavePackageName, const FString& InSoundWaveAssetName, const FString& InWavFilename) const { // Find or create the package to host the sound wave UPackage* const SoundWavePackage = CreatePackage(nullptr, *InSoundWavePackageName); if (!SoundWavePackage) { FMessageLog("Import").Error(FText::Format(LOCTEXT("SoundWavePackageError", "Failed to create a sound wave package '{0}'."), FText::FromString(InSoundWavePackageName))); return nullptr; } // Make sure the destination package is loaded SoundWavePackage->FullyLoad(); // We set the correct options in the constructor, so run the import silently USoundFactory* SoundWaveFactory = NewObject<USoundFactory>(); SoundWaveFactory->SuppressImportOverwriteDialog(); // Perform the actual import USoundWave* const SoundWave = ImportObject<USoundWave>(SoundWavePackage, *InSoundWaveAssetName, RF_Public | RF_Standalone, *InWavFilename, nullptr, SoundWaveFactory); if (!SoundWave) { FMessageLog("Import").Error(FText::Format(LOCTEXT("SoundWaveImportError", "Failed to import the sound wave asset '{0}.{1}' from '{2}'"), FText::FromString(InSoundWavePackageName), FText::FromString(InSoundWaveAssetName), FText::FromString(InWavFilename))); return nullptr; } // Compress to whatever formats the active target platforms want prior to saving the asset { ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); if (TPM) { const TArray<ITargetPlatform*>& Platforms = TPM->GetActiveTargetPlatforms(); for (ITargetPlatform* Platform : Platforms) { SoundWave->GetCompressedData(Platform->GetWaveFormat(SoundWave)); } } } FAssetRegistryModule& AssetRegistry = FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>("AssetRegistry"); AssetRegistry.AssetCreated(SoundWave); return SoundWave; }
bool FDeployCommand::Run( ) { bool bDeployed = false; // get the target device FString DevicesList; FParse::Value(FCommandLine::Get(), TEXT("-DEVICE="), DevicesList); // get the file manifest FString Manifest; FParse::Value(FCommandLine::Get(), TEXT("-MANIFEST="), Manifest); FString SourceDir; FParse::Value(FCommandLine::Get(), TEXT("-SOURCEDIR="), SourceDir); ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); if (!TPM) { return false; } // Initialize the messaging subsystem so we can do device discovery. FModuleManager::Get().LoadModuleChecked("Messaging"); // load plug-in modules // @todo: allow for better plug-in support in standalone Slate apps IPluginManager::Get().LoadModulesForEnabledPlugins(ELoadingPhase::PreDefault); while (!DevicesList.IsEmpty()) { FString Device; if (!DevicesList.Split(TEXT("+"), &Device, &DevicesList)) { Device = DevicesList; DevicesList.Empty(); } double DeltaTime = 0.0; double LastTime = FPlatformTime::Seconds(); // We track the message sent time because we have to keep updating the loop until the message is *actually sent*. (ie all packets queued, sent, buffer flushed, etc.) double MessageSentTime = 0.0; bool bMessageSent = false; while (!GIsRequestingExit && ((MessageSentTime > LastTime + 1.0) || (MessageSentTime <= 0.1))) { FTaskGraphInterface::Get().ProcessThreadUntilIdle(ENamedThreads::GameThread); FTicker::GetCoreTicker().Tick(DeltaTime); FPlatformProcess::Sleep(0); DeltaTime = FPlatformTime::Seconds() - LastTime; LastTime = FPlatformTime::Seconds(); if (!bMessageSent) { const TArray<ITargetPlatform*>& Platforms = TPM->GetActiveTargetPlatforms(); FString Platform; FString DeviceName; Device.Split(TEXT("@"), &Platform, &DeviceName); FTargetDeviceId DeviceId(Platform, DeviceName); ITargetDevicePtr TargetDevice; for (int32 Index = 0; Index < Platforms.Num(); ++Index) { TargetDevice = Platforms[Index]->GetDevice(DeviceId); if (TargetDevice.IsValid()) { FString OutId; if (Platforms[Index]->PackageBuild(SourceDir)) { if (TargetDevice->Deploy(SourceDir, OutId)) { bDeployed = true; } MessageSentTime = LastTime; bMessageSent = true; } else { MessageSentTime = LastTime; bMessageSent = true; } } } } } } return bDeployed; }
void RecompileShadersForRemote( const FString& PlatformName, EShaderPlatform ShaderPlatformToCompile, const FString& OutputDirectory, const TArray<FString>& MaterialsToLoad, const TArray<uint8>& SerializedShaderResources, TArray<uint8>* MeshMaterialMaps, TArray<FString>* ModifiedFiles, bool bCompileChangedShaders ) { // figure out what shader platforms to recompile ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); ITargetPlatform* TargetPlatform = TPM->FindTargetPlatform(PlatformName); if (TargetPlatform == NULL) { UE_LOG(LogShaders, Display, TEXT("Failed to find target platform module for %s"), *PlatformName); return; } TArray<FName> DesiredShaderFormats; TargetPlatform->GetAllTargetedShaderFormats(DesiredShaderFormats); UE_LOG(LogShaders, Display, TEXT("Loading %d materials..."), MaterialsToLoad.Num()); // make sure all materials the client has loaded will be processed TArray<UMaterialInterface*> MaterialsToCompile; for (int32 Index = 0; Index < MaterialsToLoad.Num(); Index++) { UE_LOG(LogShaders, Display, TEXT(" --> %s"), *MaterialsToLoad[Index]); MaterialsToCompile.Add(LoadObject<UMaterialInterface>(NULL, *MaterialsToLoad[Index])); } UE_LOG(LogShaders, Display, TEXT(" Done!")) // figure out which shaders are out of date TArray<FShaderType*> OutdatedShaderTypes; TArray<const FVertexFactoryType*> OutdatedFactoryTypes; // Pick up new changes to shader files FlushShaderFileCache(); if( bCompileChangedShaders ) { FShaderType::GetOutdatedTypes( OutdatedShaderTypes, OutdatedFactoryTypes ); UE_LOG( LogShaders, Display, TEXT( "We found %d out of date shader types, and %d out of date VF types!" ), OutdatedShaderTypes.Num(), OutdatedFactoryTypes.Num() ); } { for (int32 FormatIndex = 0; FormatIndex < DesiredShaderFormats.Num(); FormatIndex++) { // get the shader platform enum const EShaderPlatform ShaderPlatform = ShaderFormatToLegacyShaderPlatform(DesiredShaderFormats[FormatIndex]); // Only compile for the desired platform if requested if (ShaderPlatform == ShaderPlatformToCompile || ShaderPlatformToCompile == SP_NumPlatforms) { if( bCompileChangedShaders ) { // Kick off global shader recompiles BeginRecompileGlobalShaders( OutdatedShaderTypes, ShaderPlatform ); // Block on global shaders FinishRecompileGlobalShaders(); } // we only want to actually compile mesh shaders if a client directly requested it, and there's actually some work to do if (MeshMaterialMaps != NULL && (OutdatedShaderTypes.Num() || OutdatedFactoryTypes.Num() || bCompileChangedShaders == false)) { TMap<FString, TArray<TRefCountPtr<FMaterialShaderMap> > > CompiledShaderMaps; UMaterial::CompileMaterialsForRemoteRecompile(MaterialsToCompile, ShaderPlatform, CompiledShaderMaps); // write the shader compilation info to memory, converting fnames to strings FMemoryWriter MemWriter(*MeshMaterialMaps, true); FNameAsStringProxyArchive Ar(MemWriter); // pull the serialized resource ids into an array of resources TArray<FShaderResourceId> ClientResourceIds; FMemoryReader MemReader(SerializedShaderResources, true); MemReader << ClientResourceIds; // save out the shader map to the byte array FMaterialShaderMap::SaveForRemoteRecompile(Ar, CompiledShaderMaps, ClientResourceIds); } // save it out so the client can get it (and it's up to date next time) FString GlobalShaderFilename = SaveGlobalShaderFile(ShaderPlatform, OutputDirectory); // add this to the list of files to tell the other end about if (ModifiedFiles) { // need to put it in non-sandbox terms FString SandboxPath(GlobalShaderFilename); check(SandboxPath.StartsWith(OutputDirectory)); SandboxPath.ReplaceInline(*OutputDirectory, TEXT("../../../")); FPaths::NormalizeFilename(SandboxPath); ModifiedFiles->Add(SandboxPath); } } } } }
void UBodySetup::PostLoad() { Super::PostLoad(); // Our owner needs to be post-loaded before us else they may not have loaded // their data yet. UObject* Outer = GetOuter(); if (Outer) { Outer->ConditionalPostLoad(); } if ( GetLinkerUE4Version() < VER_UE4_BUILD_SCALE_VECTOR ) { BuildScale3D = FVector( BuildScale_DEPRECATED ); } DefaultInstance.FixupData(this); if ( GetLinkerUE4Version() < VER_UE4_REFACTOR_PHYSICS_BLENDING ) { if ( bAlwaysFullAnimWeight_DEPRECATED ) { PhysicsType = PhysType_Simulated; } else if ( DefaultInstance.bSimulatePhysics == false ) { PhysicsType = PhysType_Kinematic; } else { PhysicsType = PhysType_Default; } } if ( GetLinkerUE4Version() < VER_UE4_BODYSETUP_COLLISION_CONVERSION ) { if ( DefaultInstance.GetCollisionEnabled() == ECollisionEnabled::NoCollision ) { CollisionReponse = EBodyCollisionResponse::BodyCollision_Disabled; } } // Compress to whatever formats the active target platforms want ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); if (TPM) { const TArray<ITargetPlatform*>& Platforms = TPM->GetActiveTargetPlatforms(); for (int32 Index = 0; Index < Platforms.Num(); Index++) { GetCookedData(Platforms[Index]->GetPhysicsFormat(this)); } } // make sure that we load the physX data while the linker's loader is still open CreatePhysicsMeshes(); // fix up invalid transform to use identity // this can be here because BodySetup isn't blueprintable if ( GetLinkerUE4Version() < VER_UE4_FIXUP_BODYSETUP_INVALID_CONVEX_TRANSFORM ) { for (int32 i=0; i<AggGeom.ConvexElems.Num(); ++i) { if ( AggGeom.ConvexElems[i].GetTransform().IsValid() == false ) { AggGeom.ConvexElems[i].SetTransform(FTransform::Identity); } } } }
int32 UDerivedDataCacheCommandlet::Main( const FString& Params ) { TArray<FString> Tokens, Switches; ParseCommandLine(*Params, Tokens, Switches); bool bFillCache = Switches.Contains("FILL"); // do the equivalent of a "loadpackage -all" to fill the DDC bool bStartupOnly = Switches.Contains("STARTUPONLY"); // regardless of any other flags, do not iterate packages // Subsets for parallel processing uint32 SubsetMod = 0; uint32 SubsetTarget = MAX_uint32; FParse::Value(*Params, TEXT("SubsetMod="), SubsetMod); FParse::Value(*Params, TEXT("SubsetTarget="), SubsetTarget); bool bDoSubset = SubsetMod > 0 && SubsetTarget < SubsetMod; double FindProcessedPackagesTime = 0.0; double GCTime = 0.0; if (!bStartupOnly && bFillCache) { FCoreDelegates::PackageCreatedForLoad.AddUObject(this, &UDerivedDataCacheCommandlet::MaybeMarkPackageAsAlreadyLoaded); TArray<FString> FilesInPath; Tokens.Empty(2); Tokens.Add(FString("*") + FPackageName::GetAssetPackageExtension()); Tokens.Add(FString("*") + FPackageName::GetMapPackageExtension()); uint8 PackageFilter = NORMALIZE_DefaultFlags; if ( Switches.Contains(TEXT("MAPSONLY")) ) { PackageFilter |= NORMALIZE_ExcludeContentPackages; } if ( !Switches.Contains(TEXT("DEV")) ) { PackageFilter |= NORMALIZE_ExcludeDeveloperPackages; } // assume the first token is the map wildcard/pathname TArray<FString> Unused; for ( int32 TokenIndex = 0; TokenIndex < Tokens.Num(); TokenIndex++ ) { TArray<FString> TokenFiles; if ( !NormalizePackageNames( Unused, TokenFiles, Tokens[TokenIndex], PackageFilter) ) { UE_LOG(LogDerivedDataCacheCommandlet, Display, TEXT("No packages found for parameter %i: '%s'"), TokenIndex, *Tokens[TokenIndex]); continue; } FilesInPath += TokenFiles; } if ( FilesInPath.Num() == 0 ) { UE_LOG(LogDerivedDataCacheCommandlet, Warning, TEXT("No files found.")); } ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); const TArray<ITargetPlatform*>& Platforms = TPM->GetActiveTargetPlatforms(); for (int32 Index = 0; Index < Platforms.Num(); Index++) { TArray<FName> DesiredShaderFormats; Platforms[Index]->GetShaderFormats(DesiredShaderFormats); for (int32 FormatIndex = 0; FormatIndex < DesiredShaderFormats.Num(); FormatIndex++) { const EShaderPlatform TargetPlatform = ShaderFormatToLegacyShaderPlatform(DesiredShaderFormats[FormatIndex]); // Kick off global shader compiles for each target platform GetGlobalShaderMap(TargetPlatform); } } const int32 GCInterval = 100; int32 NumProcessedSinceLastGC = GCInterval; bool bLastPackageWasMap = true; // 'true' is to prime the ProcessedPackages list TSet<FString> ProcessedPackages; UE_LOG(LogDerivedDataCacheCommandlet, Display, TEXT("%d packages to load..."), FilesInPath.Num()); for( int32 FileIndex = FilesInPath.Num() - 1; ; FileIndex-- ) { // Keep track of which packages have already been processed along with the map. if (NumProcessedSinceLastGC >= GCInterval || bLastPackageWasMap || FileIndex == FilesInPath.Num() - 1) { const double FindProcessedPackagesStartTime = FPlatformTime::Seconds(); TArray<UObject *> ObjectsInOuter; GetObjectsWithOuter(NULL, ObjectsInOuter, false); for( int32 Index = 0; Index < ObjectsInOuter.Num(); Index++ ) { UPackage* Pkg = Cast<UPackage>(ObjectsInOuter[Index]); if (!Pkg) { continue; } FString Filename; if (FPackageName::DoesPackageExist(Pkg->GetName(), NULL, &Filename)) { if (!ProcessedPackages.Contains(Filename)) { ProcessedPackages.Add(Filename); PackagesToNotReload.Add(Pkg->GetName()); Pkg->PackageFlags |= PKG_ReloadingForCooker; { TArray<UObject *> ObjectsInPackage; GetObjectsWithOuter(Pkg, ObjectsInPackage, true); for( int32 IndexPackage = 0; IndexPackage < ObjectsInPackage.Num(); IndexPackage++ ) { ObjectsInPackage[IndexPackage]->CookerWillNeverCookAgain(); } } } } } FindProcessedPackagesTime += FPlatformTime::Seconds() - FindProcessedPackagesStartTime; } if (NumProcessedSinceLastGC >= GCInterval || FileIndex < 0 || bLastPackageWasMap) { const double StartGCTime = FPlatformTime::Seconds(); if (NumProcessedSinceLastGC >= GCInterval || FileIndex < 0) { UE_LOG(LogDerivedDataCacheCommandlet, Display, TEXT("GC (Full)...")); CollectGarbage( RF_Native ); NumProcessedSinceLastGC = 0; } else { UE_LOG(LogDerivedDataCacheCommandlet, Display, TEXT("GC...")); CollectGarbage( RF_Native | RF_Standalone ); } GCTime += FPlatformTime::Seconds() - StartGCTime; bLastPackageWasMap = false; } if (FileIndex < 0) { break; } const FString& Filename = FilesInPath[FileIndex]; if (ProcessedPackages.Contains(Filename)) { continue; } if (bDoSubset) { const FString& PackageName = FPackageName::PackageFromPath(*Filename); if (FCrc::StrCrc_DEPRECATED(*PackageName.ToUpper()) % SubsetMod != SubsetTarget) { continue; } } UE_LOG(LogDerivedDataCacheCommandlet, Display, TEXT("Loading (%d) %s"), FilesInPath.Num() - FileIndex, *Filename ); UPackage* Package = LoadPackage( NULL, *Filename, LOAD_None ); if( Package == NULL ) { UE_LOG(LogDerivedDataCacheCommandlet, Error, TEXT("Error loading %s!"), *Filename ); } else { bLastPackageWasMap = Package->ContainsMap(); NumProcessedSinceLastGC++; } } } IConsoleManager::Get().ProcessUserConsoleInput(TEXT("Tex.DerivedDataTimings"), *GWarn, NULL); UE_LOG(LogDerivedDataCacheCommandlet, Display, TEXT("Waiting for shaders to finish.")); GShaderCompilingManager->FinishAllCompilation(); UE_LOG(LogDerivedDataCacheCommandlet, Display, TEXT("Done waiting for shaders to finish.")); GetDerivedDataCacheRef().WaitForQuiescence(true); UE_LOG(LogDerivedDataCacheCommandlet, Display, TEXT("%.2lfs spent looking for processed packages, %.2lfs spent on GC."), FindProcessedPackagesTime, GCTime); return 0; }
/** Build the streamed audio. This function is safe to call from any thread. */ void BuildStreamedAudio() { GetStreamedAudioDerivedDataKeySuffix(SoundWave, AudioFormatName, KeySuffix); DerivedData->Chunks.Empty(); ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); const IAudioFormat* AudioFormat = NULL; if (TPM) { AudioFormat = TPM->FindAudioFormat(AudioFormatName); } if (AudioFormat) { DerivedData->AudioFormat = AudioFormatName; FByteBulkData* CompressedData = SoundWave.GetCompressedData(AudioFormatName); TArray<uint8> CompressedBuffer; CompressedBuffer.Empty(CompressedData->GetBulkDataSize()); CompressedBuffer.AddUninitialized(CompressedData->GetBulkDataSize()); void* BufferData = CompressedBuffer.GetData(); CompressedData->GetCopy(&BufferData, false); TArray<TArray<uint8>> ChunkBuffers; if (AudioFormat->SplitDataForStreaming(CompressedBuffer, ChunkBuffers)) { for (int32 ChunkIndex = 0; ChunkIndex < ChunkBuffers.Num(); ++ChunkIndex) { FStreamedAudioChunk* NewChunk = new(DerivedData->Chunks) FStreamedAudioChunk(); NewChunk->DataSize = ChunkBuffers[ChunkIndex].Num(); NewChunk->BulkData.Lock(LOCK_READ_WRITE); void* NewChunkData = NewChunk->BulkData.Realloc(ChunkBuffers[ChunkIndex].Num()); FMemory::Memcpy(NewChunkData, ChunkBuffers[ChunkIndex].GetData(), ChunkBuffers[ChunkIndex].Num()); NewChunk->BulkData.Unlock(); } } else { // Could not split so copy compressed data into a single chunk FStreamedAudioChunk* NewChunk = new(DerivedData->Chunks) FStreamedAudioChunk(); NewChunk->DataSize = CompressedBuffer.Num(); NewChunk->BulkData.Lock(LOCK_READ_WRITE); void* NewChunkData = NewChunk->BulkData.Realloc(CompressedBuffer.Num()); FMemory::Memcpy(NewChunkData, CompressedBuffer.GetData(), CompressedBuffer.Num()); NewChunk->BulkData.Unlock(); } DerivedData->NumChunks = DerivedData->Chunks.Num(); // Store it in the cache. PutDerivedDataInCache(DerivedData, KeySuffix); } if (DerivedData->Chunks.Num()) { bool bInlineChunks = (CacheFlags & EStreamedAudioCacheFlags::InlineChunks) != 0; bSucceeded = !bInlineChunks || DerivedData->TryInlineChunkData(); } else { UE_LOG(LogAudio, Warning, TEXT("Failed to build %s derived data for %s"), *AudioFormatName.GetPlainNameString(), *SoundWave.GetPathName() ); } }