You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Followed pattern set out by texture streaming so that each chunk of audio data resides in its own bulkdata struct. It is currently possible to split audio into chunks when SoundWaves are marked for streaming but there is no way of doing this exposed at present. Changed the parameters of FAudioDevice::GetRuntimeFormat so that the relevant SoundWave must be passed in, to allow for different formats for individual sounds/streaming options. USoundWave::FreeResources no longer resets the NumChannels as it is unnecessary and causes sounds to be unable to play after the OGG data is flushed when attempting to switch to OPUS. [CL 2099012 by Matthew Griffin in Main branch]
152 lines
4.0 KiB
C++
152 lines
4.0 KiB
C++
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
IOSAudioBuffer.cpp: Unreal IOSAudio buffer interface object.
|
|
=============================================================================*/
|
|
|
|
/*------------------------------------------------------------------------------------
|
|
Includes
|
|
------------------------------------------------------------------------------------*/
|
|
|
|
#include "IOSAudioDevice.h"
|
|
#include "AudioEffect.h"
|
|
#include "Engine.h"
|
|
#include "IAudioFormat.h"
|
|
|
|
/*------------------------------------------------------------------------------------
|
|
FIOSAudioSoundBuffer
|
|
------------------------------------------------------------------------------------*/
|
|
|
|
FIOSAudioSoundBuffer::FIOSAudioSoundBuffer(FIOSAudioDevice* InAudioDevice, ESoundFormat InSoundFormat):
|
|
FSoundBuffer(),
|
|
SoundFormat(InSoundFormat),
|
|
SampleData(NULL),
|
|
SampleRate(0),
|
|
CompressedBlockSize(0),
|
|
UncompressedBlockSize(0),
|
|
BufferSize(0)
|
|
{
|
|
;
|
|
}
|
|
|
|
FIOSAudioSoundBuffer::~FIOSAudioSoundBuffer(void)
|
|
{
|
|
if (bAllocationInPermanentPool)
|
|
{
|
|
UE_LOG(LogIOSAudio, Fatal, TEXT("Can't free resource '%s' as it was allocated in permanent pool."), *ResourceName);
|
|
}
|
|
|
|
FMemory::Free(SampleData);
|
|
SampleData = NULL;
|
|
}
|
|
|
|
int32 FIOSAudioSoundBuffer::GetSize(void)
|
|
{
|
|
int32 TotalSize = 0;
|
|
|
|
switch (SoundFormat)
|
|
{
|
|
case SoundFormat_LPCM:
|
|
case SoundFormat_ADPCM:
|
|
TotalSize = BufferSize;
|
|
break;
|
|
}
|
|
|
|
return TotalSize;
|
|
}
|
|
|
|
FIOSAudioSoundBuffer* FIOSAudioSoundBuffer::CreateNativeBuffer(FIOSAudioDevice* IOSAudioDevice, USoundWave* InWave)
|
|
{
|
|
FWaveModInfo WaveInfo;
|
|
|
|
InWave->InitAudioResource(IOSAudioDevice->GetRuntimeFormat(InWave));
|
|
if (!InWave->ResourceData || InWave->ResourceSize <= 0 || !WaveInfo.ReadWaveInfo(InWave->ResourceData, InWave->ResourceSize))
|
|
{
|
|
InWave->RemoveAudioResource();
|
|
return NULL;
|
|
}
|
|
|
|
uint32 UncompressedBlockSize = 0;
|
|
uint32 CompressedBlockSize = 0;
|
|
const uint32 PreambleSize = 7;
|
|
const uint32 BlockSize = *WaveInfo.pBlockAlign;
|
|
|
|
switch (*WaveInfo.pFormatTag)
|
|
{
|
|
case SoundFormat_ADPCM:
|
|
// (BlockSize - PreambleSize) * 2 (samples per byte) + 2 (preamble samples)
|
|
UncompressedBlockSize = (2 + (BlockSize - PreambleSize) * 2) * sizeof(int16);
|
|
CompressedBlockSize = BlockSize;
|
|
|
|
if ((WaveInfo.SampleDataSize % CompressedBlockSize) != 0)
|
|
{
|
|
InWave->RemoveAudioResource();
|
|
return NULL;
|
|
}
|
|
break;
|
|
|
|
case SoundFormat_LPCM:
|
|
break;
|
|
}
|
|
|
|
// Create new buffer
|
|
FIOSAudioSoundBuffer* Buffer = new FIOSAudioSoundBuffer(IOSAudioDevice, static_cast<ESoundFormat>(*WaveInfo.pFormatTag));
|
|
|
|
Buffer->NumChannels = InWave->NumChannels;
|
|
Buffer->SampleRate = InWave->SampleRate;
|
|
Buffer->UncompressedBlockSize = UncompressedBlockSize;
|
|
Buffer->CompressedBlockSize = CompressedBlockSize;
|
|
Buffer->BufferSize = WaveInfo.SampleDataSize;
|
|
|
|
Buffer->SampleData = static_cast<int16*>(FMemory::Malloc(Buffer->BufferSize));
|
|
FMemory::Memcpy(Buffer->SampleData, WaveInfo.SampleDataStart, Buffer->BufferSize);
|
|
|
|
IOSAudioDevice->TrackResource(InWave, Buffer);
|
|
InWave->RemoveAudioResource();
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
FIOSAudioSoundBuffer* FIOSAudioSoundBuffer::Init(FIOSAudioDevice* IOSAudioDevice, USoundWave* InWave)
|
|
{
|
|
// Can't create a buffer without any source data
|
|
if (InWave == NULL || InWave->NumChannels == 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
FIOSAudioSoundBuffer *Buffer = NULL;
|
|
|
|
switch (static_cast<EDecompressionType>(InWave->DecompressionType))
|
|
{
|
|
case DTYPE_Setup:
|
|
// Has circumvented pre-cache mechanism - pre-cache now
|
|
IOSAudioDevice->Precache(InWave, true, false);
|
|
|
|
// Recall this function with new decompression type
|
|
return Init(IOSAudioDevice, InWave);
|
|
|
|
case DTYPE_Native:
|
|
if (InWave->ResourceID)
|
|
{
|
|
Buffer = static_cast<FIOSAudioSoundBuffer*>(IOSAudioDevice->WaveBufferMap.FindRef(InWave->ResourceID));
|
|
}
|
|
|
|
if (!Buffer)
|
|
{
|
|
Buffer = CreateNativeBuffer(IOSAudioDevice, InWave);
|
|
}
|
|
break;
|
|
|
|
case DTYPE_Invalid:
|
|
case DTYPE_Preview:
|
|
case DTYPE_Procedural:
|
|
case DTYPE_RealTime:
|
|
default:
|
|
// Invalid will be set if the wave cannot be played
|
|
break;
|
|
}
|
|
|
|
return Buffer;
|
|
}
|