Files
UnrealEngineUWP/Engine/Source/Runtime/Android/AndroidAudio/Private/AndroidAudioDevice.cpp
Rolando Caloca 1a30325d6f Copying //UE4/Dev-RenderPlat-Staging@9551419 to //UE4/Main
#rb none
#rnx

[CL 9551447 by Rolando Caloca in Main branch]
2019-10-11 15:33:31 -04:00

225 lines
5.9 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
/*------------------------------------------------------------------------------------
Audio includes.
------------------------------------------------------------------------------------*/
#include "AndroidAudioDevice.h"
#include "VorbisAudioInfo.h"
#include "ADPCMAudioInfo.h"
#include "AudioPluginUtilities.h"
DEFINE_LOG_CATEGORY(LogAndroidAudio);
class FSLESAudioDeviceModule : public IAudioDeviceModule
{
public:
/** Creates a new instance of the audio device implemented by the module. */
virtual FAudioDevice* CreateAudioDevice() override
{
return new FSLESAudioDevice;
}
};
IMPLEMENT_MODULE(FSLESAudioDeviceModule, AndroidAudio );
DEFINE_STAT(STAT_AudioAndroidSourcePlayerCreateTime);
DEFINE_STAT(STAT_AudioAndroidSourcePlayerRealize);
/*------------------------------------------------------------------------------------
UALAudioDevice constructor and UObject interface.
------------------------------------------------------------------------------------*/
void FSLESAudioDevice::Teardown( void )
{
// Flush stops all sources and deletes all buffers so sources can be safely deleted below.
Flush( NULL );
// Destroy all sound sources
for( int32 i = 0; i < Sources.Num(); i++ )
{
delete Sources[ i ];
}
UE_LOG( LogAndroidAudio, Warning, TEXT("OpenSLES Tearing Down HW"));
// Teardown OpenSLES..
// Destroy the SLES objects in reverse order of creation:
if (SL_OutputMixObject)
{
(*SL_OutputMixObject)->Destroy(SL_OutputMixObject);
SL_OutputMixObject = NULL;
}
if (SL_EngineObject)
{
(*SL_EngineObject)->Destroy(SL_EngineObject);
SL_EngineObject = NULL;
SL_EngineEngine = NULL;
}
}
/*------------------------------------------------------------------------------------
UAudioDevice Interface.
------------------------------------------------------------------------------------*/
/**
* Initializes the audio device and creates sources.
*
* @warning:
*
* @return TRUE if initialization was successful, FALSE otherwise
*/
bool FSLESAudioDevice::InitializeHardware(void)
{
UE_LOG(LogAndroidAudio, Warning, TEXT("SL Entered Init HW"));
SLresult result;
UE_LOG(LogAndroidAudio, Warning, TEXT("OpenSLES Initializing HW"));
SLEngineOption EngineOption[] = { {(SLuint32)SL_ENGINEOPTION_THREADSAFE, (SLuint32)SL_BOOLEAN_TRUE} };
// create engine
result = slCreateEngine(&SL_EngineObject, 1, EngineOption, 0, NULL, NULL);
//check(SL_RESULT_SUCCESS == result);
if (SL_RESULT_SUCCESS != result)
{
UE_LOG(LogAndroidAudio, Error, TEXT("Engine create failed %d"), int32(result));
}
// realize the engine
result = (*SL_EngineObject)->Realize(SL_EngineObject, SL_BOOLEAN_FALSE);
check(SL_RESULT_SUCCESS == result);
// get the engine interface, which is needed in order to create other objects
result = (*SL_EngineObject)->GetInterface(SL_EngineObject, SL_IID_ENGINE, &SL_EngineEngine);
check(SL_RESULT_SUCCESS == result);
// create output mix, with environmental reverb specified as a non-required interface
result = (*SL_EngineEngine)->CreateOutputMix(SL_EngineEngine, &SL_OutputMixObject, 0, NULL, NULL);
check(SL_RESULT_SUCCESS == result);
// realize the output mix
result = (*SL_OutputMixObject)->Realize(SL_OutputMixObject, SL_BOOLEAN_FALSE);
check(SL_RESULT_SUCCESS == result);
UE_LOG(LogAndroidAudio, Warning, TEXT("OpenSLES Initialized"));
// Initialize sources
const int32 MaxSoundSources = GetMaxSources();
for (int32 i = 0; i < MaxSoundSources; i++)
{
FSLESSoundSource* Source = new FSLESSoundSource(this);
Sources.Add(Source);
FreeSources.Add(Source);
}
UE_LOG(LogAndroidAudio, Warning, TEXT("OpenSLAudioDevice: Allocated %i sources"), MaxSoundSources);
// Set up a default (nop) effects manager
Effects = new FAudioEffectsManager(this);
return true;
}
FSoundSource* FSLESAudioDevice::CreateSoundSource()
{
return new FSLESSoundSource(this);
}
bool FSLESAudioDevice::HasCompressedAudioInfoClass(USoundWave* SoundWave)
{
#if WITH_OGGVORBIS
if(SoundWave->bStreaming)
{
return true;
}
static FName NAME_OGG(TEXT("OGG"));
if (SoundWave->HasCompressedData(NAME_OGG))
{
return true;
}
#endif
if(SoundWave->bStreaming)
{
return true;
}
static FName NAME_ADPCM(TEXT("ADPCM"));
if (SoundWave->HasCompressedData(NAME_ADPCM))
{
return true;
}
return false;
}
class ICompressedAudioInfo* FSLESAudioDevice::CreateCompressedAudioInfo(USoundWave* SoundWave)
{
if (SoundWave->IsSeekableStreaming())
{
return new FADPCMAudioInfo();
}
#if WITH_OGGVORBIS
static FName NAME_OGG(TEXT("OGG"));
if (SoundWave->bStreaming || SoundWave->HasCompressedData(NAME_OGG))
{
return new FVorbisAudioInfo();
}
#endif
static FName NAME_ADPCM(TEXT("ADPCM"));
if (SoundWave->bStreaming || SoundWave->HasCompressedData(NAME_ADPCM))
{
return new FADPCMAudioInfo();
}
return nullptr;
}
FAudioPlatformSettings FSLESAudioDevice::GetPlatformSettings() const
{
return FAudioPlatformSettings::GetPlatformSettings(FPlatformProperties::GetRuntimeSettingsClassName());
}
/** Check if any background music or sound is playing through the audio device */
bool FSLESAudioDevice::IsExernalBackgroundSoundActive()
{
#if USE_ANDROID_JNI
extern bool AndroidThunkCpp_IsMusicActive();
return AndroidThunkCpp_IsMusicActive();
#else
return false;
#endif
}
FAndroidSoundBufferNotification& FAndroidSoundBufferNotification::Get()
{
static FAndroidSoundBufferNotification Instance;
return Instance;
}
FDelegateHandle FAndroidSoundBufferNotification::AddDelegate(const FOnAndroidSoundBufferEnqueued::FDelegate& InNewDelegate)
{
FScopeLock Lock(&DelegateLock);
return InternalDelegate.Add(InNewDelegate);
}
void FAndroidSoundBufferNotification::RemoveDelegate(const FDelegateHandle& Handle)
{
FScopeLock Lock(&DelegateLock);
InternalDelegate.Remove(Handle);
}
void FAndroidSoundBufferNotification::Broadcast(const void* AudioData, int32 DataSize, int32 SampleRate, int32 NumChannels)
{
FScopeLock Lock(&DelegateLock);
InternalDelegate.Broadcast(AudioData, DataSize, SampleRate, NumChannels);
}