Beispiel #1
1
/**
 * Static function used to create an OpenAL 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 FXAudio2SoundBuffer pointer if buffer creation succeeded, NULL otherwise
 */
FXAudio2SoundBuffer* FXAudio2SoundBuffer::CreateNativeBuffer( FXAudio2Device* XAudio2Device, USoundWave* Wave )
{
	// 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;
	}

	// Create new buffer.
	FXAudio2SoundBuffer* Buffer = new FXAudio2SoundBuffer( XAudio2Device, SoundFormat_PCM );

	// Take ownership the PCM data
	Buffer->PCM.PCMData = Wave->RawPCMData;
	Buffer->PCM.PCMDataSize = Wave->RawPCMDataSize;

	Wave->RawPCMData = NULL;

	// Keep track of associated resource name.
	Buffer->InitWaveFormatEx( WAVE_FORMAT_PCM, Wave, true );

	FAudioDeviceManager* AudioDeviceManager = GEngine->GetAudioDeviceManager();
	check(AudioDeviceManager != nullptr);
	AudioDeviceManager->TrackResource(Wave, Buffer);

	Wave->RemoveAudioResource();

	return( Buffer );
}
Beispiel #2
1
/**
 * Static function used to create an OpenAL buffer and upload raw PCM data to.
 *
 * @param InWave		USoundWave to use as template and wave source
 * @param AudioDevice	audio device to attach created buffer to
 * @return FXAudio2SoundBuffer pointer if buffer creation succeeded, NULL otherwise
 */
FXAudio2SoundBuffer* FXAudio2SoundBuffer::CreatePreviewBuffer( FXAudio2Device* XAudio2Device, USoundWave* Wave, FXAudio2SoundBuffer* Buffer )
{
	FAudioDeviceManager* AudioDeviceManager = GEngine->GetAudioDeviceManager();
	check(AudioDeviceManager != nullptr);

	if (Buffer)
	{
		AudioDeviceManager->FreeBufferResource(Buffer);
	}

	// Create new buffer.
	Buffer = new FXAudio2SoundBuffer( XAudio2Device, SoundFormat_PCMPreview );

	// Take ownership the PCM data
	Buffer->PCM.PCMData = Wave->RawPCMData;
	Buffer->PCM.PCMDataSize = Wave->RawPCMDataSize;

	Wave->RawPCMData = NULL;

	// Copy over whether this data should be freed on delete
	Buffer->bDynamicResource = Wave->bDynamicResource;

	Buffer->InitWaveFormatEx( WAVE_FORMAT_PCM, Wave, true );

	AudioDeviceManager->TrackResource(Wave, Buffer);

	return( Buffer );
}
Beispiel #3
1
/**
 * Static function used to create an OpenAL buffer and upload raw PCM data to.
 *
 * @param InWave		USoundWave to use as template and wave source
 * @param AudioDevice	audio device to attach created buffer to
 * @return FCoreAudioSoundBuffer pointer if buffer creation succeeded, NULL otherwise
 */
FCoreAudioSoundBuffer* FCoreAudioSoundBuffer::CreatePreviewBuffer( FCoreAudioDevice* CoreAudioDevice, USoundWave* Wave, FCoreAudioSoundBuffer* Buffer )
{
    FAudioDeviceManager* AudioDeviceManager = GEngine->GetAudioDeviceManager();
    check(AudioDeviceManager != nullptr);
    
	if (Buffer)
	{
		AudioDeviceManager->FreeBufferResource( Buffer );
	}
	
	// Create new buffer.
	Buffer = new FCoreAudioSoundBuffer( CoreAudioDevice, SoundFormat_PCMPreview );
	
	// Take ownership the PCM data
	Buffer->PCMData = Wave->RawPCMData;
	Buffer->PCMDataSize = Wave->RawPCMDataSize;
	
	Wave->RawPCMData = NULL;
	
	// Copy over whether this data should be freed on delete
	Buffer->bDynamicResource = Wave->bDynamicResource;
	
	Buffer->InitAudioStreamBasicDescription( kAudioFormatLinearPCM, Wave, true );
	
	AudioDeviceManager->TrackResource( Wave, Buffer );
	
	return( Buffer );
}
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 );
	}

	Wave->InitAudioResource(AudioDevice->GetRuntimeFormat(Wave));

	FALSoundBuffer* Buffer = NULL;
	FAudioDeviceManager* AudioDeviceManager = GEngine->GetAudioDeviceManager();
	check(AudioDeviceManager != nullptr);

	// Find the existing buffer if any
	if( Wave->ResourceID )
	{
		Buffer = static_cast<FALSoundBuffer*>(AudioDeviceManager->WaveBufferMap.FindRef(Wave->ResourceID));
	}

	if( Buffer == NULL )
	{
		// Create new buffer.
		Buffer = new FALSoundBuffer( AudioDevice );

		alGenBuffers( 1, Buffer->BufferIds );

		AudioDevice->alError( TEXT( "RegisterSound" ) );

		AudioDeviceManager->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;
}