Files
UnrealEngineUWP/Engine/Source/Runtime/Android/AndroidAudio/Public/AndroidAudioDevice.h
Aaron McLeran a85d8ba0b5 Fixing android build
- accidentally checked these files in, reverted to previous version

[CL 2488651 by Aaron McLeran in Main branch]
2015-03-23 19:23:09 -04:00

307 lines
8.1 KiB
C++

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#pragma once
/*------------------------------------------------------------------------------------
Dependencies, helpers & forward declarations.
------------------------------------------------------------------------------------*/
class FSLESAudioDevice;
#include "Engine.h"
#include "SoundDefinitions.h"
#include "AudioEffect.h"
#include <SLES/OpenSLES.h>
#include "SLES/OpenSLES_Android.h"
DECLARE_LOG_CATEGORY_EXTERN(LogAndroidAudio,Log,VeryVerbose);
enum ESoundFormat
{
SoundFormat_Invalid,
SoundFormat_PCM,
SoundFormat_PCMRT
};
struct SLESAudioBuffer
{
uint8 *AudioData;
int32 AudioDataSize;
int32 ReadCursor;
};
/**
* OpenSLES implementation of FSoundBuffer, containing the wave data and format information.
*/
class FSLESSoundBuffer : public FSoundBuffer
{
public:
/**
* Constructor
*
* @param AudioDevice audio device this sound buffer is going to be attached to.
*/
FSLESSoundBuffer( FSLESAudioDevice* AudioDevice );
/**
* Destructor
*
* Frees wave data and detaches itself from audio device.
*/
~FSLESSoundBuffer( void );
/**
* Static function used to create a buffer and dynamically 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
*/
static FSLESSoundBuffer* CreateQueuedBuffer( FSLESAudioDevice* AudioDevice, USoundWave* Wave );
/**
* Static function used to create an Audio buffer and upload decompressed ogg vorbis data to.
*
* @param Wave 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
*/
static FSLESSoundBuffer* CreateNativeBuffer( FSLESAudioDevice* AudioDevice, USoundWave* Wave );
/**
* 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
*/
static FSLESSoundBuffer* CreateProceduralBuffer(FSLESAudioDevice* AudioDevice, USoundWave* Wave);
/**
* Static function used to create a buffer.
*
* @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
*/
static FSLESSoundBuffer* Init( FSLESAudioDevice* ,USoundWave* );
/**
* 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 ReadCompressedData( uint8* Destination, bool bLooping );
/**
* Returns the size of this buffer in bytes.
*
* @return Size in bytes
*/
int GetSize( void )
{
return( BufferSize );
}
/**
* Returns the size for a real time/streaming buffer based on decompressor
*/
int GetRTBufferSize(void);
/** Audio device this buffer is attached to */
FSLESAudioDevice* AudioDevice;
/** Data */
uint8* AudioData;
/** Number of bytes stored in OpenAL, or the size of the ogg vorbis data */
int BufferSize;
/** Sample rate of the ogg vorbis data - typically 44100 or 22050 */
int SampleRate;
/** Wrapper to handle the decompression of audio codecs */
class ICompressedAudioInfo* DecompressionState;
/** Format of data to be received by the source */
ESoundFormat Format;
};
/**
* OpenSLES implementation of FSoundSource, the interface used to play, stop and update sources
*/
class FSLESSoundSource : public FSoundSource
{
public:
/**
* Constructor
*
* @param InAudioDevice audio device this source is attached to
*/
FSLESSoundSource( class FAudioDevice* InAudioDevice );
/**
* Destructor
*/
~FSLESSoundSource( void );
/**
* Initializes a source with a given wave instance and prepares it for playback.
*
* @param WaveInstance wave instance being primed for playback
* @return TRUE if initialization was successful, FALSE otherwise
*/
virtual bool Init( FWaveInstance* WaveInstance );
/**
* Updates the source specific parameter like e.g. volume and pitch based on the associated
* wave instance.
*/
virtual void Update( void );
/**
* Plays the current wave instance.
*/
virtual void Play( void );
/**
* Stops the current wave instance and detaches it from the source.
*/
virtual void Stop( void );
/**
* Pauses playback of current wave instance.
*/
virtual void Pause( void );
/**
* Queries the status of the currently associated wave instance.
*
* @return TRUE if the wave instance/ source has finished playback and FALSE if it is
* currently playing or paused.
*/
virtual bool IsFinished( void );
/**
* Returns TRUE if source has finished playing
*/
bool IsSourceFinished( void );
/**
* Used to requeue a looping sound when the completion callback fires.
*
*/
void OnRequeueBufferCallback( SLAndroidSimpleBufferQueueItf InQueueInterface );
protected:
friend class FSLESAudioDevice;
FSLESSoundBuffer* Buffer;
FSLESAudioDevice* Device;
// OpenSL interface objects
SLObjectItf SL_PlayerObject;
SLPlayItf SL_PlayerPlayInterface;
SLAndroidSimpleBufferQueueItf SL_PlayerBufferQueue;
SLVolumeItf SL_VolumeInterface;
/** Which sound buffer should be written to next - used for double buffering. */
bool bStreamedSound;
/** A pair of sound buffers for real-time decoding */
SLESAudioBuffer AudioBuffers[2];
/** Set when we wish to let the buffers play themselves out */
bool bBuffersToFlush;
uint32 BufferSize;
int32 BufferInUse;
bool bHasLooped;
bool CreatePlayer();
void DestroyPlayer();
void ReleaseResources();
bool EnqueuePCMBuffer( bool bLoop);
bool EnqueuePCMRTBuffer( bool bLoop);
/** Decompress through FSLESSoundBuffer, or call USoundWave procedure to generate more PCM data. Returns true/false: did audio loop? */
bool ReadMorePCMData(const int32 BufferIndex);
/** Handle obtaining more data for procedural USoundWaves. Always returns false for convenience. */
bool ReadProceduralData(const int32 BufferIndex);
};
/**
* OpenSLES implementation of an Unreal audio device.
*/
class FSLESAudioDevice : public FAudioDevice
{
public:
FSLESAudioDevice() {}
virtual ~FSLESAudioDevice() {}
virtual FName GetRuntimeFormat(USoundWave* SoundWave) override
{
if (SoundWave->CompressionName.IsNone())
{
#if WITH_OGGVORBIS
static FName NAME_OGG(TEXT("OGG")); //@todo android: probably not ogg
return NAME_OGG;
#else
static FName NAME_ADPCM(TEXT("ADPCM"));
return NAME_ADPCM;
#endif
}
return SoundWave->CompressionName;
}
virtual bool HasCompressedAudioInfoClass(USoundWave* SoundWave) override;
virtual bool SupportsRealtimeDecompression() const override
{
return true;
}
virtual class ICompressedAudioInfo* CreateCompressedAudioInfo(USoundWave* SoundWave) override;
/** Starts up any platform specific hardware/APIs */
virtual bool InitializeHardware() override;
/** Check if any background music or sound is playing through the audio device */
virtual bool IsExernalBackgroundSoundActive() override;
protected:
virtual FSoundSource* CreateSoundSource() override;
/**
* Tears down audio device by stopping all sounds, removing all buffers, destroying all sources, ... Called by both Destroy and ShutdownAfterError
* to perform the actual tear down.
*/
void Teardown( void );
// Variables.
/** The name of the OpenSL Device to open - defaults to "Generic Software" */
FString DeviceName;
// SL specific
// engine interfaces
SLObjectItf SL_EngineObject;
SLEngineItf SL_EngineEngine;
SLObjectItf SL_OutputMixObject;
SLint32 SL_VolumeMax;
SLint32 SL_VolumeMin;
friend class FSLESSoundBuffer;
friend class FSLESSoundSource;
};