You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2898120 on 2016/03/07 by Chris.Babcock
Disable NvTimerQuery on Nexus 9 before Android 6.0 to fix slow frame updates
#jira UE-28013
#ue4
#android
Change 2898539 on 2016/03/08 by Matthew.Griffin
Merging //UE4/Dev-Build to //UE4/Release-4.11
Change 2887414 on 2016/03/01 by Ben.Marsh
Dump all the *.crash files produced while running commandlets, to make it easier to diagnose build system crashes cooking on Mac.
Change 2898788 on 2016/03/08 by Keith.Judge
Latest DX12.x integration from Microsoft. Brings XB1 up to PC level of functionality and improved perf.
#jira UEPLAT-325
Change 2898836 on 2016/03/08 by Taizyd.Korambayil
#jira UE-27990 Reimported River_Basin_02 Mesh with Adjacency Buffer
Change 2898897 on 2016/03/08 by Sean.Gribbin
#Jira UE-26550
Adding name to credits of Match 3
Change 2898938 on 2016/03/08 by Taizyd.Korambayil
#jira UE-26284 Fixed Up Some Materials and BP errors
Change 2898967 on 2016/03/08 by Benjamin.Hyder
Updating Qa_Materials map
#jira UE-24473
Change 2899032 on 2016/03/08 by Zachary.Wilson
Fixing broken assets in QA-LightsStationary and eliminating log errors. Fixing mispelling and player start height in QA-LightsStationary.
#jira UE-24473
Change 2899244 on 2016/03/08 by Peter.Sauerbrei
addition of launch images for iPad Pro
#jira UE-24793
Change 2899335 on 2016/03/08 by Richard.Hinckley
#jira UE-27356
Fixing code for VR headsets so that the camera starts inside the vehicle if the user has an active HMD. Found that the C++ templates never had HMD support, so mirroring the BP templates for that functionality. Works in my testing, but a proper QA pass should be performed.
Change 2899402 on 2016/03/08 by Michael.Schoell
Macro instance nodes now have a hard dependency to any object class or structs their pins reference.
Expanded UK2Node_MacroInstance::HasExternalDependencies to iterate over all pins and add their struct or object's class.
#jira UE-27795 - Split Pins on a referenced Macro Library will crash the editor on restart
Change 2899424 on 2016/03/08 by Dmitry.Rekman
Fix CrossCompilerTool on Linux (UE-28056).
#jira UE-28056
Change 2899445 on 2016/03/08 by Dmitry.Rekman
Fix CrossCompilerTool invocation in debug scripts.
#jira UE-28056
Change 2899488 on 2016/03/08 by Ryan.Vance
#jira UE-28000
We can't test how many views are in the view family when initializing a view. There's no guaruntee that the family is setup yet. We'll need to move this test to the calling code.
Change 2899546 on 2016/03/08 by Zachary.Wilson
Updating QA-PostProcessing to match the 4.12 Main version of the map.
#jira UE-24473
Change 2899553 on 2016/03/08 by Michael.Schoell
Reinstancer will no longer queue BPs to be saved when compiling skeleton class dependencies and will no longer process all queued BPs to save when it is complete.
#jira UE-27509 - Save on compile set to always causes a crash on compile
#jira UE-27856 - "Always" Save on Compile does not save the Blueprint
Change 2899558 on 2016/03/08 by Benjamin.Hyder
building Lighting for QA-Materials
#jira UE-24473
Change 2899597 on 2016/03/08 by Chris.Babcock
Change reporting level of audio buffer decompression type logging
#jira UE-28058
#ue4
#android
Change 2899704 on 2016/03/08 by Benjamin.Hyder
Updating Qa-Materials map
#Jira UE-24473
Change 2899736 on 2016/03/08 by Benjamin.Hyder
Updating TM-LPV map
#Jira UE-24473
Change 2899810 on 2016/03/08 by Lauren.Ridge
#jira UE-27995 UE-27987
Final UM3 UI Tweaks, + bug fix
Change 2899876 on 2016/03/08 by Peter.Sauerbrei
[CL 2913181 by Matthew Griffin in Main branch]
283 lines
8.2 KiB
C++
283 lines
8.2 KiB
C++
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "AndroidAudioDevice.h"
|
|
#include "AudioEffect.h"
|
|
#include "Engine.h"
|
|
#include "IAudioFormat.h"
|
|
#include "AudioDecompress.h"
|
|
#include "ContentStreaming.h"
|
|
|
|
/*------------------------------------------------------------------------------------
|
|
FSLESSoundBuffer.
|
|
------------------------------------------------------------------------------------*/
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param AudioDevice audio device this sound buffer is going to be attached to.
|
|
*/
|
|
FSLESSoundBuffer::FSLESSoundBuffer( FSLESAudioDevice* InAudioDevice )
|
|
: FSoundBuffer(InAudioDevice),
|
|
AudioData(NULL),
|
|
DecompressionState( NULL ),
|
|
Format(SoundFormat_Invalid)
|
|
{
|
|
|
|
}
|
|
|
|
/**
|
|
* Destructor
|
|
*
|
|
* Frees wave data and detaches itself from audio device.
|
|
*/
|
|
FSLESSoundBuffer::~FSLESSoundBuffer( void )
|
|
{
|
|
FMemory::Free( AudioData);
|
|
|
|
if( DecompressionState )
|
|
{
|
|
delete DecompressionState;
|
|
}
|
|
}
|
|
|
|
FSLESSoundBuffer* FSLESSoundBuffer::CreateQueuedBuffer( FSLESAudioDevice* AudioDevice, USoundWave* InWave )
|
|
{
|
|
// Check to see if thread has finished decompressing on the other thread
|
|
if (InWave->AudioDecompressor != nullptr)
|
|
{
|
|
InWave->AudioDecompressor->EnsureCompletion();
|
|
|
|
// Remove the decompressor
|
|
delete InWave->AudioDecompressor;
|
|
InWave->AudioDecompressor = nullptr;
|
|
}
|
|
|
|
// Always create a new buffer for real time decompressed sounds
|
|
FSLESSoundBuffer* Buffer = new FSLESSoundBuffer( AudioDevice);
|
|
|
|
// Prime the first two buffers and prepare the decompression
|
|
FSoundQualityInfo QualityInfo = { 0 };
|
|
|
|
Buffer->DecompressionState = AudioDevice->CreateCompressedAudioInfo(InWave);
|
|
|
|
// If the buffer was precached as native, the resource data will have been lost and we need to re-initialize it
|
|
if (InWave->ResourceData == nullptr)
|
|
{
|
|
InWave->InitAudioResource(AudioDevice->GetRuntimeFormat(InWave));
|
|
}
|
|
|
|
if (Buffer->DecompressionState && Buffer->DecompressionState->ReadCompressedInfo(InWave->ResourceData, InWave->ResourceSize, &QualityInfo))
|
|
{
|
|
// Clear out any dangling pointers
|
|
Buffer->AudioData = NULL;
|
|
Buffer->BufferSize = 0;
|
|
|
|
// Keep track of associated resource name.
|
|
Buffer->ResourceName = InWave->GetPathName();
|
|
Buffer->NumChannels = InWave->NumChannels;
|
|
Buffer->SampleRate = InWave->SampleRate;
|
|
|
|
//Android can't handle more than 48kHz, so turn on halfrate decoding and adjust parameters
|
|
if (Buffer->SampleRate > 48000)
|
|
{
|
|
UE_LOG(LogAndroidAudio, Log, TEXT( "Converting %s to halfrate from %d" ), *InWave->GetName(), Buffer->SampleRate );
|
|
Buffer->DecompressionState->EnableHalfRate( true);
|
|
Buffer->SampleRate = Buffer->SampleRate / 2;
|
|
InWave->SampleRate = InWave->SampleRate / 2;
|
|
uint32 SampleCount = QualityInfo.SampleDataSize / (QualityInfo.NumChannels * sizeof(uint16));
|
|
SampleCount /= 2;
|
|
InWave->RawPCMDataSize = SampleCount * QualityInfo.NumChannels * sizeof(uint16);;
|
|
}
|
|
|
|
Buffer->Format = SoundFormat_PCMRT;
|
|
}
|
|
else
|
|
{
|
|
InWave->DecompressionType = DTYPE_Invalid;
|
|
InWave->NumChannels = 0;
|
|
|
|
InWave->RemoveAudioResource();
|
|
}
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
/**
|
|
* Static function used to create an OpenSL buffer and upload decompressed ogg vorbis data to.
|
|
*
|
|
* @param InWave USoundWave to use as template and wave source
|
|
* @param AudioDevice audio device to attach created buffer to
|
|
* @return FSLESSoundBuffer pointer if buffer creation succeeded, NULL otherwise
|
|
*/
|
|
FSLESSoundBuffer* FSLESSoundBuffer::CreateNativeBuffer( FSLESAudioDevice* AudioDevice, USoundWave* InWave )
|
|
{
|
|
// Check to see if thread has finished decompressing on the other thread
|
|
if( InWave->AudioDecompressor != NULL )
|
|
{
|
|
InWave->AudioDecompressor->EnsureCompletion();
|
|
|
|
// Remove the decompressor
|
|
delete InWave->AudioDecompressor;
|
|
InWave->AudioDecompressor = NULL;
|
|
}
|
|
|
|
FSLESSoundBuffer* Buffer = NULL;
|
|
|
|
// Create new buffer.
|
|
Buffer = new FSLESSoundBuffer( AudioDevice );
|
|
|
|
Buffer->DecompressionState = AudioDevice->CreateCompressedAudioInfo(InWave);
|
|
|
|
FAudioDeviceManager* AudioDeviceManager = GEngine->GetAudioDeviceManager();
|
|
check(AudioDeviceManager != nullptr);
|
|
|
|
AudioDeviceManager->TrackResource(InWave, Buffer);
|
|
|
|
Buffer->NumChannels = InWave->NumChannels;
|
|
Buffer->SampleRate = InWave->SampleRate;
|
|
|
|
// Take ownership the PCM data
|
|
Buffer->AudioData = InWave->RawPCMData;
|
|
Buffer->BufferSize = InWave->RawPCMDataSize;
|
|
|
|
Buffer->Format = SoundFormat_PCM;
|
|
|
|
InWave->RawPCMData = NULL;
|
|
|
|
InWave->RemoveAudioResource();
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
/**
|
|
* Static function used to create an Audio buffer and dynamically upload procedural data to.
|
|
*
|
|
* @param InWave USoundWave to use as template and wave source
|
|
* @param AudioDevice audio device to attach created buffer to
|
|
* @return FSLESSoundBuffer pointer if buffer creation succeeded, NULL otherwise
|
|
*/
|
|
FSLESSoundBuffer* FSLESSoundBuffer::CreateProceduralBuffer(FSLESAudioDevice* AudioDevice, USoundWave* InWave)
|
|
{
|
|
FSLESSoundBuffer* Buffer = new FSLESSoundBuffer(AudioDevice);
|
|
|
|
// Setup any default information
|
|
Buffer->DecompressionState = NULL;
|
|
Buffer->AudioData = NULL;
|
|
Buffer->BufferSize = 0;
|
|
Buffer->Format = SoundFormat_PCMRT;
|
|
Buffer->NumChannels = InWave->NumChannels;
|
|
Buffer->SampleRate = InWave->SampleRate;
|
|
|
|
InWave->RawPCMData = NULL;
|
|
|
|
// No tracking of this resource as it's temporary
|
|
Buffer->ResourceID = 0;
|
|
InWave->ResourceID = 0;
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
/**
|
|
* Static function used to create a buffer.
|
|
*
|
|
* @param InWave USoundNodeWave to use as template and wave source
|
|
* @param AudioDevice audio device to attach created buffer to
|
|
* @param bIsPrecacheRequest Whether this request is for precaching or not
|
|
* @return FSLESSoundBuffer pointer if buffer creation succeeded, NULL otherwise
|
|
*/
|
|
|
|
FSLESSoundBuffer* FSLESSoundBuffer::Init( FSLESAudioDevice* AudioDevice ,USoundWave* InWave )
|
|
{
|
|
SCOPE_CYCLE_COUNTER( STAT_AudioResourceCreationTime );
|
|
|
|
// Can't create a buffer without any source data
|
|
if( InWave == NULL || InWave->NumChannels == 0 )
|
|
{
|
|
UE_LOG( LogAndroidAudio, Warning, TEXT("InitBuffer with Null sound data"));
|
|
return( NULL );
|
|
}
|
|
|
|
FAudioDeviceManager* AudioDeviceManager = GEngine->GetAudioDeviceManager();
|
|
FSLESSoundBuffer* Buffer = NULL;
|
|
|
|
EDecompressionType DecompressionType = InWave->DecompressionType;
|
|
|
|
UE_LOG(LogAndroidAudio, Verbose, TEXT("Init: Using decompression type: %d"), int32(DecompressionType));
|
|
|
|
switch( DecompressionType )
|
|
{
|
|
case DTYPE_Setup:
|
|
// Has circumvented precache mechanism - precache now
|
|
AudioDevice->Precache(InWave, true, false);
|
|
|
|
// if it didn't change, we will recurse forever
|
|
check(InWave->DecompressionType != DTYPE_Setup);
|
|
|
|
// Recall this function with new decompression type
|
|
return( Init( AudioDevice, InWave ) );
|
|
break;
|
|
|
|
case DTYPE_Native:
|
|
// Upload entire wav
|
|
if( InWave->ResourceID )
|
|
{
|
|
Buffer = static_cast<FSLESSoundBuffer*>(AudioDeviceManager->WaveBufferMap.FindRef(InWave->ResourceID));
|
|
}
|
|
|
|
if( Buffer == NULL )
|
|
{
|
|
Buffer = CreateNativeBuffer( AudioDevice, InWave );
|
|
}
|
|
break;
|
|
|
|
case DTYPE_RealTime:
|
|
// Always create a new buffer for streaming ogg vorbis data
|
|
Buffer = CreateQueuedBuffer( AudioDevice, InWave );
|
|
break;
|
|
|
|
case DTYPE_Procedural:
|
|
// New buffer for procedural data
|
|
Buffer = CreateProceduralBuffer(AudioDevice, InWave);
|
|
break;
|
|
|
|
case DTYPE_Invalid:
|
|
case DTYPE_Preview:
|
|
default:
|
|
UE_LOG( LogAndroidAudio, Warning, TEXT("Init Buffer on unsupported sound type name = %s type = %d"), *InWave->GetName(), int32(DecompressionType));
|
|
break;
|
|
}
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
|
|
/**
|
|
* Decompresses a chunk of compressed audio to the destination memory
|
|
*
|
|
* @param Destination Memory to decompress to
|
|
* @param bLooping Whether to loop the sound seamlessly, or pad with zeroes
|
|
* @return Whether the sound looped or not
|
|
*/
|
|
bool FSLESSoundBuffer::ReadCompressedData( uint8* Destination, bool bLooping )
|
|
{
|
|
ensure( DecompressionState);
|
|
return(DecompressionState->ReadCompressedData(Destination, bLooping, DecompressionState->GetStreamBufferSize() * NumChannels));
|
|
}
|
|
|
|
void FSLESSoundBuffer::Seek(const float SeekTime)
|
|
{
|
|
if (ensure(DecompressionState))
|
|
{
|
|
DecompressionState->SeekToTime(SeekTime);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the size for a real time/streaming buffer based on decompressor
|
|
*
|
|
* @return Size of buffer in bytes for a single channel or 0 if no decompression state
|
|
*/
|
|
int FSLESSoundBuffer::GetRTBufferSize(void)
|
|
{
|
|
return DecompressionState ? DecompressionState->GetStreamBufferSize() : MONO_PCM_BUFFER_SIZE;
|
|
}
|