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); FAudioDeviceManager* AudioDeviceManager = GEngine->GetAudioDeviceManager(); check(AudioDeviceManager != nullptr); AudioDeviceManager->TrackResource(InWave, Buffer); InWave->RemoveAudioResource(); return Buffer; }
FALSoundBuffer* FALSoundBuffer::CreateNativeBuffer( FALAudioDevice* AudioDevice, USoundWave* Wave) { SCOPE_CYCLE_COUNTER( STAT_AudioResourceCreationTime ); // This code is not relevant for now on HTML5 but adding this for consistency with other platforms. // Check to see if thread has finished decompressing on the other thread if (Wave->AudioDecompressor != NULL) { Wave->AudioDecompressor->EnsureCompletion(); // Remove the decompressor delete Wave->AudioDecompressor; Wave->AudioDecompressor = NULL; } // Can't create a buffer without any source data if( Wave == NULL || Wave->NumChannels == 0 ) { return( NULL ); } FWaveModInfo WaveInfo; Wave->InitAudioResource(AudioDevice->GetRuntimeFormat(Wave)); FALSoundBuffer* Buffer = NULL; // Find the existing buffer if any if( Wave->ResourceID ) { Buffer = static_cast<FALSoundBuffer*>(AudioDevice->WaveBufferMap.FindRef( Wave->ResourceID )); } if( Buffer == NULL ) { // Create new buffer. Buffer = new FALSoundBuffer( AudioDevice ); alGenBuffers( 1, Buffer->BufferIds ); AudioDevice->alError( TEXT( "RegisterSound" ) ); AudioDevice->TrackResource(Wave, Buffer); Buffer->InternalFormat = AudioDevice->GetInternalFormat( Wave->NumChannels ); Buffer->NumChannels = Wave->NumChannels; Buffer->SampleRate = Wave->SampleRate; if (Wave->RawPCMData) { // upload it Buffer->BufferSize = Wave->RawPCMDataSize; alBufferData( Buffer->BufferIds[0], Buffer->InternalFormat, Wave->RawPCMData, Wave->RawPCMDataSize, Buffer->SampleRate ); // Free up the data if necessary if( Wave->bDynamicResource ) { FMemory::Free( Wave->RawPCMData ); Wave->RawPCMData = NULL; Wave->bDynamicResource = false; } } else { // get the raw data uint8* SoundData = ( uint8* )Wave->RawData.Lock( LOCK_READ_ONLY ); // it's (possibly) a pointer to a wave file, so skip over the header int SoundDataSize = Wave->RawData.GetBulkDataSize(); // is there a wave header? FWaveModInfo WaveInfo; if (WaveInfo.ReadWaveInfo(SoundData, SoundDataSize)) { // if so, modify the location and size of the sound data based on header SoundData = WaveInfo.SampleDataStart; SoundDataSize = WaveInfo.SampleDataSize; } // let the Buffer know the final size Buffer->BufferSize = SoundDataSize; // upload it alBufferData( Buffer->BufferIds[0], Buffer->InternalFormat, SoundData, Buffer->BufferSize, Buffer->SampleRate ); // unload it Wave->RawData.Unlock(); } if( AudioDevice->alError( TEXT( "RegisterSound (buffer data)" ) ) || ( Buffer->BufferSize == 0 ) ) { Buffer->InternalFormat = 0; } if( Buffer->InternalFormat == 0 ) { UE_LOG ( LogAudio, Log,TEXT( "Audio: sound format not supported for '%s' (%d)" ), *Wave->GetName(), Wave->NumChannels ); delete Buffer; Buffer = NULL; } } return Buffer; }